Как быстро протестировать пересечение лучей против плотной группы OOBB?

У меня есть тысячи OOBB (объектно-ориентированных ограничивающих прямоугольников) в трехмерном пространстве, которые охватывают простые удлиненные трехмерные сетки. Они плотно упакованы вместе.

Я хотел бы выстрелить в них лучами и выяснить, какие OOBB попадают под удар. Из-за количества тестов пересечения лучей, которые мне нужно выполнить (миллионы), грубой силы для всех OOBB будет недостаточно.

Первоначально я думал, что будет легко использовать какую-то систему пространственного разбиения, чтобы быстро сузить потенциальные результаты, но такие системы, как BVH или KDTrees, полагаются на AABB (ограничительные рамки, выровненные по оси) для ускорения запросов, и в моем случае это было бы очень неэффективно. (потому что многие мои плотно упакованные OOBB имеют примерно одинаковую AABB из-за диагонального характера сетки, которую они охватывают).

Я читал о OBBT-деревьях в библиотеке RAPID, но кажется, что они строятся сверху вниз (начинают с полигонального супа и подразделяются на все более мелкие группы OOBB, чтобы сформировать дерево), а не снизу вверх (начинают с большого количества OOBB). и построить из них дерево).

Существуют ли какие-либо другие структуры данных, которые я могу использовать для ускорения тестов пересечения?

Вот фото моих OOBB. Как вы можете видеть, они плотно упакованы, и если вы можете представить себе, как будет выглядеть их AABB, вы увидите, что они будут перекрываться до такой степени, что дерево на основе AABB не будет действительно повышать производительность (потому что практически все они будет поражен лучом, проходящим через центр группы).

Стоит отметить, что мне нужно запросить все OOBB, на которые попал луч, а не только первый/ближайший.

OOBBs


person Tyson    schedule 02.05.2017    source источник
comment
попробуйте повернуть луч в какое-то пространство, где большинство bbs близки к aabbs, и использовать какой-то алгоритм разделения пространства в этом новом пространстве. другое решение, которое применяется, если объект не меняется от луча к лучу, за исключением линейного преобразования: вы также можете создать трехмерный массив, в котором каждая ячейка имеет список пересекающих ее треугольников / oobbs, и шагать по лучу через этот трехмерный множество.   -  person programmerjake    schedule 02.05.2017
comment
Насколько динамична сцена? То есть, сколько лучей вы отбросите, пока не изменятся OOBB, и насколько сильно они изменятся?   -  person Angew is no longer proud of SO    schedule 02.05.2017
comment
@programmerjake К сожалению, первое предложение не сработает, потому что OOBB не всегда будут хорошо выровнены, как в моем примере изображения. Второй вариант может быть ближе к чему-то, но объем памяти и требования к предварительной обработке могут быть проблемой ... Мне нужно решение для работы в очень больших трехмерных средах, где трехмерный массив невозможен (потребуются миллиарды ячеек). включить все, сохраняя при этом разумную степень детализации). Но спасибо за предложения.   -  person Tyson    schedule 02.05.2017
comment
@Angew Я проведу несколько миллионов лучей, прежде чем изменятся OOBB. Они могут довольно сильно меняться на каждом шаге моделирования (они охватывают треугольники, движущиеся по произвольным траекториям).   -  person Tyson    schedule 02.05.2017
comment
@Tyson Как насчет использования трехмерной сетки, где каждую ячейку со слишком большим количеством треугольников вы делите на меньшую сетку?   -  person programmerjake    schedule 02.05.2017
comment
@programmerjake Думаю, это будет похоже на октодерево или что-то в этом роде?   -  person Tyson    schedule 02.05.2017
comment
@programmerjake На самом деле ваше предложение натолкнуло меня на идею. Вместо того, чтобы разбивать сетку, я думаю, что попытаюсь разделить каждый OOBB вдоль его самой длинной оси, пока его форма не станет ближе к кубу. Каждый из этих разделенных OOBB будет содержать указатели на базовую геометрию, поэтому независимо от того, какой из них будет затронут, он все равно будет связан с сеткой, которую я хочу протестировать. Затем я разделю их, используя обычную структуру с ускорением AABB. Преобразование всех их в кубоиды должно уменьшить их количество, возвращаемое для любого заданного луча.   -  person Tyson    schedule 02.05.2017


Ответы (1)


Вероятно, лучше всего использовать выровненную по 3D-оси структуру сетки. Каждая ячейка в сетке содержит (вектор, массив и т. д.) все oobb, которые пересекают эту ячейку. 8 пустых ячеек можно свернуть в большую пустую ячейку, чтобы ускорить обход пустого пространства. Для размера сетки вам придется провести некоторое тестирование, чтобы найти оптимальный размер.

Обход этой сетки тривиален, вам придется начать с ближайшей к началу луча ячейки, протестировать все объекты там, а затем перейти к следующей ячейке вдоль луча. Обход ячейки — это, по сути, трехмерная консервативная растеризация линий, которая очень проста по сложности. Подробнее об этом здесь


Кроме того, если данные сильно перекрываются, вы можете захотеть иметь большую сетку (где ячейки очень маленькие). В этом случае я бы посоветовал вам изучить кривые заполнения пространства для хранения данных сетки. . (кривая z-порядка удивительно проста)

person Raxvan    schedule 03.05.2017