(蘇州大學計算機科學與技術學院 江蘇 蘇州 215000)
可匹配于任意骨骼模型的剛體與關節編輯系統
徐大偉
(蘇州大學計算機科學與技術學院江蘇蘇州215000)
使用physX物理引擎模擬布娃娃效果時,需要使用Nvidia公司作為3D Max插件的布娃娃剛體與關節的編輯器。該編輯器生成的文件含有冗余數據,其生成的剛體間的關節數據格式與我們Flexi引擎的格式不兼容,也不利于與我們的Flexi引擎及相關工具的集成。
本方法提供一種高效的流暢的集成于圖形引擎的編輯布娃娃剛體與關節的工具。通過直接使用physX庫提供的API生成、編輯和保存布娃娃的剛體與關節數據,并與圖形引擎有效集成,更符合圖形引擎用戶的使用習慣。并增加了根據當前游戲角色的骨骼與蒙皮信息,自動生成相應的剛體與關節,做到一鍵從無到有生成布娃娃對象,可以迅速看到角色的模擬效果。在生成布娃娃所需要的剛體與關節后,可根據當前場景中骨骼動畫模型中的各骨骼數據自動修正關節所需要的旋轉角度,從而解決關節數據難以編輯與調整的問題,提調高用戶的工作效率。并結合了數據驅動與直觀的所見既所得的兩種布娃娃編輯方式。

圖1
1.通過physX API實現相應版本的剛體與關節數據的保存與加載功能;剛體是對現實物體的抽象,它具有現實物體的絕大多數物理屬性,如:質量、滾動時的滾動摩擦力、滑動時的滑動摩擦力及碰撞時反彈的性質,但不同于現實的物體屬性,它在碰撞時,不會發生變形,這在現實中的物體是不存在的。關節是描述兩個剛體間相互作用的一種約束,它對自己所關聯的兩個剛體的相對運動起約束作用,就像門與門框間的鉸鏈使門僅能相對于鉸鏈作旋轉運動。
2.通過代碼編寫把physX庫集成到圖形引擎中,完成在加載模型時,加載對應的布娃娃的剛體與關節數據;
3.因為游戲角色的基礎骨骼數與骨骼名及對應的關節是固定的,如任何一個人物或怪物都有頭、四肢,所有可以預先配置好其具體的剛體與關節列表,角色模型加載時,根據該列表自動生成基本的剛體與關節。
4.剛體的大小與位置是根據角色的動作文件每一個骨骼的矩陣及不同骨骼矩陣間的關系計算出來:
[1]遍歷每一個骨骼影響到的蒙皮頂點集合;根據該集合計算出包圍合的大小,包圍合足夠大時,或者其子骨骼足夠大時,才生成對應的骨骼剛體。
[2]為生成的剛體填充碰撞信息:
<1>計算碰撞單元的朝向信息;遍歷骨骼子節點位置朝向數據,當前遍歷到的子節點的位置距原點的向量,為當前要計算的骨骼的Z軸方向向量。
<2>當前骨骼的X,Y軸據隨機算法,隨機確定;
5.本發明包含另一種算法是直接根據蒙皮頂點集合生成指定大小的剛體:
<1>累加所有頂點的向量再求其平均值U
<2>記錄骨骼的每一個頂點距該平均值U的差值(xi,yi,zi),i=0…N-1;
<3>生成協方差矩陣:
(∑(xi*xi))/N (∑(xi*yi))/N (∑(xi*zi))/N
(∑(yi*xi))/N (∑(yi*yi))/N (∑(yi*zi))/N
(∑(zi*xi))/N (∑(zi*yi))/N (∑(zi*zi))/N
<4>計算該協方差矩陣的特征向量,該向量為本剛體朝向的Z軸向量(計算方法為PowerIteration):
[1]取Z軸方向的單位向量vectorZ(0,0,1),且長度length=VectorZ.length( );
[2]進行最多32次的迭代;
[3]每次迭代執行vectorZ=covarianceMatrix*vectorZ/length
[4]返回最終的單位化的vectorZ.
<5>在Z軸向量的基礎,隨機建立正交的X,Y軸向量從而構成剛體的朝向向量,根據該三個正交向量初步建立本剛體變換矩陣;
<6>據本骨骼所有影響的蒙皮頂點位置的集合,統計出包圍盒位置與大小(適時進行相應的空間變換)。
<7>統計出的包圍盒位置數據添加到剛體的變換矩陣中。
<8>得到了包圍盒的大小,剛體的變換矩陣,就可以生成出指定形狀類型的匹配于原始模型的剛體。
6.布娃娃編輯器有兩部分組成:第一部分是控制與參數面板,第二部分是在場景中布娃娃效果在角色模型上的表現。
7.編輯布娃娃時,可以在控制與參數面板中直接輸入剛體或關節的參數數值,點擊更新按紐后,可以在第二部分中看到布娃娃的編輯效果。
8.也可以在場景中,即布娃娃編輯器的第二部分,直接拖動剛體的位置、所處的空間朝向,來實時編輯剛體的相關屬性;
9.關節的自動修正功能實現,角色模型的骨骼數據是在美術建模時就確定了。但當前所編輯的關節所連接的兩個剛體間相對朝向,多數都不能使用當初美術建模時定下的數據。這類骨骼數據不符合當前關節所表達的兩剛體的相互朝向(或相對旋轉)。這兩剛體存在著相對旋轉角度的偏差。通過計算這種偏差,并把其記錄到剛體的矩陣中,從而實現關節所關聯的兩剛體間旋轉角度的修正。
10.具體的兩剛體間旋轉角度的修正過程:
<1>取兩剛體處于符合原角色模型要求下的世界矩陣;
<2>從世界矩陣中取出兩剛體的世界空間下的位置;
<3>A剛體的位置為兩剛體間中間位置;計算出的位置放入A剛體的局部矩陣中。A剛體的矩陣再轉到世界空間下;<4>B剛體的矩陣計算過程與A剛體相同;
<5>所得到的兩剛體矩陣傳給physX生成關節的API從而生成出修正后的關節。
<6>公式概括為:
[1]transformA.position=(positionA+positionB)/2;
[2]transformA.quaternion=inverseTransformA.quaternion*localTransformA.quaternion;
[3]transformB.position=(positionA+positionB)/2;
[4]transformB.quaternion=inverseTransformB.quaternion*localTransformB.quaternion;
11.另一種修正關節角度的方法(根據關節編輯的方式,適時選擇一種關節旋轉角度算法):
transformA=inverseCenterOfMassA*inverseTransformA*transformB*centerOfMassB;
transformB=Identity(單位陣);
得到的transformA、transformB給physX API使用即可。
12.增加通過鼠標拾取場景中布娃娃功能。鼠標可以選中布娃娃的任意剛體,并驅動整個布娃娃的運動。即把人撿起來,拋向空中,可以觀察到近乎真實的模型的運動、碰撞、反彈的過程。
13.優化拾取過程的算法:
<1>記錄選中剛體時,計算該剛體距當前攝像機的距離;
<2>在鼠標拖動過程中的RayTrace計算時,使用上一步中得到的距離作為被拖動剛體距離攝像機的距離從解決因二維的屏幕鼠標坐標轉換到三維游戲空間時,Z軸坐標不確定而導致的被拾取物體在拖動過程中時而近,時而遠的問題;算法如圖1所示:
[1]Distance=A-C;
[2]B=C+D*Distance;
[1]http://en.wikipedia.org/wiki/Power_iteration
徐大偉(1988.03-),男,漢,江蘇盱眙縣,研究方向計算機及應用。