Рейкастинг (raycasting) — это метод, позволяющий определить пересечение луча с объектами физического мира. В Cannon.js луч задаётся начальной точкой, направлением и длиной, после чего можно определить объекты, через которые он проходит. Основное применение рейкастов — проверка столкновений, лучевой сенсор, определение видимости и трассировка пути.
В Cannon.js рейкаст реализуется с помощью класса Ray.
Простейший пример создания луча:
const ray = new CANNON.Ray(from, to); // from и to — вектора CANNON.Vec3
Где:
from — начальная точка луча;to — конечная точка, определяющая направление и
длину.Рейкаст в Cannon.js имеет несколько режимов, которые
определяют, какие пересечения будут возвращены: ANY,
CLOSEST, ALL. Эти режимы позволяют гибко
управлять производительностью и точностью расчётов.
Режим ANY возвращает первое найденное
пересечение луча с телом, не проверяя остальные объекты. Этот
режим эффективен, когда интересует факт пересечения, а не все объекты
или ближайшее пересечение.
Ключевые особенности:
Пример использования:
const ray = new CANNON.Ray(from, to);
ray.intersectWorld(world, {
mode: CANNON.Ray.ANY,
result: result
});
if(result.hasHit){
console.log('Луч пересек объект:', result.body);
}
В объекте result содержатся основные данные о
пересечении:
hasHit — логическое значение, произошло ли
пересечение;body — тело, с которым произошло пересечение;hitPointWorld — координаты точки пересечения.Режим CLOSEST возвращает ближайшее к начальной
точке пересечение, независимо от других объектов, которые могут
лежать на пути луча. Этот режим используется, когда необходимо
определить ближайший объект перед лучом.
Особенности:
Пример использования:
const ray = new CANNON.Ray(from, to);
ray.intersectWorld(world, {
mode: CANNON.Ray.CLOSEST,
result: result
});
if(result.hasHit){
console.log('Ближайшее пересечение с объектом:', result.body);
console.log('Точка пересечения:', result.hitPointWorld);
}
Для CLOSEST полезно использовать, когда луч может
пересекать несколько объектов, но интересует только первый на пути,
например, при симуляции лазера, сенсоров или линий прицеливания.
Режим ALL возвращает все пересечения
луча с объектами мира. Этот режим применяется для полного
анализа пути луча, например, при симуляции прозрачных поверхностей,
множественных сенсоров или сложной трассировки.
Особенности:
ANY и
CLOSEST.Пример использования:
const ray = new CANNON.Ray(from, to);
const results = [];
ray.intersectWorld(world, {
mode: CANNON.Ray.ALL,
result: results
});
results.forEach(r => {
console.log('Объект на пути луча:', r.body);
console.log('Точка пересечения:', r.hitPointWorld);
});
В режиме ALL объект result представляет
собой массив, где каждый элемент содержит:
body — объект, пересечённый лучом;hitPointWorld — точка пересечения;distance — расстояние от начала луча до точки
пересечения.Для всех режимов доступны дополнительные параметры:
collisionFilterMask и collisionFilterGroup
— позволяют фильтровать объекты по группам столкновений.skipBackfaces — игнорирование задних граней тел.checkCollisionResponse — учитывать только объекты с
включённым откликом на столкновение.Пример с фильтрацией:
ray.intersectWorld(world, {
mode: CANNON.Ray.CLOSEST,
collisionFilterMask: 1, // учитываем только объекты определённой группы
skipBackfaces: true,
result: result
});
ANY для быстрого определения препятствия
на пути.CLOSEST при необходимости точного измерения
расстояния до объекта.ALL для анализа всех объектов на пути,
например, при расчёте сложного освещения или множественных
сенсоров.| Режим | Возвращает | Производительность | Использование |
|---|---|---|---|
| ANY | Первое пересечение | Высокая | Проверка наличия препятствия |
| CLOSEST | Ближайшее пересечение | Средняя | Лазеры, сенсоры, линии прицеливания |
| ALL | Все пересечения | Низкая | Полная трассировка, прозрачные объекты |
Эта классификация позволяет грамотно выбирать режим рейкаста в зависимости от целей симуляции и требований к производительности.