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

jMonkeyEngine SDK — Сцена

Опубликованно: 17.10.2017, 7:34
Последняя редакция, Andry: 17.10.2017 22:12

Чтобы уменьшить системные издержки, jMonkeyEngine SDK Core поставляет одну scene/jme3 приложения, которая используется совместно с плагинами. Кроме того, есть SceneExplorer, который показывает визуальное представление графа сцены и свойств его объектов в плагинах.

Как получить доступ к Сцене

Существует несколько способов взаимодействия вашего плагина со сценой:

  • Это прослушивать выбор spatials/объекты и предлагает опции для них
  • Это запрашивает всю сцену для себя и загружает/упорядочивает содержимое в ней (например, редактор ландшафта или плагин анимации модели).

Слушатель для выбора узла

В jMonkeyEngine SDK все объекты завернуты в узлы NetBeans «Nodes» (иначе, чем jme Nodes!). Такие узлы могут иметь свойства и значки и могут отображаться и выбираться в пользовательском интерфейсе jMonkeyEngine SDK. SceneExplorer показывает дерево узлов, которые обертывают Spatials текущей сцены и позволяют управлять их свойствами при выборе. Например, jME Spatial обернут узлом JmeSpatial. Одним из преимуществ этих узлов является то, что можно манипулировать свойствами Spatials непосредственно из потока AWT.

Чтобы прослушать текущий выбор, выполните org.openide.util.LookupListener и зарегистрируйтесь следующим образом:

private final Result<JmeSpatial> result;

//метод регистрации слушателя
private void registerListener(){
    result = Utilities.actionsGlobalContext().lookupResult(JmeSpatial.class);
    result.addLookupListener(this);
}

//реализуем org.openide.util.LookupListener (вызывается из потока AWT)
public void resultChanged(LookupEvent ev) {
    Collection<JmeSpatial> items = (Collection<JmeSpatial>) result.allInstances();
    for (JmeSpatial jmeSpatial : items) {
        //Используя свойства JmeSpatials, вы можете изменить spatial напрямую из потока AWT:
        jmeSpatial.getPropertySets()[0].setValue("Local Translation", Vector3f.ZERO);
        return;
    }
}

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

//получить "real" spatial класс из JmeNode
for (JmeSpatial jmeSpatial : items) {
    //spatial хранится внутри JmeSpatials "Lookup", общий контейнер для Objects
    final Spatial realSpatial = jmeSpatial.getLookup().lookup(Spatial.class);
    //используйте Callable для выполнения в потоке рендеринга:
    SceneApplication.getApplication().enqueue(new Callable() {
        public Object call() throws Exception {
            realSpatial.setLocalTranslation(Vector3f.ZERO);
            return null;
        }
    });
    return;
}

Запрос сцены

Если ваш плагин хочет использовать сцену для себя, сначала нужно реализовать SceneListener и зарегистрироваться в сцене, а затем отправить SceneRequest в SceneApplication. Когда SceneRequest одобрен и текущая Scene закрыта, SceneListener (ваш класс) вызывается со своим собственным SceneRequest в качестве параметра. Когда другой плагин отправляет SceneRequest, вам также сообщается, что ваш RootNode был удален из Scene, и вы больше не контролируете его. Вы также можете подключиться к SceneRequests других плагинов, чтобы узнать, если/когда они активированы для отображения дополнительных плагинов для этого плагина.

Объект SceneRequest должен содержать несколько вещей. То, что вы должны предоставить, — это jme «Node», обернутый в объект «JmeNode». Это ваш rootNode, который вы используете для отображения и создания вашей сцены. Как только вы получите контроль над сценой, вам придется самостоятельно управлять камерой и.т.д.

com.jme3.scene.Node rootNode = new com.jme3.scene.Node("MyRootNode");

private void registerSceneListener(){
    SceneApplication.getApplication().addSceneListener(this);
}

private void requestScene(){
    //создадим jmeNode из rootNode с помощью NodeUtility
    JmeNode jmeNode = NodeUtility.createNode(rootNode);
    //создадим запрос сцены
    SceneRequest request=new SceneRequest(this, jmeNode, assetManager);
    //запросим сцену
    SceneApplication.getApplication().openScene(request);
}

//реализуем SceneListener (вызывается из потока AWT)
public void sceneOpened(SceneRequest request){
    //check if its our request
    if (request.getRequester() == this) {
        //теперь у нас есть сцена, любые операции на сцене должны выполняться через Callables
    }
}

public void sceneClosed(SceneRequest request) {
    if (request.getRequester() == this) {
        //мы должны закрыть сцену, любые операции на сцене должны выполняться через Callables
    }
}

Поддержка Undo/Redo(Отменить/повторить)

jMonkeyEngine SDK имеет глобальную очередь отмены/повтора, которая активирует кнопки отмены/повтора. Чтобы использовать её в своем TopComponent, добавьте следующий метод:

@Override
public UndoRedo getUndoRedo() {
return Lookup.getDefault().lookup(SceneUndoRedoManager.class);
}

Чтобы добавить событие отмены/повтора, которое изменяет объекты в Scenegraph, существует специальная версия AbstractUndoableEdit, которая выполняет вызовы отмены/повтора в потоке сцены. Просто реализуйте этот класс и добавьте его в очередь следующим образом:

Lookup.getDefault().lookup(SceneUndoRedoManager.class).addEdit(this, new AbstractUndoableSceneEdit() {

@Override
public void sceneUndo() {
    //отменить что то в сцене здесь
}

@Override
public void sceneRedo() {
    //повторить что то в сцене здесь
}

@Override
public void awtUndo() {
    //отменить что то в awt потоке здесь(обновление визуальных узлов и.т.д., называемое редактированием сцены)
}

@Override
public void awtRedo() {
    //повторить что то в awt потоке здесь
}
});
Важно, чтобы вы использовали метод addEdit(Object source, UndoableEdit edit);

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

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

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