⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xskinmesh.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		DWORD size;
		D3DXMATRIXA16 *pMatrix;
		if (SUCCEEDED(pDataObj->GetData(NULL, &size, (VOID **)&pMatrix )))
		{
			pParentFrame->m_matOrig = *pMatrix;
			pParentFrame->m_matTrans = *pMatrix;
		}
	}
	
	// Load the child DataObjects
	IDirectXFileObject *pFileObj;
	IDirectXFileData   *pFileData;
	IDirectXFileDataReference *pFileRef;
	
	while (SUCCEEDED( pDataObj->GetNextObject(&pFileObj)))
	{
		if ( SUCCEEDED( pFileObj->QueryInterface(IID_IDirectXFileDataReference, (VOID **)&pFileRef)))
		{
			if ( SUCCEEDED( pFileRef->Resolve( &pFileData) ))
			{
				ParseXFileData( pFileData, pSubFrame );
				SAFE_RELEASE(pFileData);
			}
			SAFE_RELEASE(pFileRef);
		}
		else if ( SUCCEEDED( pFileObj->QueryInterface(IID_IDirectXFileData, (VOID **)&pFileData)))
		{
			ParseXFileData( pFileData, pSubFrame );
			SAFE_RELEASE(pFileData);
		}
		SAFE_RELEASE( pFileObj );
	}
	return TRUE;
}

BOOL XSKINMESH::ReadAnimationSet(IDirectXFileData * pDataObj,Frame * pParentFrame )
{
	const GUID				*pType = NULL;
	IDirectXFileObject		*pFileObj = NULL;
	IDirectXFileData		*pFileData = NULL;
	TCHAR					*pName = NULL;
	DWORD					 cchName;
	
	if (FAILED(pDataObj->GetName(NULL, &cchName )))
	{	
		return FALSE;
	}	

	if( cchName )
	{
		if ( NULL == (pName = new TCHAR[cchName] ) )
		{						
			return FALSE;
		}

		if (FAILED(pDataObj->GetName(pName, &cchName ) ))
		{	
			return FALSE;
		}
	}
	else
	{
		pName = new TCHAR[15];
		strcpy(pName, "$AnimationSet$" );
	}
	
	AnimationSet * pAnimationSet = new AnimationSet;
	
	pAnimationSet->m_pParent = pParentFrame;
	pAnimationSet->m_pName = pName;
	pName = NULL;
	
	pAnimationSet->m_pNext = m_pAnimationSet;
	m_pAnimationSet = pAnimationSet;
	
	while (SUCCEEDED(pDataObj->GetNextObject(&pFileObj)))
	{
		if (SUCCEEDED(pFileObj->QueryInterface( IID_IDirectXFileData, (LPVOID *)&pFileData)))
		{
			if (FAILED(pFileData->GetType( &pType)))
			{
				SAFE_RELEASE(pFileData);	
				return FALSE;						
			}

			if ( *pType == TID_D3DRMAnimation )
			{
				ReadAnimation(pFileData, pAnimationSet );
			}
			SAFE_RELEASE(pFileData);
		}
		SAFE_RELEASE(pFileObj);	
	}

	return TRUE;
}

VOID XSKINMESH::DrawSkinMesh()
{
	DrawFrame(m_pRootFrame);
}

VOID XSKINMESH::DrawFrame(Frame *pFrame)
{
	if ( NULL == pFrame )
		return;
	Mesh *pMesh = pFrame->m_pMeshList;
	
	while ( pMesh )
	{
		DrawOriginalMesh(pMesh);
		pMesh = pMesh->m_pNext;
	}
	DrawFrame( pFrame->m_pChild );
	DrawFrame( pFrame->m_pSibling);
}

VOID XSKINMESH::DrawOriginalMesh(Mesh * pMesh)
{
    UINT ipattr;
    HRESULT hr = S_OK;

    LPD3DXBONECOMBINATION pBoneComb;
    DWORD AttribIdPrev;

    if (pMesh->m_pSkinMesh)
    {
        if (m_nMethod != pMesh->m_Method)
        {
            MakeSkinMesh(pMesh);
        }

        if (m_nMethod == D3DNONINDEXED)
        {
            AttribIdPrev = UNUSED32; 
            pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMesh->m_pBoneCombinationBuf->GetBufferPointer());
            // Draw using default vtx processing of the device (typically HW)
            for (ipattr = 0; ipattr < pMesh->m_cpattr; ipattr++)
            {
                DWORD numBlend = 0;
                for (DWORD i = 0; i < pMesh->m_maxFaceInfl; ++i)
                {
                    if (pBoneComb[ipattr].BoneId[i] != UINT_MAX)
                    {
                        numBlend = i;
                    }
                }

                if (m_d3dCaps.MaxVertexBlendMatrices >= numBlend + 1)
                {
                    for (DWORD i = 0; i < pMesh->m_maxFaceInfl; ++i)
                    {
                        DWORD matid = pBoneComb[ipattr].BoneId[i];
                        if (matid != UINT_MAX)
                        {
                            m_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(i), pMesh->m_pBoneMatrix[matid]);
                            m_pD3DDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pMesh->m_pBoneOffsetMat[matid]);
                        }
                    }

                    m_pD3DDevice->SetRenderState(D3DRS_VERTEXBLEND, numBlend);

                    if ((AttribIdPrev != pBoneComb[ipattr].AttribId) || (AttribIdPrev == UNUSED32))
                    {
                        m_pD3DDevice->SetMaterial(&(pMesh->m_rgMaterials[pBoneComb[ipattr].AttribId]));
                        m_pD3DDevice->SetTexture(0, pMesh->m_pTextures[pBoneComb[ipattr].AttribId]);
                        AttribIdPrev = pBoneComb[ipattr].AttribId;
                    }

		            hr = pMesh->m_pMesh->DrawSubset( ipattr );
                    if(FAILED(hr))
                        return;
                }

            }

            // If necessary, draw parts that HW could not handle using SW
            if (pMesh->m_iAttrSplit < pMesh->m_cpattr)
            {
                AttribIdPrev = UNUSED32; 
                m_pD3DDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
                for (ipattr = pMesh->m_iAttrSplit; ipattr < pMesh->m_cpattr; ipattr++)
                {
                    DWORD numBlend = 0;
                    for (DWORD i = 0; i < pMesh->m_maxFaceInfl; ++i)
                    {
                        if (pBoneComb[ipattr].BoneId[i] != UINT_MAX)
                        {
                            numBlend = i;
                        }
                    }

                    if (m_d3dCaps.MaxVertexBlendMatrices < numBlend + 1)
                    {
                        for (DWORD i = 0; i < pMesh->m_maxFaceInfl; ++i)
                        {
                            DWORD matid = pBoneComb[ipattr].BoneId[i];
                            if (matid != UINT_MAX)
                            {
                                m_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(i), pMesh->m_pBoneMatrix[matid]);
                                m_pD3DDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pMesh->m_pBoneOffsetMat[matid]);
                            }
                        }

                        m_pD3DDevice->SetRenderState(D3DRS_VERTEXBLEND, numBlend);

                        if ((AttribIdPrev != pBoneComb[ipattr].AttribId) || (AttribIdPrev == UNUSED32))
                        {
                            m_pD3DDevice->SetMaterial(&(pMesh->m_rgMaterials[pBoneComb[ipattr].AttribId]));
                            m_pD3DDevice->SetTexture(0, pMesh->m_pTextures[pBoneComb[ipattr].AttribId]);
                            AttribIdPrev = pBoneComb[ipattr].AttribId;
                        }

		                hr = pMesh->m_pMesh->DrawSubset( ipattr );
                        if(FAILED(hr))
                            return;
                    }
                }
                m_pD3DDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
            }
            m_pD3DDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
        }

        else if (m_nMethod == D3DINDEXED)
        {
            if (pMesh->m_bUseSW)
            {
                m_pD3DDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, TRUE);
            }

            if (pMesh->m_maxFaceInfl == 1)
                m_pD3DDevice->SetRenderState(D3DRS_VERTEXBLEND, D3DVBF_0WEIGHTS);
            else
                m_pD3DDevice->SetRenderState(D3DRS_VERTEXBLEND, pMesh->m_maxFaceInfl - 1);
            if (pMesh->m_maxFaceInfl)
                m_pD3DDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, TRUE);
            pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMesh->m_pBoneCombinationBuf->GetBufferPointer());
            for (ipattr = 0; ipattr < pMesh->m_cpattr; ipattr++)
            {
                for (DWORD i = 0; i < pMesh->m_paletteSize; ++i)
                {
                    DWORD matid = pBoneComb[ipattr].BoneId[i];
                    if (matid != UINT_MAX)
                    {
                        m_pD3DDevice->SetTransform(D3DTS_WORLDMATRIX(i), pMesh->m_pBoneMatrix[matid]);
                        m_pD3DDevice->MultiplyTransform(D3DTS_WORLDMATRIX(i), &pMesh->m_pBoneOffsetMat[matid]);
                    }
                }
                
                m_pD3DDevice->SetMaterial(&(pMesh->m_rgMaterials[pBoneComb[ipattr].AttribId]));
                m_pD3DDevice->SetTexture(0, pMesh->m_pTextures[pBoneComb[ipattr].AttribId]);

                hr = pMesh->m_pMesh->DrawSubset( ipattr );
                if(FAILED(hr))
                    return;
            }
            m_pD3DDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
            m_pD3DDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);

            if (pMesh->m_bUseSW)
            {
                m_pD3DDevice->SetRenderState(D3DRS_SOFTWAREVERTEXPROCESSING, FALSE);
            }
        }
        else if (m_nMethod == SOFTWARE)
        {
            D3DXMATRIX  Identity;
            DWORD       cBones  = pMesh->m_pSkinMesh->GetNumBones();

            // set up bone transforms
            for (DWORD iBone = 0; iBone < cBones; ++iBone)
            {
                D3DXMatrixMultiply
                (
                    &m_pBoneMatrices[iBone],                 // output
                    &pMesh->m_pBoneOffsetMat[iBone], 
                    pMesh->m_pBoneMatrix[iBone]
                );
            }

            // set world transform
            D3DXMatrixIdentity(&Identity);
            hr = m_pD3DDevice->SetTransform(D3DTS_WORLD, &Identity);
            if (FAILED(hr))
                return;

            // generate skinned mesh
            hr = pMesh->m_pSkinMesh->UpdateSkinnedMesh(m_pBoneMatrices, NULL, pMesh->m_pMesh);
            if (FAILED(hr))
                return;

            for (ipattr = 0; ipattr < pMesh->m_cpattr; ipattr++)
            {
                m_pD3DDevice->SetMaterial(&(pMesh->m_rgMaterials[pMesh->m_pAttrTable[ipattr].AttribId]));
                m_pD3DDevice->SetTexture(0, pMesh->m_pTextures[pMesh->m_pAttrTable[ipattr].AttribId]);
		        hr  = pMesh->m_pMesh->DrawSubset(pMesh->m_pAttrTable[ipattr].AttribId);
                if (FAILED(hr))
                    return;
            }
            return;
        }
    }
    else
    {
        for (ipattr = 0; ipattr < pMesh->m_cpattr; ipattr++)
        {
            m_pD3DDevice->SetMaterial(&(pMesh->m_rgMaterials[ipattr]));
            m_pD3DDevice->SetTexture(0, pMesh->m_pTextures[ipattr]);
		    hr = pMesh->m_pMesh->DrawSubset( ipattr );
            if(FAILED(hr))
                return;
        }
    }
}

