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

📄 xskinmesh.cpp

📁 VC++ DEMO, used for the beginners and the amour
💻 CPP
📖 第 1 页 / 共 3 页
字号:
					}
				}
				
				if (cInfl > m_d3dCaps.MaxVertexBlendMatrices)
				{
					break;
				}
			}
			
			// if there is both HW and SW, add the Software Processing flag
			if (pMesh->m_iAttrSplit < pMesh->m_cpattr)
			{
				LPD3DXMESH pMeshTmp;
				
				hr = pMesh->m_pMesh->CloneMeshFVF(D3DXMESH_SOFTWAREPROCESSING|pMesh->m_pMesh->GetOptions(), 
					pMesh->m_pMesh->GetFVF(),
					m_pD3DDevice, &pMeshTmp);
				if (FAILED(hr))
				{
					SAFE_RELEASE( pMeshTmp );
					return FALSE;
				}
				
				pMesh->m_pMesh->Release();
				pMesh->m_pMesh = pMeshTmp;
				pMeshTmp = NULL;
			}
		}
		else
		{
			pMesh->m_iAttrSplit = pMesh->m_cpattr;
		}
	}
	else if (m_nMethod == D3DINDEXED)
	{
		DWORD maxFaceInfl;
		DWORD flags = D3DXMESHOPT_VERTEXCACHE;
		
		hr = pMesh->m_pSkinMesh->GetMaxFaceInfluences(&maxFaceInfl);
		if (FAILED(hr))
			return FALSE;
		
		// 12 entry palette guarantees that any triangle (4 independent influences per vertex of a tri)
		// can be handled
		maxFaceInfl = min(maxFaceInfl, 12);
		
		if (m_d3dCaps.MaxVertexBlendMatrixIndex + 1 < maxFaceInfl)
		{
			// HW does not support indexed vertex blending. Use SW instead
			pMesh->m_paletteSize = min(256, pMesh->m_pSkinMesh->GetNumBones());
			pMesh->m_bUseSW = true;
			flags |= D3DXMESH_SYSTEMMEM;
		}
		else
		{
			pMesh->m_paletteSize = min(m_d3dCaps.MaxVertexBlendMatrixIndex + 1, pMesh->m_pSkinMesh->GetNumBones());
			pMesh->m_bUseSW = FALSE;
			flags |= D3DXMESH_MANAGED;
		}
		
		hr = pMesh->m_pSkinMesh->ConvertToIndexedBlendedMesh(flags, pMesh->m_rgiAdjacency, pMesh->m_paletteSize, NULL,
			&pMesh->m_cpattr, &pMesh->m_pBoneCombinationBuf, NULL, NULL, &pMesh->m_pMesh);
		if (FAILED(hr))
			return FALSE;
		
		// Here we are talking of max vertex influence which we determine from 
		// the FVF of the returned mesh
		if ((pMesh->m_pMesh->GetFVF() & D3DFVF_POSITION_MASK) != D3DFVF_XYZ)
		{
			pMesh->m_maxFaceInfl = ((pMesh->m_pMesh->GetFVF() & D3DFVF_POSITION_MASK) - D3DFVF_XYZRHW) / 2;
		}
		else
		{
			pMesh->m_maxFaceInfl = 1;
		}
	}
	else if (m_nMethod == SOFTWARE)
	{
		hr = pMesh->m_pSkinMesh->GenerateSkinnedMesh(
			D3DXMESH_WRITEONLY,          // options
			0.0f,                        // minimum bone weight allowed
			pMesh->m_rgiAdjacency,     // adjacency of in-mesh
			NULL,     // adjacency of out-mesh
			NULL,     // face remap array
			NULL,     // vertex remap buffer
			&pMesh->m_pMesh );              // out-mesh
		
		if (FAILED(hr))
			return FALSE;
		
		hr = pMesh->m_pMesh->GetAttributeTable(NULL, &pMesh->m_cpattr);
		if (FAILED(hr))
			return FALSE;
		
		SAFE_DELETE_ARRAY(pMesh->m_pAttrTable);
		pMesh->m_pAttrTable  = new D3DXATTRIBUTERANGE[pMesh->m_cpattr];
		if (pMesh->m_pAttrTable == NULL)
		{
			return FALSE;
		}
		
		hr = pMesh->m_pMesh->GetAttributeTable(pMesh->m_pAttrTable, NULL);
		if (FAILED(hr))
			return FALSE;
		
		hr = pMesh->m_pSkinMesh->GetMaxFaceInfluences(&pMesh->m_maxFaceInfl);
		if (FAILED(hr))
			return FALSE;
		
		// Allocate space for blend matrices
		m_pBoneMatrices  = new D3DXMATRIXA16[m_maxBones];
		
		if (m_pBoneMatrices == NULL)
		{
			return FALSE;
		}
	}
	pMesh->m_Method = m_nMethod;
	return TRUE;
}

