Ammo.js представляет собой порт популярного C++ движка Bullet Physics на JavaScript через Emscripten. Основная задача библиотеки — реализация твердотельной физики, включая столкновения, динамику тел и ограничения. В стандартной работе движка все физические объекты обновляются на каждом шаге симуляции, что обеспечивает точное моделирование, но может создавать значительную нагрузку на процессор при большом количестве объектов.
Спящий режим (sleeping) позволяет оптимизировать производительность, отключая физические вычисления для объектов, которые находятся в состоянии покоя. Объекты, находящиеся в спящем состоянии, не участвуют в расчетах силы, столкновений и интеграции движения до момента, пока на них не воздействует внешняя сила.
В Ammo.js каждый объект физического тела (btRigidBody)
имеет параметры, отвечающие за спящий режим:
Activation State — текущее состояние активности объекта:
ACTIVE_TAG — тело активно, участвует в симуляции.ISLAND_SLEEPING — тело находится в спящем режиме,
расчеты не производятся.WANTS_DEACTIVATION — тело потенциально может перейти в
сон при низкой активности.DISABLE_DEACTIVATION — тело всегда активно, игнорирует
спящий режим.Linear и angular velocity thresholds — пороги, определяющие минимальные значения скорости, при которых тело считается неподвижным. Если скорости тела ниже этих значений в течение заданного времени, тело переходит в спящий режим.
Deactivation time — время, в течение которого тело должно оставаться в покое, чтобы стать спящим.
Применение этих параметров позволяет экономить ресурсы, особенно при работе с большим числом объектов.
Для включения спящего режима в Ammo.js используется метод
setActivationState и связанные с ним свойства тела. Пример
настройки для динамического объекта:
let mass = 1;
let shape = new Ammo.btBoxShape(new Ammo.btVector3(1,1,1));
let transform = new Ammo.btTransform();
transform.setIdentity();
transform.setOrigin(new Ammo.btVector3(0,5,0));
let motionState = new Ammo.btDefaultMotionState(transform);
let localInertia = new Ammo.btVector3(0,0,0);
shape.calculateLocalInertia(mass, localInertia);
let rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia);
let body = new Ammo.btRigidBody(rbInfo);
// Включение спящего режима
body.setActivationState(Ammo.DISABLE_DEACTIVATION); // Для объектов всегда активных
body.setSleepingThresholds(0.1, 0.1); // Линейная и угловая скорость
Здесь ключевой момент — правильная установка порогов скорости и времени до деактивации, чтобы объекты не «усыпали» слишком быстро, нарушая физическую правдоподобность.
Спящий режим оказывает значительное влияние на производительность симуляции:
Для примера: сцена с 1000 кубов без спящего режима может тормозить браузер, тогда как при правильной активации спящего режима большинство объектов будут отключены от расчетов, оставляя активными только движущиеся тела.
btHingeConstraint,
btPoint2PointConstraint) спящие тела могут вести себя
нестабильно, если одно из тел активно, а другое нет. В таких случаях
рекомендуется временно активировать связанные тела.DISABLE_DEACTIVATION для ключевых
объектов — для объектов, на которые постоянно воздействуют
силы, отключение спящего режима предотвращает неожиданные ошибки.setActivationState(state) — устанавливает состояние
активации объекта.getActivationState() — возвращает текущее
состояние.setSleepingThresholds(linear, angular) — задает пороги
спящего режима.forceActivationState(state) — принудительно меняет
состояние, полезно для управления объектами через код.activate(force) — принудительно «разбудить» тело,
полезно для объектов, которые должны сразу реагировать на события.Эффективное использование этих инструментов позволяет балансировать точность симуляции и производительность, делая Ammo.js пригодным даже для сложных браузерных игр и интерактивных 3D-сцен.
Спящий режим в Ammo.js является мощным механизмом для оптимизации, экономии ресурсов и управления симуляцией крупных сцен, обеспечивая при этом сохранение физической достоверности движущихся объектов.