📄 game_skinmesh.cpp
字号:
}
if (m_d3dCaps.MaxVertexBlendMatrices >= NumBlend + 1){
for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i){
iMatrixIndex = pBoneComb[iAttrib].BoneId[i];
if (iMatrixIndex != UINT_MAX){
D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
g_sGlobal.g_pDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp );
}
}
g_sGlobal.g_pDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend);
if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32)){
g_sGlobal.g_pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
g_sGlobal.g_pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
AttribIdPrev = pBoneComb[iAttrib].AttribId;
}
pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib);
}
}
if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups){
AttribIdPrev = UNUSED32;
g_sGlobal.g_pDevice->SetSoftwareVertexProcessing(TRUE);
for (iAttrib = pMeshContainer->iAttributeSW; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++){
NumBlend = 0;
for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i){
if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX){
NumBlend = i;
}
}
if (m_d3dCaps.MaxVertexBlendMatrices < NumBlend + 1){
for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i){
iMatrixIndex = pBoneComb[iAttrib].BoneId[i];
if (iMatrixIndex != UINT_MAX){
D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[iMatrixIndex], pMeshContainer->ppBoneMatrixPtrs[iMatrixIndex] );
g_sGlobal.g_pDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp );
}
}
g_sGlobal.g_pDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend);
if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32)){
g_sGlobal.g_pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
g_sGlobal.g_pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
AttribIdPrev = pBoneComb[iAttrib].AttribId;
}
pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib);
}
}
g_sGlobal.g_pDevice->SetSoftwareVertexProcessing(FALSE);
}
g_sGlobal.g_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
}
else if (m_SkinningMethod == D3DINDEXED){
if (pMeshContainer->UseSoftwareVP){
g_sGlobal.g_pDevice->SetSoftwareVertexProcessing(TRUE);
}
if (pMeshContainer->NumInfl == 1)
g_sGlobal.g_pDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS);
else
g_sGlobal.g_pDevice->SetRenderState(D3DRS_VERTEXBLEND, pMeshContainer->NumInfl - 1);
if (pMeshContainer->NumInfl)
g_sGlobal.g_pDevice->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] );
g_sGlobal.g_pDevice->SetTransform( D3DTS_WORLDMATRIX( iPaletteEntry ), &matTemp );
}
}
g_sGlobal.g_pDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
g_sGlobal.g_pDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib );
}
g_sGlobal.g_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
g_sGlobal.g_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
if (pMeshContainer->UseSoftwareVP){
g_sGlobal.g_pDevice->SetSoftwareVertexProcessing(FALSE);
}
}
else if (m_SkinningMethod == SOFTWARE){
D3DXMATRIX Identity;
DWORD cBones = pMeshContainer->pSkinInfo->GetNumBones();
DWORD iBone;
PBYTE pbVerticesSrc;
PBYTE pbVerticesDest;
for (iBone = 0; iBone < cBones; ++iBone){
D3DXMatrixMultiply
(
&m_pBoneMatrices[iBone], // output
&pMeshContainer->pBoneOffsetMatrices[iBone],
pMeshContainer->ppBoneMatrixPtrs[iBone]
);
}
D3DXMatrixIdentity(&Identity);
g_sGlobal.g_pDevice->SetTransform(D3DTS_WORLD, &Identity);
pMeshContainer->pOrigMesh->LockVertexBuffer(D3DLOCK_READONLY, (LPVOID*)&pbVerticesSrc);
pMeshContainer->MeshData.pMesh->LockVertexBuffer(0, (LPVOID*)&pbVerticesDest);
// generate skinned mesh
pMeshContainer->pSkinInfo->UpdateSkinnedMesh(m_pBoneMatrices, NULL, pbVerticesSrc, pbVerticesDest);
pMeshContainer->pOrigMesh->UnlockVertexBuffer();
pMeshContainer->MeshData.pMesh->UnlockVertexBuffer();
for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++){
g_sGlobal.g_pDevice->SetMaterial(&(pMeshContainer->pMaterials[pMeshContainer->pAttributeTable[iAttrib].AttribId].MatD3D));
g_sGlobal.g_pDevice->SetTexture(0, pMeshContainer->ppTextures[pMeshContainer->pAttributeTable[iAttrib].AttribId]);
pMeshContainer->MeshData.pMesh->DrawSubset(pMeshContainer->pAttributeTable[iAttrib].AttribId);
}
}
else{
return;
}
}
else{
g_sGlobal.g_pDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix);
for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++){
g_sGlobal.g_pDevice->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D );
g_sGlobal.g_pDevice->SetTexture( 0, pMeshContainer->ppTextures[iMaterial] );
pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial);
}
}
}
VOID Game_SkinMesh::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 Game_SkinMesh::SetAnim(BOOL bAnim){
m_bMoving=bAnim;
if(!m_bMoving && m_pAnimController)
{
#if (D3D_SDK_VERSION & 32)
m_pAnimController->ResetTime();//
#else m_pAnimController->SetTime(0);
#endif
}
}
BOOL Game_SkinMesh::SetAnimationName(char *strAnimName){
if(!m_bMoving || !m_pAnimController ) return FALSE;
DWORD nAnimSet;
char strTempName[256];
nAnimSet=m_pAnimController->GetNumAnimationSets();
LPD3DXANIMATIONSET pAnimSet;
for(DWORD i=0;i<nAnimSet;i++){
m_pAnimController->GetAnimationSet(i,&pAnimSet);
strcpy(strTempName, pAnimSet->GetName());
if(strcmp(strAnimName,strTempName)==0) {
m_pAnimController->SetTrackAnimationSet(0,pAnimSet);
return TRUE;
}
}
return FALSE;
};
//使用索引和顶点缓冲区,求Mesh和射线交点
BOOL Game_SkinMesh::InterSect( D3DVECTOR *pRayOrig,
D3DVECTOR *pRayDir,D3DVECTOR* pVRet){
return S_OK;
}
VOID Game_SkinMesh::GetPosition(D3DXVECTOR3 *vPos){
*vPos=m_vPos;
}
const LPD3DXVECTOR3 Game_SkinMesh::GetPosition(){
return &m_vPos;
}
//前后移动
VOID Game_SkinMesh::MoveFront(D3DXVECTOR3 *vDir){
vDir->x=sinf(m_fAngle);
vDir->y=0;
vDir->z=cosf(m_fAngle);
}
VOID Game_SkinMesh::WalkFoward(float fDistance,Game_Terrain *Terrain){
if(fDistance==0)
return;
m_vPosOld=m_vPos;
D3DXVECTOR3 vDir;
MoveFront(&vDir);
m_vPos+=fDistance*vDir;
m_vPos.y=Terrain->GetHeight(m_vPos.x,m_vPos.z);
}
//左右移动
VOID Game_SkinMesh::GetDirection2(D3DXVECTOR3 *vDir){
vDir->x=cosf(m_fAngle);
vDir->y=0;
vDir->z=-sinf(m_fAngle);
}
// 目 的:设置是否循环播放
VOID Game_SkinMesh::SetLoop( BOOL bLoop ){ m_bLoop = bLoop; }
// 目 的:判断当前动画是否播完
BOOL Game_SkinMesh::IsAnimEnd( float& passTime ){
float couTime = (float)m_pCurAnimSet->GetPeriod();
// 如果播放的时间超过了动画时间即播放完毕,返回ture
/*if( m_bLoop )
{
m_CurTime = 0.0;
return false;
}
else*/
{
// 超出播放时间
if( m_CurTime + passTime >= couTime )
{
passTime = couTime - m_CurTime;
//m_CurTime = 0.0;
return true;
}
else
{
m_CurTime += passTime;
return false;
}
}
}
VOID Game_SkinMesh::GetBoundingBox(D3DXVECTOR3 *vMin,D3DXVECTOR3 *vMax){
*vMin=m_vPos+m_vMin*m_fScale;
*vMax=m_vPos+m_vMax*m_fScale;
}
VOID Game_SkinMesh::Turn(float fAngle){
m_fAngle+=fAngle;
}
VOID Game_SkinMesh::Back(){
m_vPos=m_vPosOld;
}
VOID Game_SkinMesh::SetAltitude(float y){
m_vPos.y=y;
}
////求2点之间的距离
FLOAT Game_SkinMesh::DistanceOfTwoVec3(const D3DXVECTOR3 v1, const D3DXVECTOR3 v2){
float x,z,dist;
x = v1.x - v2.x;
z = v1.z - v2.z;
dist = sqrt(x*x + z*z);
return dist;
}
//求2点间线段与坐标系夹角
FLOAT Game_SkinMesh::GetYaw(const D3DXVECTOR3 v1, const D3DXVECTOR3 v2){
float x,m_alpha,z, dist;
x = v1.x - v2.x;
z = v1.z - v2.z;
dist = DistanceOfTwoVec3(v1, v2);
if(dist == 0)
return 0;
else
m_alpha = asin(z/dist);
if(x > 0)
return 3*D3DX_PI/2-m_alpha;
return -(3*D3DX_PI/2-m_alpha);
}
VOID Game_SkinMesh::RenderAABB(D3DXVECTOR3 *pVmin,D3DXVECTOR3 *pVmax){
/*
0------MAX
/ /|
/ / |
3-----2 5
| | /
| |/
min------6
*/
struct VERTEX_BOUNDINGBOX{
float x,y,z;
DWORD color;
};
VERTEX_BOUNDINGBOX VB[]={
{pVmin->x,pVmax->y,pVmax->z,0xffff0000}, //上表面
{pVmax->x,pVmax->y,pVmax->z,0xffff0000},
{pVmax->x,pVmax->y,pVmin->z,0xffff0000},
{pVmin->x,pVmax->y,pVmin->z,0xffff0000},
{pVmin->x,pVmin->y,pVmax->z,0xffff0000}, //下边四条线
{pVmax->x,pVmin->y,pVmax->z,0xffff0000},
{pVmax->x,pVmin->y,pVmin->z,0xffff0000},
{pVmin->x,pVmin->y,pVmin->z,0xffff0000},
};
WORD IB[]={
0,1,1,2,2,3,3,0,
4,5,5,6,6,7,7,4,
0,4,1,5,2,6,3,7
};
//单位矩阵
D3DXMATRIX matIdentity;
D3DXMatrixIdentity(&matIdentity);
g_sGlobal.g_pDevice->SetTransform(D3DTS_WORLD, &matIdentity);
g_sGlobal.g_pDevice->SetTexture(0,NULL);
g_sGlobal.g_pDevice->SetFVF(D3DFVF_CUSTOM_BOUNDINGBOX);
g_sGlobal.g_pDevice->DrawIndexedPrimitiveUP(D3DPT_LINELIST,0,24,12,IB,D3DFMT_INDEX16,
VB,sizeof(VERTEX_BOUNDINGBOX));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -