btConvexTriangleMeshShape представляет собой одну из специализированных форм столкновений в физическом движке Ammo.js, основанного на Bullet Physics. Она используется для создания выпуклых треугольных сеток, позволяющих симулировать объекты сложной геометрии с корректным физическим взаимодействием, сохраняя при этом производительность. Основное отличие от других форм заключается в том, что она принимает произвольные треугольники, но автоматически преобразует их в выпуклую оболочку.
setLocalScaling, что
автоматически корректирует столкновения.Для создания требуется объект btTriangleMesh, который хранит вершины и индексы треугольников. Последовательность действий:
// Создание треугольной сетки
let triangleMesh = new Ammo.btTriangleMesh();
// Добавление треугольников
triangleMesh.addTriangle(
new Ammo.btVector3(0, 0, 0),
new Ammo.btVector3(1, 0, 0),
new Ammo.btVector3(0, 1, 0),
true
);
// Создание выпуклой формы на основе сетки
let convexShape = new Ammo.btConvexTriangleMeshShape(triangleMesh, true);
Параметры конструктора:
btStridingMeshInterface, чаще всего
btTriangleMesh.true,
автоматически пересчитывается ограничивающий параллелепипед (AABB) для
коллизий.btConvexTriangleMeshShape наследует большинство методов базового класса btConvexShape, включая:
getBoundingSphere(center, radius) – получение центра и
радиуса огибающей сферы.recalcLocalAabb() – пересчёт локального AABB после
изменения формы или масштаба.setLocalScaling(scalingVector) – масштабирование
формы.getLocalScaling() – получение текущего масштаба.calculateLocalInertia(mass, inertia) – вычисление
инерции для динамических тел.Пример вычисления инерции:
let mass = 10;
let localInertia = new Ammo.btVector3(0, 0, 0);
convexShape.calculateLocalInertia(mass, localInertia);
Масштабирование через setLocalScaling применяется к
каждой вершине сетки при расчёте столкновений:
convexShape.setLocalScaling(new Ammo.btVector3(2, 1, 1.5));
После масштабирования важно вызвать recalcLocalAabb,
чтобы физический движок корректно обновил границы объекта:
convexShape.recalcLocalAabb();
Для использования формы в симуляции необходимо создать btRigidBody:
let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(0, 10, 0));
let motionState = new Ammo.btDefaultMotionState(transform);
let mass = 5;
let localInertia = new Ammo.btVector3(0, 0, 0);
convexShape.calculateLocalInertia(mass, localInertia);
let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, convexShape, localInertia);
let rigidBody = new Ammo.btRigidBody(rbInfo);
// Добавление тела в физический мир
physicsWorld.addRigidBody(rigidBody);
Особенности:
0.calculateLocalInertia.motionState обеспечивает синхронизацию между
визуализацией и физическим движком.btConvexShape, а
не через модификацию вершин напрямую.btCompoundShape.Для сложных объектов допустимо объединять несколько
btConvexTriangleMeshShape в
btCompoundShape:
let compound = new Ammo.btCompoundShape();
let offsetTransform = new Ammo.btTransform();
offsetTransform.setIdentity();
offsetTransform.setOrigin(new Ammo.btVector3(0, 0, 0));
compound.addChildShape(offsetTransform, convexShape);
Это позволяет создавать объекты с несколькими выпуклыми областями, сохраняя стабильность динамики.
btConvexTriangleMeshShape корректно взаимодействует с
другими convex shapes, включая:
btBoxShapebtSphereShapebtCapsuleShapebtConvexHullShapeКоллизии рассчитываются на основе алгоритма GJK (Gilbert–Johnson–Keerthi) для выпуклых тел, что обеспечивает точное и стабильное поведение в симуляции.
Ammo.destroy() для
предотвращения утечек памяти.