Докуметация Cтарт Статьи Форум Лента Вход
Не официальное русскоязычное сообщество

Отладка

Опубликованно: 03.06.2017, 16:31
Последняя редакция, Andry: 03.09.2017 21:36

Когда вы имеете дело со сложными функциями игрового движка, такими как анимация или физика, полезно получить обратную связь от движка, как он интерпретирует текущее состояние. Является ли форма столкновения физического объекта на самом деле такой, как вы думаете? Является ли скелет анимированного персонажа движущимся так, как вы думаете, это должно быть? В этом документе показано, как активировать визуальные помощники отладки.

Что делать, если вы просто хотите быстро написать код, который загружает модели и выводит их в исходное положение? Возможно, вам не захочется искать образец модели, конвертировать ее, добавлять источники света и загружать материалы. Вместо этого вы используете «простые формы» и «незатененный материал или каркас: нет модели, нет источника света, нет материалов, необходимых для их просмотра на тестовой сцене.

Если у вас когда-либо возникли проблемы с объектами, появляющимися в неправильном месте, с неправильным масштабом или неправильной ориентацией, просто присоедините фигуры отладки к вашей сцене, чтобы иметь точку отсчета в 3D-пространстве — точно так же, как гигантская линейка. Если ваш код правильно размещает фигуры отладки, но модели остаются невидимыми, когда вы применяете к ним один и тот же код, вы понимаете, что проблема должна быть либо в модели (где расположена ее координата?), Либо в свете (слишком темный? Слишком яркий ? Отсутствует?), Или материал модели (отсутствует?), А не размещающий код.

Вот несколько разных фигур отладки:

debug-shapes

Отладочные фигуры

Координатные оси(Coordinate Axes)

Координатные оси (com.jme3.scene.debug.Arrow) помогут вам увидеть основные направления (X, Y, Z) из их центральной точки. Масштабируйте стрелки, чтобы использовать их как линейку на определенную длину.

private void attachCoordinateAxes(Vector3f pos){
  Arrow arrow = new Arrow(Vector3f.UNIT_X);
  arrow.setLineWidth(4); // сделать стрелку толще
  putShape(arrow, ColorRGBA.Red).setLocalTranslation(pos);

  arrow = new Arrow(Vector3f.UNIT_Y);
  arrow.setLineWidth(4); // сделать стрелку толще
  putShape(arrow, ColorRGBA.Green).setLocalTranslation(pos);

  arrow = new Arrow(Vector3f.UNIT_Z);
  arrow.setLineWidth(4); // сделать стрелку толще
  putShape(arrow, ColorRGBA.Blue).setLocalTranslation(pos);
}

private Geometry putShape(Mesh shape, ColorRGBA color){
  Geometry g = new Geometry("coordinate axis", shape);
  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  mat.getAdditionalRenderState().setWireframe(true);
  mat.setColor("Color", color);
  g.setMaterial(mat);
  rootNode.attachChild(g);
  return g;
}

Каркас Сетки(Wireframe Grid)

Используйте каркас сетки (com.jme3.scene.debug.Grid) как линейку или простой пол.

private Geometry attachGrid(Vector3f pos, float size, ColorRGBA color){
  Geometry g = new Geometry("wireframe grid", new Grid(size, size, 0.2f) );
  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  mat.getAdditionalRenderState().setWireframe(true);
  mat.setColor("Color", color);
  g.setMaterial(mat);
  g.center().move(pos);
  rootNode.attachChild(g);
  return g;
}

Каркас Куба(Wireframe Cube)

Используйте каркас куба (com.jme3.scene.debug.WireBox) в качестве объекта ожидания, чтобы проверить, правильно ли загружаются ваши модели, местоположение или ориентация загружаемых моделей.

public Geometry attachWireBox(Vector3f pos, float size, ColorRGBA color){
  Geometry g = new Geometry("wireframe cube", new WireBox(size, size, size));
  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  mat.getAdditionalRenderState().setWireframe(true);
  mat.setColor("Color", color);
  g.setMaterial(mat);
  g.setLocalTranslation(pos);
  rootNode.attachChild(g);
  return g;
}

Каркас Сферы(Wireframe Sphere)

Используйте каркас сферы (com.jme3.scene.debug.WireSphere) в качестве объекта ожидания, чтобы проверить, правильно ли загружаются ваши модели, местоположение или ориентация загружаемых моделей.

private Geometry attachWireSphere(Vector3f pos, float size, ColorRGBA color){
  Geometry g = new Geometry("wireframe sphere", new WireSphere(size));
  Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
  mat.getAdditionalRenderState().setWireframe(true);
  mat.setColor("Color", color);
  g.setMaterial(mat);
  g.setLocalTranslation(pos);
  rootNode.attachChild(g);
  return g;
}

