Режимы рейкаста: ANY, CLOSEST, ALL

Рейкастинг (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

Режим 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

Режим 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

Режим 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 — расстояние от начала луча до точки пересечения.

Настройка параметров Ray

Для всех режимов доступны дополнительные параметры:

  • collisionFilterMask и collisionFilterGroup — позволяют фильтровать объекты по группам столкновений.
  • skipBackfaces — игнорирование задних граней тел.
  • checkCollisionResponse — учитывать только объекты с включённым откликом на столкновение.

Пример с фильтрацией:

ray.intersectWorld(world, {
    mode: CANNON.Ray.CLOSEST,
    collisionFilterMask: 1, // учитываем только объекты определённой группы
    skipBackfaces: true,
    result: result
});

Практические советы

  • Использовать ANY для быстрого определения препятствия на пути.
  • Применять CLOSEST при необходимости точного измерения расстояния до объекта.
  • Использовать ALL для анализа всех объектов на пути, например, при расчёте сложного освещения или множественных сенсоров.
  • Комбинировать фильтры столкновений для повышения производительности и точности.

Сравнительная таблица режимов

Режим Возвращает Производительность Использование
ANY Первое пересечение Высокая Проверка наличия препятствия
CLOSEST Ближайшее пересечение Средняя Лазеры, сенсоры, линии прицеливания
ALL Все пересечения Низкая Полная трассировка, прозрачные объекты

Эта классификация позволяет грамотно выбирать режим рейкаста в зависимости от целей симуляции и требований к производительности.