高階碰撞檢測技術

2021-07-22 11:26:19 字數 2332 閱讀 8033

閱讀這篇文章前首先假設你對與碰撞檢測相關的幾何和數學知識已經有了基本的了解。在文章的最後,我將提供一些這方面的參考資料,以免你對它們感覺有點生疏。另外我還假設你已經讀過 jeff lander 的圖形專欄裡關於碰撞檢測文章(「crashing into the new year,」 ; 「when two hearts collide,」;和 「collision response: bouncy, trouncy, fun,」)。我將首先進行乙個大概的描述,然後快速地切入到核心內容裡,通過這兩步從上至下地深入到碰撞檢測中。我將討論兩種型別的圖形引擎中的碰撞檢測:基於 portal 的和基於 bsp 的。每種引擎中多邊形的組織各不相同,因此在 world-object 型的碰撞檢測上存在很大的差別。而object-object 型的碰撞檢測絕大多數地方在上述兩種引擎裡的是一樣的,主要看你是如何實現的了。當我們接觸到多邊形的碰撞檢測時,我們還會實驗如何將其擴充套件到我們學過的凸型物體上。

預覽

為了建立乙個理想的碰撞檢測程式,我們不得不在開發乙個遊戲的的圖形管道的同時就開始計畫並建立它的框架。在專案的最後加入碰撞檢測是相當困難的。想在開發周期的末尾建立快速的碰撞檢測將很有可能會使整個遊戲被毀掉,因為我們不可能使它能高效地執行。在好的遊戲引擎中,碰撞檢測應該是精確、有效並且十分快速的。這些要求意味著碰撞檢測將要與場景的多邊形管理管道緊緊地聯絡起來。這也意味著窮舉法將無法工作――今天的3d遊戲中每幀處理的資料量很可能導致打格,當你還在檢測乙個物體的各多邊形是否與場景中的其它多邊形碰撞時,時間已經過去了。

讓我們從基本的遊戲引擎迴圈開始吧(列表1)。快速瀏覽這些**來得到碰撞檢測的相關策略。我們先假設碰撞沒有發生,然後更新物體的位置,如果發現發生了碰撞,我們將把物體移回原來的位置不允許它穿越邊界(或將物體銷毀或執行一些預防措施)。然而,這個假設太過簡單因為我們無法得知物體原來的位置是否仍然有效。你必須為這種情況設計乙個方案(否則你可能會體驗到墜機或被子彈擊中的感覺――就是前面舉的例子)。如果你是乙個熱心的玩家,你可能已經注意到了在一些遊戲當中,當你挨著牆壁並試圖穿過去的時候,攝像機就開始震動。你正經歷的就是將主角移回原位的情況。震動是因為取了較大的時間片引起的。

但是我們的方法有缺陷,我們忘了在等式中加入時間。圖1告訴我們時間太重要了不能忘了它。即便物體在 t1 或 t2 時刻沒有發生碰撞,它仍有可能在 t 時刻穿過邊界(t1 0那麼點在平面的正面;如果ax + by + cz + d < 0點在平面的背面。

在碰撞沒發生的時候有乙個重要的事情需要注意,就是乙個物體(或它的包圍盒)必須在分割面的正面或背面。如果在平面的正面和背面都有頂點,說明物體與這個平面相交了。

不幸的是,我們還沒有乙個很好的方法檢測在乙個時間間隔內的碰撞(在文章開頭提到的方法現在仍在使用)。然而,我已經看到有另外的資料結構像bsp樹一樣開始廣泛使用了。

曲面物體及碰撞檢測

現在我們已經看到了兩種多邊形物體的碰撞檢測,下面一看看如何計算彎曲物體的碰撞。99年發布的幾款遊戲已經大量地採用曲面了,因此在接下來幾年裡高效的曲面碰撞檢測將變得十分重要。曲面碰撞檢測(要求有給定點上精確的曲面等式)運算開銷極大,所以我們要盡量避開它。實際上我們已經討論了幾種能用在這種情況下的方法。最明顯的方法就是用低網格來近似表示曲面,然後使用這個多面體進行碰撞檢測。甚至還有更簡單的(但精度比較低),就是在曲面的控制頂點(譯者:大概意思就是說每隔一定量的頂點就構造乙個凸殼)上構造凸殼用來做碰撞檢測。在這種情況下,曲面的碰撞檢測十分近擬於傳統的多面體碰撞檢測。如圖9顯示了曲面及它在控制頂點上形成的凸殼。

是否我們可以結合這兩種技術形成一種混合方法?首先我們用凸殼進行碰撞檢測然後逐步在凸殼所屬的部分細分下去,這樣就增加了精度。

由你決定

現在我們已經瀏覽了一些高階的碰撞檢測(有一些也是基本的),你應該能夠決定什麼樣的系統更適合你的遊戲。你要決定的主要事情是精度、速度、實現的簡單程度及系統的適應性。

for further info

碰撞檢測 膠囊體碰撞檢測

膠囊體 給定一條線段l,所有道l的距離為r的點的集合。由定義可知,膠囊體由半徑r和線段l標識。檢測兩個膠囊體是否發生碰撞,即檢測兩條線段l1 l2的最短距離d是否大於l1 l2的半徑r1 r2之和,d r1 r2 則未碰撞,否則發生碰撞。設線段l1端點為a1 a2,線段l2端點為b1 b2,號表示兩...

Unity碰撞檢測

碰撞個必要條件為兩個角色必須都掛載 rigibody 剛體元件,至少乙個角色掛載 collider指令碼 第一種 觸發器,必須開啟 collider的 istrigger 為 true 兩個碰撞物件會相互穿過 void ontriggerenter collider collider 開始觸發器 v...

cocos碰撞檢測

兩個矩形的碰撞檢測,主要看boundingbox是否接觸 rect rc1 spriteauto getboundingbox rect rc2 spritectrl getboundingbox if rc1.intersectsrect rc2 則認為碰撞 兩個圓的碰撞檢測,看圓心距離 poin...