Библиотека Ammo.js представляет собой порт
популярного физического движка Bullet Physics на
JavaScript через Emscripten. Одной из ключевых возможностей работы с
физическими объектами является управление их трансформациями в мировом
пространстве. Методы getWorldTransform и
setWorldTransform позволяют получить и задать положение и
ориентацию объекта на уровне движка, минуя интерфейсы рендеринга. Это
критически важно для точного синхронизирования физики с
визуализацией.
getWorldTransformМетод getWorldTransform используется для извлечения
текущей мировой трансформации объекта, обычно
представленной матрицей или объектом типа btTransform.
let transform = new Ammo.btTransform();
rigidBody.getWorldTransform(transform);
Ключевые моменты:
btTransform хранит:
origin) — объект
btVector3.rotation) — объект
btQuaternion.Извлечение позиции:
let origin = transform.getOrigin();
let x = origin.x();
let y = origin.y();
let z = origin.z();
let rotation = transform.getRotation();
let qx = rotation.x();
let qy = rotation.y();
let qz = rotation.z();
let qw = rotation.w();
setWorldTransformМетод setWorldTransform позволяет прямо задать
мировую трансформацию для объекта. Он используется для
перемещения объектов без учета физических взаимодействий, либо для
синхронизации внешних изменений с физическим телом.
let newTransform = new Ammo.btTransform();
newTransform.setIdentity(); // Сброс трансформации
newTransform.setOrigin(new Ammo.btVector3(0, 5, 0));
newTransform.setRotation(new Ammo.btQuaternion(0, 0, 0, 1));
rigidBody.setWorldTransform(newTransform);
Особенности работы:
setWorldTransform напрямую обновляет положение
и ориентацию тела.rigidBody.setLinearVelocity(new Ammo.btVector3(0, 0, 0));
rigidBody.setAngularVelocity(new Ammo.btVector3(0, 0, 0));
getWorldTransform и setWorldTransform
напрямую взаимодействуют с состоянием
btRigidBody, позволяя:
Пример синхронизации визуальной модели с физикой:
let transform = new Ammo.btTransform();
rigidBody.getWorldTransform(transform);
let origin = transform.getOrigin();
mesh.position.set(origin.x(), origin.y(), origin.z());
let rotation = transform.getRotation();
mesh.quaternion.set(rotation.x(), rotation.y(), rotation.z(), rotation.w());
setWorldTransform безопасно, так как тело не подвержено
физическим силам.setWorldTransform только при
необходимости и синхронизировать скорости.btTransform и btVector3 является затратной
операцией, поэтому рекомендуется повторно использовать
объекты в циклах.Хотя btTransform не является напрямую матрицей WebGL,
его можно легко преобразовать:
let mat = new THREE.Matrix4();
let origin = transform.getOrigin();
let rotation = transform.getRotation();
mat.makeRotationFromQuaternion(new THREE.Quaternion(rotation.x(), rotation.y(), rotation.z(), rotation.w()));
mat.setPosition(new THREE.Vector3(origin.x(), origin.y(), origin.z()));
Это обеспечивает точное соответствие между физическим телом и визуальной моделью, необходимое для игр и симуляций с высокой точностью.
setWorldTransform без сброса скоростей
для динамических тел вызывает неустойчивое
поведение.btTransform на каждом кадре приводит к
утечкам памяти. Следует повторно использовать один
объект.btQuaternion хранит
[x, y, z, w], а не [w, x, y, z]. При
интеграции с Three.js или другими движками это важно учитывать.Методы getWorldTransform и
setWorldTransform предоставляют низкоуровневый контроль над
состоянием объектов, обеспечивая точное управление положением и
ориентацией в мире Ammo.js, а также синхронизацию с графической частью
приложения.