Axiom3D:Ogre動畫基本流程與骨骼動畫


  在Axiom中,Animation類用於管理動畫,在此對象中主要管理着AnimationTrack對象,此對象用於管理動畫的各種類型的每一楨.在Axiom中,動畫類型主要有變形動畫,姿態動畫,骨骼動畫以及他們之間的混合.而此對象的各子類如NodeAnimationTrack常用於骨骼動畫.而VertexAnimationTrack常用於頂點動畫(包括變形動畫與姿態動畫),還有一種是NumericAnimationTrack用於擴展動畫功能.而KeyFrame管理一楨,主要屬性是當前楨的位置(time).AnimationTrack子類與KeyFrame子類有對應關系,其中NumbericAnimationTrack對應NumericKeyFrame,NodeAnimationTrack對應的是TransformKeyFrame,先說一句,Bone這個類就是繼承的Node這個類.而VertexAnimationTrack對應VertexMorphKeyFrame(變形動畫楨)和VertexPoseKeyFrame(姿態動畫楨).可以簡單看下,TransformKeyFrame對應骨骼楨,在骨骼動畫中,每楨不同的是骨骼的位置,所以他增加(Rotaton,Scale,Translate)用來表示骨骼的位置變動.而變形動畫楨每楨都有不同的頂點集合,所以他增加了VertexBuffer用來表示頂點集合.  

  如上面圖中,AnimationTrack對象主要管理多個楨(KeyFrame),在AnimationTrack中提供一個關鍵方法,根據GetKeyFrameAtTime,傳入一個時間點,獲取這個時間點在動畫中的前一楨與后一楨,以及在這二楨之間的比例.還提供一個抽象方法Apply,供子類實現,讓子類本身AnimationTrack結合對應的子類KeyFrame得到正確的展張屬性.簡單來說,GetKeyFrameAtTime當前楨的位置,而Apply是得到當前楨上的數據. 

     簡單說下變形動畫,在VerterAnimationTrack這個類,其中他的屬性AnimationType指出對應實體是變形動畫還是姿態動畫,變形動畫就如MD2動畫格式,請參看MD2關鍵楨動畫3D模型加載.在這里面,對應的VertexMorphKeyFrame用HardwareVertexBuffer保存了每一楨的數據.根據父類前面的GetKeyFrameAtTime得到當前所需要的二楨,然后實現父類Apply混合二楨正確以得到正確的HardwareVertexBuffer,在Axiom中,可以分別交給GPU處理和CPU處理,二者的實現過程一樣,根據二楨以及在二楨間的位置來計算混合楨的數據,交給GPU的話,在此處只需傳入二個楨的數據,以及二楨間的位置,上面的實現交給相關着色器代碼實現.姿態動畫了解不多,相關代碼可以參考ApplyToVertexData與ApplyPoseToVertexData,大致意思應該混合每楨里的參考,和骨骼動畫有些類似,會有權重,頂點間偏移信息.姿態動畫多用於面部表情. 

     再來說下骨骼動畫,可以先參考MD5骨骼動畫模型加載, 骨骼動畫用到的控制類是NodeAnimationTrack,他對應用的動畫楨是TransformKeyFrame,不同頂點動畫,根據線性插值當前二楨與二楨位置得到當前楨,在NodeAnimationTrack中,求得當前楨需要父類Animation里定義的二種插值算法,分別對應是旋轉插值與常用插值.常用插值分為線性插值與平滑插值.旋轉插值分為線性插值與球面插值.實際上旋轉插值實用球面插值相當於常用的線性插值,我們簡單想一下,旋轉留下的曲線是一條球面曲線,他在單位時間內走的是球面,而不是線性的.這二種算法分別對應的是Quaternion里的Nlerp與Slerp,具體講解一些網站都有詳細介紹.不同的插值算法會有不同的結果,然后和上面的VerterAnimationTrack一樣,在Apply里當前楨結合Node中計算骨骼坐標. 

     Node這個類比較重要,這里不詳細說,只說一些和此處有關的,Node里面包含自己的集合類,就是樹那一類型的結構,Node里Orientation,Position用來表示他自己的方法,有方法Transform與Rotate,默認這二個方法都是針對父Node來進行操作的.而Bone繼承Node,也繼承了這些元素. 

     重溫下MD5骨骼動畫模型加載,大致過程如下,靜態文件包含一些mesh,mesh由一些三角形(面,相當於頂點索引),而每個頂點索引是關聯上對應1-4個權重點,權重點有實際的位置,並關聯到對應骨骼上.而在動畫文件中,每楨中多個骨骼隨着改變位置,相應的權重點跟着改變,跟着頂點變,頂點構成的面也隨之變化了. 

     而Ogre中相應骨骼動畫過程也差不多,我們可以理解MD5中的靜態文件是Ogre中的mesh文件,在Axiom3D:Ogre中Mesh文件格式分析(一)在mesh文件中會保存面(頂點索引),頂點(實際位置),頂點與骨骼關聯對象VertexBoneAssignment(頂點索引,骨骼索引,權重).其實這里的頂點就相當於MD5中的權重點,而在VertexBoneAssignment記錄了對應的頂點與骨骼的聯系.其實是和MD5算起來是一樣的. 

     而在MD5中的動畫文件是Ogre中的skeleton,在MD5中,每楨記錄了不同的骨骼位置,Ogre中的skeleton也是如此,記錄了每楨的不同位置.不同MD5的是,他每個骨骼楨的記錄是單獨分開的,如骨骼點一有八楨,而骨骼點二有十楨.MD5所有的骨骼點是一起記錄的. 

     可能這么說有些不清楚,先看下相關的Ogre中的帶骨骼動畫的.mesh文件和skeleton的文件.(本來為二進制文件,圖是轉成的XML文件,請看OgreXmlConverter)

     如上中,相關節點與代碼關系. 

