DXUTD3D骨骼动画Word文档格式.docx
- 文档编号:19411851
- 上传时间:2023-01-06
- 格式:DOCX
- 页数:35
- 大小:638.39KB
DXUTD3D骨骼动画Word文档格式.docx
《DXUTD3D骨骼动画Word文档格式.docx》由会员分享,可在线阅读,更多相关《DXUTD3D骨骼动画Word文档格式.docx(35页珍藏版)》请在冰豆网上搜索。
结构D3DXMESHCONTAINER_DERIVED继承自Direct3D提供的结构D3DXMESHCONTAINER,结构D3DXFRAME_DERIVED继承自Direct3D提供的结构D3DXFRAME,分别进行了相应的扩充,使其能够保存所需要的其他数据。
cAllocateHierarchy类负责从动画网格模型文件加载各种数据,该类继承自Direct3D中的ID3DXAllocateHierarchy接口。
cAnimMesh类是唯一对外开放的类,它通过cAllocateHierarchy类的对象从模型文件中加载所需的数据,并负责处理骨骼动画信息以及网格模型的渲染。
继承并扩展结构体D3DXFRAME
为了在渲染网格模型的同时播放包含在网格模型的动画,需要处理两个单独的实体:
骨骼结构(即框架结构)和网格模型。
框架结构和网格模型的相关数据分别使用D3DXFRAME_DERIVED和D3DXMESHCONTAINER_DERIVED结构保存。
需要指出的是.x文件中的一个网格模型可以由多个框架和多个网格组成,但具体到某一个框架时,它一般只有一个网格,当然它也可以有多个网格。
为了方便加载骨骼动画网格模型,Direct3D提供了两个重要的结构体:
D3DXFRAME和D3DXMESHCONTAINER,其中D3DXFRAME用来加载框架,其定义如下:
typedefstructD3DXFRAME{
LPSTRName;
D3DXMATRIXTransformationMatrix;
LPD3DXMESHCONTAINERpMeshContainer;
D3DXFRAME*pFrameSibling;
D3DXFRAME*pFrameFirstChild;
}D3DXFRAME,*LPD3DXFRAME;
显然在实现动画网格模型的绘制前,不仅要得到每个框架的初始变换矩阵,同时还要得到从该框架的所有父节点到本级框架的组合变换矩阵,这是因为任何一个父框架的位置改变都会影响该框架自身位置的变化,所以在此将结构D3DXFRAME扩展为D3DXFRAME_DERIVED,在D3DXFRAME_DERIVED中添加一个成员变量CombinedTransformMaitrx,用TransformationMatrix记录在任何动画数据未加载前框架的初始变换矩阵,也就是该框架的初始位置,用CombinedTransformMaitrx来记录从所有的父框架到该框架自身所积累起来的组合变换矩阵,这样就将整个网格模型很方便地组织起来了。
结构D3DXFRAME_DERIVED的定义如下:
structD3DXFRAME_DERIVED:
publicD3DXFRAME
{
D3DXMATRIXCombinedTransformMatrix;
};
继承并扩展结构体D3DXMESHCONTAINER
结构体D3DXMESHCONTAINER用来加载每个具体网格模型的数据,其定义如下:
typedefstructD3DXMESHCONTAINER{
D3DXMESHDATAMeshData;
LPD3DXMATERIALpMaterials;
LPD3DXEFFECTINSTANCEpEffects;
DWORDNumMaterials;
DWORD*pAdjacency;
LPD3DXSKININFOpSkinInfo;
D3DXMESHCONTAINER*pNextMeshContainer;
}D3DXMESHCONTAINER,*LPD3DXMESHCONTAINER;
结构体中没有记录网格模型的纹理信息,所以将该结构体扩展为D3DXMESHCONTAINER_DERIVED,定义如下:
structD3DXMESHCONTAINER_DERIVED:
publicD3DXMESHCONTAINER
IDirect3DTexture9**ppTextures;
其中ppTextures用来存储网格模型的纹理对象。
为了方便加载.x文件中的框架和网格模型数据,Direct3D提供了一个ID3DXAllocateHierarchy接口,该接口中有4个纯虚函数:
用来创建框架的CreateFrame(),创建网格容器的CreateMeshContainer(),销毁框架的DestroyFrame(),销毁网格容器的DestroyMeshContainer()。
应用程序会在相应的时机自动调用这些对应的函数,以构建或者销毁对应的框架或网格模型。
Method
Description
ID3DXAllocateHierarchy:
:
CreateFrame
Requestsallocationofaframeobject.
CreateMeshContainer
Requestsallocationofameshcontainerobject.
DestroyFrame
Requestsdeallocationofaframeobject.
DestroyMeshContainer
Requestsdeallocationofameshcontainerobject.
HRESULTCreateFrame(
LPCSTRName,
LPD3DXFRAME*ppNewFrame
);
HRESULTCreateMeshContainer(
CONSTD3DXMESHDATA*pMeshData,
CONSTD3DXMATERIAL*pMaterials,
CONSTD3DXEFFECTINSTANCE*pEffectInstances,
DWORDNumMaterials,
CONSTDWORD*pAdjacency,
LPD3DXSKININFOpSkinInfo,
LPD3DXMESHCONTAINER*ppNewMeshContainer
HRESULTDestroyFrame(
LPD3DXFRAMEpFrameToFree
HRESULTDestroyMeshContainer(
LPD3DXMESHCONTAINERpMeshContainerToFree
cAllocateHierarchy类继承自ID3DXAllocateHierarchy接口,在cAllocateHierarchy类需要重载这4个纯虚函数以实现动画网格模型数据的加载和释放。
该类的定义如下:
classcAllocateHierarchy:
publicID3DXAllocateHierarchy//?
private:
HRESULTAllocateName(LPCSTRname,LPSTR*ret_name);
public:
STDMETHOD(CreateFrame)(LPCSTRname,LPD3DXFRAME*ret_frame);
STDMETHOD(CreateMeshContainer)(LPCSTRname,
CONSTD3DXMESHDATA*mesh_data,
CONSTD3DXMATERIAL*xmaterials,
CONSTD3DXEFFECTINSTANCE*effect_instances,
DWORDnum_materials,
CONSTDWORD*adjacency,
LPD3DXSKININFOskin_info,
LPD3DXMESHCONTAINER*ret_mesh_container);
STDMETHOD(DestroyFrame)(THIS_LPD3DXFRAMEframe_to_free);
STDMETHOD(DestroyMeshContainer)(THIS_LPD3DXMESHCONTAINERbase_mesh_container);
函数AllocateFrame()用来为框架生成一个名称:
HRESULTcAllocateHierarchy:
AllocateName(LPCSTRname,LPSTR*ret_name)
if(name!
=NULL)
{
UINTlength=(UINT)strlen(name)+1;
*ret_name=newCHAR[length];
if(*ret_name==NULL)
returnE_OUTOFMEMORY;
memcpy(*ret_name,name,length*sizeof(CHAR));
}
else
*ret_name=NULL;
returnS_OK;
}
函数CreateFrame()的作用在于生成一个新的扩展框架,并按照指定的参数为该框架命名:
CreateFrame(LPCSTRname,LPD3DXFRAME*ret_frame)
*ret_frame=NULL;
D3DXFRAME_DERIVED*new_frame=newD3DXFRAME_DERIVED;
if(new_frame==NULL)
returnE_OUTOFMEMORY;
HRESULThr=AllocateName(name,&
new_frame->
Name);
if(FAILED(hr))
deletenew_frame;
returnhr;
D3DXMatrixIdentity(&
TransformationMatrix);
CombinedTransformMatrix);
new_frame->
pMeshContainer=NULL;
pFrameSibling=NULL;
pFrameFirstChild=NULL;
*ret_frame=new_frame;
在一个框架创建好后,需要创建该框架的网格容器,这通过函数CreateMeshContainer()来实现:
CreateMeshContainer(LPCSTRname,
LPD3DXMESHCONTAINER*ret_mesh_container)
*ret_mesh_container=NULL;
if(mesh_data->
Type!
=D3DXMESHTYPE_MESH)
returnE_FAIL;
ID3DXMesh*mesh_ptr=mesh_data->
pMesh;
DWORDfvf=mesh_ptr->
GetFVF();
if(fvf==0)
//createameshcontainerandzeroit
D3DXMESHCONTAINER_DERIVED*new_mesh_container=newD3DXMESHCONTAINER_DERIVED;
if(new_mesh_container==NULL)
memset(new_mesh_container,0,sizeof(D3DXMESHCONTAINER_DERIVED));
//copymeshname
new_mesh_container->
DestroyMeshContainer(new_mesh_container);
IDirect3DDevice9*device;
mesh_ptr->
GetDevice(&
device);
new_mesh_container->
MeshData.Type=D3DXMESHTYPE_MESH;
//besuremeshcontainnormal
if(!
(fvf&
D3DFVF_NORMAL))
hr=mesh_ptr->
CloneMeshFVF(mesh_ptr->
GetOptions(),fvf|D3DFVF_NORMAL,device,
&
MeshData.pMesh);
if(FAILED(hr))
{
release_com(device);
DestroyMeshContainer(new_mesh_container);
returnhr;
}
mesh_ptr=new_mesh_container->
MeshData.pMesh;
D3DXComputeNormals(mesh_ptr,NULL);
new_mesh_container->
MeshData.pMesh=mesh_ptr;
mesh_ptr->
AddRef();
//!
!
important,soDestroyMeshContainer()willnotcrash.
//loadmaterialsandtextures
UINTnum_faces=mesh_ptr->
GetNumFaces();
NumMaterials=max(1,num_materials);
pMaterials=newD3DXMATERIAL[new_mesh_container->
NumMaterials];
ppTextures=newLPDIRECT3DTEXTURE9[new_mesh_container->
pAdjacency=newDWORD[num_faces*3];
if((new_mesh_container->
pAdjacency==NULL)||(new_mesh_container->
pMaterials==NULL)||
(new_mesh_container->
ppTextures==NULL))
release_com(device);
memcpy(new_mesh_container->
pAdjacency,adjacency,sizeof(DWORD)*num_faces*3);
memset(new_mesh_container->
ppTextures,0,sizeof(LPDIRECT3DTEXTURE9)*new_mesh_container->
NumMaterials);
D3DXMATERIAL*xmaterials_ptr=new_mesh_container->
pMaterials;
if(num_materials>
0)
memcpy(xmaterials_ptr,xmaterials,sizeof(D3DXMATERIAL)*num_materials);
xmaterials_ptr->
MatD3D.Ambient=xmaterials_ptr->
MatD3D.Diffuse;
for(UINTi=0;
i<
num_materials;
i++)
if(xmaterials_ptr[i].pTextureFilename!
{
WCHARw_texture_path[MAX_PATH];
WCHARw_filename[MAX_PATH];
RemovePathFromFileName(xmaterials_ptr[i].pTextureFilename,w_filename);
DXUTFindDXSDKMediaFileCch(w_texture_path,MAX_PATH,w_filename);
if(FAILED(D3DXCreateTextureFromFileW(device,w_texture_path,&
ppTextures[i])))
new_mesh_container->
ppTextures[i]=NULL;
}
xmaterials_ptr[0].pTextureFilename=NULL;
memset(&
xmaterials_ptr[0].MatD3D,0,sizeof(D3DMATERIAL9));
xmaterials_ptr[0].MatD3D.Diffuse.r=0.5f;
xmaterials_ptr[0].MatD3D.Diffuse.b=0.5f;
xmaterials_ptr[0].MatD3D.Specular=xmaterials_ptr[0].MatD3D.Diffuse;
xmaterials_ptr[0].MatD3D.Ambient=xmaterials_ptr[0].MatD3D.Diffuse;
release_com(device);
*ret_mesh_container=new_mesh_container;
在此实现的骨骼动画网格模型中没有涉及到蒙皮信息,所以在CreateMeshContainer()函数中没有处理参数skin_info指向的蒙皮信息。
函数DestroyFrame
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- DXUTD3D 骨骼 动画