BOOL XSKINMESH::ReadSkinMesh(IDirectXFileData *pDataObj, Frame *pParentFrame)
{
	HRESULT hr;
	LPD3DXBUFFER pbufMaterials = NULL;
	LPD3DXBUFFER pbufAdjacency = NULL;
	LPDWORD		 pAdjacencyIn = NULL;
	Mesh *pMesh = NULL;
	
	DWORD cchName;
	UINT nFaces;
	UINT nMaterial;
	
	pMesh = new Mesh();
	if (pMesh == NULL)
	{
		return FALSE;
	}
	
	hr = pDataObj->GetName(NULL, &cchName);
	if (FAILED(hr))
	{
		SAFE_DELETE(pMesh);
		return FALSE;
	}
	
	if (cchName > 0)
	{
		pMesh->m_szName = new TCHAR[cchName];
		if (pMesh->m_szName == NULL)
		{
			return FALSE;
		}
		hr = pDataObj->GetName(pMesh->m_szName, &cchName);
		if (FAILED(hr))
		{
			SAFE_DELETE(pMesh);
			return FALSE;
		}
	}
	else
	{
		pMesh->m_szName = new TCHAR[9];
		strcpy(pMesh->m_szName,"$Mesh$");
	}
	
	hr = D3DXLoadSkinMeshFromXof(pDataObj, m_dwMeshOptions, m_pD3DDevice, &pbufAdjacency, &pbufMaterials, &pMesh->m_cMaterials, 
		&pMesh->m_pBoneNamesBuf, &pMesh->m_pBoneOffsetBuf, &pMesh->m_pSkinMesh);
	if (FAILED(hr))
	{
		SAFE_DELETE(pMesh);
		SAFE_RELEASE(pbufAdjacency);
		SAFE_RELEASE(pbufMaterials);
		if (hr == D3DXERR_LOADEDMESHASNODATA) return TRUE;
		
		return FALSE;
	}

	// Calculate the bounding box and sphere
	LPBYTE Ptr;
	if(SUCCEEDED(pMesh->m_pSkinMesh->LockVertexBuffer(D3DLOCK_READONLY, (BYTE**)&Ptr))) 
	{
		D3DXComputeBoundingBox((void*)Ptr, pMesh->m_pSkinMesh->GetNumVertices(), pMesh->m_pSkinMesh->GetFVF(), &pMesh->m_vMin, &pMesh->m_vMax);
		D3DXComputeBoundingSphere((void*)Ptr, pMesh->m_pSkinMesh->GetNumVertices(), pMesh->m_pSkinMesh->GetFVF(), &D3DXVECTOR3(0.0f,0.0f,0.0f), &pMesh->m_fRadius);
		m_vMin.x = min(m_vMin.x, pMesh->m_vMin.x);
		m_vMin.y = min(m_vMin.y, pMesh->m_vMin.y);
		m_vMin.z = min(m_vMin.z, pMesh->m_vMin.z);
		m_vMax.x = max(m_vMax.x, pMesh->m_vMax.x);
		m_vMax.y = max(m_vMax.y, pMesh->m_vMax.y);
		m_vMax.z = max(m_vMax.z, pMesh->m_vMax.z);
		m_fRadius = max(m_fRadius, pMesh->m_fRadius);
		pMesh->m_pSkinMesh->UnlockVertexBuffer();
	}
	
	nFaces = pMesh->m_pSkinMesh->GetNumFaces();
	
	pAdjacencyIn = static_cast<LPDWORD>(pbufAdjacency->GetBufferPointer());
	
	pMesh->m_rgiAdjacency = new DWORD[nFaces * 3];
	
	if (pMesh->m_rgiAdjacency == NULL)
	{
		SAFE_DELETE(pMesh);
		SAFE_RELEASE(pbufAdjacency);
		SAFE_RELEASE(pbufMaterials);
		return FALSE;
	}
	
	memcpy(pMesh->m_rgiAdjacency, pAdjacencyIn, nFaces * 3 * sizeof(DWORD));
	
	// Process skinning data
	if ( (pMesh->m_numBoneComb = pMesh->m_pSkinMesh->GetNumBones()))
	{
		// Update max bones of any mesh in the app
		m_maxBones = max(pMesh->m_pSkinMesh->GetNumBones(), m_maxBones);
		
		pMesh->m_pBoneMatrix = new D3DXMATRIXA16*[pMesh->m_pSkinMesh->GetNumBones()];
		if (pMesh->m_pBoneMatrix == NULL)
		{
			SAFE_DELETE(pMesh);
			SAFE_RELEASE(pbufAdjacency);
			SAFE_RELEASE(pbufMaterials);
			return FALSE;
		}		
		pMesh->m_pBoneOffsetMat = reinterpret_cast<D3DXMATRIXA16*>(pMesh->m_pBoneOffsetBuf->GetBufferPointer());
		
		hr = MakeSkinMesh(pMesh);
		if (FAILED(hr))
		{
			SAFE_DELETE(pMesh);
			SAFE_RELEASE(pbufAdjacency);
			SAFE_RELEASE(pbufMaterials);
			return FALSE;
		}

	}
	else
	{
		pMesh->m_pSkinMesh->GetOriginalMesh(&(pMesh->m_pMesh));
		pMesh->m_pSkinMesh->Release();
		pMesh->m_pSkinMesh = NULL;
		pMesh->m_cpattr = pMesh->m_cMaterials;
	}
	
	if ((pbufMaterials == NULL) || (pMesh->m_cMaterials == 0))
	{
		pMesh->m_rgMaterials = new D3DMATERIAL8[1];
		pMesh->m_pTextures = new LPDIRECT3DTEXTURE8[1];
		if (pMesh->m_rgMaterials == NULL || pMesh->m_pTextures == NULL)
		{
			SAFE_DELETE(pMesh);
			SAFE_RELEASE(pbufAdjacency);
			SAFE_RELEASE(pbufMaterials);
			return FALSE;
		}
		
		memset(pMesh->m_rgMaterials, 0, sizeof(D3DMATERIAL8));
		pMesh->m_rgMaterials[0].Diffuse.r = 0.5f;
		pMesh->m_rgMaterials[0].Diffuse.g = 0.5f;
		pMesh->m_rgMaterials[0].Diffuse.b = 0.5f;
		pMesh->m_rgMaterials[0].Specular = pMesh->m_rgMaterials[0].Diffuse;
		pMesh->m_pTextures[0] = NULL;
	}
	else
	{
		pMesh->m_rgMaterials = new D3DMATERIAL8[pMesh->m_cMaterials];
		pMesh->m_pTextures = new LPDIRECT3DTEXTURE8[pMesh->m_cMaterials];
		if (pMesh->m_rgMaterials == NULL || pMesh->m_pTextures == NULL)
		{
			SAFE_DELETE(pMesh);
			SAFE_RELEASE(pbufAdjacency);
			SAFE_RELEASE(pbufMaterials);
			return FALSE;
		}
		
		LPD3DXMATERIAL pMaterials = (LPD3DXMATERIAL)pbufMaterials->GetBufferPointer();
		
		for (nMaterial = 0; nMaterial < pMesh->m_cMaterials; nMaterial++)
		{
			
			pMesh->m_rgMaterials[nMaterial] = pMaterials[nMaterial].MatD3D;
			
			pMesh->m_pTextures[nMaterial] = NULL;
			if (pMaterials[nMaterial].pTextureFilename != NULL)
			{
				TCHAR szPath[MAX_PATH];
				if ( m_strFilePath )
				{
					wsprintf(szPath,"%s%s",m_strFilePath,pMaterials[nMaterial].pTextureFilename);
				}				
				hr = D3DXCreateTextureFromFile(m_pD3DDevice, szPath, &(pMesh->m_pTextures[nMaterial]));
				if (FAILED(hr))
					pMesh->m_pTextures[nMaterial] = NULL;
			}
		}
	}

	// add the mesh to the parent frame
	pMesh->m_pNext = pParentFrame->m_pMeshList;
	pParentFrame->m_pMeshList = pMesh;
	pMesh = NULL;
	
	SAFE_RELEASE(pbufAdjacency);
	SAFE_RELEASE(pbufMaterials);
	return TRUE;
}

