В физическом движке Oimo.js метод
rayCastAll позволяет определить все объекты, пересекающие
заданный луч в трехмерном пространстве. В отличие от
rayCast, который возвращает только первое столкновение,
rayCastAll собирает все пересечения, что
особенно полезно для анализа сложных сцен или реализации точного
взаимодействия с множеством тел.
Метод вызывается через объект мира (world) или через
отдельные коллайдеры, и имеет следующую структуру:
world.rayCastAll(origin, direction, maxDistance, callback);
OIMO.Vec3.OIMO.Vec3.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 единиц.
Сортировка по расстоянию rayCastAll
возвращает пересечения в порядке возрастания hit.fraction.
Это позволяет обрабатывать объекты последовательно от ближайшего к
дальнему.
Совместимость с динамическими и статическими
телами Луч обнаруживает столкновения с любыми телами сцены —
статическими (static) и динамическими
(dynamic). Для исключения определённых объектов можно
использовать фильтры коллайдеров или проверку свойств тел внутри
callback.
Производительность Каждый вызов
rayCastAll обходится по всем телам, пересечения проверяются
через Bounding Volume Hierarchy (BVH). Для большого числа объектов
рекомендуется ограничивать длину луча или заранее
исключать неактуальные тела, чтобы снизить нагрузку.
Нормали и локальные координаты Нормаль
hit.normal всегда возвращается в мировых координатах. Для
вычисления локальной точки пересечения относительно тела используется
метод:
const localPoint = hit.body.toLocalPoint(hit.point);
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 мощным
инструментом для анализа сложных сцен, точного обнаружения всех
пересечений и управления физическими реакциями объектов в
пространстве.