Система координат и единицы измерения

Ammo.js использует трехмерную правостороннюю систему координат, аналогичную той, что применяется в WebGL и большинстве движков для рендеринга. Оси координат определяются следующим образом:

  • X — горизонтальное направление вправо.
  • Y — вертикальное направление вверх.
  • Z — направление «вглубь» сцены, от наблюдателя к объектам.

В физическом мире это соответствует стандартной правой системе координат, где вращение считается положительным по правилу правого винта.

Единицы измерения

Ammo.js не накладывает жестких ограничений на выбор единиц, но для корректной симуляции и стабильной работы рекомендуется использовать реалистичные физические масштабы:

  • Длина: метры. Пример: куб со стороной 1 соответствует кубу 1×1×1 метра.
  • Масса: килограммы. Масса тела задается через btRigidBody и влияет на динамику при столкновениях и ускорениях.
  • Сила и импульс: Ньютоны и ньютон-секунды соответственно. Силы применяются через методы applyCentralForce и applyTorque.
  • Время: секунды. Параметр deltaTime при обновлении мира (stepSimulation) указывает величину временного шага.

Неправильный масштаб объектов может приводить к нестабильности симуляции, чрезмерным вибрациям и «пролетающим» телам. Например, объекты с длиной меньше 0.01 метра или больше 100 метров часто создают численные артефакты из-за ограничений интегратора.

Координаты и положение объектов

Каждое тело (btRigidBody) имеет трансформацию, включающую положение и ориентацию:

let transform = new Ammo.btTransform();
rigidBody.getMotionState().getWorldTransform(transform);
let origin = transform.getOrigin();
let rotation = transform.getRotation();
  • origin возвращает объект btVector3 с координатами X, Y, Z.
  • rotation возвращает объект btQuaternion с компонентами X, Y, Z, W, определяющими вращение тела.

Использование кватернионов вместо углов Эйлера позволяет избежать проблем с гимбал-локом при вращении объектов.

Масштабирование и взаимодействие с графикой

При интеграции Ammo.js с рендерингом (Three.js, Babylon.js) важно поддерживать одинаковый масштаб:

  • Объект, созданный как куб 1×1×1 в Ammo.js, должен иметь такие же размеры в визуализации.
  • Единицы времени симуляции должны соответствовать частоте обновления сцены: типично 1/60 секунды для 60 FPS.

Любое несоответствие масштабов приводит к разнице в скорости падения, столкновениях и вращениях.

Вращение и локальные координаты

Каждое тело имеет локальную систему координат, относительно которой задаются силы и торки. Методы applyLocalForce и applyTorque используют эти локальные координаты.

Для преобразования между мировыми и локальными координатами применяются методы:

let localPoint = body.getCenterOfMassTransform().inverse().op_mul(worldPoint);

Это позволяет корректно рассчитывать прикладываемые силы на основе ориентации тела.

Советы по численной стабильности

  • Поддерживать масштаб объектов от 0.1 до 10 метров для большинства сцен.
  • Использовать массы от 0.1 до 1000 кг, избегая слишком малых или огромных значений.
  • Время симуляции (deltaTime) лучше держать постоянным или дробить на несколько шагов для точности.
  • Избегать длинных тонких объектов, так как они чувствительны к столкновениям при малом временном шаге.

Итоговые правила

  1. Правая система координат: X — вправо, Y — вверх, Z — вперед.
  2. Единицы: метры, килограммы, секунды, Ньютоны.
  3. Кватернионы для вращений, btVector3 для положения.
  4. Масштаб и время должны соответствовать реалистичным физическим значениям.
  5. Локальные и мировые координаты корректно преобразуются для точных сил и торков.

Это фундаментальные принципы, на которых строится корректная работа физических тел в Ammo.js, обеспечивая стабильную симуляцию и точное соответствие визуализации.