В физическом движке Ammo.js, основанном на
Bullet Physics, ключевым элементом при работе с
объектами является форма коллизии (btCollisionShape).
Масштабирование формы позволяет изменять её размер без необходимости
пересоздавать сам объект. Это особенно полезно при динамическом
изменении размеров игровых объектов или симуляции анимационных
эффектов.
setLocalScalingМетод setLocalScaling применяется к экземплярам класса
btCollisionShape. Он принимает объект типа
btVector3, задающий масштаб по осям X, Y и Z:
shape.setLocalScaling(new Ammo.btVector3(scaleX, scaleY, scaleZ));
1 сохраняет исходный размер.1 уменьшает объект, больше
1 — увеличивает.Масштабирование напрямую влияет на вычисление столкновений,
физические границы объекта и генерацию контактных точек. Изменение
масштаба после добавления объекта в мир
(btDiscreteDynamicsWorld) автоматически обновляет
физическую симуляцию без пересоздания rigid body, если форма
поддерживает динамическое масштабирование.
Разные формы коллизии ведут себя по-разному при масштабировании:
Примитивные формы
btBoxShape, btSphereShape,
btCylinderShape поддерживают масштабирование
напрямую.
Пример для куба:
let boxShape = new Ammo.btBoxShape(new Ammo.btVector3(1, 1, 1));
boxShape.setLocalScaling(new Ammo.btVector3(2, 0.5, 1.5));
Куб увеличится в два раза по X, уменьшится вдвое по Y и увеличится на 50% по Z.
Составные формы
(btCompoundShape)
Масштабирование влияет на все дочерние формы.
При использовании btCompoundShape рекомендуется
применять масштаб к корневой форме:
let compound = new Ammo.btCompoundShape();
compound.addChildShape(transform, childShape);
compound.setLocalScaling(new Ammo.btVector3(1.5, 1.5, 1.5));Сложные меши
(btBvhTriangleMeshShape)
btScaledBvhTriangleMeshShape, который оборачивает
оригинальный меш с указанным масштабом.Масштабирование формы изменяет геометрию коллизии, но не изменяет массу тела напрямую. Для корректной физики необходимо учитывать новое соотношение размеров и массы:
let mass = 2; // кг
let localInertia = new Ammo.btVector3(0, 0, 0);
shape.calculateLocalInertia(mass, localInertia);
После изменения масштаба рекомендуется пересчитывать локальную инерцию, иначе движение объекта может стать неестественным.
Анимация увеличения объекта
let scale = 1;
function animate() {
scale += 0.01;
boxShape.setLocalScaling(new Ammo.btVector3(scale, scale, scale));
requestAnimationFrame(animate);
}
animate();Реакция на столкновение Масштабирование можно использовать для имитации деформаций при ударе:
function onCollision() {
let currentScale = boxShape.getLocalScaling();
boxShape.setLocalScaling(new Ammo.btVector3(
currentScale.x() * 0.9,
currentScale.y() * 0.9,
currentScale.z() * 0.9
));
}btConvexHullShape, после
масштабирования требуют пересоздания BVH (Bounding Volume Hierarchy) для
корректной обработки столкновений.btBoxShape, btSphereShape) для
стабильного масштабирования.btScaledBvhTriangleMeshShape.Механизм setLocalScaling предоставляет гибкий инструмент
для изменения размеров объектов на лету, обеспечивая контроль над
физикой без дорогостоящей пересозданной структуры. Правильное сочетание
масштабирования с пересчетом инерции и синхронизацией с визуальной
моделью позволяет создавать динамичные, реалистичные симуляции в
Ammo.js.