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

📄 game_skinmesh.cpp

📁 自己写的一个D3D游戏Dome。实现了基本的游戏功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#include "..\Include\Game_SkinMesh.h"

HRESULT AllocateName( LPCSTR Name, LPSTR *pNewName ){
	UINT cbLength;

	if( Name != NULL ){
		cbLength = (UINT)strlen(Name) + 1;
		*pNewName = new CHAR[cbLength];
		if (*pNewName == NULL)
			return E_OUTOFMEMORY;
		memcpy( *pNewName, Name, cbLength*sizeof(CHAR) );
	}
	else{
		*pNewName = NULL;
	}

	return S_OK;
}

HRESULT CAllocateHierarchy::CreateFrame(LPCSTR Name, LPD3DXFRAME *ppNewFrame){
    HRESULT hr = S_OK;
    D3DXFRAME_DERIVED *pFrame;
	
    *ppNewFrame = NULL;
	
    pFrame = new D3DXFRAME_DERIVED;
    if (pFrame == NULL)
    {
        hr = E_OUTOFMEMORY;
        goto e_Exit;
    }
	//初试化帧名字
    hr = AllocateName(Name, &pFrame->Name);
    if (FAILED(hr))
        goto e_Exit;
	
    // initialize other data members of the frame
	//初始化帧的数据
    D3DXMatrixIdentity(&pFrame->TransformationMatrix);
    D3DXMatrixIdentity(&pFrame->CombinedTransformationMatrix);
	
    pFrame->pMeshContainer = NULL;
    pFrame->pFrameSibling = NULL;
    pFrame->pFrameFirstChild = NULL;
	
    *ppNewFrame = pFrame;
    pFrame = NULL;
e_Exit:
    delete pFrame;
    return hr;
}

