home *** CD-ROM | disk | FTP | other *** search
- //-----------------------------------------------------------------------------
- // File: mdraw.cpp
- //
- // Copyright (c) 1999-2000 Microsoft Corporation. All rights reserved.
- //-----------------------------------------------------------------------------
-
- #include <d3d8.h>
- #include <d3dx8.h>
- #include "D3DApp.h"
- #include "D3DFont.h"
- #include "D3DUtil.h"
- #include "DXUtil.h"
- #include "SkinnedMesh.h"
-
-
- HRESULT CMyD3DApplication::DrawMeshContainer(SMeshContainer *pmcMesh)
- {
- UINT ipattr;
- HRESULT hr = S_OK;
- LPD3DXBONECOMBINATION pBoneComb;
- LPDIRECT3DDEVICE8 m_pDevice = m_pd3dDevice;
-
- if (pmcMesh->m_pSkinMesh)
- {
- D3DCAPS8 caps;
-
- m_pDevice->GetDeviceCaps(&caps);
-
- if (m_method != pmcMesh->m_Method)
- {
- GenerateMesh(pmcMesh);
- }
-
- if (m_method == D3DNONINDEXED)
- {
- if (caps.MaxVertexBlendMatrices >= pmcMesh->m_maxFaceInfl || (pmcMesh->pMeshSW == NULL && pmcMesh->pMeshHW == NULL))
- {
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, pmcMesh->m_maxFaceInfl - 1);
- pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
- for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
- {
- for (DWORD i = 0; i < pmcMesh->m_maxFaceInfl; ++i)
- {
- DWORD matid = pBoneComb[ipattr].BoneId[i];
- if (matid != UINT_MAX && (ipattr == 0 || matid != pBoneComb[ipattr - 1].BoneId[i]))
- {
- m_pDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
- m_pDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
- }
- }
-
- if (ipattr == 0 || (pBoneComb[ipattr].AttribId != pBoneComb[ipattr - 1].AttribId))
- {
- m_pDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
- m_pDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
- }
-
- hr = pmcMesh->pMesh->DrawSubset( ipattr );
- if(FAILED(hr))
- return hr;
- }
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
- }
- else
- {
- if (pmcMesh->pMeshHW != NULL)
- {
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 1); // Two matrix blending
- pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
- for (ipattr = 0; ipattr < pmcMesh->iAttrSplit; ipattr++)
- {
- for (DWORD i = 0; i < 2; ++i)
- {
- DWORD matid = pBoneComb[ipattr].BoneId[i];
- if (matid != UINT_MAX && (ipattr == 0 || matid != pBoneComb[ipattr - 1].BoneId[i]))
- {
- m_pDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
- m_pDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
- }
- }
-
- if (ipattr == 0 || (pBoneComb[ipattr].AttribId != pBoneComb[ipattr - 1].AttribId))
- {
- m_pDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
- m_pDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
- }
-
- hr = pmcMesh->pMeshHW->DrawSubset( ipattr );
- if(FAILED(hr))
- return hr;
- }
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
- }
-
- if (pmcMesh->pMeshSW != NULL)
- {
- m_pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, pmcMesh->m_maxFaceInfl - 1);
- pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
- for (ipattr = pmcMesh->iAttrSplit; ipattr < pmcMesh->cpattr; ipattr++)
- {
- for (DWORD i = 0; i < pmcMesh->m_maxFaceInfl; ++i)
- {
- DWORD matid = pBoneComb[ipattr].BoneId[i];
- if (matid != UINT_MAX && (ipattr == pmcMesh->iAttrSplit || matid != pBoneComb[ipattr - 1].BoneId[i]))
- {
- m_pDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
- m_pDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
- }
- }
-
- if (ipattr == pmcMesh->iAttrSplit || (pBoneComb[ipattr].AttribId != pBoneComb[ipattr - 1].AttribId))
- {
- m_pDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
- m_pDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
- }
-
- hr = pmcMesh->pMeshSW->DrawSubset( ipattr );
- if(FAILED(hr))
- return hr;
- }
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
- m_pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
- }
- }
- }
- else if (m_method == D3DINDEXED)
- {
- if (caps.MaxVertexBlendMatrixIndex < pmcMesh->m_pSkinMesh->GetNumBones())
- {
- m_pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
- }
-
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, pmcMesh->m_maxFaceInfl - 1);
- if (pmcMesh->m_maxFaceInfl - 1)
- m_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
- pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pmcMesh->m_pBoneCombinationBuf->GetBufferPointer());
- for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
- {
- for (DWORD i = 0; i < 255/*paletteSize*/; ++i)
- {
- DWORD matid = pBoneComb[ipattr].BoneId[i];
- if (matid != UINT_MAX)
- {
- m_pDevice->SetTransform(D3DTS_WORLDMATRIX(i), pmcMesh->m_pBoneMatrix[matid]);
- m_pDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pmcMesh->m_pBoneOffsetMat[matid]);
- }
- }
-
- m_pDevice->SetMaterial(&(pmcMesh->rgMaterials[pBoneComb[ipattr].AttribId]));
- m_pDevice->SetTexture(0, pmcMesh->pTextures[pBoneComb[ipattr].AttribId]);
-
- hr = pmcMesh->pMesh->DrawSubset( ipattr );
- if(FAILED(hr))
- return hr;
- }
- m_pDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
- m_pDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
-
- if (caps.MaxVertexBlendMatrixIndex < pmcMesh->m_pSkinMesh->GetNumBones())
- {
- m_pDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
- }
- }
- else if (m_method == SOFTWARE)
- {
- D3DXMATRIX Identity;
-
- DWORD cBones = pmcMesh->m_pSkinMesh->GetNumBones();
-
- // set up bone transforms
-
- D3DXMATRIX* rgBoneMatrices = NULL;
-
- rgBoneMatrices = new D3DXMATRIX[cBones];
-
- if (rgBoneMatrices == NULL)
- {
- hr = E_OUTOFMEMORY;
-
- goto e_ExitSOFTWARE;
- }
-
- {
- for (DWORD iBone = 0; iBone < cBones; ++iBone)
- {
- D3DXMatrixMultiply
- (
- &rgBoneMatrices[iBone], // output
- &pmcMesh->m_pBoneOffsetMat[iBone],
- pmcMesh->m_pBoneMatrix[iBone]
- );
- }
- }
-
- // set world transform
- D3DXMatrixIdentity(&Identity);
-
- hr = m_pDevice->SetTransform(D3DTS_WORLD, &Identity);
-
- if (FAILED(hr))
- goto e_ExitSOFTWARE;
-
-
- // generate skinned mesh
- hr = pmcMesh->m_pSkinMesh->UpdateSkinnedMesh(rgBoneMatrices, pmcMesh->pMesh);
-
- if (FAILED(hr))
- goto e_ExitSOFTWARE;
-
-
- for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
- {
- m_pDevice->SetMaterial(&(pmcMesh->rgMaterials[ipattr]));
- m_pDevice->SetTexture(0, pmcMesh->pTextures[ipattr]);
-
- hr = pmcMesh->pMesh->DrawSubset(ipattr);
-
- if (FAILED(hr))
- goto e_ExitSOFTWARE;
- }
-
- e_ExitSOFTWARE:
-
- delete[] rgBoneMatrices;
-
- return hr;
- }
- }
- else
- {
- for (ipattr = 0; ipattr < pmcMesh->cpattr; ipattr++)
- {
- m_pDevice->SetMaterial(&(pmcMesh->rgMaterials[ipattr]));
- m_pDevice->SetTexture(0, pmcMesh->pTextures[ipattr]);
- hr = pmcMesh->pMesh->DrawSubset( ipattr );
- if(FAILED(hr))
- return hr;
- }
- }
-
- return S_OK;
-
-
- }
-
-
-
-
- HRESULT CMyD3DApplication::UpdateFrames(SFrame *pframeCur, D3DXMATRIX &matCur)
- {
- HRESULT hr = S_OK;
- pframeCur->matCombined = matCur;
- D3DXMatrixMultiply(&pframeCur->matCombined, &pframeCur->matRot, &matCur);
- D3DXMatrixMultiply(&pframeCur->matCombined, &pframeCur->matCombined, &pframeCur->matTrans );
- SFrame *pframeChild = pframeCur->pframeFirstChild;
- while (pframeChild != NULL)
- {
- hr = UpdateFrames(pframeChild, pframeCur->matCombined);
- if (FAILED(hr))
- return hr;
-
- pframeChild = pframeChild->pframeSibling;
- }
- return S_OK;
- }
-
-
-
-
- HRESULT CMyD3DApplication::DrawFrames(SFrame *pframeCur, UINT &cTriangles)
- {
- HRESULT hr = S_OK;
- SMeshContainer *pmcMesh;
- SFrame *pframeChild;
- LPDIRECT3DDEVICE8 m_pDevice = m_pd3dDevice;
-
- if (pframeCur->pmcMesh != NULL)
- {
- hr = m_pDevice->SetTransform(D3DTS_WORLD, &pframeCur->matCombined);
- if(FAILED(hr))
- return hr;
- }
-
- pmcMesh = pframeCur->pmcMesh;
- while (pmcMesh != NULL)
- {
- hr = DrawMeshContainer(pmcMesh);
- if (FAILED(hr))
- return hr;
-
- cTriangles += pmcMesh->pMesh->GetNumFaces();
-
- pmcMesh = pmcMesh->pmcNext;
- }
-
- pframeChild = pframeCur->pframeFirstChild;
- while (pframeChild != NULL)
- {
- hr = DrawFrames(pframeChild, cTriangles);
- if (FAILED(hr))
- return hr;
-
- pframeChild = pframeChild->pframeSibling;
- }
-
- return S_OK;
- }
-
-
-
-
- void SFrame::SetTime(float fGlobalTime)
- {
- UINT iKey;
- UINT dwp2;
- UINT dwp3;
- D3DXMATRIX matResult;
- D3DXMATRIX matTemp;
- float fTime1;
- float fTime2;
- float fLerpValue;
- D3DXVECTOR3 vScale;
- D3DXVECTOR3 vPos;
- D3DXQUATERNION quat;
- BOOL bAnimate = false;
- float fTime;
-
- if (m_pMatrixKeys )
- {
- fTime = (float)fmod(fGlobalTime, m_pMatrixKeys[m_cMatrixKeys-1].dwTime);
-
- for (iKey = 0 ;iKey < m_cMatrixKeys ; iKey++)
- {
- if ((float)m_pMatrixKeys[iKey].dwTime > fTime)
- {
- dwp3 = iKey;
-
- if (iKey > 0)
- {
- dwp2= iKey - 1;
- }
- else // when iKey == 0, then dwp2 == 0
- {
- dwp2 = iKey;
- }
-
- break;
- }
- }
- fTime1 = (float)m_pMatrixKeys[dwp2].dwTime;
- fTime2 = (float)m_pMatrixKeys[dwp3].dwTime;
-
- if ((fTime2 - fTime1) ==0)
- fLerpValue = 0;
- else
- fLerpValue = (fTime - fTime1) / (fTime2 - fTime1);
-
- if (fLerpValue > 0.5)
- {
- iKey = dwp3;
- }
- else
- {
- iKey = dwp2;
- }
-
- pframeToAnimate->matRot = m_pMatrixKeys[iKey].mat;
- }
- else
- {
- D3DXMatrixIdentity(&matResult);
-
- if (m_pScaleKeys)
- {
- dwp2 = dwp3 = 0;
-
- fTime = (float)fmod(fGlobalTime, m_pScaleKeys[m_cScaleKeys-1].dwTime);
-
- for (iKey = 0 ;iKey < m_cScaleKeys ; iKey++)
- {
- if ((float)m_pScaleKeys[iKey].dwTime > fTime)
- {
- dwp3 = iKey;
-
- if (iKey > 0)
- {
- dwp2= iKey - 1;
- }
- else // when iKey == 0, then dwp2 == 0
- {
- dwp2 = iKey;
- }
-
- break;
- }
- }
- fTime1 = (float)m_pScaleKeys[dwp2].dwTime;
- fTime2 = (float)m_pScaleKeys[dwp3].dwTime;
-
- if ((fTime2 - fTime1) ==0)
- fLerpValue = 0;
- else
- fLerpValue = (fTime - fTime1) / (fTime2 - fTime1);
-
- D3DXVec3Lerp(&vScale,
- &m_pScaleKeys[dwp2].vScale,
- &m_pScaleKeys[dwp3].vScale,
- fLerpValue);
-
-
- D3DXMatrixScaling(&matTemp, vScale.x, vScale.y, vScale.z);
-
- D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
-
- bAnimate = true;
- }
-
- //check rot keys
- if (m_pRotateKeys )
- {
- dwp2 = dwp3 = 0;
-
- fTime = (float)fmod(fGlobalTime, m_pRotateKeys[m_cRotateKeys-1].dwTime);
-
- for (iKey = 0 ;iKey < m_cRotateKeys ; iKey++)
- {
- if ((float)m_pRotateKeys[iKey].dwTime > fTime)
- {
- dwp3 = iKey;
-
- if (iKey > 0)
- {
- dwp2= iKey - 1;
- }
- else // when iKey == 0, then dwp2 == 0
- {
- dwp2 = iKey;
- }
-
- break;
- }
- }
- fTime1 = (float)m_pRotateKeys[dwp2].dwTime;
- fTime2 = (float)m_pRotateKeys[dwp3].dwTime;
-
- if ((fTime2 - fTime1) ==0)
- fLerpValue = 0;
- else
- fLerpValue = (fTime - fTime1) / (fTime2 - fTime1);
-
- //s=0;
- D3DXQUATERNION q1,q2;
- q1.x =-m_pRotateKeys[dwp2].quatRotate.x;
- q1.y =-m_pRotateKeys[dwp2].quatRotate.y;
- q1.z =-m_pRotateKeys[dwp2].quatRotate.z;
- q1.w =m_pRotateKeys[dwp2].quatRotate.w;
-
- q2.x =-m_pRotateKeys[dwp3].quatRotate.x;
- q2.y =-m_pRotateKeys[dwp3].quatRotate.y;
- q2.z =-m_pRotateKeys[dwp3].quatRotate.z;
- q2.w =m_pRotateKeys[dwp3].quatRotate.w;
-
- D3DXQuaternionSlerp(&quat,
- &q1,
- &q2,
- fLerpValue);
-
- D3DXMatrixRotationQuaternion(&matTemp, &quat);
-
- D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
- bAnimate = true;
- }
-
- if (m_pPositionKeys)
- {
- dwp2=dwp3=0;
-
- fTime = (float)fmod(fGlobalTime, m_pPositionKeys[m_cRotateKeys-1].dwTime);
-
- for (iKey = 0 ;iKey < m_cPositionKeys ; iKey++)
- {
- if ((float)m_pPositionKeys[iKey].dwTime > fTime)
- {
- dwp3 = iKey;
-
- if (iKey > 0)
- {
- dwp2= iKey - 1;
- }
- else // when iKey == 0, then dwp2 == 0
- {
- dwp2 = iKey;
- }
-
- break;
- }
- }
- fTime1 = (float)m_pPositionKeys[dwp2].dwTime;
- fTime2 = (float)m_pPositionKeys[dwp3].dwTime;
-
- if ((fTime2 - fTime1) ==0)
- fLerpValue = 0;
- else
- fLerpValue = (fTime - fTime1) / (fTime2 - fTime1);
-
-
- D3DXVec3Lerp((D3DXVECTOR3*)&vPos,
- &m_pPositionKeys[dwp2].vPos,
- &m_pPositionKeys[dwp3].vPos,
- fLerpValue);
-
- D3DXMatrixTranslation(&matTemp, vPos.x, vPos.y, vPos.z);
-
- D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
- bAnimate = true;
- }
- else
- {
- D3DXMatrixTranslation(&matTemp, pframeToAnimate->matRotOrig._41, pframeToAnimate->matRotOrig._42, pframeToAnimate->matRotOrig._43);
-
- D3DXMatrixMultiply(&matResult, &matResult, &matTemp);
- }
-
- if (bAnimate)
- {
- pframeToAnimate->matRot = matResult;
- }
- }
- }
-
-
-
-
-