В Ammo.js создание физического мира начинается с определения конфигурации и компонентов, управляющих симуляцией. Основными элементами являются:
btDefaultCollisionConfiguration —
задаёт базовые параметры коллизий и выделение памяти под алгоритмы
столкновений.btCollisionDispatcher — отвечает за
обработку столкновений между объектами.btDbvtBroadphase — структура для
ускоренной проверки потенциальных столкновений.btSequentialImpulseConstraintSolver —
решатель физических ограничений, обеспечивающий корректную симуляцию сил
и импульсов.Создание физического мира выполняется через:
const collisionConfiguration = new Ammo.btDefaultCollisionConfiguration();
const dispatcher = new Ammo.btCollisionDispatcher(collisionConfiguration);
const broadphase = new Ammo.btDbvtBroadphase();
const solver = new Ammo.btSequentialImpulseConstraintSolver();
const physicsWorld = new Ammo.btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
physicsWorld.setGravity(new Ammo.btVector3(0, -9.81, 0));
После инициализации мир готов к добавлению объектов и проведению симуляции.
Физические объекты делятся на несколько типов:
Процесс создания rigid body состоит из нескольких шагов:
btBoxShape, btSphereShape или
btCapsuleShape.calculateLocalInertia(mass).const transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(x, y, z));
const motionState = new Ammo.btDefaultMotionState(transform);
btRigidBodyConstructionInfo:const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia);
const body = new Ammo.btRigidBody(rbInfo);
physicsWorld.addRigidBody(body);
Ключевым моментом является управление памятью Ammo.js: объекты типа
btVector3, btTransform требуют явного
освобождения через Ammo.destroy() после использования,
иначе возникает утечка памяти.
Симуляция физики выполняется через метод
stepSimulation(deltaTime, maxSubSteps, fixedTimeStep).
Параметры:
deltaTime — время, прошедшее с
предыдущего кадра (в секундах).maxSubSteps — максимальное количество
внутренних шагов симуляции для компенсации больших кадров.fixedTimeStep — фиксированный интервал
времени для каждого внутреннего шага.Пример:
physicsWorld.stepSimulation(1/60, 10, 1/60);
Система автоматически обновляет позиции и ориентации всех добавленных тел. Для получения текущего состояния rigid body используется метод motion state:
const ms = body.getMotionState();
if (ms) {
const transform = new Ammo.btTransform();
ms.getWorldTransform(transform);
const origin = transform.getOrigin();
const rotation = transform.getRotation();
}
Ammo.js поддерживает расширенные возможности взаимодействия:
physicsWorld.addRigidBody(body, group, mask);
getDispatcher().getManifoldByIndexInternal(i), позволяя
считывать силу столкновения, нормали и позиции контакта.body.applyCentralForce(new Ammo.btVector3(fx, fy, fz));
body.applyImpulse(new Ammo.btVector3(ix, iy, iz), new Ammo.btVector3(px, py, pz));
Позиции объектов в физическом мире необходимо синхронизировать с
графикой (Three.js, Babylon.js или Canvas). После
stepSimulation можно извлечь трансформации:
const transform = new Ammo.btTransform();
body.getMotionState().getWorldTransform(transform);
mesh.position.set(transform.getOrigin().x(), transform.getOrigin().y(), transform.getOrigin().z());
mesh.quaternion.set(transform.getRotation().x(), transform.getRotation().y(), transform.getRotation().z(), transform.getRotation().w());
Для оптимизации производительности рекомендуется повторно
использовать объекты btTransform и btVector3,
а не создавать их каждый кадр.
Ammo.js не использует сборщик мусора JavaScript для своих объектов C++. После завершения симуляции необходимо:
physicsWorld.removeRigidBody(body).Ammo.destroy(body),
Ammo.destroy(shape), Ammo.destroy(transform) и
т.д.Ammo.destroy(physicsWorld);
Ammo.destroy(solver);
Ammo.destroy(broadphase);
Ammo.destroy(dispatcher);
Ammo.destroy(collisionConfiguration);
Правильная очистка предотвращает утечки памяти и обеспечивает стабильную работу приложения при длительной симуляции или перезапуске сцен.
Жизненный цикл симуляции в Ammo.js требует внимательного управления объектами и памяти, что обеспечивает реалистичную физику и стабильную работу приложения в JavaScript.