为了确保任何区域的空间不被多于1个物体占用,咱们须要基于物体间的空间信息来作碰撞检测。算法
碰撞检测中重要的事情是有大量的测试,所以须要理由GPU资源。测试
例如:若是咱们有n个物体,一个物体将会碰撞n-1个物体(由于本身不会撞本身嘛),第二个物体撞剩下的n-2个。所以可能的碰撞是(n-1) * (n-2) * (n-3) ... 1动画
这几乎等于 n! / 2!*(n-2)! spa
在动画播放时,咱们可能须要在每一帧检测碰撞,所以有效的碰撞检测是很是重要的。咱们所以须要考虑下面的事情:orm
检测碰撞过程的数量是基于物体的数量,可能的碰撞数量是基于两个移动物体的位置,这大体将会与移动对象数目的平方成正比。对象
下降碰撞测试数量的方法是分割空间,例如规则立方体、三维格子、octtrees、k-d树、BSP树,咱们此时将只能在一个给定空间(或者可能邻接的空间)检测物体碰撞。这个假定是物体相对空间大小不是太大,咱们可能须要为每一个大物体好比地面作特殊安排。blog
这容许咱们在咱们的模拟中扩展移动物体,并保持以O(N)而不是O(N^2)时间来处理。资源
![]() |
在这个场景里,每一个形状都被一个红色长方形边界包围。若是有任何边界重叠,形状可能重叠,须要进一步检测,若是边界没有重叠,那就没有碰撞。所以这须要CPU来检测任何复杂形状的重叠。 |
检测盒子的重叠是很简单的,若是提供了同一方向的数据,咱们只须要比较每一个方向(x,y,z)的最大值和最小值。it
好比盒子A定义了AxMin, AxMax, AyMin, AyMax, AzMin, and AzMax.盒子B定义了BxMin, BxMax, ByMin, ByMax, BzMin, and BzMax.io
若是知足下面条件就能够判断盒子重叠: AxMin < BxMax and AxMax > BxMin 右面的图展现了X方向的条件判断。固然,必须在y,z方向也知足才能肯定碰撞。 |
![]() |
![]() |
|
![]() |
|
![]() |
然而这种算法只是在包围盒以象限对齐时有效。若是包围盒被定义在本地坐标系,而且包围盒带了旋转咱们将必须:
若是针对物体的单一包围盒不能给予足够精确的碰撞检测,咱们能够用更多的盒子好比oct树。 |
![]() |
为了高效计算,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之间的每一个三角形。
咱们能够计算下面展现的各个平面上的每一个三角形。让咱们能够计算出没量过平面的相交。
若是两个三角形都在同一部分的线上,则三角形相交。
许多物体间碰撞检测算法要求物体是凸的,就是说这些算法不能处理物体里有空洞或者齿。若是咱们用这些算法检测非凸物体,咱们必须首先把物体分割成不少小的的凸形状。尽管这些凸分解成更小的凸形状,这种计算在每一帧是很密集的。