【3D技术宅公社】XR数字艺术论坛  XR技术讨论 XR互动电影 定格动画

 找回密码
 立即注册

QQ登录

只需一步,快速开始

调查问卷
论坛即将给大家带来全新的技术服务,面向三围图形学、游戏、动画的全新服务论坛升级为UTF8版本后,中文用户名和用户密码中有中文的都无法登陆,请发邮件到324007255(at)QQ.com联系手动修改密码

3D技术论坛将以计算机图形学为核心,面向教育 推出国内的三维教育引擎该项目在持续研发当中,感谢大家的关注。

查看: 2932|回复: 2

DirectX实现骨骼动画代码!

[复制链接]
发表于 2006-12-11 23:52:35 | 显示全部楼层 |阅读模式
#ifndef MODEL_H
#define MODEL_H
#ifndef UNICODE
#define UNICODE
#endif
#include <d3dx9.h>
class CModel
{
protected:
LPD3DXFRAMEm_pFrameRoot;
LPD3DXANIMATIONCONTROLLERm_pAnimController;
D3DXVECTOR3m_vCenter;
FLOATm_fRadius;
D3DXMATRIXA16m_NormalizeMatrix;
VOID CalcNormalizeMatrix();
VOID UpdateFrameMatrices(LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix);
VOID DrawMeshContainer(LPDIRECT3DDEVICE9 pDevice,
LPD3DXMESHCONTAINER pMeshContainerBase,
LPD3DXFRAME pFrameBase);
VOID DrawFrame(LPDIRECT3DDEVICE9 pDevice, LPD3DXFRAME pFrame);
HRESULT SetupBoneMatrixPointersOnMesh(LPD3DXMESHCONTAINER pMeshContainerBase);
HRESULT SetupBoneMatrixPointers(LPD3DXFRAME pFrame);
public:
D3DXMATRIXA16& GetNormalizeTransform() { return m_NormalizeMatrix; }
FLOAT GetX() { return m_vCenter.x; }
FLOAT GetY() { return m_vCenter.y; }
FLOAT GetZ() { return m_vCenter.z; }
FLOAT GetR() { return m_fRadius; }
HRESULT Load(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pFileName);
HRESULT Free();
HRESULT Draw(LPDIRECT3DDEVICE9 pDevice, LPD3DXMATRIX pWorldMatrix = NULL);
HRESULT AdvanceTime(DOUBLE TimeDelta);
HRESULT ResetTime();
public:
CModel();
~CModel();
};
#endif


