В физическом движке Ammo.js btTransform представляет
собой фундаментальный объект для работы с положением и ориентацией тел в
трёхмерном пространстве. Он объединяет позицию
(origin) и вращение
(rotation) в единый контейнер, обеспечивая удобный способ
управления положением объектов и их преобразованиями.
btTransformbtTransform содержит два основных компонента:
Позиция (origin) Представлена
объектом типа btVector3. Хранит координаты тела в
пространстве:
let position = new Ammo.btVector3(x, y, z);
Здесь x, y, z — координаты в
мировых единицах. btVector3 поддерживает стандартные
операции векторов: сложение, вычитание, масштабирование и
нормализацию.
Ориентация (rotation) Ориентация
задаётся объектом btQuaternion, который хранит поворот
через кватернион. Кватернионы позволяют избежать углов
Эйлера и связанных с ними проблем gimbal lock.
let rotation = new Ammo.btQuaternion(x, y, z, w);
x, y, z, w — компоненты кватерниона. Основные операции с
кватернионами: умножение, нормализация, преобразование в матрицу
поворота.
btTransformДля создания нового объекта btTransform используется
конструктор без параметров или с параметрами позиции и вращения:
let transform = new Ammo.btTransform();
transform.setIdentity(); // инициализация как нейтральный трансформ
setIdentity() устанавливает трансформ в нулевое
смещение и отсутствие вращения.setOrigin(btVector3) задаёт позицию объекта.setRotation(btQuaternion) задаёт ориентацию
объекта.Пример задания позиции и ориентации одновременно:
let transform = new Ammo.btTransform();
let origin = new Ammo.btVector3(0, 5, 0);
let rotation = new Ammo.btQuaternion(0, 0, 0, 1);
transform.setOrigin(origin);
transform.setRotation(rotation);
btTransformДля получения текущих координат и ориентации используются методы:
getOrigin() — возвращает btVector3,
содержащий позицию.getRotation() — возвращает btQuaternion,
содержащий ориентацию.let pos = transform.getOrigin();
let rot = transform.getRotation();
console.log(pos.x(), pos.y(), pos.z());
console.log(rot.x(), rot.y(), rot.z(), rot.w());
btTransform используется в:
Создании динамических и статических тел через
btRigidBodyConstructionInfo.
Обновлении позиции объекта в мире:
body.setWorldTransform(transform);Считывании текущего состояния тела:
let currentTransform = body.getWorldTransform();
let currentPos = currentTransform.getOrigin();Трансформации можно комбинировать с помощью кватернионного умножения и сложения векторов:
let t1 = new Ammo.btTransform();
let t2 = new Ammo.btTransform();
t1.setIdentity();
t2.setIdentity();
t1.setOrigin(new Ammo.btVector3(1, 2, 3));
t2.setRotation(new Ammo.btQuaternion(0, 0, 0.707, 0.707));
t1.op_mul(t2); // комбинирование трансформаций
Метод op_mul() выполняет композицию
трансформаций, объединяя смещение и поворот. Это полезно для
расчета позиции дочерних объектов относительно родителя.
btTransformВращение объекта через btTransform обычно выполняется с
использованием кватерниона. Прямое задание углов Эйлера требует
преобразования в кватернион:
function eulerToQuaternion(yaw, pitch, roll) {
let cy = Math.cos(yaw * 0.5);
let sy = Math.sin(yaw * 0.5);
let cp = Math.cos(pitch * 0.5);
let sp = Math.sin(pitch * 0.5);
let cr = Math.cos(roll * 0.5);
let sr = Math.sin(roll * 0.5);
let q = new Ammo.btQuaternion(
sr * cp * cy - cr * sp * sy,
cr * sp * cy + sr * cp * sy,
cr * cp * sy - sr * sp * cy,
cr * cp * cy + sr * sp * sy
);
return q;
}
let rotation = eulerToQuaternion(0, Math.PI / 2, 0);
transform.setRotation(rotation);
btTransform в матрицуДля интеграции с графикой или WebGL трансформ можно преобразовать в 4×4 матрицу:
let matrix = new Ammo.btMatrix3x3();
transform.getBasis(matrix);
let origin = transform.getOrigin();
Базис (basis) — это матрица 3×3, представляющая поворот.
Совмещая её с позицией, можно получить полную матрицу модели.
Всегда использовать setIdentity() при создании новых
трансформов для предотвращения неопределённого состояния.
Для последовательного применения нескольких поворотов предпочтительно использовать кватернионы вместо углов Эйлера.
Для анимации тел можно интерполировать кватернионы с помощью SLERP, сохраняя плавность вращения.
Освобождение памяти объектов Ammo.js важно, т.к. библиотека управляет памятью вручную:
Ammo.destroy(transform);
Ammo.destroy(origin);
Ammo.destroy(rotation);btTransform с физическим миромВ контексте btDiscreteDynamicsWorld
btTransform определяет:
btRigidBody.setWorldTransform() без влияния силы.Комбинирование позиции и ориентации через btTransform
позволяет точно моделировать движение объектов в трехмерной физике,
обеспечивая синхронизацию с визуальной частью сцены и корректное
взаимодействие тел.