LRESULT CAllocateHierarchy::CreateMeshContainer(
	LPCSTR Name,								//网格容器名
	CONST D3DXMESHDATA *pMeshData,             //网格数据 
	CONST D3DXMATERIAL *pMaterials,              //材质
	CONST D3DXEFFECTINSTANCE *pEffectInstances,  //特效
	DWORD NumMaterials,                          //传入的材质数
	CONST DWORD *pAdjacency,                     //传入的邻接三角形面的信息
	LPD3DXSKININFO pSkinInfo,                    //蒙皮信息
	LPD3DXMESHCONTAINER *ppNewMeshContainer){    //下一个的指针
		
		HRESULT hr;
		D3DXMESHCONTAINER_DERIVED *pMeshContainer = NULL;
		UINT NumFaces;//网格中的面数,在填充网格容器结构的邻接信息成员时使用
		UINT iMaterial;//纹理操作时的循环变量
		UINT iBone, cBones;
		LPDIRECT3DDEVICE9 pd3dDevice = NULL;
		
		LPD3DXMESH pMesh = NULL;
		
		*ppNewMeshContainer = NULL;
		
		if (pMeshData->Type != D3DXMESHTYPE_MESH){
			hr = E_FAIL;
			goto e_Exit;
		}
		
		pMesh = pMeshData->pMesh;
		
		if (pMesh->GetFVF()==0){
			hr = E_FAIL;
			goto e_Exit;
		}
		
		//为网格容器分配内存
		pMeshContainer = new D3DXMESHCONTAINER_DERIVED;
		if (pMeshContainer == NULL){
			hr = E_OUTOFMEMORY;
			goto e_Exit;
		}
		memset(pMeshContainer, 0, sizeof(D3DXMESHCONTAINER_DERIVED));
		
		//填充网格容器结构D3DXMESHCONTAINER_DERIVED的成员
		hr = AllocateName(Name, &pMeshContainer->Name);
		if (FAILED(hr))
			goto e_Exit;        
		
		//取得网格所关联的D3D设备
		pMesh->GetDevice(&pd3dDevice);
		NumFaces = pMesh->GetNumFaces();
		
		//确保网格顶点包含法线
		//取得网格的三角形面数
		//如果没有法向量,则添加它们
		if ((pMesh->GetFVF() & D3DFVF_NORMAL)){
			pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
			
			//用复制的方法插入法向量数据方式
			hr = pMesh->CloneMeshFVF( pMesh->GetOptions(), 
				pMesh->GetFVF() | D3DFVF_NORMAL, 
				pd3dDevice, &pMeshContainer->MeshData.pMesh );
			if (FAILED(hr))
				goto e_Exit;

			pMesh = pMeshContainer->MeshData.pMesh;
			
			//在网格容器中生成法向量
			D3DXComputeNormals( pMesh, NULL );
		}
		else{//如果网格中已包含法向量数据

			//为创建的网格容器添加网格数据
			pMeshContainer->MeshData.pMesh = pMesh;
			//设置网格容器的类型
			pMeshContainer->MeshData.Type = D3DXMESHTYPE_MESH;
			//引用计数加1
			pMesh->AddRef();
		}
		
		//为网格模型准备材质和纹理
		pMeshContainer->NumMaterials = max(1, NumMaterials);
		pMeshContainer->pMaterials = new D3DXMATERIAL[pMeshContainer->NumMaterials];
		pMeshContainer->ppTextures = new LPDIRECT3DTEXTURE9[pMeshContainer->NumMaterials];
		pMeshContainer->pAdjacency = new DWORD[NumFaces*3];
		if ((pMeshContainer->pAdjacency == NULL)||(pMeshContainer->pMaterials == NULL)){
			hr = E_OUTOFMEMORY;
			goto e_Exit;
		}
		
		memcpy(pMeshContainer->pAdjacency, pAdjacency, sizeof(DWORD) * NumFaces*3);
		memset(pMeshContainer->ppTextures, 0, sizeof(LPDIRECT3DTEXTURE9) * pMeshContainer->NumMaterials);
		
		//如果有材质数据,生成纹理对象,并放入扩展后的网格容器中

		if (NumMaterials > 0)            {
			//复制材质属性,设置材质环境光属性
			memcpy(pMeshContainer->pMaterials, pMaterials, sizeof(D3DXMATERIAL) * NumMaterials);
		
			//提取纹理文件,创建纹理对象
			for (iMaterial = 0; iMaterial < NumMaterials; iMaterial++){
				if (pMeshContainer->pMaterials[iMaterial].pTextureFilename != NULL){
					WCHAR wszBuf[MAX_PATH];
					MultiByteToWideChar( CP_ACP, 0, pMeshContainer->pMaterials[iMaterial].pTextureFilename, -1, wszBuf, MAX_PATH );
					wszBuf[MAX_PATH - 1] = L'\0';
					if( FAILED( D3DXCreateTextureFromFile( pd3dDevice, wszBuf, 
						&pMeshContainer->ppTextures[iMaterial] ) ) )
						pMeshContainer->ppTextures[iMaterial] = NULL;
					
					pMeshContainer->pMaterials[iMaterial].pTextureFilename = NULL;
				}
			}
		}
		else{//没有材质,则添加一个默认值
			pMeshContainer->pMaterials[0].pTextureFilename = NULL;
			memset(&pMeshContainer->pMaterials[0].MatD3D, 0, sizeof(D3DMATERIAL9));
			pMeshContainer->pMaterials[0].MatD3D.Diffuse.r = 0.5f;
			pMeshContainer->pMaterials[0].MatD3D.Diffuse.g = 0.5f;
			pMeshContainer->pMaterials[0].MatD3D.Diffuse.b = 0.5f;
			pMeshContainer->pMaterials[0].MatD3D.Specular = pMeshContainer->pMaterials[0].MatD3D.Diffuse;
		}
		
		//存在蒙皮信息

		if (pSkinInfo != NULL){
			pMeshContainer->pSkinInfo = pSkinInfo;
			pSkinInfo->AddRef();
			
			pMeshContainer->pOrigMesh = pMesh;//备份指针

			pMesh->AddRef();
			
			cBones = pSkinInfo->GetNumBones();//取得总骨骼数

			//创建骨骼的权重矩阵
			pMeshContainer->pBoneOffsetMatrices = new D3DXMATRIX[cBones];
			if (pMeshContainer->pBoneOffsetMatrices == NULL){
				hr = E_OUTOFMEMORY;
				goto e_Exit;
			}
			
			//将骨骼的权重矩阵放置在性的位置处
			for (iBone = 0; iBone < cBones; iBone++){
				pMeshContainer->pBoneOffsetMatrices[iBone] = *(pMeshContainer->pSkinInfo->GetBoneOffsetMatrix(iBone));
			}
			
			//生成蒙皮网格
			hr = m_pSkinMesh->GenerateSkinnedMesh(pMeshContainer);
			if (FAILED(hr))
				goto e_Exit;
		}
		//返回网格容器的指针
		*ppNewMeshContainer = pMeshContainer;
		//释放无用指针
		pMeshContainer = NULL;

	e_Exit:
		SAFE_RELEASE(pd3dDevice);
		
		//释放网格容器
		if (pMeshContainer != NULL){
			DestroyMeshContainer(pMeshContainer);
		}
		
		return hr;
}

HRESULT CAllocateHierarchy::DestroyFrame(LPD3DXFRAME pFrameToFree) {
    SAFE_DELETE_ARRAY( pFrameToFree->Name );
    SAFE_DELETE( pFrameToFree );
    return S_OK; 
}

