Dynamic 有效检测物体间碰撞的最佳算法

Dynamic 有效检测物体间碰撞的最佳算法,dynamic,structure,collision-detection,Dynamic,Structure,Collision Detection,我很困惑。好吧,不要困惑,甚至不想做6个测试程序,看看哪种算法是最好的。所以我想我应该请我在So的专家朋友们给我他们的经验 该场景是一个3d场景,与其中对象的大小相比,可能有相当大的面积。场景中可能有数千个对象。物体的大小从十分之一个单位到大约10个单位不等,但没有更大(或更小)。对象倾向于聚集在一起,但这些聚集可能出现在场景中的任何位置。所有对象都是动态和移动的。星团倾向于一起移动,但当它们一起移动时,它们的速度可能并不总是相同的。还有静态几何要考虑。虽然有大量的动态对象,但场景中也有一些静态

我很困惑。好吧,不要困惑,甚至不想做6个测试程序,看看哪种算法是最好的。所以我想我应该请我在So的专家朋友们给我他们的经验

该场景是一个3d场景,与其中对象的大小相比,可能有相当大的面积。场景中可能有数千个对象。物体的大小从十分之一个单位到大约10个单位不等,但没有更大(或更小)。对象倾向于聚集在一起,但这些聚集可能出现在场景中的任何位置。所有对象都是动态和移动的。星团倾向于一起移动,但当它们一起移动时,它们的速度可能并不总是相同的。还有静态几何要考虑。虽然有大量的动态对象,但场景中也有一些静态对象(静态对象往往比动态对象大一到两个数量级)

现在,我想要的是一个空间数据结构,用于有效地执行场景中所有项目的碰撞检测。如果该算法也支持可见性查询(对于渲染管道),那就太好了。为简单起见,假设此处的碰撞检测是宽相位(即所有动态对象都是完美球体)

因此,在我的研究中,我可以使用以下方法之一:

(1) 八叉树 (2) 松散八叉树 (3) 线性八叉树(+松散) (4) KD树 (5) BSP树 (6) 散列

到目前为止(6)是我唯一尝试过的。如果场景中的对象平均分布均匀,那么在速度方面(在我的系统中,8192个项目在1ms内被检查到)它实际上是非常棒的。如果所有对象都耦合到一个较小的区域,那么这不是一个好的算法,我认为这是可能的

有没有人知道该用哪一种,或者我可以用什么技巧来加速?我认为无论发生什么,我都可以对静态几何体使用单独的BSP树。我想动态的“球体”是我在这里最关心的。注意:没有CUDA,这只是CPU:p

谢谢

编辑:好的,多亏了Floris,我找到了更多关于AABB树的信息。这里有一个关于GameDev的老讨论:。看来这是一个很好的妥协


最终编辑:决定不重新发明轮子。bullet physics library有可能为我完成所有这些工作(其中包含AABB树,可能也进行了很好的优化)。

许多物理引擎使用AABBTree(轴对齐边界框树),它将对象细分为越来越小的块。使用此算法可以获得非常好的碰撞检测。这棵树看起来有点像八叉树

OOBBTree(定向边界框)是最好的对应部分。

好问题

基本上,您需要在以下两者之间进行复杂的权衡:

  • 完整碰撞检测阶段的速度
  • 对象移动时更新/维护数据结构的开销
  • 坏消息是,没有“完美”的答案,因为这将真正取决于许多不同的因素独特的情况。例如,BSP对于1的速度非常快。当它们通过大量静态平面几何进行预计算时,这就解释了为什么它们在早期FPS游戏中如此流行

    我个人的猜测是,一个松散的AABB(轴对齐的边界框)树,在每个底层边界框中有合理数量的对象(5-10?),可能在您的情况下效果最好。原因:

    • 您有一个相当大/稀疏的空间,其中包含对象簇。AABB树在这方面很好,因为你可以裁剪出很多你需要的关卡
    • 你假设的是完美球体。球体到球体碰撞测试非常便宜,因此您可以轻松地为每个底层节点进行10-45次测试。基本上,N^2适用于较小的N:-)
    • 与大多数替代方案相比,轴对齐使更新树更加简单,交点测试更加便宜。由于您假设的是大致呈球形的对象,因此我认为您不会从定向边界框中获得太多好处(只有当您在有趣的角度有许多长/细形状时,定向边界框才真正给您带来优势)
    • 通过允许边界框松散并包含合理数量的对象,可以减少任何单个对象的运动超出AABB边界的可能性。除非发生这种情况,否则不需要更新树。这将为您节省大量的树更新时间。当它发生时,用一点边距延伸边界,这样你就不必立即在下一帧重新延伸-记住,大多数运动倾向于在同一方向上持续几帧

    对不起,有点毛骨悚然的回答,但我希望这给你一些有用的想法/事情要考虑。 对于动态场景,您可能可以跳过KD树。KD tree在静态数据集上的工作,每次单个元素移动时,您都必须重建整个(子)树,它看起来太密集,无法在动态场景中使用。当然。这是一个边界卷层次结构,对于细粒度交叉测试来说可能更好。我想要的是宽相位(即单个运动球体/粒子)检测的想法。-我的错误。。。我会进一步调查的。我在网络上发现的第一个例子看起来像是在进行细粒度碰撞,但我将在mo中看到更多。精彩答案mikera。谢谢你,不用担心。您还可以在该链接中找到其他一些好主意: