d3d 骨骼动画1

上传人:仙*** 文档编号:180775202 上传时间:2023-01-07 格式:DOC 页数:41 大小:425.50KB
收藏 版权申诉 举报 下载
d3d 骨骼动画1_第1页
第1页 / 共41页
d3d 骨骼动画1_第2页
第2页 / 共41页
d3d 骨骼动画1_第3页
第3页 / 共41页
资源描述:

《d3d 骨骼动画1》由会员分享,可在线阅读,更多相关《d3d 骨骼动画1(41页珍藏版)》请在装配图网上搜索。

1、第14讲 骨骼动画 1、模型动画信息 骨骼动画模型中的骨骼是以树状层次结构组织起来的,整个骨骼结构中有一块根骨骼(Root),其他的骨骼都直接或间接连接到根骨骼上,从而形成角色模型的整个骨骼框架,如图所示。 不含动画的普通X文件,有一个Mesh单元,保存了各顶点信息、各三角面的索引信息、材质种类及定义等。而动画X文件,则在这个单元中增加了“各骨骼蒙皮信息”、“骨骼层次及结构信息”、“各时刻骨骼矩阵信息”等。 (1)在X文件中,骨骼信息是有框架(Frame)组成的,由于Frame模板是开放模板类型,所以在其中可以包含其他的Frame。框架中通过嵌套定义也就形成了父子框架,而并列定义

2、也就形成了兄弟框架,从而形成一个层次结构。同时每块骨骼都包含两个矩阵:初始变换矩阵LocalTransformMatrix和组合变换矩阵CombinedTransformMatrix,其中初始变换矩阵用于表示骨骼的初始位置,而组合变换矩阵用于对骨骼进行各种变换。 在Directx中,用一个D3DXFRAME结构或者X文件中的Frame template来表示帧对象。下面看一下Frame template和D3DXFRAME结构的定义: template Frame {         < 3D82AB46-62DA-11cf-AB39-0020AF71E433 >        

3、 FrameTransformMatrix frameTransformMatrix;       // 骨骼相对于父节点的坐标变换矩阵,就是一个matrix         Mesh mesh;                                                   // 骨骼的Mesh }  typedef struct _D3DXFRAME {  LPSTR                   Name;                            // 骨骼名称  D3DXMATRIX         Transfor

4、mationMatrix;        // 相对与父节点的坐标变换矩阵    LPD3DXMESHCONTAINER     pMeshContainer;  // LPD3DXMESHCONTAINER对象,  用来加载MESH,  struct _D3DXFRAME  *pFrameSibling;  //兄弟节点指针     struct _D3DXFRAME       *pFrameFirstChild;      // 子节点指针 } D3DXFRAME, *LPD3DXFRAME; (2)为了使一个X文件产生动画,必须至少提供一个动画集,每个动画集都应具有一个对某

5、个框架的引用。在X文件中,动画集由AnimationSet模板定义,其中由多个开放性模板Animation模板组成。AnimationSet模板及Animation模板的定义如下: template AnimationSet { < 3D82AB50-62DA-11cf-AB39-0020AF71E433 > [ Animation < 3D82AB4F-62DA-11cf-AB39-0020AF71E433 > ] } template Animation { < 3D82AB4F-62DA-11cf-AB39-0020AF71E433

6、> [...] } AnimationSet模板只存储Animation对象,而Animation通常是由AnimationKey模板进行填充。这个模板用于存储动画关键帧码,这个模板的每一个实例都包含帧码的类型(位置,缩放,转动,矩阵)和帧码数组。数组中的每一个元素包含帧码的值和一个DWORD型的值指出帧的持续时间。AnimationKey模板的定义如下: template AnimationKey //骨骼的各个动画帧时刻的动作数据模板 { < 10DD46A8-775B-11CF-8F52-0040333594A3 > DWORD keyTy

7、pe; DWORD nKeys; array TimedFloatKeys keys[nKeys]; } template TimedFloatKeys { < F406B180-7B3B-11cf-8F52-0040333594A3 > DWORD time; FloatKeys tfkeys; } 其中,AnimationKey模板中的keyType表示当前关键帧的类型。若该值为0,则表示旋转键,表示将使用四个分量w、x、y、z存储模型的旋转值。其值为1表示缩放键,它表示分别对应x、y、z轴的模型缩放值。而对于

8、平移键,其值将为2。该值为4,则表示变换矩阵键,此时关键帧的变换数组将使用16个浮点数实现该模型的各种变换。例如: AnimationSet walk{ Animation { AnimationKey { 4; //变换矩阵键 2; //2个动作 //第一个动作 0;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,1.000000,0.000000,0.0000

9、00,0.000000,0.000000,1.000000;;, //第二个动作 4960;16;1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000, 0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;; } { Scene_Root } } … } (3)皮肤属性由XSkinMeshHeader模板定义,其中包含了影

10、响皮肤网格顶点的最大变换数和骨骼数。皮肤权重由SkinWeights模板定义,其中包含了一个具体的骨骼对于相应顶点的影响权重。这两个模板的定义如下: template XSkinMeshHeader { < 3CF169CE-FF7C-44ab-93C0-F78F62D172E2 > WORD nMaxSkinWeightsPerVertex; //一个顶点可以受到骨骼影响的最大骨骼数,可用于计算共同作用时减少遍历次数 WORD nMaxSkinWeightsPerFace; //一个三角面可以受到骨骼影响的最大骨骼数。这个数字对硬件顶点混合计算提出了基本要求

11、。 WORD nBones; //当前Mesh的骨骼总数 } 由于每个骨骼的蒙皮信息都需要用SkinWeights结构去描述,所以有多少块骨骼,在Mesh中就有多少个SkinWeights对象。注意,一般把SkinWeights视作Mesh的一部分。这种Mesh又称Skinned Mesh (蒙皮网格),SkinWeights 结构如下: template SkinWeights { < 6F0D123B-BAD2-4167-A0D0-80224F25FABB > STRING transformNodeName; //骨骼名 DWORD

12、 nWeights; //权重数组的元素个数,即该骨骼相关的顶点个数 array DWORD vertexIndices[nWeights]; //受该骨骼控制的顶点索引,实际上定义了该骨骼的蒙皮 array float weights[nWeights]; //蒙皮各顶点的受本骨骼影响的权值 Matrix4x4 matrixOffset; //骨骼偏移矩阵,用来从初始Mesh坐标,反向计算顶点在子骨骼坐标系中的初始坐标。 } 在有的书中,把上面的matrixOffset叫骨骼权重矩阵,是不恰当的。我们应该称为骨骼偏移矩阵比较合适。 2、加载骨骼动画数据 保

13、存从X文件中读取的骨骼动画数据,Direct3D定义了D3DXFRAME和D3DXMESHCONTAINER两个结构。其中,D3DXFRAME结构用于保存X文件中的骨骼信息(框架通常用来描述骨骼,所以也可以将框架看作骨骼),而D3DXMESHCONTAINER结构则用于保存网格蒙皮信息。这两个结构体的定义。 typedef struct _D3DXFRAME //保存框架骨骼信息 { LPSTR Name; // 骨骼的名称 D3DXMATRIX TransformationMatrix; // 本骨骼的转换矩阵 LPD3D

14、XMESHCONTAINER pMeshContainer; // 本骨骼所对应Mesh数据 struct _D3DXFRAME *pFrameSibling; // 兄弟骨骼 struct _D3DXFRAME *pFrameFirstChild; // 子骨骼 } D3DXFRAME, *LPD3DXFRAME; typedef struct _D3DXMESHCONTAINER //网格容器 保存网格蒙皮信息 { LPSTR Name; // Mesh名称 D3DXMESHDATA MeshDa

15、ta; // Mesh数据 LPD3DXMATERIAL pMaterials; // 材质数组 LPD3DXEFFECTINSTANCE pEffects; // 效果 DWORD NumMaterials; // 材质数 DWORD *pAdjacency; // 邻接三角形数组 LPD3DXSKININFO pSkinInfo; // 蒙皮信息 struct _D3DXMESHCONTAINER *pNextMeshContainer; } D3DXMESH

16、CONTAINER, *LPD3DXMESHCONTAINER; 在实现动画网格模型的绘制前,不仅要得到每个框架的初始变换矩阵,同时还要得到从该框架的所有父节点到本级框架的组合变换矩阵。这是因为任何一个父框架的位置改变都会影响该框架自身位置的变化,所以在此将结构D3DXFRAME 扩展为D3DXFRAME_ DERIVED。例如: struct D3DXFRAME_DERIVED: public D3DXFRAME { D3DXMATRIXA16 TransformationMatrix; D3DXMATRIXA16 CombinedTransformation

17、Matrix; //组合转换矩阵 }; 由于在D3DXMESHCONTAINER结构中并没有记录网格模型的纹理、蒙皮等信息,所以在应用程序中还需要将该结构扩展为D3DXMESHCONTAINER_DERIVED。例如: struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER { LPDIRECT3DTEXTURE9* ppTextures; // 纹理数组 LPD3DXMESH pOrigMesh; // 原始网格 LPD3D

18、XATTRIBUTERANGE pAttributeTable; // 网格的属性表 DWORD NumAttributeGroups; // 属性组数量,即子网格数量 DWORD NumInfl; // 每个顶点最多受多少骨骼的影响 LPD3DXBUFFER pBoneCombinationBuf; // 骨骼结合表 D3DXMATRIX** ppBoneMatrixPtrs; // 存放骨骼的组合

19、变换矩阵 D3DXMATRIX* pBoneOffsetMatrices; // 存放骨骼的初始变换矩阵 DWORD NumPaletteEntries; // 骨骼数量上限 bool UseSoftwareVP; // 标志是否使用软件顶点处理 }; 其中,pBoneCombBuffer指向骨骼结合表,骨骼结合表中的数据按属性组结构体D3DXBONECOMBINATION组织起来。该结构体定义如下: typedef struct

20、D3DXBONECOMBINATION { DWORD AttribId; // 属性ID DWORD FaceStart; // 起始的三角面 DWORD FaceCount; // 三角面面数 DWORD VertexStart; // 起始的顶点 DWORD VertexCount; // 顶点数 DWORD * BoneId; // 在每次绘制时所用到的骨骼矩阵 } D3DXBONECOMBINATION, *LPD3DXBONECOMBINATION; Direct3D

21、提供了多种骨骼数据的加载方式,然而标准的加载方式是通过调用D3DX库中D3DXLoadMeshHierarchyFromX函数读取Mesh层次信息。该函数的声明如下: HRESULT D3DXLoadMeshHierarchyFromX( //网格层次结构模型 LPCSTR Filename, // X文件名 DWORD MeshOptions, // 加载选项,通常为D3DXMESH_MANAGED LPDIRECT3DDEVICE9 pDevice, LPD3DXALLOCATEHIERARCHY pAlloc, //

22、自定义数据容器 LPD3DXLOADUSERDATA pUserDataLoader, // 用户数据加载器,通常设为NULL LPD3DXFRAME *ppFrameHierarchy, // 框架层次结构的根框架 LPD3DXANIMATIONCONTROLLER *ppAnimController // 动画控制器 ); (1)自定义数据容器类:CAllocateHierarchy类自ID3DXAllocateHierarchy接口继承,该类分别重载了ID3DXAllocateHierarchy接口中四个方法,用于实现动画网格模型数据的加载

23、和释放。该类的定义如下: //这里是Directx9.0a的 class CAllocateHierarchy: public ID3DXAllocateHierarchy { public: STDMETHOD(CreateFrame)(THIS_ LPCTSTR Name, LPD3DXFRAME *ppNewFrame); #if ((D3D_SDK_VERSION & 0xFF)== 31) //这里是Directx9.0b的 STDMETHOD(CreateMeshContainer)(THIS_ LPCTSTR Name, LPD3DXMESH

24、DATA pMeshData, LPD3DXMATERIAL pMaterials, LPD3DXEFFECTINSTANCE pEffectInstances, DWORD NumMaterials, DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer); #else //这里是Directx9.0c的 STDMETHOD(CreateMeshContainer)(THIS_ LPCSTR Name,

25、 CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer); #endif STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME p

26、FrameToFree); STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerBase); CAllocateHierarchy(CSkinMesh *pSkinMesh) :m_pSkinMesh(pSkinMesh) {} public: CSkinMesh* m_pSkinMesh; }; 其中,CreateFrame函数仅仅用来创建一个D3DXFRAME对象,并按照指定的参数为该框架命名。 HRESULT CAllocateHierarchy::CreateFra

27、me(LPCTSTR Name, LPD3DXFRAME *ppNewFrame) { HRESULT hr = S_OK; D3DXFRAME_DERIVED *pFrame; *ppNewFrame = NULL; pFrame = new D3DXFRAME_DERIVED;//为框架指定名称,创建框架结构对象 if (pFrame == NULL) { hr = E_OUTOFMEMORY; goto e_Exit; } hr = AllocateName(Nam

28、e, &pFrame->Name); if (FAILED(hr)) goto e_Exit; //初始化frame其他成员变量 D3DXMatrixIdentity(&pFrame->TransformationMatrix); D3DXMatrixIdentity(&pFrame->CombinedTransformationMatrix); pFrame->pMeshContainer = NULL; pFrame->pFrameSibling = NULL; pFrame->pFrameFirstChild

29、= NULL; *ppNewFrame = pFrame; pFrame = NULL; e_Exit: delete pFrame; return hr; } AllocateName函数用于为一个LPSTR类型字符串分配内存,并用LPCSTR类型的字符串对它进行赋值。 HRESULT AllocateName( LPCTSTR Name, LPTSTR *pNewName ) { UINT cbLength; if (Name != NULL) { cbLength = lstrlen(Name

30、) + 1; *pNewName = new TCHAR[cbLength]; if (*pNewName == NULL) return E_OUTOFMEMORY; memcpy(*pNewName, Name, cbLength*sizeof(TCHAR)); } else { *pNewName = NULL; } return S_OK; } DestroyFrame函数比较简单,它只有一个LPD3DXFRAME类型参数,并指向准备

31、释放的框架对象。该函数首先通过SAFE_DELETE_ARRAY宏实现框架对象的命名,然后通过SAFE_DELETE宏释放该对象。该函数的实现代码如下 HRESULT CAllocateHierarchy::DestroyFrame( LPD3DXFRAME pFrameToFree ) { SAFE_DELETE_ARRAY( pFrameToFree->Name ); SAFE_DELETE( pFrameToFree ); return S_OK; } 其中: #define SAFE_DELETE(p) { if(p) { del

32、ete (p); (p)=NULL; } } #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } 从CreateMeshContainer函数的声明中可以看出,传入该函数的参数包括pMeshData、pMaterials、pEffectInstances、NumMaterials、pAjacency和pSkinInfo等。因此,在该函数体内需要将这些数据保存到一个D3DXM

