В Cannon.js объекты столкновений представлены с помощью различных форм, среди которых ключевую роль играют AABB (Axis-Aligned Bounding Box) и OBB (Oriented Bounding Box). Они используются для предварительного определения возможных пересечений и оптимизации физического расчета столкновений.
AABB — это ограничивающий прямоугольный параллелепипед, стороны которого всегда ориентированы вдоль глобальных осей координат (X, Y, Z). Это делает расчёт пересечений очень быстрым, но менее точным для объектов, повернутых относительно осей.
Создание и обновление AABB:
const boxShape = new CANNON.Box(new CANNON.Vec3(1, 2, 3));
const aabb = new CANNON.AABB();
boxShape.calculateWorldAABB(
new CANNON.Vec3(0, 0, 0), // позиция
new CANNON.Quaternion(0, 0, 0, 1), // ориентация
aabb.lowerBound,
aabb.upperBound
);
lowerBound и upperBound — минимальные и
максимальные координаты коробки.calculateWorldAABB учитывает положение и ориентацию
объекта в мире.Основные операции с AABB:
if(aabb1.overlaps(aabb2)) {
console.log("Пересечение обнаружено");
}
aabb1.extend(aabb2);
if(aabb1.containsPoint(new CANNON.Vec3(1, 0, 0))) {
console.log("Точка внутри AABB");
}
AABB применяется на этапе broad-phase, когда необходимо быстро отсеять объекты, которые точно не могут пересечься, прежде чем переходить к более точной проверке столкновений.
OBB — это ограничивающий параллелепипед, который может быть повернут относительно глобальных осей. В Cannon.js прямой поддержки полноценного OBB нет, но его можно реализовать через комбинацию Box формы и ориентации объекта через кватернионы.
Пример использования OBB через Box с ориентацией:
const boxShape = new CANNON.Box(new CANNON.Vec3(1, 2, 3));
const position = new CANNON.Vec3(0, 0, 0);
const quaternion = new CANNON.Quaternion();
quaternion.setFromEuler(Math.PI/4, Math.PI/6, 0);
const aabb = new CANNON.AABB();
boxShape.calculateWorldAABB(position, quaternion, aabb.lowerBound, aabb.upperBound);
Таким образом, OBB косвенно учитывается через ориентацию и последующее вычисление AABB, что позволяет интегрировать ориентированные объекты в broad-phase алгоритмы.
Особенности работы с OBB:
Пересечение двух AABB производится сравнением минимальных и максимальных координат по каждой оси:
aabb1.upperBound.x >= aabb2.lowerBound.x &&
aabb1.lowerBound.x <= aabb2.upperBound.x &&
aabb1.upperBound.y >= aabb2.lowerBound.y &&
aabb1.lowerBound.y <= aabb2.upperBound.y &&
aabb1.upperBound.z >= aabb2.lowerBound.z &&
aabb1.lowerBound.z <= aabb2.upperBound.z
Расширение AABB для включения новой точки:
aabb.extendPoint(point); // point — CANNON.Vec3
Расширение для объединения с другой AABB:
aabb.extend(aabb2);
Эти операции позволяют динамически поддерживать актуальные границы объектов, что критично для реалистичной физики и оптимизации broad-phase столкновений.
В Cannon.js этап broad-phase реализован через
NaiveBroadphase или SAPBroadphase:
Пример инициализации world с broad-phase:
const world = new CANNON.World();
world.broadphase = new CANNON.SAPBroadphase(world);
world.gravity.set(0, -9.82, 0);
AABB и косвенно OBB обеспечивают корректное функционирование этих алгоритмов, так как они предоставляют минимальные ограничивающие объекты для быстрой фильтрации потенциальных столкновений.