Структура модуля после инициализации

После инициализации библиотеки Ammo.js создаётся объект, содержащий полный набор классов и функций физического движка Bullet Physics, транспилированного в WebAssembly/JavaScript. Этот объект выступает как пространственно именованный контейнер, внутри которого можно работать с физическими телами, формами, мировыми объектами и различными вспомогательными инструментами.

Основные компоненты объекта

  1. btVector3, btQuaternion Эти классы обеспечивают базовые математические структуры:

    • btVector3 — трёхмерный вектор, используемый для координат, линейной скорости, силы. Методы: setValue(x, y, z), length(), normalize(), op_add, op_sub.
    • btQuaternion — кватернион для описания ориентации объектов в пространстве. Методы: setValue(x, y, z, w), setRotation(axis, angle), normalize().
  2. btCollisionShape и наследники Физическая форма объекта, определяющая его столкновения. Основные варианты:

    • btBoxShape — коробка, принимающая btVector3 с половинными размерами.
    • btSphereShape — сфера, принимающая радиус.
    • btCylinderShape, btConeShape, btCapsuleShape — стандартные геометрические формы.
    • btCompoundShape — составная форма, позволяющая объединять несколько форм в один объект. Каждая форма имеет методы для расчёта объёма, массы и инерционных свойств.
  3. btRigidBody и btRigidBodyConstructionInfo Центральный класс, описывающий физическое тело:

    • btRigidBodyConstructionInfo(mass, motionState, shape, localInertia) — объект конфигурации тела.
    • btRigidBody — создаётся на основе конфигурации и содержит состояние тела, методы применения силы (applyForce, applyTorque), контроля позиции и скорости.
  4. btDefaultMotionState Класс для управления положением и ориентацией тела в мире. Поддерживает:

    • Получение/установку трансформации через getWorldTransform, setWorldTransform.
    • Связывание с объектами визуализации (например, mesh в Three.js) через обновление матрицы трансформации.
  5. btDiscreteDynamicsWorld и btSequentialImpulseConstraintSolver Центральный объект мира, управляющий симуляцией:

    • btDiscreteDynamicsWorld — хранит список тел, форм и ограничений, обновляет симуляцию через метод stepSimulation(deltaTime).
    • btSequentialImpulseConstraintSolver — решатель, отвечающий за обработку столкновений и ограничений.
    • btCollisionDispatcher и btDbvtBroadphase — компоненты системы столкновений, отвечающие за детектирование контактов и оптимизацию проверок.
  6. Констрейнты (Constraints) Позволяют создавать физические связи между телами:

    • btPoint2PointConstraint — точка к точке, используется для подвешивания объектов.
    • btHingeConstraint — шарнир с вращением вокруг одной оси.
    • btSliderConstraint, btConeTwistConstraint — более сложные ограничения движения. Констрейнты прикрепляются к телам через методы addConstraint в динамическом мире.
  7. Дополнительные инструменты

    • btTransform — хранит позицию и ориентацию одновременно.
    • btMatrix3x3 — матрица вращения, используется для расчёта инерции и ориентации.
    • Методы расчёта столкновений, центра масс и кинематических свойств (calculateLocalInertia, getCenterOfMassTransform).

Иерархия и структура

После загрузки Ammo() создаётся объект, в котором все классы располагаются как свойства:

Ammo().then(function(AmmoLib) {
    let vector = new AmmoLib.btVector3(1, 2, 3);
    let shape = new AmmoLib.btBoxShape(new AmmoLib.btVector3(1,1,1));
});

Структура условно делится на уровни:

  1. Математика: btVector3, btQuaternion, btTransform, btMatrix3x3.
  2. Физические формы: btCollisionShape и наследники.
  3. Тела: btRigidBody, btRigidBodyConstructionInfo, btDefaultMotionState.
  4. Мир: btDiscreteDynamicsWorld, решатели, диспетчеры, broadphase.
  5. Констрейнты и вспомогательные объекты.

Каждый уровень связан с предыдущим: тела используют формы и математику, мир управляет телами и их взаимодействием.

Особенности работы с памятью

Ammo.js использует WebAssembly, поэтому объекты не удаляются автоматически сборщиком мусора. Для освобождения памяти необходимо вызывать delete:

let vector = new Ammo.btVector3(1, 2, 3);
// Использование
vector.delete(); // освобождение памяти

Это правило распространяется на все объекты, кроме промисов и объектов ядра Ammo().

Порядок инициализации объектов

  1. Создаётся мир (btDiscreteDynamicsWorld) с решателем и диспетчером.
  2. Определяются формы (btBoxShape, btSphereShape и др.).
  3. Создаются тела (btRigidBody) с motionState и формой.
  4. Добавляются тела в мир через addRigidBody.
  5. Симуляция запускается методом stepSimulation.
  6. Обновляются визуальные объекты через getWorldTransform из motionState.

Каждый компонент имеет взаимосвязи: изменение формы тела автоматически корректирует расчёт инерции, а применение силы через тело обновляет трансформацию motionState для визуализации.


Эта структура обеспечивает точное воспроизведение физики Bullet в браузере, позволяя строить как простые, так и сложные динамические сцены с телами, ограничениями и столкновениями.