Коллизии в Three.js определяют взаимодействие объектов в 3D-пространстве. В отличие от игровых движков, Three.js не предоставляет встроенного физического движка, поэтому разработка столкновений требует применения математических методов, таких как проверка пересечения Bounding Box, Bounding Sphere или кастомных Raycasting-алгоритмов.
Bounding Box (оси-выравненный) — это прямоугольный
параллелепипед, полностью охватывающий объект. В Three.js для его
создания используется THREE.Box3:
const box = new THREE.Box3().setFromObject(mesh);
Проверка пересечения двух объектов выполняется через метод
intersectsBox:
if (box1.intersectsBox(box2)) {
console.log('Столкновение обнаружено');
}
Bounding Sphere подходит для объектов, близких к
сферической форме. Создание сферы выполняется через
THREE.Sphere и метод setFromPoints для набора
вершин объекта.
const sphere = new THREE.Sphere().setFromPoints(mesh.geometry.attributes.position.array);
Проверка столкновения выполняется через
intersectsSphere:
if (sphere1.intersectsSphere(sphere2)) {
console.log('Сфера столкнулась с другой сферой');
}
THREE.Raycaster — мощный инструмент для обнаружения
пересечений луча с объектами сцены. Это основной способ определения
коллизий для мыши и направления движения объектов.
const raycaster = new THREE.Raycaster(origin, direction);
const intersects = raycaster.intersectObjects(scene.children, true);
if (intersects.length > 0) {
console.log('Объект пересечен лучом', intersects[0].object);
}
Особенности Raycasting:
point) и
нормаль поверхности (face.normal).recursive = true.Three.js не содержит собственной системы событий для коллизий, поэтому обычно создаются кастомные события через проверку условий и вызов функций обратного вызова.
Пример создания события столкновения между двумя объектами:
function checkCollision(obj1, obj2, callback) {
const box1 = new THREE.Box3().setFromObject(obj1);
const box2 = new THREE.Box3().setFromObject(obj2);
if (box1.intersectsBox(box2)) {
callback(obj1, obj2);
}
}
checkCollision(mesh1, mesh2, (a, b) => {
console.log(`${a.name} столкнулся с ${b.name}`);
});
Можно объединять Raycasting с событиями коллизий для более сложной логики, например, при наведении курсора на объект или при движении персонажа.
Проверка столкновений на больших сценах может быть ресурсоёмкой. Основные методы оптимизации:
layers): объекты могут
иметь отдельные слои, чтобы исключить ненужные проверки.Box3 и Sphere для статических объектов
уменьшают накладные расходы.Игровые персонажи и препятствия Объект персонажа
имеет Bounding Box, а объекты сцены (стены, платформы)
проверяются на пересечение. При столкновении персонаж останавливается
или получает физический отталкивающий эффект.
Навигация камеры Камера может использовать
Raycaster для обнаружения стен и предотвращения прохождения
через объекты.
Интерактивные объекты С помощью Raycaster реализуется выбор объектов мышью, подсветка при наведении и активация событий при клике.
Для сложных физических взаимодействий интегрируются внешние движки, такие как Cannon.js или Ammo.js, а Three.js выступает в роли визуализатора. В этом случае коллизии рассчитываются движком, а сцена обновляется по координатам объектов.
Пример интеграции с Cannon.js:
const shape = new CANNON.Box(new CANNON.Vec3(1, 1, 1));
const body = new CANNON.Body({ mass: 1 });
body.addShape(shape);
world.addBody(body);
// Обновление позиции Three.js объекта по данным физики
mesh.position.copy(body.position);
mesh.quaternion.copy(body.quaternion);
Box3 и Sphere для базовых
коллизий.Raycaster для интерактивных действий и
направления движения.Такой подход обеспечивает точное и эффективное управление столкновениями и событиями в 3D-сценах на Three.js.