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

Анимация в jME3

Опубликованно: 09.05.2017, 20:43
Последняя редакция, Andry: 10.05.2017 22:08

В 3D-играх вы не только загружаете статические 3D-модели, но также можете запускать анимацию модели из кода Java.

Требования

JME3 не только загружает и воспроизводит анимированные модели, но и создает их.

Что требуется для анимированной модели? (См. Также: Терминология анимации)

  1. Для каждой модели вам нужно сегментировать модель в скелет (костная оснастка).
  2. Для каждого движения вы должны указать, как анимация искажает части модели (скинирование).
  3. Для каждой анимации вы должны указать серию снимков того, как расположены кости (ключевые кадры).
  4. Одна модель может содержать несколько анимаций. Вы даете каждой анимации имя, когда сохраняете её в редакторе сетки.

Если вы не загружаете бесплатные модели или не покупаете их у 3D-художника, вы должны сами создать свои анимированные модели во внешнем редакторе сетки (например, Blender).

Что необходимо вашему базовому java-классу JME3?

  • Один Animation Control для анимированной модели
  • Сколько каналов анимации нужно на один Control, сколько вам нужно, чтобы воспроизвести анимацию. В простых случаях достаточно одного канала, иногда вам нужно два или более канала для модели, чтобы параллельно играть жесты и движения.

Образцы кода

Управление анимацией

Animation Control

Создайте один объект com.jme3.animation.AnimControl в вашем приложении JME3 для каждой анимированной модели, которую вы хотите контролировать. Вы должны зарегистрировать каждую анимированную модель в одном из этих Animation Control. Объект Control предоставляет доступ к доступным последовательностям анимации в модели.

  AnimControl playerControl; // вам нужно по одному Control для каждой модели
  Node player = (Node) assetManager.loadModel("Models/Oto/Oto.mesh.xml"); // загрузим модель
  playerControl = player.getControl(AnimControl.class); // получим Control над этой моделью
  playerControl.addListener(this); // добавим слушателя

Каналы Анимации

У Animation Control есть несколько каналов анимации (com.jme3.animation.AnimChannel). Каждый канал может воспроизводить одну анимационную последовательность за раз.

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

  AnimChannel channel_walk = playerControl.createChannel();
  AnimChannel channel_jump = playerControl.createChannel();
  ...

Чтобы сбросить Control, вызовите control.clearChannels();

Свойства Animation Control

Для AnimControl доступна следующая информация.

Свойства AnimControl  Применение
createChannel()  Возвращает новый канал, управляющий умолчанию всеми костями по.
getNumChannels()  Количество каналов, зарегистрированных в этом Control.
getChannel(0)  Получать определенный канал по номеру индекса. Не более getNumChannels().
clearChannels()  Очистите все каналы в этом Control.
addListener(animEventListener)
removeListener(animEventListener)
clearListeners() 
Добавляет или удаляет слушателей для получения связи событий с анимациями.
Свойства AnimControl  Применение
setAnimations(aniHashMap)  Устанавливает анимации, которые этот AnimControl будет способен проинрывать. Анимации должны быть совместимы со скелетом, данным в конструкторе.
addAnim(boneAnim)
removeAnim(boneAnim) 
Добавляет или удаляет анимацию из этого Control.
getAnimationNames()  String Коллекция названий всех анимаций, которые этот Control может проигрывать для этой модели.
getAnim(“anim)  Получить анимацию из списка анимаций.
getAnimationLength(“anim)  Возвращает продолжительность указанной именованной анимации в секундах
Свойства AnimControl  Применение
getSkeleton()  Объект Skeleton, управляемый этим Control.
getTargets()  Объекты Skin, управляемые этим Control, в качестве Mesh-массива.
getAttachmentsNode(“bone)  Возвращает узел к которому прикреплены кости. Прикрепите модели и эффекты к этому узлу, чтобы они следовали за движениями этой кости.

Свойства канала анимации

Для AnimChannel установлены следующие свойства.

Свойства AnimChannel  Применение
setLoopMode(LoopMode.Loop);  Теперь анимация на этом канале будет повторяться с самого начала, всякий раз когда она закончится.
setLoopMode(LoopMode.DontLoop);  Теперь анимация на этом канале будет воспроизводиться один раз, со стоп-кадром — на последнем ключевом кадре.
setLoopMode(LoopMode.Cycle);  Теперь анимация на этом канале будет воспроизводиться вперед, затем назад, затем снова вперед и так далее.
setSpeed(1f);  Теперь анимация бедет проигрыватся медленнее (<1f) или быстрее (> 1f) или со скоростью по умолчанию (1f).
setTime(1.3f);  Быстрая перемотка вперед или назад до определенного момента времени анимации.

Для канала доступна следующая информация.

Свойства AnimChannel  Применение
getAnimationName()  Название анимации, воспроизводимой на этом канале. Возвращает null, когда анимация не воспроизводится.
getLoopMode()  Текущий режим цикла на этом канале. Возвращаемый com.jme3.animation может быть одним их этих LoopMode.Loop, LoopMode.DontLoop или LoopMode.Cycle.
getAnimMaxTime()  Общая длина анимации на этом канале. Или 0f, если ничего не проигрывается.
getTime()  Как долго анимация на этом канале уже проигрывается. Он возвращает 0f, если канал еще не начал проигрывать, или значение до getAnimMaxTime().
getControl()  AnimControl, принадлежащий этому AnimChannel.

Используйте следующие методы для добавления или удаления отдельных костей в AnimChannel. Это полезно, когда вы параллельно воспроизводите две анимации по двум каналам, и каждый контролирует подмножество костей (например, одно оружие, а другое — ноги).

Методы AnimChannel  Применение
addAllBones()  Добавьте все кости скелета модели, чтобы влиять на этот канал анимации. (по умолчанию)
addBone(“bone1)
addBone(bone1) 
Добавьте одну кость, на которую будет воздействовать этот канал анимации.
addToRootBone(“bone1)
addToRootBone(bone1) 
Добавьте серию костей, на которые будет влиять этот канал анимации: Добавьте все косточки, начиная с данной кости, к корневой кости.
addFromRootBone(“bone1)
addFromRootBone(bone1) 
Добавьте серию костей, на которые будет влиять этот канал анимации: добавьте все кости, начиная с заданной корневой кости, и идите к костям потомкам.

Воспроизведение анимаций

Анимации воспроизводятся по каналу. Примечание: Не важно, воспроизводится ли канал анимации непрерывно или только один раз, это зависит от свойства Loop, которые вы установили.

Методы Channel  Применение
channel_walk.setAnim(“Walk,0.50f);  Запустите анимацию под названием «Walk(Прогулка) по каналу channel_walk.
Значение float определяет время, в течение которого анимация должна пересекаться с предыдущей на этом канале. Если установлено значение 0f, то смешение не произойдет, и новая анимация будет применена немедленно.
Используйте AnimEventLister приведенный ниже, чтобы реагировать на завершение или начало цикла анимации.

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

В этом кратком примере мы определяем клавишу пробела для запуска воспроизведения анимации Walk на канале 2.

  public void simpleInitApp() {
    ...
    inputManager.addMapping("Walk", new KeyTrigger(KeyInput.KEY_SPACE));
    inputManager.addListener(actionListener, "Walk");
    ...
  }

  private ActionListener actionListener = new ActionListener() {
    public void onAction(String name, boolean keyPressed, float tpf) {
      if (name.equals("Walk") && !keyPressed) {
        if (!channel2.getAnimationName().equals("Walk")) {
          channel2.setLoopMode(LoopMode.Loop);
          channel2.setAnim("Walk", 0.50f);
        }
      }
    }
  };

Анимационный слушатель событий

Приложение jME3, содержащее анимацию, может реализовать интерфейс com.jme3.animation.AnimEventListener.

public class HelloAnimation extends SimpleApplication
                     implements AnimEventListener { ... }

Этот необязательные слушатели позволяет вам реагировать на события начала и конца анимации, onAnimChange() и onAnimCycleDone().

Ответ на конец анимации

Событие onAnimCycleDone() вызывается, когда цикл анимации завершен. Для не циклических анимаций это событие вызывается, когда анимация завершается. Для циклических анимаций это событие вызывается каждый раз при перезапуске цикла анимации.

У вас есть доступ к следующим объектам:

  • Control, которому назначен слушатель.
  • Воспроизводимый канал анимации.
  • Название анимации, которая только что закончила воспроизведение.
  public void onAnimCycleDone(AnimControl control, AnimChannel channel, String animName) {
    // проверить состояние, которое вас интересует, например. ...
    if (animName.equals("Walk")) {
      // ответьте на это событие здесь, например. ...
      channel.setAnim("Stand", 0.50f);
    }
  }

Ответ на запуск анимации

Событие onAnimChange() вызывается каждый раз перед тем, как пользователем задается анимация, которая будет воспроизводиться на данном канале (channel.setAnim()).

У вас есть доступ к следующим объектам

  • Элемент управления, которому назначен прослушиватель.
  • Воспроизводимый канал анимации.
  • Имя анимации, которая начнет воспроизводиться.
  public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
    // проверить состояние, которое вас интересует, например. ...
    if (animName.equals("Walk")) {
      // ответьте на это событие здесь, например. ...
      channel.setAnim("Reset", 0.50f);
    }
  }

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

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

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