При работе с физикой в браузере с помощью библиотеки Cannon.js производительность напрямую зависит от сложности физических тел (коллайдеров). Тяжёлые или высокополигональные меши визуальной сцены создают избыточную нагрузку на движок физики. Для эффективного моделирования используют упрощённые коллайдеры — примитивные формы, приближённо описывающие объект.
Ключевые принципы:
В Cannon.js доступны базовые типы тел:
Box – прямоугольный параллелепипед, задаётся размером по трём осям.
const halfExtents = new CANNON.Vec3(1, 2, 1);
const boxShape = new CANNON.Box(halfExtents);
Box отлично подходит для мебели, ящиков и стен.
Sphere – сферический коллайдер, определяется радиусом.
const radius = 1;
const sphereShape = new CANNON.Sphere(radius);
Sphere удобна для шаров, мячей и круглых деталей.
Cylinder – цилиндр, задаётся радиусами оснований и высотой.
const radiusTop = 0.5;
const radiusBottom = 0.5;
const height = 2;
const numSegments = 8;
const cylinderShape = new CANNON.Cylinder(radiusTop, radiusBottom, height, numSegments);
Cylinder эффективен для бочек, труб и колонн.
ConvexPolyhedron – многогранник с произвольной формой. Используется только тогда, когда примитивы не обеспечивают достаточной точности. Нагрузка на движок заметно выше.
Смешивание примитивов Сложные объекты разбиваются на комбинацию нескольких простых форм. Например, автомобиль можно представить как комбинацию Box для корпуса и цилиндров для колёс.
Использование невидимых физических тел Для визуальных мешей создаются отдельные тела с упрощённой геометрией. Визуальная сцена и физика не привязаны напрямую, что уменьшает вычислительную нагрузку.
Масштабирование и центрирование В Cannon.js коллайдеры задаются относительно центра тела. Для сложных объектов важно корректно смещать примитивы, чтобы центр масс совпадал с визуальной моделью.
const carBody = new CANNON.Body({ mass: 1500 });
// Корпус автомобиля
const chassisShape = new CANNON.Box(new CANNON.Vec3(2, 0.5, 4));
carBody.addShape(chassisShape, new CANNON.Vec3(0, 0.5, 0));
// Колёса
const wheelShape = new CANNON.Sphere(0.4);
const wheelPositions = [
new CANNON.Vec3(-1.5, 0, 3),
new CANNON.Vec3(1.5, 0, 3),
new CANNON.Vec3(-1.5, 0, -3),
new CANNON.Vec3(1.5, 0, -3),
];
wheelPositions.forEach(pos => carBody.addShape(wheelShape, pos));
В этом примере корпус автомобиля и колёса заменены на Box и Sphere. Физика остаётся правдоподобной, а производительность значительно выше, чем при использовании полного меша автомобиля.
Применение нескольких примитивов вместо одного сложного полигона снижает вероятность проскакивания коллизий и уменьшает количество сложных вычислений для движка.
Использование упрощённых коллайдеров в Cannon.js позволяет создать реалистичную физику без чрезмерной нагрузки на браузер, обеспечивая плавную работу даже на сложных сценах с большим количеством объектов.