Библиотека Cannon.js используется для физического моделирования объектов в 3D-пространстве. Одной из ключевых особенностей является поддержка различных коллайдеров, каждый из которых имеет свои преимущества с точки зрения производительности и стабильности симуляции. Часто возникает необходимость заменить сложные Trimesh на более оптимальные структуры, такие как ConvexPolyhedron или примитивы (Box, Sphere, Cylinder), чтобы снизить нагрузку на CPU и улучшить стабильность расчётов.
Trimesh представляет собой набор треугольников, формирующих поверхность объекта. Он подходит для точного столкновения с произвольными моделями, но имеет несколько серьёзных ограничений:
Эти проблемы делают Trimesh нежелательным выбором для динамичных объектов и интерактивных сцен.
ConvexPolyhedron — это объёмный выпуклый многогранник, определяемый набором вершин и граней. Он подходит для большинства динамических объектов благодаря упрощённой математике столкновений. Основные шаги для замены Trimesh на ConvexPolyhedron:
Генерация выпуклой оболочки: Для произвольной
модели необходимо получить выпуклую оболочку (Convex Hull). Это можно
сделать с помощью алгоритмов вроде QuickHull или сторонних библиотек
(например, three.js +
THREE.ConvexGeometry).
Создание ConvexPolyhedron:
import * as CANNON from 'cannon-es';
const vertices = [
new CANNON.Vec3(-1, -1, -1),
new CANNON.Vec3(1, -1, -1),
new CANNON.Vec3(1, 1, -1),
new CANNON.Vec3(-1, 1, -1),
new CANNON.Vec3(-1, -1, 1),
new CANNON.Vec3(1, -1, 1),
new CANNON.Vec3(1, 1, 1),
new CANNON.Vec3(-1, 1, 1)
];
const faces = [
[0, 1, 2, 3],
[4, 5, 6, 7],
[0, 1, 5, 4],
[1, 2, 6, 5],
[2, 3, 7, 6],
[3, 0, 4, 7]
];
const shape = new CANNON.ConvexPolyhedron({ vertices, faces });
const body = new CANNON.Body({ mass: 1 });
body.addShape(shape);Преимущества использования ConvexPolyhedron:
В ситуациях, когда точность формы объекта не критична, предпочтительно заменять сложные Trimesh на базовые примитивы:
Пример создания примитива Box:
const boxShape = new CANNON.Box(new CANNON.Vec3(1, 2, 3));
const boxBody = new CANNON.Body({ mass: 5 });
boxBody.addShape(boxShape);
Преимущество использования примитивов заключается в том, что физический движок может рассчитывать столкновения очень быстро, а поведение объекта остаётся предсказуемым. В большинстве игровых и интерактивных приложений это важнее точной геометрии.
Для оптимизации сцены рекомендуется автоматически заменять Trimesh:
Выделение выпуклых частей модели:
Апроксимация сложных форм примитивами:
Динамическая замена:
Использование ConvexPolyhedron и примитивов вместо Trimesh в Cannon.js позволяет создавать более производительные и стабильные физические симуляции, сохраняя достаточную точность взаимодействия объектов.