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

MotionPath

Опубликованно: 14.09.2015, 5:56
Последняя редакция, AdiDOS: 11.05.2017 16:52

Сегодня решил посвятить немного времени  неплохой технологии под название MotionPath  — Motion (Движение) Path (Путь) простыми словами данная технология позволяет просто реализовать анимацию движения по определенном пути , перейдем наверно к коду.

import com.jme3.animation.LoopMode;
import com.jme3.app.SimpleApplication;
import com.jme3.cinematic.MotionPath;
import com.jme3.cinematic.MotionPathListener;
import com.jme3.cinematic.events.MotionEvent;
import com.jme3.light.AmbientLight;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Spline.SplineType;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.util.SkyFactory;

public class TestMotionPath extends SimpleApplication implements MotionPathListener {
 private Spatial teapot;
 private MotionPath path;
 MotionEvent motionControl;
 public static void main(String[] args) {
   new TestMotionPath().start();

 }

 @Override
 public void simpleInitApp() {
   flyCam.setMoveSpeed(20);
   createTeapot();
   createAmbienLight();
   createDirectionLight();
   createSkyBox();
   //Создание пути
   path = new MotionPath();
   //Тип построения линий маршрута
 
   //Добавление точек
   path.addWayPoint(new Vector3f(10, 3, 0));
   path.addWayPoint(new Vector3f(10, 3, 10));
   path.addWayPoint(new Vector3f(-40, 3, 10));
   path.addWayPoint(new Vector3f(-40, 3, 0));
   path.addWayPoint(new Vector3f(-40, 8, 0));
   path.addWayPoint(new Vector3f(10, 8, 0));
   path.addWayPoint(new Vector3f(10, 8, 10));
   path.addWayPoint(new Vector3f(15, 8, 10));

   path.setPathSplineType(SplineType.CatmullRom);
   //Визуальное отображение пути 
   path.enableDebugShape(assetManager, rootNode);
   //Добавляем обработчик событий
   path.addListener(this);
 
   //Класс отвечающий за движение анимации
   motionControl = new MotionEvent(teapot,path);
   //Говорим что наша модель будет двигатся и вращатся 
   motionControl.setDirectionType(MotionEvent.Direction.PathAndRotation);
   //Поворачиваем на 180 градусов по оси Y
   motionControl.setRotation(new Quaternion().fromAngleNormalAxis(-FastMath.HALF_PI, Vector3f.UNIT_Y));
 
   //Продолжительность анимации на время в секундах
   motionControl.setInitialDuration(20f);
   //Скорость анимации
   motionControl.setSpeed(1f); 
   //Циклическая анимация
   motionControl.setLoopMode(LoopMode.Loop);
   //Старт анимации
   motionControl.play();
 
 }
 //Создание чайника
 private void createTeapot(){
   Material mat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
   mat.setFloat("Shininess", 1f);
   mat.setBoolean("UseMaterialColors", true);
   mat.setColor("Ambient", ColorRGBA.Black);
   mat.setColor("Diffuse", ColorRGBA.DarkGray);
   mat.setColor("Specular", ColorRGBA.White.mult(0.6f));
 
   teapot = assetManager.loadModel("Models/Teapot/Teapot.obj");
   teapot.setName("Teapot");
   teapot.setLocalScale(3);
   teapot.setMaterial(mat);

   rootNode.attachChild(teapot);
 }
 
 // Направленный свет
 private void createDirectionLight() {
   DirectionalLight sun = new DirectionalLight();
   sun.setColor(ColorRGBA.White);
   sun.setDirection(new Vector3f(-1f, -1f, -1f).normalizeLocal());
   rootNode.addLight(sun);
 }

 // Рассеянный свет
 private void createAmbienLight() {
   AmbientLight al = new AmbientLight();
   al.setColor(ColorRGBA.White.mult(0.4f));
   rootNode.addLight(al);
 }

 // Небо
 private void createSkyBox() {
   Spatial sky = SkyFactory.createSky(assetManager, "Scenes/Beach/FullskiesSunset0068.dds", false);
   sky.setLocalScale(350);
   rootNode.attachChild(sky);
 }
 @Override
 public void onWayPointReach(MotionEvent motionControl, int wayPointIndex) {
    System.out.println(wayPointIndex);
  }

}

2

1

Этот пример демонстрирует движение чайника по определенном пути , класс MotionPath его задача построить путь по нашим указанным точкам , с каждым добавлением точки класс генерирует нам маршрут с пред идущей точкой.

Данная функция определяет тип построения линий маршрута , поддерживает 2 параметра CatmullRom — линии строятся плавно с закруглениями на поворотах подобно кривым безье, Linear — строгие линии получаются острые углы на поворотах , её желательно вызывать после добавления точек так как при вызове строи маршрут .

setPathSplineType(SplineType.CatmullRom);

Функция добавления точек

 path.addWayPoint(new Vector3f(10, 3, 0));

Эта функция автоматически создает нам линии маршрута и на каждой точке ставит кубики , очень хорошая для визуальной оценки.

 path.enableDebugShape(assetManager, rootNode);

Тип направления при движении может принять 5 параметра

Non — Объекта всегда в стартовом направлении

Path — Объект  вращается с направлением пути.

Rotation — Движение пропорционально маршруту не поворачивает на изгибах.

PathAndRotation  — Объект вращается с направлением пути при использовании функции setRotation.

LookAt — Объект вращается но при указанной координате точки с помощью функции setLookAt.

setDirectionType(MotionEvent.Direction.PathAndRotation)

Продолжительность анимации.

 motionControl.setInitialDuration(20f);

Скорость движения.

motionControl.setSpeed(1f);

Есть 3 параметра этой функции

Loop — Анимация будет выполнятся повторно при достижении конечной точки начинать с первой.

DontLoop— Анимация будет выполнятся один раз до достижения конечной точки.

Cycle— Анимация будет выполнятся повторно при достижения конечной точки будет продолжать движение.

setLoopMode(LoopMode.Cycle);

Запуск анимации.

play();

Остановка анимации и при повторном вызове функции play модель перемещается на начальную точку.

stop();

Приостановка анимации и при повторном вызове функции play модель продолжает движение.

pause();

Я добавлю по поводу обработки  события onWayPointReach этот метод вызывается каждый раз при достижении объектом каждой точки и  переменная wayPointIndex возвращает индекс точки.

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

Спасибо за внимание !!!

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

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