http://hi.baidu.com/zyb_debug/blog/item/cb3fe2ca9ca3f015bf09e682.html
开始了Advanced Animation with DirectX的阅读
基础类库的构建是重要的,过后打算把它们加入我的zybToos的Framework里。
代码来自书中
#ifndef ZYBANIMATIONTOOLS_H
#define ZYBANIMATIONTOOLS_H
#include "DXUT.h"
//=========================================
/**
扩充D3DXMESHCONTAINER
扩充D3DXFrame
*/
//=========================================
namespace zyb
{
#define ReleaseCOM(x) { if(x!=NULL) x->Release(); x=NULL; }
// Declare an extended version of D3DXFRAME
// that contains a constructor and destructor
// as well as a combined transformation matrix
struct D3DXFRAME_EX : D3DXFRAME
{
D3DXMATRIX matCombined; // Combined matrix
D3DXMATRIX matOriginal; // Original transformation from .X
D3DXFRAME_EX()
{
Name = NULL;
pMeshContainer = NULL;
pFrameSibling = pFrameFirstChild = NULL;
D3DXMatrixIdentity(&matCombined);
D3DXMatrixIdentity(&matOriginal);
D3DXMatrixIdentity(&TransformationMatrix);
}
~D3DXFRAME_EX()
{
delete [] Name; Name = NULL;
delete pFrameSibling; pFrameSibling = NULL;
delete pFrameFirstChild; pFrameFirstChild = NULL;
}
// Function to scan hierarchy for matching frame name
D3DXFRAME_EX *Find(const char *FrameName)
{
D3DXFRAME_EX *pFrame, *pFramePtr;
// Return this frame instance if name matched
if(Name && FrameName && !strcmp(FrameName, Name))
return this;
// Scan siblings
if((pFramePtr = (D3DXFRAME_EX*)pFrameSibling)) {
if((pFrame = pFramePtr->Find(FrameName)))
return pFrame;
}
// Scan children
if((pFramePtr = (D3DXFRAME_EX*)pFrameFirstChild)) {
if((pFrame = pFramePtr->Find(FrameName)))
return pFrame;
}
// Return none found
return NULL;
}
// Reset transformation matrices to originals
void Reset()
{
// Copy original matrix
TransformationMatrix = matOriginal;
// Reset sibling frames
D3DXFRAME_EX *pFramePtr;
if((pFramePtr = (D3DXFRAME_EX*)pFrameSibling))
pFramePtr->Reset();
// Reset child frames
if((pFramePtr = (D3DXFRAME_EX*)pFrameFirstChild))
pFramePtr->Reset();
}
// Function to combine matrices in frame hiearchy
void UpdateHierarchy(D3DXMATRIX *matTransformation = NULL)
{
D3DXFRAME_EX *pFramePtr;
D3DXMATRIX matIdentity;
// Use an identity matrix if none passed
if(!matTransformation) {
D3DXMatrixIdentity(&matIdentity);
matTransformation = &matIdentity;
}
// Combine matrices w/supplied transformation matrix
matCombined = TransformationMatrix * (*matTransformation);
// Combine w/sibling frames
if((pFramePtr = (D3DXFRAME_EX*)pFrameSibling))
pFramePtr->UpdateHierarchy(matTransformation);
// Combine w/child frames
if((pFramePtr = (D3DXFRAME_EX*)pFrameFirstChild))
pFramePtr->UpdateHierarchy(&matCombined);
}
void Count(DWORD *Num)
{
// Error checking
if(!Num)
return;
// Increase count of frames
(*Num)+=1;
// Process sibling frames
D3DXFRAME_EX *pFrame;
if((pFrame=(D3DXFRAME_EX*)pFrameSibling))
pFrame->Count(Num);
// Process child frames
if((pFrame=(D3DXFRAME_EX*)pFrameFirstChild))
pFrame->Count(Num);
}
};
// Declare an extended version of D3DXMESHCONTAINER
// that contains a constructor and destructor
// as well as an array of textures, a mesh object
// that contains the generated skin mesh, and
// matrices that map to the frame hierarchy's and
// for updating bones.
struct D3DXMESHCONTAINER_EX : D3DXMESHCONTAINER
{
IDirect3DTexture9 **pTextures;
ID3DXMesh *pSkinMesh;
D3DXMATRIX **ppFrameMatrices;
D3DXMATRIX *pBoneMatrices;
D3DXMESHCONTAINER_EX()
{
Name = NULL;
MeshData.pMesh = NULL;
pMaterials = NULL;
pEffects = NULL;
NumMaterials = 0;
pAdjacency = NULL;
pSkinInfo = NULL;
pNextMeshContainer = NULL;
pTextures = NULL;
pSkinMesh = NULL;
ppFrameMatrices = NULL;
pBoneMatrices = NULL;
}
~D3DXMESHCONTAINER_EX()
{
if(pTextures && NumMaterials) {
for(DWORD i=0;i<NumMaterials;i++)
ReleaseCOM(pTextures[i]);
}
delete [] pTextures; pTextures = NULL;
NumMaterials = 0;
delete [] Name; Name = NULL;
delete [] pMaterials; pMaterials = NULL;
delete pEffects; pEffects = NULL;
delete [] pAdjacency; pAdjacency = NULL;
delete [] ppFrameMatrices; ppFrameMatrices = NULL;
delete [] pBoneMatrices; pBoneMatrices = NULL;
ReleaseCOM(MeshData.pMesh);
ReleaseCOM(pSkinInfo);
ReleaseCOM(pSkinMesh);
delete pNextMeshContainer; pNextMeshContainer = NULL;
}
D3DXMESHCONTAINER_EX *Find(char *MeshName)
{
D3DXMESHCONTAINER_EX *pMesh, *pMeshPtr;
// Return this mesh instance if name matched
if(Name && MeshName && !strcmp(MeshName, Name))
return this;
// Scan next in list
if((pMeshPtr = (D3DXMESHCONTAINER_EX*)pNextMeshContainer)) {
if((pMesh = pMeshPtr->Find(MeshName)))
return pMesh;
}
// Return none found
return NULL;
}
};
}
#endif