我在3d空间中有成千上万个OOBB(面向对象的边界框),它包含简单的细长3d网格。他们紧紧地挤在一起。
我想拍摄光线并找出哪些OOBB被击中。由于我需要执行的光线交叉测试的数量(数百万),对所有OOBB的暴力方法是不够的。
最初我认为使用某种空间分区系统来快速缩小潜在结果会很容易,但像BVHs或KDTrees这样的系统依赖于AABB(轴对齐的边界框)来加速查询,在我的情况下,那些会效率非常低(因为我所包含的网格的对角线性质使得我的紧密堆积的OOBB大致具有相同的AABB)。
我在RAPID库中读到了OBBTrees,但似乎它们是从上到下构建的(从多边形汤开始并细分为逐渐变小的OOBB组以形成树),而不是自下而上(从大量的OOBB开始,并从中构建一个树。)
我可以使用其他任何数据结构来加速交叉口测试吗?
这是我的OOBB图片。正如你所看到的,它们是紧密的,如果你可以想象它们的AABB会是什么样子,你会发现它们重叠到基于AABB的树不会真正提升性能的程度(因为实际上所有人都会被群体中心的射线击中。
值得注意的是,我需要查询所有被光线击中的OOBB,而不仅仅是第一个/最近的一个OOBB。
答案 0 :(得分:1)
最好的方法是使用对齐grid structure的3d轴。网格中的每个单元格保持与该单元格相交的所有oobb的(向量,数组等)。 8个空单元格可以折叠成更大的空单元格,以加速空白空间的遍历。对于网格的大小,您必须进行一些测试才能找到最佳尺寸。
遍历该网格是微不足道的,您必须从距离射线原点最近的单元格开始,测试那里的所有对象,然后沿着光线移动到下一个单元格。遍历单元格基本上是一个3d保守的行光栅化,复杂度非常低。有关here
的更多信息此外,如果数据非常重叠,您可能希望有一个大网格(单元格非常小)。在这种情况下,我建议你研究space filling curves来存储网格数据。 (z-order curve非常简单)