Класс Transform: совмещение позиции и ориентации

Класс Transform в Oimo.js представляет собой фундаментальный инструмент для управления положением и ориентацией объектов в 3D-пространстве. Он объединяет в себе позицию и ориентацию, позволяя работать с телами, связанными с физическим движком, единым образом. В отличие от отдельных векторов позиции и матриц поворота, Transform хранит их совместно, что упрощает преобразования и интеграцию с физикой.

Структура Transform

Объект Transform включает два ключевых свойства:

  1. position — экземпляр класса Vec3, задающий координаты объекта в мировом пространстве:

    transform.position.x
    transform.position.y
    transform.position.z

    Значения задаются в единицах сцены и обычно используются для установки начального положения или получения текущего.

  2. rotation — экземпляр класса Quat (кватернион), представляющий ориентацию объекта:

    transform.rotation.x
    transform.rotation.y
    transform.rotation.z
    transform.rotation.w

    Кватернионы обеспечивают стабильное и эффективное представление вращений без эффекта гимбал-лок.

Дополнительно Transform может содержать scale, если требуется поддержка масштабирования, но в стандартной физике Oimo.js масштабирование обычно учитывается на уровне коллайдеров.

Создание и инициализация

Создание нового Transform осуществляется через конструктор с возможностью передачи позиции и ориентации:

const transform = new OIMO.Transform(
    new OIMO.Vec3(0, 5, 0),
    new OIMO.Quat(0, 0, 0, 1)
);
  • Если кватернион не указан, используется единичный кватернион (0, 0, 0, 1), который соответствует отсутствию вращения.
  • Позиция по умолчанию (0, 0, 0).

Основные методы

Класс Transform предоставляет методы для управления положением и ориентацией объектов:

  • setPosition(x, y, z) — установка позиции:
transform.position.set(2, 3, 5);
  • setRotation(quat) — установка кватерниона:
transform.rotation.copy(new OIMO.Quat().setFromEuler(0, Math.PI / 2, 0));
  • translate(vec3) — перемещение объекта относительно текущего положения:
transform.position.add(new OIMO.Vec3(1, 0, 0));
  • rotate(quat) — добавление вращения к текущему кватерниону:
transform.rotation.mul(new OIMO.Quat().setFromEuler(0, Math.PI/4, 0));

Преобразования и комбинирование

Transform позволяет эффективно комбинировать несколько преобразований:

  1. Мировое и локальное преобразование

    • Для движения объекта в локальной системе координат используется комбинация позиции и поворота:
    const localMove = new OIMO.Vec3(0, 0, 1);
    localMove.applyQuat(transform.rotation);
    transform.position.add(localMove);
  2. Комбинирование Transform

    • Чтобы получить итоговое преобразование от двух объектов:
    const combined = new OIMO.Transform();
    combined.position.copy(transform1.position).add(transform2.position);
    combined.rotation.copy(transform1.rotation).mul(transform2.rotation);
  3. Преобразование точки

    • Трансформ позволяет переводить точки из локальной системы в мировую:
    const point = new OIMO.Vec3(1, 0, 0);
    point.applyTransform(transform);

Интеграция с физикой

Transform тесно связан с объектами физического мира:

  • RigidBody хранит текущий Transform, который обновляется движком при симуляции.
  • Изменение Transform напрямую влияет на позицию и ориентацию тела:
body.getTransform().position.set(0, 10, 0);
body.getTransform().rotation.setFromEuler(0, Math.PI/2, 0);
  • Для динамических объектов рекомендуется использовать методы body.setPosition() и body.setRotation(), чтобы сохранить согласованность между Transform и внутренними данными физики.

Вращение с кватернионами

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

  • Избежать Gimbal lock, возникающего при работе с углами Эйлера.
  • Плавно интерполировать вращения с помощью SLERP:
OIMO.Quat.slerp(transform1.rotation, transform2.rotation, 0.5, transform.rotation);

Практические советы

  • Хранение позиции и ориентации в одном объекте упрощает управление сложными иерархиями объектов, например, при симуляции суставов или соединений.
  • Для анимации и физики рекомендуется использовать Transform для вычислений, а затем обновлять физические тела через соответствующие методы RigidBody.
  • Комбинирование Transform упрощает создание сложных движений, например, вращение платформы вместе с перемещением.

Заключение по использованию Transform

Класс Transform в Oimo.js обеспечивает единый интерфейс для управления положением и ориентацией объектов. Правильное использование кватернионов и методов трансформации позволяет создавать точные и стабильные физические симуляции, избегая проблем с нестабильными вращениями и неконсистентными позициями.

Он становится ключевым элементом при работе с RigidBody, коллайдерами и динамическими сценами, предоставляя полный контроль над положением и ориентацией в пространстве.