VOID XSKINMESH::AnimationMesh(FLOAT fTime, const D3DXMATRIXA16 & matCur,FLOAT fSpeed)
{
	if ( m_pAnimationCur ) 
	{
		Animation *pAnim = m_pAnimationCur->m_pAnim;
		while ( pAnim )
		{
			pAnim->SetAnimationCyc( fTime,fSpeed );
			pAnim = pAnim->m_pNext;
		}
	}
	UpdateFrame(m_pRootFrame,  &matCur );
	
}

BOOL XSKINMESH::ReadMeshHierarchy(TCHAR * strFileName,
								  LPDIRECT3DDEVICE8 device,
								  DWORD dwMeshOptions,
								  UINT nDrawMethod)
{
	
	IDirectXFile	*pDXFile = NULL;
	IDirectXFileEnumObject	*pDXEnumObj = NULL;
	IDirectXFileData		*pDXDataObj = NULL;
	
	SAFE_DELETE( m_pRootFrame );
	
	m_pD3DDevice = device;
	m_nMethod = nDrawMethod;
	m_dwMeshOptions = dwMeshOptions;
	
	if (FAILED(m_pD3DDevice->GetDeviceCaps(&m_d3dCaps)))
		return FALSE;
	
	
	if ( FAILED(DirectXFileCreate( &pDXFile ) ))
		return FALSE;

	if ( FAILED(pDXFile->RegisterTemplates( (LPVOID)D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES) ))
		return FALSE;

	if ( FAILED(pDXFile->CreateEnumObject( (LPVOID)strFileName, DXFILELOAD_FROMFILE, &pDXEnumObj) ))
		return FALSE;
	
	m_pRootFrame = new Frame;
	
	// Enum DataObjects
	while ( SUCCEEDED(pDXEnumObj->GetNextDataObject(&pDXDataObj) ))
	{
		ParseXFileData( pDXDataObj, m_pRootFrame );
		SAFE_RELEASE( pDXDataObj );
	}
	
	LinkAllMesh(m_pRootFrame);

	SetMeshBones(m_pRootFrame);
	
	SetMeshAnimations(m_pRootFrame);

	m_pAnimationCur = FindAnimationSet("Idle");
	
	SAFE_RELEASE( pDXEnumObj );
	SAFE_RELEASE( pDXFile );
	return TRUE;
}
		
Frame *	XSKINMESH::ReadFrame(IDirectXFileData *pDataObj, Frame *pParentFrame)
{
	TCHAR		*pName = NULL;
	DWORD		cchName;	
	if ( FAILED(pDataObj->GetName(NULL, &cchName ) ))
		return NULL;
	if ( cchName )
	{
		if ( NULL == (pName = new TCHAR[cchName]) )
			return NULL;
		pDataObj->GetName(pName, &cchName);
	}else
	{
		pName = new TCHAR[9];
		strcpy(pName, "$Frame$");
	}
	
	Frame	*pFrame = new Frame;
	pFrame->m_pName = pName;
	pName = NULL;
	
	pFrame->m_pParent = pParentFrame;
	pFrame->m_pSibling = pParentFrame->m_pChild;
	pParentFrame->m_pChild = pFrame;
	
	return pFrame;
}

BOOL XSKINMESH::ParseXFileData(IDirectXFileData *pDataObj, Frame *pParentFrame)
{
	const GUID	*pType = NULL;
	Frame		*pSubFrame = pParentFrame;

	// Get the type of the DataObject
	if ( FAILED(pDataObj->GetType(&pType) ))
		return FALSE;
	
	if ( *pType == TID_D3DRMFrame )
	{
		pSubFrame = ReadFrame(pDataObj,pParentFrame);		
	}
	else if ( *pType == TID_D3DRMMesh )
	{
		ReadSkinMesh( pDataObj, pParentFrame );
	}
	else if ( *pType == TID_D3DRMAnimationSet )
	{
		ReadAnimationSet( pDataObj, pParentFrame );	
	}
	else if ( *pType == TID_D3DRMFrameTransformMatrix )
	{

⌨️ 快捷键说明

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