碰撞及剛體動力學算法
一些碰撞/物理系統:http://www.gamedev.net/community/forums/topic.asp?topic_id=463024性能優化
- I-Collide:http://cs.unc.edu/I-COLLIDE
- SWIFT:
- ODE:http://www.ode.org
- Bullet:http://code.google.com/p/bullet/
- TrueAxis:http://trueaxis.com/
- PhysX:
- Havok:
- PAL:http://www.adrianboeing.com/pal/index.ht ml
- DMM:
碰撞檢測系統
物理世界
形狀:
- 相交、
- 接觸(分離矢量,沿該矢量運動就能高效脫離碰撞妝容)、
- 凸(由形狀內發射的光線不會穿越形狀兩次以上)
原型:
- 球體、
- 膠囊體、
- 軸對其包圍盒AABB、
- 定向包圍盒OBB、
- 離散定向多胞形discrete oriented polytope DOP、
- 任意凸體積、
- 多邊形湯(碰撞引擎必須和每一個三角形測試)、
- 複合形狀
碰撞測試:
- 點和球體相交
- 球體和球體相交
- 分離軸定理:凸形狀於該軸(分離軸)上的投影不重疊,能肯定兩個形狀不相交。分離兩個物體的軸/面稱爲分離線/面。三維空間中,分離軸仍然是個軸,分離線變成分離面。能夠把形狀逐一投影到各個潛在分離軸,並檢查投影區間是否相交
- AABB相交:分離軸定理。三個軸x,y,z。只有在三個軸都重疊,纔是相交的。
- 檢測凸碰撞:GJK算法。依賴閔可夫斯基差:把A中的全部點與B中的全部點都成對相減,獲得的集合就是閔可夫斯基差。當且僅當兩個形狀相交,閔可夫斯基差包含原點。GJK嘗試在閔科夫斯基的凸包內,嘗試找出一個包含原點的四面體。若找到,則相交。
- 運動物體間的碰撞:
- 離散的靜態碰撞;
- sweep shape掃瓊形狀作靜態測試(結果不許確);
- 連續碰撞檢測continuous collision detection CCD,求出最先的衝擊時間TOI
性能優化:
- 利用時間一致性避免每幀從新計算一些類型的信息
- 空間劃分:八叉樹、二元空間分割樹、kd樹等
- 粗略階段,中間階段,精確階段:先AABB測試哪些物體會碰撞;再用符合形狀的逼近包圍體檢測;最終測試碰撞體中個別碰撞原形是否相交。
- 掃瓊裁剪:sweep and prune,對各個膨脹提的AABB的最小,最大座標再三個主軸上排序,而後經過遍歷改有序表檢測AABB之間是否重疊
碰撞查詢:
- 光線投射:投射的物體並不存在於碰撞世界,不會影響其餘物體。返回一個t值,P = P0(起點) + td(矢量增量)
struct RayCastContact{
F32 m_t;//此接觸點的t值
U32 m_collidableId;//擊中哪一個可碰撞體?
Vector m_normal;//接觸點的法向量
//其餘信息
};
- 形狀投射:傳回的接觸信息比光線投射更復雜,且必須返回多個接觸點。
struct RayCastContact{
F32 m_t;//此接觸點的t值
U32 m_collidableId;//擊中哪一個可碰撞體?
Point m_contactPoint;//實際接觸點的位置
Vector m_normal;//接觸點的法向量
//其餘信息
};
- Phantom:查詢碰撞體是否在其餘指定體積裏。對於其餘碰撞體是透明的,也不參與動力學模擬。phantom會持續在碰撞世界裏存在。
碰撞過濾:決定碰撞體之間的接觸是否成立
- 碰撞掩碼及碰撞層:對世界中物體分類,而後用一個查找表判斷某類碰撞物體可否與另外一些分類碰撞。
- 碰撞回調:當碰撞庫檢測到碰撞時調用回調函數。回調函數能夠檢查碰撞的具體信息,而後按本身的條件決定接受或拒絕碰撞。
- 碰撞材質:每一個碰撞表面關聯一組屬性,它定義了某種表面在物理上和碰撞上的行爲。包含碰撞屬性,如音效,粒子效果,摩擦係數等等。
剛體動力學
無約束剛體指能夠在3個笛卡爾軸上自由移動,並繞3個軸自由旋轉,所以它含6個自由度(degree of freedom ,DOF)。
無約束剛體的運動分爲兩個部分:
- 線性動力學:剛體除旋轉之外的運動
- 旋轉動力學:剛體的旋轉性運動
對於均勻密度的剛體,其質心位於剛體的幾何中心;若剛體的密度不均勻,那麼就要令每一個小塊以其質量爲權值,求加權平均值做爲整個剛體的質心
其中,
r表示半徑或位置矢量,即從世界空間原點到該點的矢量。
線性動力學(質點)
運動方程求解
- 力做爲函數:位置、速度、時間等的函數(常微分方程(ordinary differential equation ODE))。F(t,r(t),v(t),...) = ma(t)
- 解析解:找到閉合式函數,描述全部可能的時間值t的剛體位置(例如拋物線),可是遊戲中幾乎不可能。
- 數值積分:遊戲引擎使用數值積分求解運動方程
- 顯示歐拉:一階近似,用切線逼近。
- 距離近似方程:r(t2) = r(t1) + v(t1)Δt
- 速度近似方程:v(t2) = v(t1) + a(t1)Δt
- 常微分方程的數值解的特性:
- 收斂性:Δt趨近於0的時候,近似解趨近真實解?
- 階數:偏差是O(t^?)
- 穩定性:數值解是否會穩定下來?
其餘的數值積分方法
- 向後歐拉法
- 中點歐拉法
- Runge-Kutta方法族
- 韋爾萊積分
韋爾萊積分是三階方法,它須要已知待求時間點的前兩個Δt的位置信息或速度信息。其實是經過泰勒展開消去重複項。
待求時間點是t1 + Δt,已知t1和t1 - Δt的位置信息。則:
相減獲得:
速度韋爾萊積分dom
- 計算r(t + Δt) = r(t1) + v(t1)Δt + 0.5a(t1)*Δt2
- 計算v(t1 + 0.5Δt) = v(t1) + 0.5a(t1)Δt
- 求a(t1 + Δt) (假設a僅僅依賴位置,若是依賴速度,則須要先計算速度近似值)a(t1 + Δt) = a(t2) = m-1F(t2,r(t2),v(t2))
- 計算v(t + Δt) = v(t1 + 0.5Δt) + 0.5a(t1 + Δt)Δt
旋轉動力學(剛體)
- 二維:
- 定向:角度θ(t)(繞z軸旋轉)
- 角速率&加速度:
-
- 轉動慣量moment of inertia:改變角速率的難易程度。用I表示
- 力矩torque:用N表示:N = r x F
二維中力矩必然和z軸平行
二維旋轉方程求解異步
速度韋爾萊積分ide
三維旋轉動力學:函數
- 慣性張量:inertia tensor,標記爲I。剛體的旋轉質量由3x3矩陣表示。若是3個主軸對稱,則主對角線之外的元素(也叫慣量積)就是0。物理引擎中慣性張量簡化爲三元素矢量[Ixx, Iyy, Izz]
剛體的定向能夠用四元數q表示:性能
三維中的角速度:測試
三維旋轉動力學中,一個剛體在無外力的狀況下旋轉,其角速度
ω(t)可能不是常量,由於旋轉軸方向可能會不斷改變。所以角速度不守恆,可是角動量(angular momentum,表示爲
L)守恆。
因爲
ω不守恆,因此不會像線性速度通常,視角速度爲一個基本的量。角速度是第二級別的量,在肯定了角動量L後才計算出
ω
三維力矩:N = r x F = Iα = I dω(t)/dt = d(Iω(t))/dt = dL/dt優化
三維旋轉求解:動畫
須要直接對L求解
將角速度轉化成四元數:
ω = [ω
x, ω
y, ω
z, 0]
且:d
q(t)/dt = ½
ω(t))
q(t)
顯示歐拉:
須要按期把定向q(t)從新歸一化,以消除浮點小數累計沒法避免的偏差。
碰撞響應
衝量碰撞響應
徹底彈性碰撞無任何能量損失;徹底非彈性碰撞,兩個剛體一塊兒損失動能。
- 無摩擦力下瞬時碰撞的牛頓恢復定律:假設接觸點沒有摩擦力,衝量必然垂直於表面法線
恢復係數:
v
2'-
v
1'=ε(
v
2 -
v
1)
將二者求解得
若恢復係數ε爲1,剛體2的有效質量無窮大,則1/m
2 = 0、v
2 = 0;則:
其餘碰撞響應方法
- 懲罰性力:力會在短但有限的時間內產生所需的碰撞響應。就相似一個堅硬的阻尼彈簧。它容易實現及理解,適合低速撞擊,但不適合高速移動的物體。
- 約束
摩擦力
5. 休眠
將休眠物體移除模擬以外,可是仍然參與碰撞檢測
條件:
- 剛體受到支持
- 剛體的線性和角動量低於閾值
- 線性和角動量的移動平均低於閾值
- 總動能(0.5p·v+0.5L·ω)低於閾值
- 逐漸減慢其運動,使其平滑的中止
Havok中有模擬島:潛在近期會互動的物體組成。模擬島能獨立於其餘島模擬,並以整個島爲單位進入休眠。
6.約束
- 點對點約束:剛體中某個點和其餘剛體的指定點對齊
- 彈簧約束:與點對點約束不一樣的是,它的兩個點會分開一段距離
- 鉸鏈約束:只能繞鉸鏈旋轉。
- 活塞約束:滑移鉸,相似活塞同樣的移動。
- 平面約束
輪子:無限旋轉的鉸鏈+阻尼彈簧加入某種形式的垂直懸掛系統
約束鏈:特殊羣組,內含供求解程序使用的物體鏈接信息。模擬一長串的剛體信息。
布娃娃:剛體用約束互相連接,一般使用約束鏈提升模擬的穩定性。是由物理系統驅動的程序式動畫。
富動力約束(powered constraint):外部引擎間接控制布娃娃的平移和定向。力+動
畫,力改變更畫
控制剛體的運動
- 引力
- 施加力:多數引擎設計爲每幀調用一次,力的影響也在該幀內
- 施加力矩:改變速度&角速度;力偶:同樣大,方向相反,離質心距離相同的對點上施加。
- 施加衝量:速度瞬間改變,無窮短期內的施力
8.遊戲對象和剛體:
物理驅動的剛體
遊戲驅動的剛體(動畫、玩家驅動):可看成含有無窮質量,力和力矩沒法改變遊戲驅動剛的速度
固定剛體:不參加動力學模擬,只有碰撞的剛體。
9.更新模擬
- 更新遊戲驅動剛體
- 更新phantom
- 施以力,衝量並調整約束
- 步進模擬:
- 對運動方程數值積分,求出次幀物理狀態
- 碰撞檢測
- 碰撞決議
- 實行約束
- 更新物理驅動的遊戲對象
- 執行phantom碰撞投射查詢(以回調方式異步查詢or使用上一幀的結果同步查詢)