Паузы, сброс и пересоздание мира

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

Пример реализации паузы:

let isPaused = false;
function animate() {
    requestAnimationFrame(animate);
    if (!isPaused) {
        world.step(timeStep);
    }
    // рендеринг сцены
    renderer.render(scene, camera);
}

Ключевой момент — условие проверки isPaused перед шагом мира. При true физика не обновляется, но графическая сцена может продолжать рендериться, что позволяет сохранять визуальную интерактивность интерфейса.

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

world.step(timeStep, deltaTime, maxSubSteps);
  • timeStep — фиксированный шаг симуляции (например, 1/60).
  • deltaTime — фактическое прошедшее время с прошлого кадра.
  • maxSubSteps — максимальное число шагов за один кадр для предотвращения пропусков.

Сброс мира

Иногда требуется полностью очистить физический мир, чтобы начать симуляцию заново. Cannon.js не имеет встроенного метода reset, поэтому процесс осуществляется вручную. Основные шаги:

  1. Удаление всех тел
world.bodies.forEach(body => {
    world.removeBody(body);
});
  1. Удаление всех ограничений
world.constraints.forEach(constraint => {
    world.removeConstraint(constraint);
});
  1. Очистка контактов и накопленных данных
world.contacts.length = 0;
world.accumulators.forEach(acc => acc.clear());
  1. Сброс глобальных параметров мира Значения gravity, solver.iterations, broadphase можно оставить или переопределить:
world.gravity.set(0, -9.82, 0);
world.solver.iterations = 10;

Полный сброс гарантирует отсутствие артефактов старой симуляции и позволяет безопасно пересоздавать объекты.

Пересоздание мира

Пересоздание мира часто используется при изменении основных параметров симуляции, например при смене размеров объектов или изменении физического движка (solver, broadphase). Создание нового мира происходит следующим образом:

world = new CANNON.World();
world.gravity.set(0, -9.82, 0);
world.broadphase = new CANNON.NaiveBroadphase();
world.solver.iterations = 10;

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

const material = new CANNON.Material("default");
const sphereBody = new CANNON.Body({
    mass: 5,
    shape: new CANNON.Sphere(1),
    material: material
});
world.addBody(sphereBody);

Важные аспекты при пересоздании и сбросе

  • Ссылки на старые объекты: после пересоздания мира все старые Body, Constraint и Material становятся недействительными в новом мире. Их необходимо создавать заново.
  • Глобальные свойства мира: параметры gravity, solver, broadphase задаются заново, иначе используются значения по умолчанию.
  • Производительность: удаление большого количества тел и пересоздание мира может быть дорогим по ресурсу. Для игр с динамическими сценами рекомендуется минимизировать полный сброс и использовать обновление отдельных тел.
  • События мира: после пересоздания необходимо заново подписываться на события postStep, beginContact, если они использовались.

Практические сценарии

  1. Пауза при интерактивной настройке: пользователь может приостановить симуляцию, изменить параметры тела и продолжить без потери состояния.
  2. Сброс после неудачного эксперимента: например, обрушение конструкции, после чего сцена очищается и симуляция начинается с нуля.
  3. Пересоздание мира для смены физики: изменение solver или broadphase требует создания нового мира, так как эти параметры не могут быть изменены на лету.

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