Засыпание тел: sleepState и пороги засыпания

В физическом движке Cannon.js управление активностью тел является критически важным для оптимизации производительности симуляции. Одним из инструментов для этого является механика засыпания тел, позволяющая отключать вычисления для объектов, находящихся в состоянии покоя.

SleepState и его значения

Каждое тело в Cannon.js имеет свойство sleepState, которое определяет его текущее состояние активности:

  • CANNON.Body.AWAKE (0) — тело активно. Все физические вычисления (силы, столкновения, интеграция) выполняются в полной мере.
  • CANNON.Body.SLEEPY (1) — тело почти не движется, но ещё не полностью отключено. Это промежуточное состояние, в котором движок следит за возможным пробуждением.
  • CANNON.Body.SLEEPING (2) — тело полностью «уснуло». Оно исключается из большинства вычислений, что экономит ресурсы.

Переход между этими состояниями управляется автоматическими проверками движения и силами, действующими на тело.

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

Чтобы определить, когда тело должно перейти в состояние покоя, Cannon.js использует два ключевых параметра:

  • sleepSpeedLimit — максимальная скорость, при которой тело считается почти неподвижным. Если линейная и угловая скорости тела опускаются ниже этого порога, оно может начать процесс засыпания.
  • sleepTimeLimit — минимальное время, которое тело должно находиться ниже порога скорости, прежде чем оно полностью «уснет». Это предотвращает преждевременное засыпание при кратковременных колебаниях скорости.
const body = new CANNON.Body({
    mass: 1,
    shape: new CANNON.Sphere(1)
});

// Настройка порогов засыпания
body.sleepSpeedLimit = 0.1; // скорость ниже 0.1 м/с считается покоем
body.sleepTimeLimit = 1.0;  // тело должно оставаться в покое 1 секунду

Механизм перехода состояний

Процесс засыпания тела реализуется через постепенное снижение активности:

  1. Если скорость тела остаётся ниже sleepSpeedLimit дольше времени sleepTimeLimit, sleepState меняется с AWAKE на SLEEPY.
  2. В состоянии SLEEPY движок продолжает отслеживать малые колебания скорости. Если тело остаётся неподвижным, оно переходит в SLEEPING.
  3. Любое воздействие внешней силы или столкновение пробуждает тело, возвращая sleepState в AWAKE.

Методы управления состоянием сна

Cannon.js предоставляет методы для прямого контроля засыпанием:

  • body.sleep() — принудительно переводит тело в состояние SLEEPING, игнорируя текущую скорость и пороги.
  • body.wakeUp() — пробуждает тело, возвращая ему состояние AWAKE и активируя расчёт сил и столкновений.
  • body.isSleeping() — возвращает true, если тело в состоянии SLEEPING.
if (body.isSleeping()) {
    body.wakeUp(); // тело пробуждается при необходимости
}

Применение засыпания тел

Использование засыпания критично для оптимизации симуляций с большим количеством объектов:

  • Статические элементы сцены — объекты, которые долго находятся в покое, автоматически переходят в SLEEPING, снижая нагрузку на CPU.
  • Механика столкновений — засыпающие тела не участвуют в расчетах столкновений до момента пробуждения, что особенно важно при симуляции множества мелких объектов.
  • Стабилизация симуляции — предотвращает дрожание или колебания малоподвижных тел, которые могут возникать из-за численных ошибок интеграции.

Настройка глобального поведения

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

  • world.allowSleep — включает или отключает автоматическое засыпание всех тел в мире.
  • world.sleepSpeedLimit и world.sleepTimeLimit — задают значения по умолчанию для всех тел, если индивидуальные настройки отсутствуют.
const world = new CANNON.World();
world.allowSleep = true;
world.sleepSpeedLimit = 0.05;
world.sleepTimeLimit = 0.5;

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

Рекомендации по использованию

  • Для объектов с малой массой и высокой подвижностью рекомендуется использовать более низкий sleepSpeedLimit, чтобы избежать преждевременного засыпания.
  • Для тяжёлых и статичных объектов порог можно увеличить, позволяя им быстрее «усыпать», снижая нагрузку на симуляцию.
  • В динамических сценах с множеством мелких объектов критически важно включать allowSleep, иначе вычисления столкновений будут непрерывными и затратными.

Правильная настройка механизма sleepState и порогов засыпания позволяет сочетать реалистичную физику с высокой производительностью, что делает Cannon.js мощным инструментом для сложных 3D симуляций.