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

📄 game_skinmesh.cpp

📁 我做的毕业设计
💻 CPP
📖 第 1 页 / 共 3 页
字号:

				if (m_d3dCaps.MaxVertexBlendMatrices >= NumBlend + 1)
				{
					// first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends
					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] );
							m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp );
						}
					}

					m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend);

					// lookup the material used for this subset of faces
					if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32))
					{
						m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
						m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
						AttribIdPrev = pBoneComb[iAttrib].AttribId;
					}

					// draw the subset now that the correct material and matrices are loaded
					pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib);
				}
			}

			// If necessary, draw parts that HW could not handle using SW
			if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups)
			{
				AttribIdPrev = UNUSED32; 
				m_pd3dDevice->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)
					{
						// first calculate the world matrices for the current set of blend weights and get the accurate count of the number of blends
						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] );
								m_pd3dDevice->SetTransform( D3DTS_WORLDMATRIX( i ), &matTemp );
							}
						}

						m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, NumBlend);

						// lookup the material used for this subset of faces
						if ((AttribIdPrev != pBoneComb[iAttrib].AttribId) || (AttribIdPrev == UNUSED32))
						{
							m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
							m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );
							AttribIdPrev = pBoneComb[iAttrib].AttribId;
						}

						// draw the subset now that the correct material and matrices are loaded
						pMeshContainer->MeshData.pMesh->DrawSubset(iAttrib);
					}
				}
				m_pd3dDevice->SetSoftwareVertexProcessing(FALSE);
			}

			m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);
		}
		else if (m_SkinningMethod == D3DINDEXED)
		{
			// if hw doesn't support indexed vertex processing, switch to software vertex processing
			if (pMeshContainer->UseSoftwareVP)
			{
				m_pd3dDevice->SetSoftwareVertexProcessing(TRUE);
			}

			// set the number of vertex blend indices to be blended
			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);

			// for each attribute group in the mesh, calculate the set of matrices in the palette and then draw the mesh subset
			pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());
			for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++)
			{
				// first calculate all the world matrices
				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 );
					}
				}

				// setup the material of the mesh subset - REMEMBER to use the original pre-skinning attribute id to get the correct material id
				m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[pBoneComb[iAttrib].AttribId].MatD3D );
				m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[pBoneComb[iAttrib].AttribId] );

				// finally draw the subset with the current world matrix palette and material state
				pMeshContainer->MeshData.pMesh->DrawSubset( iAttrib );
			}

			// reset blending state
			m_pd3dDevice->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
			m_pd3dDevice->SetRenderState(D3DRS_VERTEXBLEND, 0);

			// remember to reset back to hw vertex processing if software was required
			if (pMeshContainer->UseSoftwareVP)
			{
				m_pd3dDevice->SetSoftwareVertexProcessing(FALSE);
			}
		}
		else if (m_SkinningMethod == SOFTWARE)
		{
			D3DXMATRIX  Identity;
			DWORD       cBones  = pMeshContainer->pSkinInfo->GetNumBones();
			DWORD       iBone;
			PBYTE       pbVerticesSrc;
			PBYTE       pbVerticesDest;

			// set up bone transforms
			for (iBone = 0; iBone < cBones; ++iBone)
			{
				D3DXMatrixMultiply
					(
					&m_pBoneMatrices[iBone],                 // output
					&pMeshContainer->pBoneOffsetMatrices[iBone], 
					pMeshContainer->ppBoneMatrixPtrs[iBone]
					);
			}

			// set world transform
			D3DXMatrixIdentity(&Identity);
			m_pd3dDevice->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++)
			{
				m_pd3dDevice->SetMaterial(&(pMeshContainer->pMaterials[pMeshContainer->pAttributeTable[iAttrib].AttribId].MatD3D));
				m_pd3dDevice->SetTexture(0, pMeshContainer->ppTextures[pMeshContainer->pAttributeTable[iAttrib].AttribId]);
				pMeshContainer->MeshData.pMesh->DrawSubset(pMeshContainer->pAttributeTable[iAttrib].AttribId);
			}
		}
		else // bug out as unsupported mode
		{
			return;
		}
	}
	else  // standard mesh, just draw it after setting material properties
	{
		m_pd3dDevice->SetTransform(D3DTS_WORLD, &pFrame->CombinedTransformationMatrix);

		for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++)
		{
			m_pd3dDevice->SetMaterial( &pMeshContainer->pMaterials[iMaterial].MatD3D );
			m_pd3dDevice->SetTexture( 0, pMeshContainer->ppTextures[iMaterial] );
			pMeshContainer->MeshData.pMesh->DrawSubset(iMaterial);
		}
	}
}