Каркас для Физики

Вы можете отображать каркасы (обычно невидимой) фигур столкновения вокруг всех объектов с физикой. Используйте это для отладки при анализе неожиданного поведения. Не работает с физикой DETACHED, пожалуйста, переключитесь на PARALLEL или SEQUENTIAL для отладки.

physicsSpace.enableDebug(assetManager);

При отладке включаются цвета используемые для обозначения различных типов физических объектов:

  • Пурпурная проволочная сетка указывает на активное твердое тело.
  • Синяя проволочная сетка указывает на твердое тело, которое является новым или неактивным.
  • Желтая проволочная сетка указывает на призрак.
  • Две зеленые стрелки указывают на соединение.
  • Розовая сетка указывает персонажа.

Каркас для анимации

Создание скелета, видимого внутри анимированных моделей, может быть удобно для отладки анимации. Объектом control является AnimControl, player — загруженная модель.

     SkeletonDebugger skeletonDebug =
         new SkeletonDebugger("skeleton", control.getSkeleton());
     Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
     mat.setColor("Color", ColorRGBA.Green);
     mat.getAdditionalRenderState().setDepthTest(false);
     skeletonDebug.setMaterial(mat);
     player.attachChild(skeletonDebug);

Пример: переключение каркаса на модель

Мы предполагаем, что вы загрузили модель с материалом mat.

Затем вы можете добавить переключатель для включения и выключения каркаса модели, например:

  1. Создайте триггер клавиши ввода, который будет переключается между двумя материалами: например. Мы переключаемся при нажатии клавиши Т:
        inputManager.addMapping("toggle wireframe", new KeyTrigger(KeyInput.KEY_T));
        inputManager.addListener(actionListener, "toggle wireframe");
  2. Теперь добавьте действие toggle к слушателю действий
      private ActionListener actionListener = new ActionListener() {
        @Override
        public void onAction(String name, boolean pressed, float tpf) {
          // toggle каркаса
          if (name.equals("toggle wireframe") && !pressed) {
            wireframe = !wireframe; // toggle boolean
            mat.getAdditionalRenderState().setWireframe(wireframe);
          }
          // иначе ... другие тесты ввода.
        }
      };
  3. Кроме того, вы можете перемещаться по всей сцене и переключаться так для всех объектов геометрий там, если вы не хотите создавать новый SceneProcessor
      private ActionListener actionListener = new ActionListener() {
        boolean wireframe = false;
    
        @Override
        public void onAction(String name, boolean pressed, float tpf) {
          // toggle каркаса
          if (name.equals("toggle wireframe") && !pressed) {
            wireframe = !wireframe; // toggle boolean
            rootNode.depthFirstTraversal(new SceneGraphVisitor() {
              public void visit(Spatial spatial) {
                if (spatial instanceof Geometry)
                  ((Geometry)spatial).getMaterial().getAdditionalRenderState().setWireframe(wireframe);
              }
            });
          }
          // иначе ... другие тесты ввода.
        }
      };
    
Чтобы установить ширину линии отображения каркаса, используйте mesh.setLineWidth(lineWidth). Ширина линии по умолчанию — 1.

Пример: переключение каркаса сцены

Чтобы отображать каркас всей сцены вместо одного материала за раз, сначала создайте следующий Scene Processor

public class WireProcessor implements SceneProcessor {

    RenderManager renderManager;
    Material wireMaterial;

    public WireProcessor(AssetManager assetManager) {
        wireMaterial = new Material(assetManager, "/Common/MatDefs/Misc/Unshaded.j3md");
        wireMaterial.setColor("Color", ColorRGBA.Blue);
        wireMaterial.getAdditionalRenderState().setWireframe(true);
    }

    public void initialize(RenderManager rm, ViewPort vp) {
        renderManager = rm;
    }

    public void reshape(ViewPort vp, int w, int h) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public boolean isInitialized() {
        return renderManager != null;
    }

    public void preFrame(float tpf) {
    }

    public void postQueue(RenderQueue rq) {
        renderManager.setForcedMaterial(wireMaterial);
    }

    public void postFrame(FrameBuffer out) {
        renderManager.setForcedMaterial(null);
    }

    public void cleanup() {
        renderManager.setForcedMaterial(null);
    }

}

Затем присоедините Scene Processor к GUI Viewport.

getViewPort().addProcessor(new WireProcessor());

Смотрите так же

  • Spatial— если вы не видите некоторые spatial, вы можете изменить поведение отсечения, чтобы идентифицировать проблемы (например, пользовательские сетки отображаемые с внутренней стороны)

Переведено для jmonkeyengine.ru, оригинал
Автор перевода: Andry

Добавить комментарий

jMonkeyEngine.ru © 2017. Все права сохранены.