VOID XSKINMESH::UpdateFrame(Frame *pFrame, const D3DXMATRIXA16 * matCur)
{
	if ( pFrame == NULL )
		return;
	if ( matCur )
	{
		D3DXMatrixMultiply(&pFrame->m_matCombined, &pFrame->m_matRot, matCur);
		D3DXMatrixMultiply(&pFrame->m_matCombined, &pFrame->m_matTrans,&pFrame->m_matCombined );
	}
	else
	{
		pFrame->m_matCombined = pFrame->m_matTrans;
	}

    Frame *pChild = pFrame->m_pChild;
    while (pChild != NULL)
    {
        UpdateFrame(pChild, &pFrame->m_matCombined);
        pChild = pChild->m_pSibling;
    }
}

VOID XSKINMESH::SetMeshBones(Frame * pParentFrame)
{
	if ( pParentFrame == NULL )
		return;
	Mesh *pMesh = pParentFrame->m_pMeshList;
	while ( pMesh )
	{
		if ( pMesh->m_pSkinMesh )
		{
			for (DWORD i = 0; i <pMesh->m_numBoneComb; i++ )
			{
				TCHAR **pNames = (TCHAR **)pMesh->m_pBoneNamesBuf->GetBufferPointer();
				Frame *pFrame = m_pRootFrame->FindFrame( pNames[i] );
				if ( pFrame )
				{
					pMesh->m_pBoneMatrix[i] = &pFrame->m_matCombined;
				}
				else
					pMesh->m_pBoneMatrix[i] = NULL;
			}
		}
		pMesh = pMesh->m_pNext;
	}
	SetMeshBones( pParentFrame->m_pChild );
	SetMeshBones( pParentFrame->m_pSibling );
}

VOID XSKINMESH::SetMeshAnimations(Frame *pParentFrame)
{
	if ( pParentFrame )
	{
		AnimationSet	*pAnimSet = m_pAnimationSet;
		while ( pAnimSet )
		{
			Animation	*pAnim = pAnimSet->m_pAnim;
			while ( pAnim )
			{
				pAnim->m_pFrame	= m_pRootFrame->FindFrame( pAnim->m_pFrameName );
				pAnim = pAnim->m_pNext;
			}
			pAnimSet = pAnimSet->m_pNext;
		}
	}
}

AnimationSet * XSKINMESH::FindAnimationSet(const TCHAR *szName)
{
	if ( NULL == szName )
		return NULL;
	
	AnimationSet *pAnimSet = m_pAnimationSet;
	while ( pAnimSet )
	{
		if( _tcscmp(szName, pAnimSet->m_pName ) == 0 )
			return pAnimSet;
		pAnimSet = pAnimSet->m_pNext;
	}
	return NULL;
}

VOID XSKINMESH::SetAnimationSet(TCHAR *szName)
{
	m_pAnimationCur = FindAnimationSet(szName);
}

VOID XSKINMESH::LinkAllMesh(Frame *pParentFrame)
{
	if ( pParentFrame == NULL )
		return;

	Mesh *pMesh = pParentFrame->m_pMeshList;
	Mesh *pHeadMesh = pMesh;
	while ( pMesh != NULL && pMesh->m_pNext != NULL )
	{
		pMesh = pMesh->m_pNext;
	}

	if ( pMesh != NULL )
	{
		pMesh->m_pNext = m_pMeshList;
		m_pMeshList = pHeadMesh;
	}

	LinkAllMesh( pParentFrame->m_pChild );
	LinkAllMesh( pParentFrame->m_pSibling );
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -