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

Траверс SceneGraph

Опубликованно: 06.05.2017, 22:38
Последняя редакция, Andry: 06.05.2017 22:51

Вы можете выполнить поиск по всему графику сцены и выполнить поиск отдельных Spatial объектов (узлов и геометрий) по специальным критериям, таким как имя Spatial объекта или класс Spatial объектов, пользовательские данные Spatial или элементы Control Spatial. Вы делаете это, когда хотите изменить найденные узлы (переместить их, вызвать метод и.т.д.), Но у вас нет локальной переменной для них.

Примеры использования

Пример 1:

  1. Вы создали процедурный сценарий с большим количеством динамически генерируемых элементов.
  2. Вы хотите найти конкретный Spatial в постоянно меняющихся условиях и изменять его состояние.

Пример 2:

  1. Вы создали статичную сцену в jMonkeyEngine SDK и экспортировали ее как .j3o-файл.
    Сцена также содержит интерактивные объекты, например эмиттер частиц, spatial данные с пользовательскими данными или spatial объекты с пользовательскими элементами Control.
  2. Вы загружаете сцену .j3o, используя assetManager.
  3. Вы хотите взаимодействовать с одним из загруженных элементов интерактивной сцены в вашем Java-коде.
    Например, вы хотите вызвать emitAllParticles() на эмиттер частиц. Или вы хотите найти все геометрии NPC с пользовательским CivilianControl и вызвать метод CivilianControl, который заставит их начать действовать.

В этом случае вы можете использовать SceneGraphVisitorAdapter для идентификации и доступа к рассматриваемым Spatial.

Пример кода

Для каждого поиска вы создаете com.jme3.scene.SceneGraphVisitorAdapter, который определяет ваши критерии поиска и что вы хотите сделать с найденными Spatials. Затем вы вызываете метод depthFirstTraversal (посетитель) или breadthFirstTraversal (посетитель) Spatial (например, rootNode или, лучше, подузел), чтобы начать поиск.

SceneGraphVisitor visitor = new SceneGraphVisitor() {

  @Override
  public void visit(Spatial spat) {
    // Критерием поиска может быть класс Control:
    MyControl control = spatial.getControl(MyControl.class);
    if (control != null) {
      // у вас есть доступ к любому методу, например. имя.
      System.out.println("Instance of " + control.getClass().getName()
                       + " found for " + spatial.getName());
    }
  }

};

// Теперь сканируйте дерево сначала в глубину ...
rootNode.depthFirstTraversal(visitor);
// ... или отсканируйте его в ширину.
rootNode.breadthFirstTraversal(visitor);

Какой из этих двух методов работает быстрее, зависит от того, как вы спроектировали сканер и какой древовидный элемент вы ищете. Если вы ищете одну единственную геометрию, которая является «листом дерева», а затем прекратите поиск, то в глубину может быть быстрее. Если вы ищете узел группирования высокого уровня, в ширину может быть быстрее.

Выбор в глубину в ширину также влияет на порядок, в котором найденные элементы возвращаются (сначала потомки или родители). Если вы хотите изменить пользовательские данные, унаследованные от родительского узла (например, преобразования), порядок применения важен, потому что побочные эффекты складываются.

Класс SceneGraphVisitorAdapter можно использовать для отдельного сканирования для геометрий и узлов.

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

  • Граф сцены
  • Spatial

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

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

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