RayCastAll: все пересечения вдоль луча

В физическом движке Oimo.js метод rayCastAll позволяет определить все объекты, пересекающие заданный луч в трехмерном пространстве. В отличие от rayCast, который возвращает только первое столкновение, rayCastAll собирает все пересечения, что особенно полезно для анализа сложных сцен или реализации точного взаимодействия с множеством тел.


Синтаксис и основные параметры

Метод вызывается через объект мира (world) или через отдельные коллайдеры, и имеет следующую структуру:

world.rayCastAll(origin, direction, maxDistance, callback);
  • origin — вектор начала луча, OIMO.Vec3.
  • direction — нормализованный вектор направления луча, OIMO.Vec3.
  • maxDistance — максимальная длина луча. Все пересечения за пределами этого расстояния игнорируются.
  • callback — функция обратного вызова, которая вызывается для каждого пересечения.

Callback-функция принимает один аргумент — объект столкновения (hit), содержащий следующую информацию:

  • hit.body — ссылка на тело (OIMO.RigidBody), с которым произошло пересечение.
  • hit.point — точка пересечения в мировых координатах, OIMO.Vec3.
  • hit.normal — нормаль поверхности в точке пересечения.
  • hit.fraction — доля длины луча до точки пересечения (значение от 0 до 1, где 1 — максимальное расстояние).

Пример базового использования

const origin = new OIMO.Vec3(0, 5, 0);
const direction = new OIMO.Vec3(0, -1, 0).normalize();
const maxDistance = 10;

world.rayCastAll(origin, direction, maxDistance, (hit) => {
    console.log(`Пересечение с телом: ${hit.body.name}`);
    console.log(`Точка: (${hit.point.x}, ${hit.point.y}, ${hit.point.z})`);
    console.log(`Нормаль: (${hit.normal.x}, ${hit.normal.y}, ${hit.normal.z})`);
});

В этом примере луч направлен вниз и фиксирует все объекты, расположенные под точкой (0, 5, 0) на расстоянии до 10 единиц.


Важные особенности

  1. Сортировка по расстоянию rayCastAll возвращает пересечения в порядке возрастания hit.fraction. Это позволяет обрабатывать объекты последовательно от ближайшего к дальнему.

  2. Совместимость с динамическими и статическими телами Луч обнаруживает столкновения с любыми телами сцены — статическими (static) и динамическими (dynamic). Для исключения определённых объектов можно использовать фильтры коллайдеров или проверку свойств тел внутри callback.

  3. Производительность Каждый вызов rayCastAll обходится по всем телам, пересечения проверяются через Bounding Volume Hierarchy (BVH). Для большого числа объектов рекомендуется ограничивать длину луча или заранее исключать неактуальные тела, чтобы снизить нагрузку.

  4. Нормали и локальные координаты Нормаль hit.normal всегда возвращается в мировых координатах. Для вычисления локальной точки пересечения относительно тела используется метод:

const localPoint = hit.body.toLocalPoint(hit.point);
  1. Использование нескольких лучей Для сложных эффектов, таких как лазеры или сенсоры, можно вызывать rayCastAll для нескольких направлений, а затем фильтровать пересечения по типу объекта или глубине проникновения.

Расширенные сценарии

  • Многослойное обнаружение Можно организовать последовательный анализ слоев сцены, вызывая rayCastAll с разными масками коллайдеров. Это позволяет реализовать, например, прицеливание через прозрачные объекты или визуальные эффекты прохождения луча через несколько тел.

  • Физические реакции на все столкновения После получения всех пересечений возможно применять силы к каждому телу:

world.rayCastAll(origin, direction, maxDistance, (hit) => {
    const forceDir = hit.normal.scale(-1);
    hit.body.applyForce(forceDir.scale(10), hit.point);
});

Такой подход полезен для симуляции взрывов, ударов или толчков.

  • Интерактивные эффекты Для игр и визуализаций rayCastAll используется для определения всех объектов под курсором или для расчета траекторий движения с точным учетом пересечений.

Рекомендации по использованию

  • Всегда нормализовать вектор направления, чтобы hit.fraction корректно отображал долю пути луча.
  • Для частых проверок в реальном времени лучше ограничивать длину луча и использовать маски коллайдеров.
  • При необходимости хранить результаты, рекомендуется сортировать их самостоятельно по дополнительным критериям, например, по типу объекта или материалу поверхности.

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