VOID CSkinMesh::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::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 CSkinMesh::SetAnimationName(char *strAnimName)
{
	DWORD i=0;
	if(!m_bMoving || !m_pAnimController  ) return FALSE;
	DWORD nAnimSet;
	char strTempName[256];
	nAnimSet=m_pAnimController->GetNumAnimationSets();
	//LPD3DXANIMATIONSET pAnimSet;
	if( strcmp( strAnimName, "wait") == 0 
		||  strcmp( strAnimName, "attak") == 0
		||	strcmp( strAnimName, "run") == 0
		||	strcmp( strAnimName, "idle") == 0
		||	strcmp( strAnimName, "walk") == 0
		||	strcmp( strAnimName, "stand") == 0)
	{
		m_bLoop = true;
	}
	else if( strcmp( strAnimName, "skil1") == 0 
		||	 strcmp( strAnimName, "skill2") == 0 
		||	 strcmp( strAnimName, "death") == 0
		||	 strcmp( strAnimName, "die") == 0
		||	 strcmp( strAnimName, "attack") == 0)

	{
		m_bLoop = false;
	}
	for(DWORD i=0;i<nAnimSet;i++)
	{	
		m_pAnimController->GetAnimationSet(i,&m_pCurAnimSet);
		strcpy(strTempName,	m_pCurAnimSet->GetName());
		if(strcmp(strAnimName,strTempName)==0) 
		{
			m_pAnimController->SetTrackAnimationSet(0,m_pCurAnimSet);	
			return TRUE;		
		}
	}
	return FALSE;
};

//-----------------------------------------
//Name:Intersect
//Desc:使用索引和顶点缓冲区,求Mesh和射线交点
//2006/6/27 JohnsonFeng
//Use: IntersectIndexBuffer
//-----------------------------------------
BOOL CSkinMesh::InterSect( D3DVECTOR *pRayOrig,
		 D3DVECTOR *pRayDir,D3DVECTOR* pVRet)
{
	return S_OK;
}

