Типичные ошибки и способы их диагностики

Ошибки при создании физического мира

Неправильная инициализация мира — одна из самых частых проблем. В Cannon.js физический мир создаётся через объект CANNON.World. Часто встречается ситуация, когда забывают настроить gravity или используют некорректные единицы измерения. Например, world.gravity.set(0, -9.82, 0) задаёт стандартное ускорение свободного падения в метрах в секунду. Использование слишком больших или слишком маленьких значений ведёт к странным эффектам: объекты могут «пролетать» сквозь пол или падать с невероятной скоростью.

Диагностика: проверить значения gravity, broadphase и solver.iterations. Некорректные параметры broadphase (например, NaiveBroadphase при большом количестве объектов) сильно снижают производительность и могут пропускать коллизии.

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

Коллизии и взаимодействие тел

Неправильные формы тел (shapes) — частая причина неожиданных физических эффектов. Например, использование CANNON.Box для сферического объекта создаёт некорректные столкновения. Ещё одна ошибка — некорректное масштабирование форм:

const sphereShape = new CANNON.Sphere(1);
const body = new CANNON.Body({ mass: 1 });
body.addShape(sphereShape, new CANNON.Vec3(0, 0, 0));

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

Диагностика: включение визуализации коллизий через cannon-debugger помогает увидеть несоответствия между формой тела и её физической коллизией.

Неправильные массы и центры масс приводят к неестественной динамике: объекты могут вращаться слишком быстро или зависать в воздухе. Для сложных тел важно правильно задавать mass и смещать shape offset:

body.addShape(boxShape, new CANNON.Vec3(0, 0.5, 0));
body.mass = 2;
body.updateMassProperties();

Проблемы с интеграцией и обновлением мира

Пропущенный шаг симуляции. В Cannon.js мир обновляется вручную через world.step(dt). Часто забывают вызывать этот метод или используют слишком большой dt, что приводит к нестабильности:

const fixedTimeStep = 1.0 / 60.0;
const maxSubSteps = 3;

world.step(fixedTimeStep, deltaTime, maxSubSteps);

Диагностика: проверка частоты вызова world.step и значения dt. При высоких deltaTime объекты могут «телепортироваться» или застревать в других телах.

Проблемы с материалами и трением

Некорректная настройка контактов. В Cannon.js используется CANNON.Material и ContactMaterial для определения трения и упругости взаимодействия. Ошибки проявляются как «липкие» или чрезмерно скользкие объекты:

const groundMaterial = new CANNON.Material("groundMaterial");
const sphereMaterial = new CANNON.Material("sphereMaterial");

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

world.addContactMaterial(contactMaterial);

Диагностика: проверка всех материалов и контактных параметров. Если объекты ведут себя нестабильно, часто проблема в несоответствии трения или упругости.

Синхронизация физики и визуальной модели

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

mesh.position.copy(body.position);
mesh.quaternion.copy(body.quaternion);

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

Потенциальные «тонкие» ошибки

  • Нулевой или отрицательный mass для динамических тел. Тело с массой 0 становится статическим, что ломает динамику.
  • Слишком мало итераций солвера (solver.iterations) приводит к «проваливаниям» объектов сквозь друг друга.
  • Использование глобальных векторов вместо копий в методах типа addShape или applyForce может привести к неожиданной мутации данных.

Методы диагностики и отладки

  • Включение логирования позиции, силы и скорости объектов через console.log(body.position, body.velocity).
  • Использование визуальных дебагеров (cannon-debugger) для проверки форм и коллизий.
  • Разделение симуляции на маленькие шаги и постепенное увеличение dt для поиска критических точек нестабильности.
  • Проверка всех зависимостей: если объект не взаимодействует с другим, проверить, что оба объекта динамические и имеют корректные материалы.

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