爲了確保任何區域的空間不被多於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之間的每一個三角形。
咱們能夠計算下面展現的各個平面上的每一個三角形。讓咱們能夠計算出沒量過平面的相交。
若是兩個三角形都在同一部分的線上,則三角形相交。
許多物體間碰撞檢測算法要求物體是凸的,就是說這些算法不能處理物體裏有空洞或者齒。若是咱們用這些算法檢測非凸物體,咱們必須首先把物體分割成不少小的的凸形狀。儘管這些凸分解成更小的凸形狀,這種計算在每一幀是很密集的。