Флаг autoSleep и пороговые значения засыпания

В Oimo.js управление энергопотреблением объектов физического мира осуществляется через механизм автоматического «засыпания» тел. Этот механизм необходим для оптимизации производительности: объекты, которые не участвуют в активных взаимодействиях, перестают рассчитываться на каждом шаге симуляции, что значительно снижает нагрузку на процессор.

Флаг autoSleep

Флаг autoSleep указывает, будет ли конкретное тело проверяться на возможность перехода в спящий режим. По умолчанию этот флаг установлен в true для всех тел, что позволяет физическому движку автоматически отключать расчёты для неподвижных объектов.

let box = world.add({
    type: "box",
    size: [1, 1, 1],
    pos: [0, 10, 0],
    move: true,
    autoSleep: true
});

Ключевые моменты работы autoSleep:

  • Только динамические объекты (move: true) могут засыпать. Статические тела (move: false) всегда остаются активными в расчётах, так как они служат опорой для других объектов.
  • При autoSleep: false объект всегда считается активным, независимо от скорости и взаимодействий.
  • Флаг можно менять динамически в процессе работы симуляции, но частое переключение может негативно сказаться на производительности.

Пороговые значения засыпания

Для того чтобы определить, когда тело может перейти в спящий режим, используются пороговые значения скорости и угловой скорости:

  • sleepThreshold – минимальная скорость линейного движения, ниже которой объект может начать засыпать.
  • angularSleepThreshold – минимальная угловая скорость вращения, ниже которой объект может засыпать.

Пример задания порогов:

box.sleepThreshold = 0.05;        // линейная скорость
box.angularSleepThreshold = 0.05; // угловая скорость

Объект считается потенциально спящим, если одновременно выполняются условия:

|velocity| < sleepThreshold  AND  |angularVelocity| < angularSleepThreshold

Когда эти условия соблюдаются в течение нескольких шагов симуляции, объект переводится в спящий режим.

Механизм пробуждения

Спящие объекты не участвуют в вычислениях коллизий и динамики до момента, пока на них не воздействует сила или момент, либо пока они не сталкиваются с активным телом. Пробуждение происходит автоматически:

  • При столкновении с динамическим объектом.
  • При применении силы или момента через API:
box.applyForce([0, 10, 0], [0, 0, 0]);
box.wakeUp();  // мгновенное пробуждение
  • Если сцена содержит глобальные события, например, гравитацию или внешние воздействия, пробуждение инициируется при изменении скорости объекта выше порогов.

Практические рекомендации

  • Для объектов, которые должны оставаться постоянно под контролем симуляции, autoSleep следует отключить.
  • Для объектов, участвующих в хаотичной динамике или часто сталкивающихся с другими, следует уменьшать sleepThreshold и angularSleepThreshold, чтобы предотвратить преждевременное засыпание.
  • В больших сценах с множеством объектов включение autoSleep и грамотная настройка порогов значительно увеличивает производительность без потери точности симуляции.

Влияние на производительность

Механизм засыпания особенно критичен при симуляции сотен и тысяч тел. Без него каждая итерация потребляет ресурсы на вычисление движений абсолютно всех объектов, включая те, которые стоят неподвижно. Включение autoSleep с корректными порогами позволяет движку:

  • Пропускать расчёт динамики спящих тел.
  • Сократить количество проверок коллизий.
  • Минимизировать нагрузку на основной цикл симуляции.

Использование autoSleep и правильная настройка порогов создают баланс между реализмом физики и эффективностью работы движка, что критично для интерактивных приложений и игр на базе Oimo.js.