|
#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
|
|