В физическом моделировании объектов в Ammo.js фундаментальное значение имеют системы координат, используемые для описания положения, ориентации и движения тел. Различают локальные и мировые (глобальные) координаты. Правильное понимание этих концепций обеспечивает корректное поведение объектов при столкновениях, трансформациях и управлении соединениями (constraints).
Локальная система координат привязана к объекту. Её начало обычно совпадает с центром масс тела, а оси направлены относительно ориентации объекта. Основные свойства:
Пример создания вектора в локальной системе:
let localPoint = new Ammo.btVector3(1, 0, 0); // точка на 1 единицу вдоль локальной оси X
Для вращений в локальной системе применяется кватернион, который задаёт ориентацию относительно начальной оси объекта:
let localRotation = new Ammo.btQuaternion(0, 0, 0, 1); // нейтральная ориентация
Ключевой момент: при изменении позиции или ориентации объекта в локальной системе координат, сама система движется вместе с объектом, поэтому все вычисления остаются относительно него.
Мировая система координат описывает положение объектов относительно сцены в целом. Начало координат фиксировано, обычно в центре сцены, и не зависит от ориентации объектов. Особенности:
Пример получения мировой позиции объекта:
let transform = new Ammo.btTransform();
rigidBody.getMotionState().getWorldTransform(transform);
let worldOrigin = transform.getOrigin();
console.log(worldOrigin.x(), worldOrigin.y(), worldOrigin.z());
Ключевой момент: при работе с внешними приложениями или глобальными эффектами необходимо всегда использовать мировые координаты, чтобы избежать несоответствия между физикой и визуализацией.
Ammo.js предоставляет методы для перевода точек и векторов между локальной и мировой системами координат. Это особенно важно для точного позиционирования соединений, приложений сил или контроля движения.
Из локальных в мировые:
let localPoint = new Ammo.btVector3(1, 0, 0);
let worldPoint = transform.op_mul(localPoint); // transform – btTransform объекта
Из мировых в локальные:
let worldPoint = new Ammo.btVector3(5, 2, 3);
let localPoint = transform.inverse().op_mul(worldPoint);
btTransform хранит положение (origin) и
ориентацию (rotation) объекта. Методы op_mul и
inverse() обеспечивают корректное преобразование координат
с учётом поворота и смещения.
Соединения в Ammo.js (constraints) требуют точного задания опорных фреймов для каждого тела. Например, hinge constraint:
let frameInA = new Ammo.btTransform();
frameInA.setIdentity();
frameInA.setOrigin(new Ammo.btVector3(0, 1, 0)); // локальная точка вращения в объекте A
let frameInB = new Ammo.btTransform();
frameInB.setIdentity();
frameInB.setOrigin(new Ammo.btVector3(0, -1, 0)); // локальная точка вращения в объекте B
let hinge = new Ammo.btHingeConstraint(bodyA, bodyB, frameInA, frameInB, true);
Особенности:
frameInA и frameInB задаются в локальных
координатах соответствующих тел.true указывает, что Ammo.js будет автоматически
учитывать трансформацию к мировым координатам для корректного
соединения.btTransform.inverse() для точного перехода между
системами.btTransform с методами
op_mul и inverse() для точного перехода между
системами.Правильное использование локальных и мировых координат обеспечивает точное, предсказуемое поведение объектов, упрощает настройку constraints и предотвращает ошибки при интеграции с визуализацией.