類對象 節點 備注
IndexData faces 頂點索引
VertexData geometry 頂點數據
VertexBoneAssignment boneassignments 頂點,骨骼,權重信息
     
Animation animation length,動畫時間
NodeAnimationTrack track node指向那個骨骼
TransformKeyFrame keyframe translate,rotate指定位置

       結合整個處理過程,Ogre中骨骼動畫會分別加載對應mesh文件與skeleton文件.在代碼中骨骼動畫是Entity對象,加載文件后,里的Mesh對象保存有頂點,紋理坐標,頂點索引,骨骼與頂點索引及權重信息.而Mesh關聯的Skeleton會保存所有的Bone信息,以及每個Bone的NodeAnimationTrack.然后會調用Mesh中的CompileBoneAssignments,其中會編歷Mesh的boneAssignments,把各個頂點關聯的骨骼,權重存入VertexData中,大約如下操作,對應的VertexDeclaration增加一個4個字節(骨骼索引),4個float(4個權重),然后添加一個新的HarderVertexBuffer(OpenGL中),就是上面的骨骼索引與權重(4Byte+4float).至於為什么是4,這是因為每個頂點最多關聯4個骨骼,如果過多,前面會對多余的去除,並重新分配權重最大的四個骨骼,不到4的部分都填充0.在這初始化過后就是動畫部分.在Entity里的UpdateAnimation方法轉到mesh中的skeleton中的NodeAnimationTrack,如變形動畫中,GetKeyFrameAtTime得到當前楨的位置.而Apply會根據當前楨的位置求得當前骨骼位置(TransformKeyFrame中的translate,rotate.骨骼位置是在父節點的基礎上求得,請看Node相關實現),在這里,如果是用CPU的方式計算頂點,就會調用Mesh的SoftwareVertexBlend,里面會對所有頂點執行BlendPosVector,這個過程就是上面說的MD5中的,骨骼位置變了(SoftwareVertexBlend方法中的matrices,代表各個骨骼的位置),然后每個頂點根據關聯的骨骼與權重求得實際的位置. 

     可以看到,Ogre中的骨骼動畫格式與MD5的區別不大,處理Ogre與我原來中的MD5關於頂點混合計算有些不同,Ogre的這種處理能很好的實現CPU與GPU處理共用大部分代碼.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM