PhysX如今是Nvidia的物理中間件.其特色是簡練且功能強大.當我最初拿到PHYSX的SDK時,就發現這個物理中間件比Havok要小不少,但該有的功能都有,甚至有軟體softbody,這是Havok沒有的功能.然後我便從Havok的坑跳到了PhysX的坑裏.下面將我在PhysX裏碰到的坑一一講述下.web
(1)Max導出插件
PhysX的Max導出插件作的不如Havok,最缺乏的功能是沒法對導出的模型進行矩陣變換.要知道Max的座標系爲Z軸向上右手座標系,而遊戲中的座標系爲Y軸向上的左手座標系.而且,我這的美術在Max中建模時,會將模型放大100倍.那麼導出的模型須要進行縮小.它的導出插件沒有提供這一功能,我只好本身寫,先說縮放,縮放碰到的最大的坑是,其慣性常量的縮放.慣性常量,這個東西物理課本上沒有講過啊.我覺得慣性常量也應該縮小100倍的,後來發現轉化出的剛體穩定性極差,有約束的剛體總會亂抖動.通過很長時間的糾結才發現慣性常量的縮放不是線性的變化.而後是Z軸向上右手座標系到Y軸向上的左手座標系的變換,這算是我寫的最糾結的代碼,原本變換原理很容易,只要將原始數據都乘上一個4*4變換矩陣就行.但這個變換矩陣很難找出來,由於我用我理論上求得的矩陣去處理,變換後的約束老是錯的,非常奇怪,這矩陣我在本身的導出插件中使用過,沒問題的.沒辦法,只好一個一個的試,試了一成天才將這個變換矩陣找出來.總之,到如今我也不知道爲何是這個矩陣.多線程
(2)剛體的縮放
在PhysX中剛體是不能有縮放的,但剛體有爲其設置矩陣的接口,設置給他的矩陣能夠有縮放信息.但若是你真給剛體設置了有縮放信息的矩陣就等着吧,問題遲早會被發現的.剛體對傳進去的變化矩陣只提取位置和旋轉.出於對性能的考慮,PhysX不會對縮放進行處理,若是有了縮放則會致使其旋轉的解析出錯.縮放的變化越大,其旋轉偏差的角度也就越大.不過有個基於PhysX的中間件Apex是能夠對布料中的變換矩陣傳入縮放信息的.有關Apex我將在下一篇文章中介紹.函數
(3)Ragdoll木偶
原本Ragdoll一般是用來模擬角色死亡後,順着地形躺的.我在的項目是一個舞蹈類遊戲,沒有殺戮.但Ragdoll一樣有用,用它來模擬辮子,項鍊以及某些布料.我想全部搞過物理的人都會碰到,刷幀率低時,剛體會亂飛的狀況,這個除了提升刷幀率還真沒有什麼可解決的方法.另外一個問題是,角色出現瞬移時,剛體也會亂飛,這時須要給Ragdoll加下是否爲teleport的狀態,當teleport爲true時調用剛體的SetTransform()接口,不然調用剛體的MoveToPose()接口.工具
(4)PhysX的文件保存
PhysX的Max導出插件能夠將剛體模型保存成3種格式的文件,它提供了開源的代碼可以解析這三種格式.有個問題是,它保存的文件是整個場景,而我這的需求是,保存具體的形狀,剛體和約束數據便可.並且導出的文件中都會有一個地平面的靜態剛體.我先寫了個工具,能夠刪除導出文件中不須要的數據.後來又讀了下PhysX對文件的解析方式的代碼,發現它代碼寫的真不怎麼樣.因而很蛋疼地自定義了一套文件格式,保存物理的形狀,剛體和約束數據.代碼寫的也至關糾結,主要是引擎有了很大的改動.不過想一想也是值得的,至少這是脫離了平臺的物理數據,之後能夠用到Bullet的物理系統裏.post
(5)PhysX的物理更新
PhysX的物理更新須要調用兩個函數simulate和fetchResults,之因此要調用兩個函數,是由於其多線程並行處理.咱們能夠在simulate和fetchResults之間插入一些與物理不相關的代碼.這樣有助於提升引擎效率.固然所帶來的問題是simulate和fetchResults之間絕對不能添加與物理相關的操做,比建立刪除個物理對象什麼的,有不少次使人糾結的崩潰就是由於在某個深深地堆棧回調中作的物理操做.性能
(6)布料
單純用PhysX作布料效果並不太好,我記得我作過一個DEMO,布料像皮筋同樣有彈性,角色一動起來,布料就會一顫一顫的.不過剛纔提到過有個基於PhysX的中間件Apex也是Nvidia出的,用它作布料效果不錯,我將在下一篇文章中介紹.fetch