33、ESHCONTAINER对象中。并且,其中所有数组所需的空间都需要在全局堆中进行分配。例如: D3DXMESHCONTAINER_DERIVED *pMeshContainer = NULL; pMeshContainer = new D3DXMESHCONTAINER_DERIVED; ……………………… pMeshContainer->NumMaterials = max( 1, NumMaterials ); pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials]; pMe

34、shContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials]; MeshContainer->pAdjacency = new DWORD[NumFaces*3]; 通过memcpy函数分别将这些对象复制到pMeshContainer对象中。由于在绘制过程中并不需要pEffectInstanes,所以就不需要对它进行保存。如果材质中未包含纹理贴图,那么将使用默认的材质属性。判断pSkinInfo是否包含蒙皮信息,如果pSkinInfo不为NULL,那么就需要通过该信息中的蒙皮信息创建蒙皮网格

35、对象。首先,将原网格对象保存到pMeshContainer对象的pOrigMesh中,然后将保存在pSkinInfo中的各骨骼的偏移矩阵复制到pMeshContainer对象的pBoneOffsetMatrices中。 CSkinMesh类中的GenerateSkinnedMesh函数用来生成蒙皮网格数据,其中调用ID3DXSkinInfo接口的ConvertToBlendedMesh或ConvertToIndexedBlendedMesh方法生成已经过顶点混合或索引顶点混合后的蒙皮网格对象。 ConvertToBlendedMesh与ConvertToIndexedBlend

