Создание и настройка World

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

import * as CANNON from 'cannon-es';

const world = new CANNON.World();

Гравитация

Гравитация задается в виде вектора CANNON.Vec3. Она определяет направление и величину силы, действующей на все тела.

world.gravity.set(0, -9.82, 0); // Стандартная гравитация вдоль оси Y

Важно учитывать единицы: Cannon.js использует метры, килограммы и секунды. Величина гравитации должна соответствовать масштабу сцены.

Интеграция

Метод интеграции определяет, как физика обновляет положение и скорость тел. Cannon.js поддерживает различные типы интеграторов, но по умолчанию используется Euler. Для повышения стабильности симуляции можно использовать более точный Runge-Kutta.

world.solver.iterations = 10;  // Количество итераций решения системы ограничений
world.broadphase = new CANNON.NaiveBroadphase(); // Простая проверка столкновений
  • solver.iterations — чем больше итераций, тем точнее расчёт контактов, но выше нагрузка на процессор.
  • broadphase — алгоритм определения потенциальных столкновений. NaiveBroadphase проверяет все пары, SAPBroadphase оптимизирован для длинных объектов.

Время симуляции

Для стабильной физики необходимо контролировать шаг времени. В Cannon.js используется метод step, который принимает фиксированный шаг времени и текущее время.

const timeStep = 1 / 60; // 60 кадров в секунду
world.step(timeStep);
  • Фиксированный шаг времени предотвращает “дрожание” объектов при изменении FPS.
  • Для более сложных симуляций рекомендуется применять интерполяцию между кадрами.

Деформации и материалы

Материалы (Material) задают физические свойства поверхности: трение и упругость. С их помощью создаются реалистичные взаимодействия между телами.

const groundMaterial = new CANNON.Material('ground');
const ballMaterial = new CANNON.Material('ball');

const contactMaterial = new CANNON.ContactMaterial(
  groundMaterial,
  ballMaterial,
  {
    friction: 0.4,
    restitution: 0.7
  }
);

world.addContactMaterial(contactMaterial);
  • friction — сила трения между поверхностями.
  • restitution — коэффициент упругости при столкновении.

Использование ContactMaterial позволяет создавать разные физические реакции для различных пар материалов.

Атрибуты мира

World имеет несколько важных атрибутов, влияющих на динамику:

  • allowSleep — разрешает телам входить в состояние покоя, если они не движутся, что оптимизирует производительность.
  • gravity — вектор силы тяжести.
  • broadphase — алгоритм предварительной фильтрации столкновений.
  • solver — объект, решающий систему ограничений.
world.allowSleep = true;

Обработка столкновений

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

ballBody.addEventListener('collide', function(event) {
    console.log('Столкновение с телом:', event.body.id);
});

event.body содержит ссылку на объект, с которым произошло столкновение, а event.contact — подробности контакта (точки, нормали, силы).

Производительность и оптимизация

  • Использование allowSleep снижает количество вычислений для неподвижных тел.
  • Выбор подходящего broadphase минимизирует проверку ненужных пар.
  • Настройка solver.iterations позволяет балансировать между точностью и нагрузкой на CPU.
  • Разделение мира на зоны с разными материалами и контактами улучшает реализм и управляемость симуляции.

Итоговые шаги создания мира

  1. Создать объект World.
  2. Задать гравитацию.
  3. Настроить интегратор и алгоритмы столкновений.
  4. Определить материалы и контактные свойства.
  5. Включить оптимизации (allowSleep, подходящий broadphase).
  6. Регулярно вызывать world.step(timeStep) в цикле обновления сцены.

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