HRESULT CAllocateHierarchy::DestroyMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase){
    UINT iMaterial;
    D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
	
    SAFE_DELETE_ARRAY( pMeshContainer->Name );
    SAFE_DELETE_ARRAY( pMeshContainer->pAdjacency );
    SAFE_DELETE_ARRAY( pMeshContainer->pMaterials );
    SAFE_DELETE_ARRAY( pMeshContainer->pBoneOffsetMatrices );
	
	//释放所有纹理对象
    if (pMeshContainer->ppTextures != NULL){
        for (iMaterial = 0; iMaterial < pMeshContainer->NumMaterials; iMaterial++){
            SAFE_RELEASE( pMeshContainer->ppTextures[iMaterial] );
        }
    }
	
    SAFE_DELETE_ARRAY( pMeshContainer->ppTextures );
    SAFE_DELETE_ARRAY( pMeshContainer->ppBoneMatrixPtrs );
    SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );
    SAFE_RELEASE( pMeshContainer->MeshData.pMesh );
    SAFE_RELEASE( pMeshContainer->pSkinInfo );
    SAFE_RELEASE( pMeshContainer->pOrigMesh );
    SAFE_DELETE( pMeshContainer );
    return S_OK;
}

Game_SkinMesh::Game_SkinMesh():m_vMax(0,0,0),m_vMin(0,0,0){
	m_fElapsedTime=0.0f;
	g_sGlobal.g_pDevice->GetDeviceCaps( &m_d3dCaps );
	m_bMoving=TRUE;
    m_pAnimController = NULL;
    m_pFrameRoot = NULL;
    m_SkinningMethod =D3DINDEXED;
    m_pBoneMatrices = NULL;
    m_NumBoneMatricesMax = 0;

	m_bnextAnim=false;
	m_vMax=D3DXVECTOR3(0,0,0);
	m_vMin=D3DXVECTOR3(0,0,0);
	m_vTarget = D3DXVECTOR3(0,0,0);
	m_bMoving=TRUE;
	m_MouseMove=false;
	m_isMoving = false;
	m_bLoop	= false;
	m_isdead = false;
	m_isAttacking = false;
	m_BoundingBox=false;
	m_speed1 = 100.0f;
	m_speed2 = 3.0f;
	m_CurTime = 0.0;
	m_flotFrameTime = 0;
	m_fDeathTime = 0;
	m_pAABBMesh=NULL;
	m_vPos= D3DXVECTOR3(0,0,0);
	m_fAngle=0.0f;
	m_fScale=1.0f;

}

Game_SkinMesh::~Game_SkinMesh(){
	CAllocateHierarchy Alloc(this);
	D3DXFrameDestroy(m_pFrameRoot, &Alloc);
    SAFE_RELEASE(m_pAnimController);
}

HRESULT Game_SkinMesh::LoadFromXFile(WCHAR * strFileName,float scalex, float scalez){
    HRESULT    hr;
	CAllocateHierarchy Alloc(this);
	
    hr = D3DXLoadMeshHierarchyFromX(strFileName, D3DXMESH_MANAGED, g_sGlobal.g_pDevice, &Alloc, NULL, &m_pFrameRoot, &m_pAnimController);
    if (FAILED(hr))
        return hr;
	
    hr = SetupBoneMatrixPointers(m_pFrameRoot);
    if (FAILED(hr))
        return hr;
	
    hr = D3DXFrameCalculateBoundingSphere(m_pFrameRoot, &m_vObjectCenter, &m_fObjectRadius);
    if (FAILED(hr))
        return hr;

	D3DXMATRIXA16 matWorld,matWorld2,matWorld1;
	D3DXMatrixRotationZ(&matWorld2,m_fAngle+D3DX_PI);
	D3DXMatrixScaling(&matWorld,m_fScale,m_fScale,m_fScale);
	D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
	D3DXMatrixRotationX(&matWorld2,4.7f);
	D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
	D3DXMatrixRotationY(&matWorld2,1.5f);
	D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
	D3DXMatrixTranslation( &matWorld2,m_vPos.x,m_vPos.y,m_vPos.z);
	D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
	g_sGlobal.g_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
	
	if(m_pFrameRoot){
		D3DXMATRIX matIdentity;
		D3DXMatrixIdentity(&matIdentity); 
		UpdateFrameMatrices(m_pFrameRoot,&matWorld); 	
		CalculateStaticBondingBox(m_pFrameRoot,&m_vMin,&m_vMax); 
		m_vMin.x = m_vMin.x*0.5;
		m_vMax.x = m_vMax.x*0.5;
		m_vMin.z = m_vMin.z*0.5;
		m_vMax.z = m_vMax.z*0.5;
		D3DXCreateMeshFVF(4,8,D3DXMESH_MANAGED,D3DFVF_XYZ|D3DFVF_TEX1,g_sGlobal.g_pDevice,&m_pAABBMesh);
	}
	return S_OK;
}

//绑定盒子
HRESULT Game_SkinMesh::CalculateStaticBondingBox(LPD3DXFRAME pFrameBase, const LPD3DXVECTOR3 pVmin, 
											 const LPD3DXVECTOR3 pVmax){
	static LPD3DXMESH pMesh;
	static LPD3DXMATRIX pMat;

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

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


	while (pMeshContainer != NULL ){

⌨️ 快捷键说明

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