3D碰撞检测

为了确保任何区域的空间不被多于1个物体占用,我们需要基于物体间的空间信息来做碰撞检测。

 

碰撞检测中重要的事情是有大量的测试,因此需要理由GPU资源。

例如:如果我们有n个物体,一个物体将会碰撞n-1个物体(因为自己不会撞自己嘛),第二个物体撞剩下的n-2个。因此可能的碰撞是(n-1) * (n-2) * (n-3) ... 1

这几乎等于 n! / 2!*(n-2)! 

在动画播放时,我们可能需要在每一帧检测碰撞,因此有效的碰撞检测是非常重要的。我们因此需要考虑下面的事情:

空间划分:

检测碰撞过程的数量是基于物体的数量,可能的碰撞数量是基于两个移动物体的位置,这大致将会与移动对象数目的平方成正比。

降低碰撞测试数量的方法是分割空间,例如规则立方体、三维格子、octtrees、k-d树、BSP树,我们此时将只能在一个给定空间(或者可能邻接的空间)检测物体碰撞。这个假定是物体相对空间大小不是太大,我们可能需要为每个大物体比如地面做特殊安排。

这允许我们在我们的模拟中扩展移动物体,并保持以O(N)而不是O(N^2)时间来处理。

包围盒

bounding boxes
在这个场景里,每个形状都被一个红色长方形边界包围。如果有任何边界重叠,形状可能重叠,需要进一步检测,如果边界没有重叠,那就没有碰撞。因此这需要CPU来检测任何复杂形状的重叠。

检测盒子的重叠是很简单的,如果提供了同一方向的数据,我们只需要比较每个方向(x,y,z)的最大值和最小值。

比如盒子A定义了AxMin, AxMax, AyMin, AyMax, AzMin, and AzMax.盒子B定义了BxMin, BxMax, ByMin, ByMax, BzMin, and BzMax.

 

如果满足下面条件就可以判断盒子重叠:

AxMin < BxMax and AxMax > BxMin
AyMin < ByMax and AyMax > ByMin
AzMin < BzMax and AzMax > BzMin

右面的图展示了X方向的条件判断。当然,必须在y,z方向也满足才能确定碰撞。

squares overlap
squares overlap
squares overlap
squares overlap

然而这种算法只是在包围盒以象限对齐时有效。如果包围盒被定义在本地坐标系,并且包围盒带了旋转我们将必须:

  1. 用一个算法来检测任意朝向、任意象限的包围盒的相交,这将是非常复杂的。
  2. 或者在每一帧以绝对坐标系为基准重新计算包围盒。这计算鸭梨也很大。

如果针对物体的单一包围盒不能给予足够精确的碰撞检测,我们可以用更多的盒子比如oct树。
octtree

为了高效计算,oct树需要以觉得象限为基准

包围球

如果包围球重叠,那检测会非常简单,例如

物体A中心点为ax,ay,az,半径为ar
物体A中心点为bx,by,bz,半径为br

如果满足下面条件包围球就相交:

(ax-bx)2+(ay-by)2+(az-bz)2 < (ar+br)2

这个方法的优点是与方向独立。因此如果有象限转换,这种方法就没问题。

包围球的缺点是对于细长的物体效果不好,在这种情况下将会一些错误的碰撞检测,但我们可以用额外的检测来更加小心地检测边界。

其他技巧

实现我们自己的碰撞检测:

如果有大量物体需要碰撞检测,每一帧都计算一个物体与其他物体是否碰撞的计算量将是巨大的。

这里有一些减少碰撞检测过程的技巧,比如

  • 只考虑边界重叠的图形对。
  • 只考虑在互相移动的图形

检测网状的相交

如果物体有复杂形状,只考虑包围盒或者包围球是不够的。尽管包围盒能筛选出没有重叠的物体。

另外一个我们能依赖包围盒或者包围球的原因是可以进行计算碰撞响应的第二个阶段,我们也需要知道相对于网状中心店的影响点。

包围树

我们可以增加包围盒方法的精度,如果不是只用一个长方体,我们用diogenes长方体会横精确地匹配不规则物体。

这些子包围盒不需要每个大小都一样,尽管这可能是一种简化算法。

三角形的相交

If we want to test for collision of meshes, made up from triangles, and we want to check for collisions accurately, using all the information from the geometry, we may need to test each triangle. Once we have culled any non contenders for collisions using the methods above we may then have to test each triangle on object 'A' with each triangle on object 'B' for intersection.

如果我们测试由三角形构成的网状物体的碰撞,我们想用所有几何信息来精确检测碰撞,我们可能需要检测A或B之间的每个三角形。

我们可以计算下面展示的各个平面上的每个三角形。让我们可以计算出没量过平面的相交。

如果两个三角形都在同一部分的线上,则三角形相交。

凸形物体

许多物体间碰撞检测算法要求物体是凸的,就是说这些算法不能处理物体里有空洞或者齿。如果我们用这些算法检测非凸物体,我们必须首先把物体分割成很多小的的凸形状。尽管这些凸分解成更小的凸形状,这种计算在每一帧是很密集的。

 

 

posted @ 2014-04-21 18:49  hailong  阅读(9343)  评论(0编辑  收藏  举报