three.js API 包山包海,除了一般常見的幾何圖形、材質之外,loader、helper 也是一大利器,如果實務當中牽扯到數學運算,three.js 的 API 也提供了一些簡單有用的數學方法幫助轉換。
今天就來講講碰撞檢測吧!
2D 的碰撞檢測相對起來比較簡單一些,因為我們只要考慮兩個維度即可。要判斷是物體是否碰撞,最簡單的方式就是針對物體的每個頂點,看看是否有和其他物件的頂點位置重疊。如果有,就代表發生碰撞。
這個方法很簡單,但有個明顯的缺點,如果是不規則的形狀,那麼要判斷的條件馬上倍增。所以在實務上我們無法很完美地實現真實的碰撞情形,必須在精准度跟效能之間作考量。
比較先進的遊戲引擎應該都有具備碰撞檢測器的功能,不過在 web 開發當中,一切都要自己來。一般來說,碰撞檢測有幾種方法:
BSP 最主要的精神是將靜態場景分割成數個集合,每次的碰撞檢測只針對某個集合裡面的物件做判斷。畢竟我們沒有必要計算太多距離過遠的物體,能省越多運算越好。
關於 BSP 演算法的介紹這裡就不多敘述,有興趣的讀者可以自行搜尋「BSP tree」原理。
定界體的判斷方式,是將物體用簡單的幾何形狀包覆起來,這樣子要判斷的頂點位置就少許多,缺點在於如果物體的形狀跟包覆的幾何形狀差別太多,那麼碰撞的效果看起來就不真實,甚至會有還沒有跟實際物體碰撞到就產生碰撞的情形發生。
實務上常用的方式是 AABB、ABT(AABB tree),進行兩回合的偵測,第一的偵測先判斷包覆的幾何形狀是否碰撞,如果有,在檢查內部的頂點是否有碰撞。這樣一來,如果距離太遠的物體就不用進入第二回合的複雜運算,在第一回合就可以先篩掉了。
關於碰撞檢測的原理,可以參考這一篇
three.js 中,每個 geometry 都有 boundingBox 這個屬性,不過一開始會是 null
,畢竟不是每個物體都需要碰撞檢測的。
同時 three.js 也提供了 geometry.computeBoundingBox()
這個方法來更新 boudningBox 這個屬性。