HRESULT CSkinMesh::CalculateStaticBondingBox(LPD3DXFRAME pFrameBase, const LPD3DXVECTOR3 pVmin, 
											 const LPD3DXVECTOR3 pVmax)
{	

	static LPD3DXMESH pMesh;
	static LPD3DXMATRIX pMat;

	static D3DXVECTOR3 *pV; 
	static D3DXVECTOR3 vTransformed;
	static D3DXMATRIX matTemp;

	D3DXMESHCONTAINER_DERIVED *pMeshContainer= (D3DXMESHCONTAINER_DERIVED*)pFrameBase->pMeshContainer; 
	//这里如果直接使用Frame自带的CombinedTransformationMatrix,将会得到模型静止状态的方盒


	while (pMeshContainer != NULL )
	{
		pMesh=pMeshContainer->MeshData.pMesh;    

		pMesh->LockVertexBuffer(0,(void**)&pV); 
		if(pMeshContainer->NumInfl>0)
		{//	pMat=*pMeshContainer->ppBoneMatrixPtrs;
			D3DXMatrixMultiply( &matTemp, &pMeshContainer->pBoneOffsetMatrices[0], pMeshContainer->ppBoneMatrixPtrs[0] );
			pMat=&matTemp; 
		}
		else 
			pMat=&((D3DXFRAME_DERIVED*)pFrameBase)->CombinedTransformationMatrix;  //只是使用第一个矩阵

		DWORD nVertex=pMesh->GetNumVertices();
		DWORD nStride=pMesh->GetNumBytesPerVertex();
		DWORD i;

		for(i=0;i<nVertex;i++)
		{
			vTransformed.x=pV->x*pMat->_11+pV->y*pMat->_21+pV->z*pMat->_31+pMat->_41;
			vTransformed.y=pV->x*pMat->_12+pV->y*pMat->_22+pV->z*pMat->_32+pMat->_42;
			vTransformed.z=pV->x*pMat->_13+pV->y*pMat->_23+pV->z*pMat->_33+pMat->_43;

			if		 (vTransformed.x<pVmin->x)	pVmin->x=vTransformed.x;
			else if  (vTransformed.x>pVmax->x)	pVmax->x=vTransformed.x;

			if		(vTransformed.y<pVmin->y)	pVmin->y=vTransformed.y;
			else if	(vTransformed.y>pVmax->y)	pVmax->y=vTransformed.y;

			if		(vTransformed.z<pVmin->z)	pVmin->z=vTransformed.z;
			else if	(vTransformed.z>pVmax->z)	pVmax->z=vTransformed.z;
			pV=(D3DXVECTOR3*)((BYTE*)pV+nStride);
		}
		pMesh->UnlockVertexBuffer(); 
		//只有一个容量
		pMeshContainer =(D3DXMESHCONTAINER_DERIVED*) pMeshContainer->pNextMeshContainer;
	}

	if(pFrameBase->pFrameSibling)
		CalculateStaticBondingBox(pFrameBase->pFrameSibling,pVmin,pVmax);

	if(pFrameBase->pFrameFirstChild)
		CalculateStaticBondingBox(pFrameBase->pFrameFirstChild,pVmin,pVmax);
	return S_OK;
}
D3DXVECTOR3 CSkinMesh::MoveTo(D3DXVECTOR3 IntersectPoint, float tFrameTime, float Speed1)
{
	float dist = 0.0f, Yaw = 0.0f;
	dist = DistanceOfTwoVec3(IntersectPoint, m_vPos);
	Yaw = GetYaw(IntersectPoint, m_vPos);

	m_vPosOld = m_vPos;

	m_vPos.x += tFrameTime*Speed1*sin(Yaw);
	m_vPos.z += tFrameTime*Speed1*cos(Yaw);
	if(dist <= tFrameTime*Speed1)
	{
		m_isMoving = false;
		//this->m_fAngle = Yaw;
		this->SetAnimationName("wait");
	}		
	return m_vPos;
}

//找到节点的矩阵
LRESULT CSkinMesh::GetFrameMatrix(LPD3DXFRAME pFrameBase, char *strFrameName,D3DMATRIX *pMat)
{
	D3DXFRAME *pFrame ;

	if(pFrameBase!=NULL)
		pFrame = pFrameBase;
	else 
		pFrame = m_pFrameRoot;

	if(pFrame->Name!=NULL && 0==strcmp(pFrame->Name,strFrameName))
	{
		*pMat=((D3DXFRAME_DERIVED*)pFrame)->CombinedTransformationMatrix; 
		return S_OK;
	}
	if (pFrame->pFrameSibling != NULL)
	{
		if(S_OK == GetFrameMatrix(pFrame->pFrameSibling,strFrameName,pMat))
			return S_OK;
	}
	if (pFrame->pFrameFirstChild != NULL)
	{
		if(S_OK == GetFrameMatrix(pFrame->pFrameFirstChild,strFrameName,pMat))
			return S_OK;
	}
	return E_FAIL;
}

⌨️ 快捷键说明

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