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

3D вращение

Опубликованно: 25.01.2016, 19:59
Последняя редакция, Andry: 02.07.2017 23:57

Плохая новость: 3D вращение осуществляется с помощью матричного исчисления.
Хорошая новость: Если вы не понимаете это исчисление, есть два простых правила, как вам все делать правильно.

3D вращение – это сумасшедшая математическая операция, где вам нужно умножить все вершины вашего объекта на четыре числа с плавающей точкой; Умножение называется конкатенацией, массив из четырех чисел {x, y, z, w} называется кватернионом. Не волнуйтесь, 3D движок сделает всю тяжелую работу за вас. Все, что вам нужно знать:

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

Использование кватернионов для вращения

Чтобы сохранить вращение в кватернионе, необходимо указать две вещи: угол и ось вращения.

  • Угол поворота определяется как кратное числу Пи.
  • Ось вращения определяется вектором: Подумайте о них с точки зрения «тангаж», «рыскание», и «крен».

Пример:

/* В этом кватернионе хранит поворот на 180 градусов в виде крена */ 
Quaternion roll180 = new Quaternion();
roll180.fromAngleAxis( FastMath.PI , new Vector3f(0,0,1) ); 
/* Применяется вращения: объект накреняется на 180 градусов.*/ 
thingamajig.setLocalRotation( roll180 );

Итак как выбрать правильные цифры для параметров кватернионна? Я дам вам мою шпаргалку:

Вращение вокруг осей Использование осевого вектора Примеры вращения такого рода
Ось X (1, 0, 0) Самолет поднимается и опускается(тангаж). Положительное кивание головой.
Ось Y (0, 1, 0) Самелет «рыскает». Авто поворачивает. Отрицательное качание головой.
Ось Z (0, 0, 1) Крен самолета или «банка». Склонить голову.
Это три наиболее распространенных примера – технически вы можете вращать вокруг любой оси, выраженной вектором.
Угол? Используем радианы! Примеры
45 градусов FastMath.PI / 4 Восьмая часть круга
90 градусов FastMath.PI / 2 Четверть круга, или 3 часа
180 градусов FastMath.PI Половина круга или 6 часов
270 градусов FastMath.PI *3/2 Три четверти круга или 9 часов
360 градусов FastMath.PI*2 Полный круг или 12 часов ;)
g градусов FastMath.PI *g/180 Любой угол g
Вы должны указать углы в радианах (кратные или доли PI). Если вы будете использовать градусы, вы просто получите бесполезные результаты.

Как использовать эти таблицы, чтобы задать определенное вращение:

 1. Выберите подходящий вектор оси из таблицы.
 2. Выберите соответствующее значение угла в радианах из таблицы.
 3. Создайте Кватернион для хранения этого вращение. … fromAngleAxis( radians , vector )
 4. Применить Кватернион к узлу, чтобы повернуть его. … setLocalRotation(…)

Объекты Кватернионы можно использовать так часто, как вы захотите, только давайте им осмысленные имена, такие как например roll90, pitch45, yaw180

Больше о Кватернионах…

Пример кода


/* Мы начнем с горизонтального объекта */ 
Cylinder cylinder = new Cylinder("post", 10, 10, 1, 10);
cylinder.setModelBound(new BoundingBox());
/* Создадим Кватернион с 90-градусным-тангажом. */
Quaternion pitch90 = new Quaternion();
pitch90.fromAngleAxis(FastMath.PI/2, new Vector3f(1,0,0));
/* Применим поворот к объекту */
cylinder.setLocalRotation(pitch90);
/* Обновим модель. Теперь она вертикальна. */
cylinder.updateModelBound();
cylinder.updateGeometry();

Интерполяция вращения

Вы можете указать два оборота, и затем jme вычислит (интерполирует) шаги между двумя вращениями:

«Добавление» вращения

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

Quaternion myRotation = pitch90.mult(roll45); /* тангаж и крен */

Поиск и устранение неисправностей при вращении

Объект оказался в неожиданном месте или под неожиданным углом? Если вы получили странные результаты, проверьте следующее:

  1. 3D преобразования являются некоммутативно! Это означает, что имеют огромное значение такие вещи как если вы сначала вы передвинули узел, а потом повернул вокруг оси, или сначала повернули узел, а потом передвинули. Убедитесь, что ваш код делает именно то, что вы от него хотите.
  2. Вы хотите повернуть объект вокруг его центра по оси или вокруг другой стежневой точки вне объекта? Если вы хотите повернуть объект вокруг стержневой точки, то вам необходимо сначала создать(невидимый) стежневой узел и прикрепить к нему объект. Затем применить вращение к родительскому стержневому узлу, а не к самому объекту потомку!
  3. Вы ввели угол в градусах (0-360°) или в радианах (0-2*PI)? 3D движок ожидает радианы, поэтому убедитесь, что вы преобразовали ваши значения! Формула: g° = FastMath.PI * g / 180

Совет: Матричные преобразования

Здесь речь идет только о вращении, но есть 3 типа 3D преобразования: вращение, масштабирование, и перемещение.

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

  • com.jme3.math.Transform, interpolateTransforms() – интерполирует шаг между двумя преобразованиями.


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

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

Содержание

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