36、Mesh方法的区别在于,前者将采用无索引的顶点混合生成蒙皮网格对象,而后者则采用含有索引的顶点混合生成蒙皮网格对象。 HRESULT ConvertToIBlendedMesh( LPD3DXMESH pMesh, DWORD Options, const DWORD *pAdjacencyIn, LPDWORD pAdjacencyOut, DWORD *pFaceRemap, LPD3DXBUFFER *ppVertexRemap, DWORD *pMaxVertexInfl, DWORD *pNumBone

37、Combinations, LPD3DXBUFFER *ppBoneCombinationTable, LPD3DXMESH *ppMesh ); HRESULT ConvertToIndexedBlendedMesh( LPD3DXMESH pMesh, DWORD Options, DWORD paletteSize, const DWORD *pAdjacencyIn, LPDWORD pAdjacencyOut, DWORD *pFaceRemap, LPD3DXBUFFER *ppVert

38、exRemap, DWORD *pMaxVertexInfl, DWORD *pNumBoneCombinations, LPD3DXBUFFER *ppBoneCombinationTable, LPD3DXMESH *ppMesh ); 3、顶点混合技术 (1)定点混合原理 网格模型是由一个个顶点构成的,如果任意一个顶点只受一块骨骼影响,那么网格模型在运动时很容易出现裂缝,特别是在一些结合部位,如肩关节和肘关节等,如图所示。 顶点混合就是Direct3D首先会根据骨骼权重和骨骼矩阵对顶点数据(包括顶点位置和顶点法向量)进行混合,然后再

39、对混合后的图形进行渲染。Direct3D最初的图形进行了两次变换。其中,第一次没有对顶点进行变换,它只相当于对顶点数据乘以一个单位矩阵。而第二次对图形进行了简单的旋转变换,它相当于对顶点数据乘以一个旋转矩阵。将两次变换后的顶点数据进行混合,再经过渲染就得到了最终显示的图形,如图所示。 Direct3D根据混合矩阵和相应的权重对顶点位置和法线进行线性插值。计算公式如下: 因为所有混合权重之和为1.0,所以在顶点数据中只需保存前n-1个混合权重,第n个混合权重为1.0减去前n-1个混合权重之和。在Direct3D引擎中,影响每个顶点的混合矩阵最大数量限定为4,所以在Direct3D

40、中顶点混合就有以下三种情况: (2)索引顶点混合 由于Direct3D限定每个顶点最多受到四个混合矩阵的影响,所以每个顶点最多具有四个矩阵索引,并用一个DWORD类型的整数存储和表示,如图所示。 在渲染一个三角形时最多可能需要使用12个混合矩阵,因此矩阵调色板中最少需要包含12个混合矩阵,如图所示 在渲染图形时,要想启用索引顶点混合,需要将渲染状态D3DRS_INDEXEDVERTEX BLENDENABLE设置为TRUE。另外,还需要在顶点数据中包含矩阵索引的数据,每个顶点的矩阵索引默认为0~3。例如: g_pd3dDevice->SetRenderStat

41、e(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE); g_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, ppMeshContainer->NumInfl-1); 4、蒙皮骨骼动画网格模型类介绍 5、相关代码: 定义SkinMesh.h文件: #pragma once #include #include #include #define SAFE_DELETE(p) { if(p) { delete (p);

42、 (p)=NULL; } } #define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } } //----------------------------------------------------------------------------- // Name: struct D3DXFRAME_DERIVED // Desc: Structure deri

43、ved from D3DXFRAME so we can add some app-specific // info that will be stored with each frame //----------------------------------------------------------------------------- struct D3DXFRAME_DERIVED: public D3DXFRAME { D3DXMATRIXA16 CombinedTransformationMatrix; }; //-----

44、------------------------------------------------------------------------ // Name: struct D3DXMESHCONTAINER_DERIVED // Desc: Structure derived from D3DXMESHCONTAINER so we can add some app-specific // info that will be stored with each mesh //------------------------------------------------

45、----------------------------- struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER { LPDIRECT3DTEXTURE9* ppTextures; // array of textures, entries are NULL if no texture specified // SkinMesh info LPD3DXMESH p

46、OrigMesh; LPD3DXATTRIBUTERANGE pAttributeTable; DWORD NumAttributeGroups; DWORD NumInfl; LPD3DXBUFFER pBoneCombinationBuf; D3DXMATRIX** ppBoneMatrixPtrs; D3DXMATRIX* pBoneOffsetMatrices; DWORD N

47、umPaletteEntries; bool UseSoftwareVP; DWORD iAttributeSW; // used to denote the split between SW and HW if necessary for non-indexed skinning }; // enum for various skinning modes possible enum METHOD { D3DNONINDEXED, D3DINDEXED, SOF

48、TWARE, NONE }; class CSkinMesh; //----------------------------------------------------------------------------- // Name: class CAllocateHierarchy // Desc: Custom version of ID3DXAllocateHierarchy with custom methods to create // frames and meshcontainers. //--------------------

49、--------------------------------------------------------- class CAllocateHierarchy: public ID3DXAllocateHierarchy { public: STDMETHOD(CreateFrame)(THIS_ LPCTSTR Name, LPD3DXFRAME *ppNewFrame); #if ((D3D_SDK_VERSION & 0xFF)==31) //这里是Directx9.0b的 STDMETHOD(CreateMeshContainer)(THIS_

50、 LPCTSTR Name, LPD3DXMESHDATA pMeshData, LPD3DXMATERIAL pMaterials, LPD3DXEFFECTINSTANCE pEffectInstances, DWORD NumMaterials, DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD

51、3DXMESHCONTAINER *ppNewMeshContainer); #else //这里是Directx9.0c的 STDMETHOD(CreateMeshContainer)( THIS_ LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances, DWORD NumMaterials, C

52、ONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer); #endif STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree); STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerBase); CAllocateHierarchy(CSkinMes

53、h *pSkinMesh) :m_pSkinMesh(pSkinMesh) {} public: CSkinMesh* m_pSkinMesh; }; //蒙皮动画 class CSkinMesh { public: VOID SetAnim(BOOL bAnim); BOOL CSkinMesh::InterSect( D3DVECTOR *pRayOrig, D3DVECTOR *pRayDir,D3DVECTOR* pVRet); VOID UpdateFrameMatrices( LPD3DXFRAME pFrameBase, LPD3D

54、XMATRIX pParentMatrix ); LPD3DXANIMATIONCONTROLLER GetAnimController() {return m_pAnimController;}; BOOL SetAnimationName(char *strAnimName); VOID Render(float fTimeFromLastFrame,D3DXVECTOR3 vPos,float angle,float scale=1.0f); HRESULT LoadFromXFile(char* strFileName); HRESULT GenerateSki

55、nnedMesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer); CSkinMesh(LPDIRECT3DDEVICE9 pD3DDevice); // CSkinMesh(LPDIRECT3DDEVICE9 pD3DDevice,char* strFileName); HRESULT CalculateBondingBox(LPD3DXFRAME pFrameParent, D3DXVECTOR3 *pVmin,D3DXVECTOR3 *pVmax) { static LPVOID pV; static LPD3DX

56、MESH pMesh; static LPD3DXMATRIX pMat; static D3DXVECTOR3 vMin,vMax; static D3DXVECTOR3 vTransFormed; if(pFrameParent->pMeshContainer) { pMesh=pFrameParent->pMeshContainer->MeshData.pMesh; pMat=&(((D3DXFRAME_DERIVED*)pFrameParent)->CombinedTransformationMatrix); pM

57、esh->LockVertexBuffer(0,&pV); D3DXComputeBoundingBox((LPD3DXVECTOR3)pV,pMesh->GetNumVertices(), pMesh->GetNumBytesPerVertex(),&vMin,&vMax); vTransFormed.x=pMat->_11*vMin.x+pMat->_21*vMin.y+pMat->_31*vMin.z+pMat->_41; vTransFormed.y=pMat->_12*vMin.x+pMat->_22*vMin.y+pMat->_32*

58、vMin.z+pMat->_42; vTransFormed.z=pMat->_13*vMin.x+pMat->_23*vMin.y+pMat->_33*vMin.z+pMat->_43; if(vTransFormed.xx) pVmin->x=vTransFormed.x; if(vTransFormed.yy) pVmin->y=vTransFormed.y; if(vTransFormed.zz) pVmin->z=vTransFormed.z; vTransFormed.x=pMat->_

59、11*vMax.x+pMat->_21*vMax.y+pMat->_31*vMax.z+pMat->_41; vTransFormed.y=pMat->_12*vMax.x+pMat->_22*vMax.y+pMat->_32*vMax.z+pMat->_42; vTransFormed.z=pMat->_13*vMax.x+pMat->_23*vMax.y+pMat->_33*vMax.z+pMat->_43; if(vTransFormed.x>pVmax->x) pVmax->x=vTransFormed.x; if(vTransFormed.y>pV

60、max->y) pVmax->y=vTransFormed.y; if(vTransFormed.z>pVmax->z) pVmax->z=vTransFormed.z; pMesh->UnlockVertexBuffer(); } //else return S_OK; if(pFrameParent->pFrameSibling) CalculateBondingBox(pFrameParent->pFrameSibling,pVmin,pVmax); if(pFrameParent->pFrameFirstChild)

61、 CalculateBondingBox(pFrameParent->pFrameFirstChild,pVmin,pVmax); return S_OK; } virtual ~CSkinMesh(); LPDIRECT3DVERTEXSHADER9 m_pIndexedVertexShader[4]; D3DXMATRIXA16* m_pBoneMatrices; UINT m_NumBoneMatricesMax; METHOD m_SkinningMethod; D3DCAPS9 m_d3dCaps; D

62、3DXVECTOR3 m_vObjectCenter; // Center of bounding sphere of object FLOAT m_fObjectRadius; // Radius of bounding sphere of object D3DXVECTOR3 m_vMin; // Center of bounding sphere of object D3DXVECTOR3 m_vMax; // Center of bounding sphere of object protected: VOID DrawMeshC

63、ontainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase); VOID DrawFrame(LPD3DXFRAME pFrame); HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainerBase ); HRESULT SetupBoneMatrixPointers( LPD3DXFRAME pFrame ); // FLOAT m_fRotateAngle; BOOL m_

64、bMoving; LPDIRECT3DDEVICE9 m_pd3dDevice; LPD3DXFRAME m_pFrameRoot; LPD3DXANIMATIONCONTROLLER m_pAnimController; FLOAT m_fElapsedTime; // Time elapsed since last frame }; 定义SkinMesh.cpp #include "SkinMesh.h" //-----------------------------------------------------------

65、------------------ // Name: AllocateName() // Desc: Allocates memory for a string to hold the name of a frame or mesh //----------------------------------------------------------------------------- HRESULT AllocateName( LPCTSTR Name, LPTSTR *pNewName ) { UINT cbLength; if (Name !=

66、NULL) { cbLength = lstrlen(Name) + 1; *pNewName = new TCHAR[cbLength]; if (*pNewName == NULL) return E_OUTOFMEMORY; memcpy(*pNewName, Name, cbLength*sizeof(TCHAR)); } else { *pNewName = NULL; } return S_OK; } //----------------------------------------------------------------------------- // Name: CAllocateHierarchy::CreateFrame() // Desc: //----------------------------------------------------------

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

相关资源

更多
正为您匹配相似的精品文档
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!