Unity3D BEPU 3D定點物理引擎實戰(zhàn)系列1.6BEPU物理引擎碰撞系統(tǒng)的架構與設計
前言
前面我們講解了如何監(jiān)聽物理引擎的碰撞事件, 在物理引擎內核中如何架構與設計碰撞規(guī)則,使得物理Entity與周圍的物理環(huán)境產生碰撞時,如何靈活的控制物理碰撞,本節(jié)給大家詳細的講解BEPUphysicsint 物理引擎內部是如何管理與控制碰撞規(guī)則的。本文主要講解3個部分:
(1) 物理引擎碰撞計算的全流程詳解;
(2) 用戶控制碰撞關系的規(guī)則詳解;
(3) 與物理碰撞相關的其它一些注意事項;
物理引擎碰撞計算的全流程詳解
物理引擎的碰撞計算是物理引擎性能消耗的部分之一,物理引擎如何高效的做好物理碰撞計算與物理引擎內核如何標準的處理碰撞檢測流程(pipeline),詳細的步驟如下:
(1) BroadPhase 快速粗略碰撞檢測。 通過這個步驟,快速的計算篩選出來可能產生碰撞的物理Entity碰撞對(Entity Collison Pair)。要實現(xiàn)這個設計目標我們可以從物體與場景入手,可以簡化物體的形狀來做碰撞檢測,通過物理場景,快速的排除掉不可能發(fā)生碰撞的物體,從而替代簡單的暴力搜索O(n^2)。每個物理Entity都有自己的包圍盒,能包圍住整個物理Entity的形狀,當兩個物理Entity的包圍盒有重疊的時候,物理引擎會產生一個潛在可能的碰撞對,如圖1.6-1
?

圖1.6-1
找到這個碰撞對后,就會把物理碰撞對加入到物理世界的碰撞列表中,來進行下一步計算。
(2) NarrowPhase 精確的計算碰撞,生成碰信息。經(jīng)過第一步的粗略計算,找出來了可能發(fā)生碰撞的物理Entity碰撞對。接下來就是要根據(jù)物理Shape形狀與角度來精確的計算出來是否有真實的碰撞以及詳細的碰撞點位置,表面法線信息等。注意不是所有的碰撞對都會產生碰撞,如上圖1.6-1所示,BroadPhase階段產生了碰撞,但是NarrowPhase階段,卻發(fā)現(xiàn)沒有產生碰撞。
(3) Collision Respones階段: 物理碰撞系統(tǒng)的最后一個階段就是迭代計算出碰撞對每個物理Entity運動改變的影響。因為物理引擎中不允許兩個物理Entity穿透。所以碰撞后就會改變物理Entity的運動狀態(tài)。
用戶定義碰撞規(guī)則
在物理引擎Pipeline的物理碰撞計算中要篩選出物理Entity碰撞規(guī)則。碰撞規(guī)則是指進入碰撞標準流程計算中采用哪種策略。用戶可以指定物體的碰撞規(guī)則,指定碰撞計算策略。用戶定義碰撞規(guī)則可由有3個地方產生出來, 這3個地方按照優(yōu)先級進行篩選,如果當前沒有,就進入下一個位置篩選,都沒有,就用默認的碰撞規(guī)則。3個地方的分別如下(按照優(yōu)先級來區(qū)分):
Specific特殊碰撞規(guī)則表:?物理Entity有一個Specific列表保存了一些物理的Entity實例以及與這些Entity實例的碰撞規(guī)則,如果碰撞對中的Entity實例在這個表中,就返回這個表中的碰撞規(guī)則。否則就進入下一個規(guī)則產生階段。
Personal 私有碰撞規(guī)則:?針對單個的物理的Entity,如果物理Entity設置了這個碰撞規(guī)則,就是用這個碰撞規(guī)則。
Group 碰撞分組:每個物體都可以設置一個碰撞分組,如果沒有設置就使用默認的碰撞分組。由所在的碰撞分組來決定碰撞規(guī)則。
這3個決定碰撞規(guī)則的地方的優(yōu)先級別如圖1.6-2所示:
?

圖1.6-2
上面提到一個概念,碰撞規(guī)則,碰撞規(guī)則是決定了物體與物體之間的碰撞該如何處理與計算。BEPU物理引擎分成了幾個規(guī)則:
CollisionRule.Normal:?允許碰撞對(Collision Pair)經(jīng)歷完整的碰撞計算,完整的碰撞計算包括了broad phase, narrow phase, collision response三個階段。
CollisionRule.NoSolver:?允許碰撞對經(jīng)歷broad phase, narrow phase階段,但是不計算碰撞信息與對物體運動狀態(tài)的改變。
CollisionRule.NoNarrowPhaseUpdate:?允許碰撞對經(jīng)歷broad phase 與第一階段的narrow phase。但是narrow phase的計算結果不更新到碰撞對中。
CollisionRule.NoNarrowPhasePair:?允許碰撞對經(jīng)歷broad phase的粗略測試,不進行narrow phase 測試。
CollisionRule.NoBroadPhase:?不做任何的碰撞測試。
CollisionRule.Defer:?延后決定,一個比較特殊的狀態(tài),上面說了有3個地方可以決定碰撞策略,如果某一個地方?jīng)]有碰撞策略,就返回CollisionRule.Defer,進入到下一個地方。如果所有都沒有,就使用默認的策略。
講解完這些基本概念以后,我們來介紹一下基于碰撞分組Group如何具體產生碰撞策略。這種模式是我們開發(fā)中最常用的模式,當Specific與Personal兩個地方無法決定碰撞策略的時候,物體的碰策略就是由它所在的分組來決定。物理引擎內核中有一個CollisionGroupRules字典,描述了哪些Group分組到碰撞規(guī)則的映射。當前物體所屬哪個組,就可以獲得該碰撞規(guī)則。要創(chuàng)建一個用戶自定義的組,只要new 一個CollisionGroup的實例,然后將與每個其它分組的碰撞規(guī)則設置到CollisionGroupRules表中即可。有時候每個物體的類型會有沖突,那么如何取舍呢?這里的碰撞策略有一個優(yōu)先級:NoBroadPhase>NoNarrowPhasePair>NoNarrowPhaseUpdate>NoSolver>Normal。
物理碰撞相關的其它事項
用戶可自定義broad phase的測試函數(shù):我們可以通過設置物理Entity的CollisionRuleCalculator 的delegate 回調函數(shù)來定制broad phase碰撞測試時候的碰撞算法。這個回調函數(shù)最終會存到BroadPhase中的CalculateCollisionRuleCallback中。
kinematic 的物理Entity采用CollisionRule.NoSolver碰撞策略,這樣可以不用改變它們的物理的運動狀態(tài)。
今天的分享就到這里了,關注我們,可以獲取Unity BEPUphysint3D實戰(zhàn)源碼。
附:視頻教程
Unity幀同步核心技術:3D定點數(shù)物理引擎架構實戰(zhàn)www.bycwedu.com/promotion_channels/1454843650??