#include "Alloc.h"
#include "Model.h"
D3DXMATRIXA16g_Identity;
D3DXMATRIXA16g_BoneMatrices[256];
LPD3DXMATRIXg_pWorldMatrix;
VOID CModel::CalcNormalizeMatrix()
{
D3DXMATRIXA16 matT, matS;
D3DXMatrixTranslation(&matT, -m_vCenter.x, -m_vCenter.y, -m_vCenter.z);
D3DXMatrixScaling(&matS, 1 / m_fRadius, 1 / m_fRadius, 1 / m_fRadius);
D3DXMatrixMultiply(&m_NormalizeMatrix, &matT, &matS);
}
VOID CModel::UpdateFrameMatrices(LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix)
{
D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
if(pParentMatrix != NULL)
D3DXMatrixMultiply(&pFrame->CombinedTransformationMatrix, &pFrame->TransformationMatrix, pParentMatrix);
else
pFrame->CombinedTransformationMatrix = pFrame->TransformationMatrix;
if(pFrame->pFrameSibling != NULL)
UpdateFrameMatrices(pFrame->pFrameSibling, pParentMatrix);
if(pFrame->pFrameFirstChild != NULL)
UpdateFrameMatrices(pFrame->pFrameFirstChild, &pFrame->CombinedTransformationMatrix);
}
VOID CModel:rawMeshContainer(LPDIRECT3DDEVICE9 pDevice, LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase)
{
D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED *)pMeshContainerBase;
if(pMeshContainer->pSkinInfo != NULL)
{
UINT cBones = pMeshContainer->pSkinInfo->GetNumBones();
for(UINT iBone = 0; iBone < cBones; iBone++)
D3DXMatrixMultiply(&g_BoneMatrices[iBone], &pMeshContainer->pBoneOffsetMatrices[iBone], pMeshContainer->ppBoneMatrixPtrs[iBone]);
LPVOID pVerticesSrc;
LPVOID pVerticesDst;
pMeshContainer->MeshData.pMesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID *)&pVerticesSrc);
pMeshContainer->pTempMesh->LockVertexBuffer(0, (LPVOID *)&pVerticesDst);
pMeshContainer->pSkinInfo->UpdateSkinnedMesh(g_BoneMatrices, NULL, pVerticesSrc, pVerticesDst);
pMeshContainer->MeshData.pMesh->UnlockVertexBuffer();
pMeshContainer->pTempMesh->UnlockVertexBuffer();
if(g_pWorldMatrix != NULL)
pDevice->SetTransform(D3DTS_WORLD, g_pWorldMatrix);
else
pDevice->SetTransform(D3DTS_WORLD, &g_Identity);
for(UINT iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
{
pDevice->SetMaterial(&pMeshContainer->pMaterials[iMaterial].MatD3D);
pDevice->SetTexture(0, pMeshContainer->ppTextures[iMaterial]);
pMeshContainer->pTempMesh->DrawSubset(iMaterial);
}
}
else
{
D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
if(g_pWorldMatrix != NULL)
{
D3DXMATRIXA16 WorldMatrix;
D3DXMatrixMultiply(&WorldMatrix, &pFrame->CombinedTransformationMatrix, g_pWorldMatrix);
pDevice->SetTransform(D3DTS_WORLD, &WorldMatrix);
}
else
pDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix);
for(UINT iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
{
pDevice->SetMaterial(&pMeshContainer->pMaterials[iMaterial].MatD3D);
pDevice->SetTexture(0, pMeshContainer->ppTextures[iMaterial]);
pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial);
}
}
}
VOID CModel:rawFrame(LPDIRECT3DDEVICE9 pDevice, LPD3DXFRAME pFrame)
{
LPD3DXMESHCONTAINER pMeshContainer = pFrame->pMeshContainer;
while(pMeshContainer != NULL)
{
DrawMeshContainer(pDevice, pMeshContainer, pFrame);
pMeshContainer = pMeshContainer->pNextMeshContainer;
}
if(pFrame->pFrameSibling != NULL)
DrawFrame(pDevice, pFrame->pFrameSibling);
if(pFrame->pFrameFirstChild != NULL)
DrawFrame(pDevice, pFrame->pFrameFirstChild);
}
HRESULT CModel::SetupBoneMatrixPointersOnMesh(LPD3DXMESHCONTAINER pMeshContainerBase)
{
D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED *)pMeshContainerBase;
if(pMeshContainer->pSkinInfo != NULL)
{
UINT cBones = pMeshContainer->pSkinInfo->GetNumBones();
pMeshContainer->ppBoneMatrixPtrs = new LPD3DXMATRIXA16[cBones];
if(pMeshContainer->ppBoneMatrixPtrs == NULL)
return E_OUTOFMEMORY;
for(UINT iBone = 0; iBone < cBones; iBone++)
{
D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED *)D3DXFrameFind(m_pFrameRoot, pMeshContainer->pSkinInfo->GetBoneName(iBone));
if(pFrame == NULL)
return E_FAIL;
pMeshContainer->ppBoneMatrixPtrs[iBone] = &pFrame->CombinedTransformationMatrix;
}
}
return S_OK;
}
HRESULT CModel::SetupBoneMatrixPointers(LPD3DXFRAME pFrame)
{
HRESULT hr;
if(pFrame->pMeshContainer != NULL)
{
hr = SetupBoneMatrixPointersOnMesh(pFrame->pMeshContainer);
if(FAILED(hr))
return hr;
}
if(pFrame->pFrameSibling != NULL)
{
hr = SetupBoneMatrixPointers(pFrame->pFrameSibling);
if(FAILED(hr))
return hr;
}
if(pFrame->pFrameFirstChild != NULL)
{
hr = SetupBoneMatrixPointers(pFrame->pFrameFirstChild);
if(FAILED(hr))
return hr;
}
return S_OK;
}
HRESULT CModel:oad(LPDIRECT3DDEVICE9 pDevice, LPCTSTR pFileName)
{
HRESULT hr;
Free();
D3DXMatrixIdentity(&g_Identity);
CAllocateHierarchy AH;
hr = D3DXLoadMeshHierarchyFromX(pFileName, D3DXMESH_MANAGED, pDevice, &AH, NULL, &m_pFrameRoot, &m_pAnimController);
if(FAILED(hr))
return hr;
UpdateFrameMatrices(m_pFrameRoot, NULL);
hr = SetupBoneMatrixPointers(m_pFrameRoot);
if(FAILED(hr))
{
Free();
return hr;
}
D3DXFrameCalculateBoundingSphere(m_pFrameRoot, &m_vCenter, &m_fRadius);
CalcNormalizeMatrix();
return S_OK;
}
HRESULT CModel::Free()
{
if(m_pFrameRoot != NULL)
{
CAllocateHierarchy AH;
D3DXFrameDestroy(m_pFrameRoot, &AH);
m_pFrameRoot = NULL;
}
SAFE_RELEASE(m_pAnimController);
m_vCenter = D3DXVECTOR3(0, 0, 0);
m_fRadius = 0;
return S_OK;
}
HRESULT CModel:raw(LPDIRECT3DDEVICE9 pDevice, LPD3DXMATRIX pWorldMatrix)
{
if(m_pFrameRoot == NULL)
return E_FAIL;
g_pWorldMatrix = pWorldMatrix;
DrawFrame(pDevice, m_pFrameRoot);
return S_OK;
}
HRESULT CModel::AdvanceTime(DOUBLE TimeDelta)
{
if(m_pAnimController == NULL)
return E_FAIL;
HRESULT hr = m_pAnimController->AdvanceTime(TimeDelta, NULL);
if(FAILED(hr))
return hr;
UpdateFrameMatrices(m_pFrameRoot, NULL);
return S_OK;
}
HRESULT CModel::ResetTime()
{
if(m_pAnimController == NULL)
return E_FAIL;
return m_pAnimController->ResetTime();
}
CModel::CModel()
{
m_pFrameRoot = NULL;
m_pAnimController = NULL;
m_vCenter = D3DXVECTOR3(0, 0, 0);
m_fRadius = 0;
D3DXMatrixIdentity(&m_NormalizeMatrix);
}
CModel::~CModel()
{
Free();
}


