為了確保任何區域的空間不被多於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)時間來處理。
包圍盒
![]() |
在這個場景里,每個形狀都被一個紅色長方形邊界包圍。如果有任何邊界重疊,形狀可能重疊,需要進一步檢測,如果邊界沒有重疊,那就沒有碰撞。因此這需要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 右面的圖展示了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之間的每個三角形。

我們可以計算下面展示的各個平面上的每個三角形。讓我們可以計算出沒量過平面的相交。

如果兩個三角形都在同一部分的線上,則三角形相交。
凸形物體
許多物體間碰撞檢測算法要求物體是凸的,就是說這些算法不能處理物體里有空洞或者齒。如果我們用這些算法檢測非凸物體,我們必須首先把物體分割成很多小的的凸形狀。盡管這些凸分解成更小的凸形狀,這種計算在每一幀是很密集的。






