網(wǎng)格模型高級(jí)技術(shù)(11)
網(wǎng)格模型動(dòng)畫一般有兩種:一種是漸變動(dòng)畫;另一種是骨骼動(dòng)畫,這種動(dòng)畫包含在網(wǎng)格模型之中,通過網(wǎng)格模型不同部分之間的相對(duì)運(yùn)動(dòng)來實(shí)現(xiàn)動(dòng)畫。
骨骼動(dòng)畫基本原理
骨骼動(dòng)畫是目前最流行也最復(fù)雜的角色動(dòng)畫,它包含以下幾個(gè)重要元素:骨骼、動(dòng)畫。骨骼動(dòng)畫思想的起源很簡單,自然界中的大多數(shù)動(dòng)物都擁有一套骨骼,身體的皮毛血肉都依附于骨骼,當(dāng)骨骼開始運(yùn)動(dòng)的時(shí)候,依附于對(duì)應(yīng)骨骼的皮毛血肉都隨骨骼一起運(yùn)動(dòng)。在三維圖形編程領(lǐng)域,角色的軀體是由網(wǎng)格模型來表示的,網(wǎng)格模型通常由大量三角形圖元組成,而三角形又是由頂點(diǎn)組成的。為了模仿現(xiàn)實(shí)世界中角色自身的動(dòng)作,就需要為角色網(wǎng)格模型添加一套骨骼,同時(shí)需要確定哪些頂點(diǎn)依附于哪塊骨骼,這樣當(dāng)骨骼運(yùn)動(dòng)時(shí)就能牽引依附骨骼的頂點(diǎn)一起運(yùn)動(dòng),這就是骨骼動(dòng)畫的基本原理。
骨骼動(dòng)畫模型的骨骼是以樹狀層次結(jié)構(gòu)組織起來的,整個(gè)骨骼結(jié)構(gòu)中有一塊根骨骼,其他的骨骼都直接或間接連接到根骨骼上,形成角色模型的整個(gè)骨骼框架。
一般每塊骨骼都帶有兩個(gè)矩陣,一個(gè)是初始變換矩陣(LocalTransformMatrix),表示骨骼的初始位置;另一個(gè)是組合變換矩陣(CombinedTransformMaitrx),用于對(duì)骨骼進(jìn)行各種變換,從而實(shí)現(xiàn)角色動(dòng)畫。在每次渲染角色模型前,需要更新整個(gè)骨骼層次結(jié)構(gòu),組合每個(gè)連續(xù)的變換,將上層骨骼的運(yùn)動(dòng)傳遞到下層骨骼,這個(gè)原理可表示為:
(子骨骼的)CombinedTransformMaitrx = (子骨骼的)LocalTransformMaitrx x (父骨骼的)CombinedTransformMaitrx
骨骼的組合變換矩陣是隨動(dòng)畫的播放不斷變化的,而它的初始變換矩陣一般是不改變的,正是所有骨骼的這些矩陣相互作用才牽引著頂點(diǎn)的變化,從而實(shí)現(xiàn)了骨骼動(dòng)畫。因?yàn)橐淮巫儞Q只能將骨骼變換到一個(gè)特定位置,要形成連續(xù)的動(dòng)畫就需要一幀一幀地連續(xù)改變骨骼的位置,每次改變骨骼的位置都需要一個(gè)骨骼變換矩陣,在網(wǎng)格模型中不可能保存任意時(shí)刻骨骼的變換矩陣,通常是保存關(guān)鍵時(shí)間點(diǎn)骨骼的變換矩陣(即關(guān)鍵楨),然后在播放角色動(dòng)畫時(shí),根據(jù)播放時(shí)間進(jìn)行插值得到任意時(shí)刻骨骼的變換矩陣,從而形成連續(xù)的角色動(dòng)畫。
骨骼動(dòng)畫是通過骨骼變換矩陣實(shí)現(xiàn)的,在網(wǎng)格模型中保存的也是關(guān)鍵時(shí)間點(diǎn)骨骼的變換矩陣,因此插值就是針對(duì)這些關(guān)鍵時(shí)間點(diǎn)上的骨骼變換矩陣進(jìn)行的。假設(shè)在s1時(shí)刻骨骼變換矩陣是mat1,在s2時(shí)刻骨骼變換矩陣是mat2,在s1和s2之間的任意時(shí)刻s,其骨骼變換矩陣mat為:
mat = (1-w) * mat1 + w * mat2
其中w是權(quán)值,通過這個(gè)權(quán)值來調(diào)節(jié)在s時(shí)刻骨骼變換矩陣中mat1和mat2所占的比重,對(duì)骨骼變換矩陣進(jìn)行插值最簡單的方法是線性插值,這時(shí)w = (s-s1) / (s2-s1)
骨骼動(dòng)畫類的設(shè)計(jì)與實(shí)現(xiàn)
我們需要將骨骼動(dòng)畫網(wǎng)格模型的相關(guān)操作封裝到一組類和結(jié)構(gòu)中,這一組類和結(jié)構(gòu)可以看成一套完整的骨骼動(dòng)畫網(wǎng)格模型接口,它們之間的關(guān)系如下圖所示:

其中,D3DXFRAME和D3DXMESHCONTAINER是Direct3D提供的兩個(gè)結(jié)構(gòu),D3DXMESHCONTAINER結(jié)構(gòu)用于保存模型的網(wǎng)格數(shù)據(jù),D3DXFRAME用于保存模型的骨骼框架。結(jié)構(gòu)D3DXMESHCONTAINER_DERIVED繼承自Direct3D提供的結(jié)構(gòu)D3DXMESHCONTAINER,結(jié)構(gòu)D3DXFRAME_DERIVED繼承自Direct3D提供的結(jié)構(gòu)D3DXFRAME,分別進(jìn)行了相應(yīng)的擴(kuò)充,使其能夠保存所需要的其他數(shù)據(jù)。
cAllocateHierarchy類負(fù)責(zé)從動(dòng)畫網(wǎng)格模型文件加載各種數(shù)據(jù),該類繼承自Direct3D中的ID3DXAllocateHierarchy接口。
cAnimMesh類是唯一對(duì)外開放的類,它通過cAllocateHierarchy類的對(duì)象從模型文件中加載所需的數(shù)據(jù),并負(fù)責(zé)處理骨骼動(dòng)畫信息以及網(wǎng)格模型的渲染。
繼承并擴(kuò)展結(jié)構(gòu)體D3DXFRAME
為了在渲染網(wǎng)格模型的同時(shí)播放包含在網(wǎng)格模型的動(dòng)畫,需要處理兩個(gè)單獨(dú)的實(shí)體:骨骼結(jié)構(gòu)(即框架結(jié)構(gòu))和網(wǎng)格模型。框架結(jié)構(gòu)和網(wǎng)格模型的相關(guān)數(shù)據(jù)分別使用D3DXFRAME_DERIVED和D3DXMESHCONTAINER_DERIVED結(jié)構(gòu)保存。需要指出的是.x文件中的一個(gè)網(wǎng)格模型可以由多個(gè)框架和多個(gè)網(wǎng)格組成,但具體到某一個(gè)框架時(shí),它一般只有一個(gè)網(wǎng)格,當(dāng)然它也可以有多個(gè)網(wǎng)格。
為了方便加載骨骼動(dòng)畫網(wǎng)格模型,Direct3D提供了兩個(gè)重要的結(jié)構(gòu)體:D3DXFRAME和D3DXMESHCONTAINER,其中D3DXFRAME用來加載框架,其定義如下:
Encapsulates a transform frame in a transformation frame hierarchy.
typedef struct D3DXFRAME {
LPSTR Name;
D3DXMATRIX TransformationMatrix;
LPD3DXMESHCONTAINER pMeshContainer;
D3DXFRAME * pFrameSibling;
D3DXFRAME * pFrameFirstChild;
} D3DXFRAME, *LPD3DXFRAME;
Members
- Name
- Name of the frame.
- TransformationMatrix
- Transformation matrix.
- pMeshContainer
- Pointer to the mesh container.
- pFrameSibling
- Pointer to a sibling frame.
- pFrameFirstChild
- Pointer to a child frame.
Remarks
An application can derive from this structure to add other data.
顯然在實(shí)現(xiàn)動(dòng)畫網(wǎng)格模型的繪制前,不僅要得到每個(gè)框架的初始變換矩陣,同時(shí)還要得到從該框架的所有父節(jié)點(diǎn)到本級(jí)框架的組合變換矩陣,這是因?yàn)槿魏我粋€(gè)父框架的位置改變都會(huì)影響該框架自身位置的變化,所以在此將結(jié)構(gòu)D3DXFRAME擴(kuò)展為D3DXFRAME_DERIVED,在D3DXFRAME_DERIVED中添加一個(gè)成員變量CombinedTransformMaitrx,用TransformationMatrix記錄在任何動(dòng)畫數(shù)據(jù)未加載前框架的初始變換矩陣,也就是該框架的初始位置,用CombinedTransformMaitrx來記錄從所有的父框架到該框架自身所積累起來的組合變換矩陣,這樣就將整個(gè)網(wǎng)格模型很方便地組織起來了。
結(jié)構(gòu)D3DXFRAME_DERIVED的定義如下:
struct D3DXFRAME_DERIVED : public D3DXFRAME
{
D3DXMATRIX CombinedTransformMatrix;
};
繼承并擴(kuò)展結(jié)構(gòu)體D3DXMESHCONTAINER
結(jié)構(gòu)體D3DXMESHCONTAINER用來加載每個(gè)具體網(wǎng)格模型的數(shù)據(jù),其定義如下:
Encapsulates a mesh object in a transformation frame hierarchy.
typedef struct D3DXMESHCONTAINER {
LPSTR Name;
D3DXMESHDATA MeshData;
LPD3DXMATERIAL pMaterials;
LPD3DXEFFECTINSTANCE pEffects;
DWORD NumMaterials;
DWORD * pAdjacency;
LPD3DXSKININFO pSkinInfo;
D3DXMESHCONTAINER * pNextMeshContainer;
} D3DXMESHCONTAINER, *LPD3DXMESHCONTAINER;
Members
- Name
- Mesh name.
- MeshData
- Type of data in the mesh.
- pMaterials
- Array of mesh materials.
- pEffects
- Pointer to a set of default effect parameters.
- NumMaterials
- Number of materials in the mesh.
- pAdjacency
- Pointer to an array of three DWORDs per triangle of the mesh that contains adjacency information.
- pSkinInfo
- Pointer to the skin information interface.
- pNextMeshContainer
- Pointer to the next mesh container.
結(jié)構(gòu)體D3DXMESHCONTAINER中沒有記錄網(wǎng)格模型的紋理信息,所以將該結(jié)構(gòu)體擴(kuò)展為D3DXMESHCONTAINER_DERIVED,定義如下:
struct D3DXMESHCONTAINER_DERIVED : public D3DXMESHCONTAINER
{
IDirect3DTexture9** ppTextures;
};
其中ppTextures用來存儲(chǔ)網(wǎng)格模型的紋理對(duì)象。
posted on 2008-06-11 14:22 lovedday 閱讀(2130) 評(píng)論(2) 編輯 收藏 引用