#ifndef ALLOC_H
#define ALLOC_H
#ifndef UNICODE
#define UNICODE
#endif
#include <d3dx9.h>
#ifndef SAFE_DELETE
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#endif
#ifndef SAFE_DELETE_ARRAY
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#endif
#ifndef SAFE_RELEASE
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
#endif
struct D3DXFRAME_DERIVED: public D3DXFRAME
{
D3DXMATRIXA16CombinedTransformationMatrix;
};
struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER
{
LPD3DXMESHpTempMesh;
LPDIRECT3DTEXTURE9*ppTextures;
LPD3DXMATRIXA16pBoneOffsetMatrices;
LPD3DXMATRIXA16*ppBoneMatrixPtrs;
};
class CAllocateHierarchy: public ID3DXAllocateHierarchy
{
public:
STDMETHOD(CreateFrame)(LPCSTR Name, LPD3DXFRAME *ppNewFrame);
STDMETHOD(CreateMeshContainer)(LPCSTR Name,
const D3DXMESHDATA *pMeshData,
const D3DXMATERIAL *pMaterials,
const D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials,
const DWORD *pAdjacency,
LPD3DXSKININFO pSkinInfo,
LPD3DXMESHCONTAINER *ppNewMeshContainer);
STDMETHOD(DestroyFrame)(LPD3DXFRAME pFrameToFree);
STDMETHOD(DestroyMeshContainer)(LPD3DXMESHCONTAINER pMeshContainerToFree);
};
#endif
发表于 2007-1-23 02:47:38 | 显示全部楼层

鼯鼠兄恕我冒昧,你写代码不喜欢注释的吗。。。

另外能给出CAllocateHierarchy接口的实现方式吗?

我想研究一下。 谢谢了

 楼主| 发表于 2007-1-23 12:06:26 | 显示全部楼层

这个是把注释代码全部删除发上来的,我会在以后的代码中保留注释`~!谢谢你的建议

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|3D数字艺术论坛 ( 沪ICP备14023054号 )

GMT+8, 2025-2-6 04:11

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表