骨骼动画
来源:互联网 发布:量化交易编程r语言 编辑:程序博客网 时间:2024/04/30 05:22
class CSkinMesh_Test;
struct D3DXFRAME_DERIVED: public D3DXFRAME
{
D3DXMATRIXA16 CombinedTransformationMatrix;
};
struct D3DXMESHCONTAINER_DERIVED: public D3DXMESHCONTAINER
{
LPDIRECT3DTEXTURE9* ppTextures; // array of textures, entries are NULL if no texture specified
// SkinMesh info
LPD3DXMESH pOrigMesh;
LPD3DXATTRIBUTERANGE pAttributeTable;
DWORD NumAttributeGroups;
DWORD NumInfl;
LPD3DXBUFFER pBoneCombinationBuf;
D3DXMATRIX** ppBoneMatrixPtrs;
D3DXMATRIX* pBoneOffsetMatrices;
DWORD NumPaletteEntries;
bool UseSoftwareVP;
DWORD iAttributeSW; // used to denote the split between SW and HW if necessary for non-indexed skinning
};
class CAllocateHierarchy: public ID3DXAllocateHierarchy
{
public:
STDMETHOD(CreateFrame)(THIS_ LPCTSTR Name, LPD3DXFRAME *ppNewFrame);//创建骨骼对象
STDMETHOD(CreateMeshContainer)(THIS_ LPCSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer);//创建Mesh数据对象
STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree);
STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerBase);
CAllocateHierarchy(CSkinMesh_Test *pSkinMesh) :m_pSkinMesh(pSkinMesh) {}
public:
CSkinMesh_Test* m_pSkinMesh;
};
class CSkinMesh_Test
{
public:
CSkinMesh_Test(void);
virtual ~CSkinMesh_Test(void);
public:
HRESULT D3DCreate( LPDIRECT3DDEVICE9 pd3dDevice );
void Render( LPDIRECT3DDEVICE9 pd3dDevice );
void SetMatrix( LPDIRECT3DDEVICE9 pd3dDevice );
public:
HRESULT GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer);
HRESULT SetupBoneMatrixPointers(LPD3DXFRAME pFrame);
HRESULT SetupBoneMatrixPointersOnMesh( LPD3DXMESHCONTAINER pMeshContainerBase );
VOID UpdateFrameMatrices(LPD3DXFRAME pFrameBase, LPD3DXMATRIX pParentMatrix);
VOID DrawFrame(LPD3DXFRAME pFrame);
VOID DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase);
private:
D3DCAPS9 m_d3dCaps;
D3DXVECTOR3 m_vObjectCenter;
FLOAT m_fObjectRadius;
LPDIRECT3DDEVICE9 m_pd3dDevice;
UINT m_NumBoneMatricesMax;
D3DXMATRIXA16* m_pBoneMatrices;
FLOAT m_fElapsedTime;
BOOL m_bMoving;
LPD3DXFRAME m_pFrameRoot;
LPD3DXANIMATIONCONTROLLER m_pAnimController;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
HRESULT AllocateName( LPCTSTR Name, LPTSTR *pNewName )
{
UINT cbLength;
if (Name != 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;
}
HRESULT CAllocateHierarchy::CreateFrame(LPCTSTR Name, LPD3DXFRAME *ppNewFrame )
{
D3DXFRAME_DERIVED *pFrame;
*ppNewFrame = NULL;
pFrame = new D3DXFRAME_DERIVED;
if (pFrame == NULL)
return E_OUTOFMEMORY;
if( FAILED ( AllocateName( Name, &pFrame->Name ) ) )
{
SAFE_DELETE(pFrame);
return S_OK;
}
D3DXMatrixIdentity(&pFrame->TransformationMatrix);
D3DXMatrixIdentity(&pFrame->CombinedTransformationMatrix);
pFrame->pMeshContainer = NULL;
pFrame->pFrameSibling = NULL;
pFrame->pFrameFirstChild = NULL;
*ppNewFrame = pFrame;
pFrame = NULL;
SAFE_DELETE(pFrame);
return S_OK;
}
LRESULT CAllocateHierarchy::CreateMeshContainer( LPCTSTR Name, CONST D3DXMESHDATA *pMeshData, CONST D3DXMATERIAL *pMaterials, CONST D3DXEFFECTINSTANCE *pEffectInstances,
DWORD NumMaterials, CONST DWORD *pAdjacency, LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer)
{
D3DXMESHCONTAINER_DERIVED *pMeshContainer = NULL;
UINT NumFaces;
UINT iMaterial;
UINT iBone, cBones;
LPDIRECT3DDEVICE9 pd3dDevice = NULL;
LPD3DXMESH pMesh = NULL;
*ppNewMeshContainer = NULL;
if (pMeshData->Type != D3DXMESHTYPE_MESH)//Mesh数据类型,是否正确
{
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_FAIL;
}
pMesh = pMeshData->pMesh;
if (pMesh->GetFVF() == 0)//mesh的顶点格式,是否为空
{
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_FAIL;
}
pMeshContainer = new D3DXMESHCONTAINER_DERIVED;
if (pMeshContainer == NULL)
{
SAFE_RELEASE(pd3dDevice);
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_OUTOFMEMORY;
}
memset(pMeshContainer, 0, sizeof(D3DXMESHCONTAINER_DERIVED));
if( FAILED( AllocateName(Name, &pMeshContainer->Name) ) )//拷贝名字
{
SAFE_RELEASE(pd3dDevice);
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_FAIL;
}
pMesh->GetDevice(&pd3dDevice);//获取设备指针
NumFaces = pMesh->GetNumFaces();//获取模型面数
if (!(pMesh->GetFVF() & D3DFVF_NORMAL))
{
pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
if( FAILED( pMesh->CloneMeshFVF( pMesh->GetOptions(), pMesh->GetFVF() | D3DFVF_NORMAL, pd3dDevice, &pMeshContainer->MeshData.pMesh ) ) )
{
SAFE_RELEASE(pd3dDevice);
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_FAIL;
}
pMesh = pMeshContainer->MeshData.pMesh;
D3DXComputeNormals( pMesh, NULL );
}
else
{
pMeshContainer->MeshData.pMesh = pMesh;
pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
pMesh->AddRef();
}
pMeshContainer->NumMaterials = max(1, NumMaterials);
pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials];
pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials];
pMeshContainer->pAdjacency = new DWORD[NumFaces*3];
if ((pMeshContainer->pAdjacency == NULL) || (pMeshContainer->pMaterials == NULL))
{
SAFE_RELEASE(pd3dDevice);
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_OUTOFMEMORY;
}
memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * NumFaces*3);
memset(pMeshContainer->ppTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials);
if (NumMaterials > 0)
{
memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * NumMaterials);
for (iMaterial = 0; iMaterial < NumMaterials; iMaterial++)
{
if (pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL)
{
std::string strTextureFilename = "Dwarf\\";
strTextureFilename += pMeshContainer->pMaterials[iMaterial].pTextureFilename;
if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, strTextureFilename.c_str(), &pMeshContainer->ppTextures[iMaterial] ) ) )
pMeshContainer->ppTextures[iMaterial] = NULL;
pMeshContainer->pMaterials[iMaterial].pTextureFilename = NULL;
}
}
}
else
{
pMeshContainer->pMaterials[0].pTextureFilename = NULL;
memset(&pMeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9));
pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f;
pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f;
pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f;
pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;
}
if (pSkinInfo != NULL)
{
pMeshContainer->pSkinInfo = pSkinInfo;
pSkinInfo->AddRef();
pMeshContainer->pOrigMesh = pMesh;
pMesh->AddRef();
cBones = pSkinInfo->GetNumBones();
pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones];
if (pMeshContainer->pBoneOffsetMatrices == NULL)
{
SAFE_RELEASE(pd3dDevice);
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_OUTOFMEMORY;
}
for (iBone = 0; iBone < cBones; iBone++)
{
pMeshContainer->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone));
}
if( FAILED( m_pSkinMesh->GenerateSkinnedMesh(pMeshContainer) ) )
{
SAFE_RELEASE(pd3dDevice);
if ( pMeshContainer != NULL )
DestroyMeshContainer(pMeshContainer);
return E_FAIL;
}
}
*ppNewMeshContainer = pMeshContainer;
pMeshContainer = NULL;
return S_OK;
}
HRESULT CAllocateHierarchy::DestroyFrame(LPD3DXFRAME pFrameToFree)
{
SAFE_DELETE_ARRAY( pFrameToFree->Name );
SAFE_DELETE( pFrameToFree );
return S_OK;
}
HRESULT CAllocateHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase)
{
UINT iMaterial;
D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
SAFE_DELETE_ARRAY( pMeshContainer->Name );
SAFE_DELETE_ARRAY( pMeshContainer->pAdjacency );
SAFE_DELETE_ARRAY( pMeshContainer->pMaterials );
SAFE_DELETE_ARRAY( pMeshContainer->pBoneOffsetMatrices );
// release all the allocated textures
if (pMeshContainer->ppTextures != NULL)
{
for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
{
SAFE_RELEASE( pMeshContainer->ppTextures[iMaterial] );
}
}
SAFE_DELETE_ARRAY( pMeshContainer->ppTextures );
SAFE_DELETE_ARRAY( pMeshContainer->ppBoneMatrixPtrs );
SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );
SAFE_RELEASE( pMeshContainer->MeshData.pMesh );
SAFE_RELEASE( pMeshContainer->pSkinInfo );
SAFE_RELEASE( pMeshContainer->pOrigMesh );
SAFE_DELETE( pMeshContainer );
return S_OK;
}
CSkinMesh_Test::CSkinMesh_Test(void)
{
m_fElapsedTime = 0.0f;
m_bMoving=TRUE;
m_pAnimController = NULL;
m_pFrameRoot = NULL;
m_pBoneMatrices = NULL;
m_NumBoneMatricesMax = 0;
}
CSkinMesh_Test::~CSkinMesh_Test(void)
{
CAllocateHierarchy Alloc(this);
D3DXFrameDestroy(m_pFrameRoot, &Alloc);
SAFE_RELEASE(m_pAnimController);
}
HRESULT CSkinMesh_Test::D3DCreate( LPDIRECT3DDEVICE9 pd3dDevice )
{
m_pd3dDevice = pd3dDevice;
m_pd3dDevice->GetDeviceCaps( &m_d3dCaps );
CAllocateHierarchy Alloc(this);
if( FAILED( D3DXLoadMeshHierarchyFromX( "Dwarf\\zhashi.X", D3DXMESH_MANAGED, m_pd3dDevice, &Alloc, NULL, &m_pFrameRoot, &m_pAnimController) ) )//从X文件加载骨骼动画信息
return E_FAIL;
if( FAILED( SetupBoneMatrixPointers(m_pFrameRoot) ) )
return E_FAIL;
//计算层次框架的包围球
//返回的是中心点 m_vObjectCenter
//和半径
if( FAILED( D3DXFrameCalculateBoundingSphere(m_pFrameRoot, &m_vObjectCenter, &m_fObjectRadius) ) )
return E_FAIL;
SetMatrix(pd3dDevice);
return S_OK;
}
HRESULT CSkinMesh_Test::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 CSkinMesh_Test::SetupBoneMatrixPointersOnMesh(LPD3DXMESHCONTAINER pMeshContainerBase)
{
UINT iBone, cBones;
D3DXFRAME_DERIVED *pFrame;
D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
// if there is a skinmesh, then setup the bone matrices
//蒙皮动画,则设置骨骼的变换矩阵
if (pMeshContainer->pSkinInfo != NULL)
{
cBones = pMeshContainer->pSkinInfo->GetNumBones();
pMeshContainer->ppBoneMatrixPtrs = new D3DXMATRIX*[cBones]; //创建骨骼
if (pMeshContainer->ppBoneMatrixPtrs == NULL)
return E_OUTOFMEMORY;
for (iBone = 0; iBone < cBones; iBone++)
{
//找到根框架的子框架
pFrame = (D3DXFRAME_DERIVED*)D3DXFrameFind(m_pFrameRoot,
pMeshContainer->pSkinInfo->GetBoneName(iBone));
if (pFrame == NULL)
return E_FAIL;
//初始化矩阵
pMeshContainer->ppBoneMatrixPtrs[iBone] = &pFrame->CombinedTransformationMatrix;
}
}
return S_OK;
}
void CSkinMesh_Test::Render( LPDIRECT3DDEVICE9 pd3dDevice )
{
m_pd3dDevice->SetRenderState(D3DRS_LIGHTING, true);
m_pd3dDevice->SetRenderState( D3DRS_AMBIENT, D3DCOLOR_XRGB( 255,255,255 ) );//设置环境光颜色值
if(m_pAnimController)
{
if (m_bMoving)
m_pAnimController->AdvanceTime(0.02f,NULL);
else
m_pAnimController->ResetTime();
}
D3DXMATRIXA16 matWorld;
D3DXMatrixTranslation( &matWorld, 0.0f, 0.0f, 0.0f );
UpdateFrameMatrices(m_pFrameRoot, &matWorld);
DrawFrame(m_pFrameRoot);
}
VOID CSkinMesh_Test::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 CSkinMesh_Test::DrawFrame(LPD3DXFRAME pFrame)
{
LPD3DXMESHCONTAINER pMeshContainer;
pMeshContainer = pFrame->pMeshContainer;
while (pMeshContainer != NULL)
{
DrawMeshContainer(pMeshContainer, pFrame);
pMeshContainer = pMeshContainer->pNextMeshContainer;
}
if (pFrame->pFrameSibling != NULL)
{
DrawFrame(pFrame->pFrameSibling);
}
if (pFrame->pFrameFirstChild != NULL)
{
DrawFrame(pFrame->pFrameFirstChild);
}
}
VOID CSkinMesh_Test::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase)
{
D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
UINT iAttrib;
LPD3DXBONECOMBINATION pBoneComb;
UINT iMatrixIndex;
UINT iPaletteEntry;
D3DXMATRIXA16 matTemp;
if (pMeshContainer->pSkinInfo != NULL)
{
if (pMeshContainer->UseSoftwareVP)
{
m_pd3dDevice->SetSoftwareVertexProcessing(TRUE);
}
if (pMeshContainer->NumInfl == 1)
m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS);
else
m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, pMeshContainer->NumInfl - 1);
if (pMeshContainer->NumInfl)
m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());
for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
{
for (iPaletteEntry = 0; iPaletteEntry < pMeshContainer->NumPaletteEntries; ++iPaletteEntry)
{
iMatrixIndex = pBoneComb[iAttrib].BoneId[iPaletteEntry];
if (iMatrixIndex != UINT_MAX)
{
D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( iPaletteEntry ), &matTemp );
}
}
pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Ambient.a = 1.0f;
pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Ambient.b = 1.0f;
pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Ambient.g = 1.0f;
pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D.Ambient.r = 1.0f;
m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib );
}
m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
if (pMeshContainer->UseSoftwareVP)
{
m_pd3dDevice->SetSoftwareVertexProcessing(FALSE);
}
}
}
void CSkinMesh_Test::SetMatrix( LPDIRECT3DDEVICE9 pd3dDevice )
{
D3DXMATRIX matView, matProj;
D3DXMatrixLookAtLH(&matView,&D3DXVECTOR3(0,30,80),&D3DXVECTOR3(0,30,0), &D3DXVECTOR3(0,1,0)); //视图变换矩阵,摄像机位置,焦点位置,向上方向
D3DXMatrixPerspectiveFovLH(&matProj,D3DX_PI/4,1.0f,1.0f,1000.0f); //PI/4的视角,4/3的长宽比,近平面1.0,远屏幕1000;
pd3dDevice->SetTransform(D3DTS_VIEW,&matView);
pd3dDevice->SetTransform(D3DTS_PROJECTION,&matProj);
}
HRESULT CSkinMesh_Test::GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer)
{
HRESULT hr = S_OK;
if (pMeshContainer->pSkinInfo == NULL)
return hr;
SAFE_RELEASE( pMeshContainer->MeshData.pMesh );
SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );
DWORD NumMaxFaceInfl;
DWORD Flags = D3DXMESHOPT_VERTEXCACHE;
LPDIRECT3DINDEXBUFFER9 pIB;
hr = pMeshContainer->pOrigMesh->GetIndexBuffer(&pIB);
if (FAILED(hr))
return hr;
hr = pMeshContainer->pSkinInfo->GetMaxFaceInfluences(pIB, pMeshContainer->pOrigMesh->GetNumFaces(), &NumMaxFaceInfl);
pIB->Release();
if (FAILED(hr))
return hr;
NumMaxFaceInfl = min(NumMaxFaceInfl, 12);
if (m_d3dCaps.MaxVertexBlendMatrixIndex + 1 < NumMaxFaceInfl)
{
pMeshContainer->NumPaletteEntries = min(256, pMeshContainer->pSkinInfo->GetNumBones());
pMeshContainer->UseSoftwareVP = true;
Flags |= D3DXMESH_SYSTEMMEM;
}
else
{
pMeshContainer->NumPaletteEntries = min( ( m_d3dCaps.MaxVertexBlendMatrixIndex + 1 ) / 2,
pMeshContainer->pSkinInfo->GetNumBones() );
pMeshContainer->UseSoftwareVP = false;
Flags |= D3DXMESH_MANAGED;
}
hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh
(
pMeshContainer->pOrigMesh,
Flags,
pMeshContainer->NumPaletteEntries,
pMeshContainer->pAdjacency,
NULL, NULL, NULL,
&pMeshContainer->NumInfl,
&pMeshContainer->NumAttributeGroups,
&pMeshContainer->pBoneCombinationBuf,
&pMeshContainer->MeshData.pMesh);
return hr;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _D3DXFRAME//框架信息(对应于骨骼)
{
LPSTR Name;
D3DXMATRIX TransformationMatrix; //本骨骼的转换矩阵
LPD3DXMESHCONTAINER pMeshContainer; //本骨骼所对应Mesh数据
struct _D3DXFRAME *pFrameSibling; //兄弟骨骼
struct _D3DXFRAME *pFrameFirstChild; //子骨骼
} D3DXFRAME, *LPD3DXFRAME;
typedef struct _D3DXMESHCONTAINER
{
LPSTR Name; //容器名
D3DXMESHDATA MeshData; //Mesh数据,可创建SkinMesh取代这个Mesh
LPD3DXMATERIAL pMaterials; //材质数组
LPD3DXEFFECTINSTANCE pEffects;
DWORD NumMaterials;//材质数
DWORD* pAdjacency; //邻接三角形数组
LPD3DXSKININFO pSkinInfo; //蒙皮信息,其中含.x中的各个skinweight蒙皮顶点索引及各骨骼偏移矩阵等。
struct _D3DXMESHCONTAINER *pNextMeshContainer;
} D3DXMESHCONTAINER, *LPD3DXMESHCONTAINER;
HRESULT WINAPI D3DXLoadMeshHierarchyFromX
(
LPCSTR Filename, //.x文件名
DWORD MeshOptions, //Mesh选项,一般选D3DXMESH_MANAGED
LPDIRECT3DDEVICE9 pD3DDevice, //指向D3D设备Device
LPD3DXALLOCATEHIERARCHY pAlloc, //自定义数据容器
LPD3DXLOADUSERDATA pUserDataLoader, //一般选NULL
LPD3DXFRAME *ppFrameHierarchy, //返回根Frame指针,指向代表整个骨架的Frame层次结构
LPD3DXANIMATIONCONTROLLER *ppAnimController //返回相应的动画控制器
);
HRESULT WINAPI D3DXFrameCalculateBoundingSphere//求有骨骼模型的包围球
(
CONST D3DXFRAME *pFrameRoot,
LPD3DXVECTOR3 pObjectCenter,
FLOAT *pObjectRadius
);
LPD3DXFRAME WINAPI D3DXFrameFind//找到根框架的子框架
(
CONST D3DXFRAME *pFrameRoot,
LPCSTR Name
);
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 骨骼动画
- 简单的骨骼动画、骨骼动画理论
- 骨骼动画(Skeletal Animation)
- Ogre的骨骼动画
- 骨骼动画解释(转)
- 骨骼蒙皮动画DEMO
- 使用骨骼动画
- 骨骼动画(Skeletal Animation)
- centos 讲tomcat加入自启动
- Ajax学习
- Android开发之旅:android架构
- 关于hudson server运行testcase时浏览器进程后台运行
- 测试用例的重要性及设计方法
- 骨骼动画
- Gowalla:淡化签到,转型旅游指南以及讲故事功能
- ubuntu解决安装deb提示软件包质量欠佳问题
- java.lang.OutOfMemoryError: Java heap space 解决方法
- PDF首页转为图片,获取PDF页数
- Android学习笔记(十六)——DataPickerDialog
- ASP.NET回调/回送
- ssh远程文件传输命令scp
- 一点小牢骚 windows python 2.6 cherrypy 安装的小问题