对象之间有效碰撞检测的最佳算法

时间:2011-08-18 12:13:56

标签: dynamic structure collision-detection

我很困惑。好吧不要混淆,不要想做6个测试程序,看看哪个算法最好。所以我想我会问我在这里的专家朋友给我带来他们经验的好处。

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

现在,我想要的是一个空间数据结构,用于有效地对场景中的所有项目执行碰撞检测。如果算法也支持可见性查询,那么对于渲染管道来说会很棒。为简单起见,假设这里的碰撞检测是宽相的(即所有动态物体都是完美的球体)。

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

(1)八月 (2)松散的八叉树 (3)线性八叉树(+松散) (4)KD树 (5)BSP树 (6)哈希

到目前为止(6)是我尝试过的唯一一个。如果场景中的物体平均均匀分布,它在速度方面实际上非常出色(在我的系统上,在1ms下检查8192项物品)。如果所有物体都被卷入一个较小的区域,这不是一个好的算法,我想这是可能的。

有没有人对使用哪一个或者我可以用来加快速度的任何技巧有所了解?我想无论发生什么,我都可以使用单独的BSP树作为静态几何体。我想动态的“领域”是我最关心的问题。注意:没有CUDA,这只是CPU:p。

由于

编辑:好的,多亏了Floris,我发现了有关AABB Trees的更多信息。这里有关于GameDev的旧讨论:http://www.gamedev.net/topic/308665-aabb-tree---wheres-the-poly-o_o/。看起来是一个很好的妥协。

最终编辑:决定不重新发明轮子。子弹物理库可能会为我做所有这些(它有AABB树,也可能非常优化)。

2 个答案:

答案 0 :(得分:18)

很棒的问题。

你们之间基本上有一个复杂的权衡:

  1. 完整碰撞检测阶段的速度
  2. 在对象移动时更新/维护数据结构的开销
  3. 坏消息是,由于这一点,没有“完美”的答案 - 它将真正依赖于您的情况所特有的许多不同因素。例如,当BSP用大量静态平面几何体预先计算时,BSP的速度非常快,这就解释了为什么它们在早期FPS游戏中如此普遍。

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

    • 你有一个很大/稀疏的空间,有很多对象。 AABB树往往对此有好处,因为你可以削减很多你需要的水平。
    • 你正在假设完美的领域。球体碰撞测试非常便宜,因此您可以轻松地为每个底层节点进行10-45次测试。基本上N ^ 2适用于N的小值: - )
    • 轴对齐使得更新树更简单,交叉点测试比大多数替代品便宜得多。由于你假设大致是球形物体,我认为你不会从定向边界框中获得太多收益(如果你有很多长/薄形状的滑稽角度,这只会给你带来优势)。
    • 通过允许边界框松散并包含合理数量的对象,可以减少任何单个对象的运动将其带到AABB边界之外的可能性。除非发生这种情况,否则您无需更新树。这将为您节省大量的树更新时间。当它确实发生时,用一点边距扩展边界,这样你就不必立即重新延长下一帧 - 记住大多数动作往往会在相同的方向上继续几帧!

    对于稍微粗略的回答感到抱歉,但我希望这能为您提供一些有用的想法/事情!

答案 1 :(得分:5)

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

OOBBTree(定向边界框)将是更好的反击部分。