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

📄 game_skinmesh.cpp

📁 自己写的一个D3D游戏Dome。实现了基本的游戏功能
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		pMesh=pMeshContainer->MeshData.pMesh;    

		pMesh->LockVertexBuffer(0,(void**)&pV); 
		if(pMeshContainer->NumInfl>0){
			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;
}

//生成蒙皮网格
HRESULT Game_SkinMesh::GenerateSkinnedMesh(D3DXMESHCONTAINER_DERIVED *pMeshContainer){
    HRESULT hr = S_OK;

    if (pMeshContainer->pSkinInfo == NULL)
        return hr;

    SAFE_RELEASE( pMeshContainer->MeshData.pMesh );
    SAFE_RELEASE( pMeshContainer->pBoneCombinationBuf );

    if (m_SkinningMethod == D3DNONINDEXED){
		//生成包含顶点骨骼权重、骨骼矩阵表和索引等信息的蒙皮网格
        hr = pMeshContainer->pSkinInfo->ConvertToBlendedMesh
                                   (
                                       pMeshContainer->pOrigMesh,
                                       D3DXMESH_MANAGED|D3DXMESHOPT_VERTEXCACHE, 
                                       pMeshContainer->pAdjacency, 
                                       NULL, NULL, NULL, 
                                       &pMeshContainer->NumInfl,
                                       &pMeshContainer->NumAttributeGroups, 
                                       &pMeshContainer->pBoneCombinationBuf, 
                                       &pMeshContainer->MeshData.pMesh
                                   );
        if (FAILED(hr))
            goto e_Exit;
		
		LPD3DXBONECOMBINATION rgBoneCombinations  = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());

        for (pMeshContainer->iAttributeSW = 0; 
			pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups; 
			pMeshContainer->iAttributeSW++){

            DWORD cInfl   = 0;

            for (DWORD iInfl = 0; iInfl < pMeshContainer->NumInfl; iInfl++){
                if (rgBoneCombinations[pMeshContainer->iAttributeSW].BoneId[iInfl] != UINT_MAX){
                    ++cInfl;
                }
            }

            if (cInfl > m_d3dCaps.MaxVertexBlendMatrices){
                break;
            }
        }

        if (pMeshContainer->iAttributeSW < pMeshContainer->NumAttributeGroups){
            LPD3DXMESH pMeshTmp;

            hr = pMeshContainer->MeshData.pMesh->CloneMeshFVF(D3DXMESH_SOFTWAREPROCESSING|pMeshContainer->MeshData.pMesh->GetOptions(), 
                                                pMeshContainer->MeshData.pMesh->GetFVF(),
                                                g_sGlobal.g_pDevice, &pMeshTmp);
            if (FAILED(hr)){
                goto e_Exit;
            }

            pMeshContainer->MeshData.pMesh->Release();
            pMeshContainer->MeshData.pMesh = pMeshTmp;
            pMeshTmp = NULL;
        }
    }
    else if (m_SkinningMethod == D3DINDEXED){
        DWORD NumMaxFaceInfl;
        DWORD Flags = D3DXMESHOPT_VERTEXCACHE;

        LPDIRECT3DINDEXBUFFER9 pIB;
        hr = pMeshContainer->pOrigMesh->GetIndexBuffer(&pIB);
        if (FAILED(hr))
            goto e_Exit;

        hr = pMeshContainer->pSkinInfo->GetMaxFaceInfluences(pIB, pMeshContainer->pOrigMesh->GetNumFaces(), &NumMaxFaceInfl);
        pIB->Release();
        if (FAILED(hr))
            goto e_Exit;

        NumMaxFaceInfl = min(NumMaxFaceInfl, 12);

        if (m_d3dCaps.MaxVertexBlendMatrixIndex + 1 < NumMaxFaceInfl){
            pMeshContainer->NumPaletteEntries = min(256, pMeshContainer->pSkinInfo->GetNumBones());
            pMeshContainer->UseSoftwareVP = true;
            Flags |= D3DXMESH_SYSTEMMEM;
        }
        else{
            pMeshContainer->NumPaletteEntries = min( ( m_d3dCaps.MaxVertexBlendMatrixIndex + 1 ) / 2, 
                                                     pMeshContainer->pSkinInfo->GetNumBones() );
            pMeshContainer->UseSoftwareVP = false;
            Flags |= D3DXMESH_MANAGED;
        }

        hr = pMeshContainer->pSkinInfo->ConvertToIndexedBlendedMesh
                                                (
                                                pMeshContainer->pOrigMesh,
                                                Flags, 
                                                pMeshContainer->NumPaletteEntries, 
                                                pMeshContainer->pAdjacency, 
                                                NULL, NULL, NULL, 
                                                &pMeshContainer->NumInfl,
                                                &pMeshContainer->NumAttributeGroups, 
                                                &pMeshContainer->pBoneCombinationBuf, 
                                                &pMeshContainer->MeshData.pMesh);
        if (FAILED(hr))
            goto e_Exit;
    }
    else if (m_SkinningMethod == SOFTWARE){
        hr = pMeshContainer->pOrigMesh->CloneMeshFVF(D3DXMESH_MANAGED, pMeshContainer->pOrigMesh->GetFVF(),
                                              g_sGlobal.g_pDevice, &pMeshContainer->MeshData.pMesh);
        if (FAILED(hr))
            goto e_Exit;

        hr = pMeshContainer->MeshData.pMesh->GetAttributeTable(NULL, &pMeshContainer->NumAttributeGroups);
        if (FAILED(hr))
            goto e_Exit;

        delete[] pMeshContainer->pAttributeTable;
        pMeshContainer->pAttributeTable  = new D3DXATTRIBUTERANGE[pMeshContainer->NumAttributeGroups];
        if (pMeshContainer->pAttributeTable == NULL){
            hr = E_OUTOFMEMORY;
            goto e_Exit;
        }

        hr = pMeshContainer->MeshData.pMesh->GetAttributeTable(pMeshContainer->pAttributeTable, NULL);
        if (FAILED(hr))
            goto e_Exit;

        if (m_NumBoneMatricesMax < pMeshContainer->pSkinInfo->GetNumBones()){
            m_NumBoneMatricesMax = pMeshContainer->pSkinInfo->GetNumBones();

            delete []m_pBoneMatrices; 
            m_pBoneMatrices  = new D3DXMATRIXA16[m_NumBoneMatricesMax];
            if (m_pBoneMatrices == NULL){
                hr = E_OUTOFMEMORY;
                goto e_Exit;
            }
        }
    }
    else{        
        hr = E_INVALIDARG;
        goto e_Exit;
    }

e_Exit:
    return hr;
}



HRESULT Game_SkinMesh::SetupBoneMatrixPointers(LPD3DXFRAME pFrame){
    HRESULT hr;

    if (pFrame->pMeshContainer != NULL){	//左序遍历
        hr = SetupBoneMatrixPointersOnMesh(pFrame->pMeshContainer);
        if (FAILED(hr))
            return hr;
    }

    if (pFrame->pFrameSibling != NULL){
        hr = SetupBoneMatrixPointers(pFrame->pFrameSibling);
        if (FAILED(hr))
            return hr;
    }

    if (pFrame->pFrameFirstChild != NULL){
        hr = SetupBoneMatrixPointers(pFrame->pFrameFirstChild);
        if (FAILED(hr))
            return hr;
    }

    return S_OK;
}

HRESULT Game_SkinMesh::SetupBoneMatrixPointersOnMesh(LPD3DXMESHCONTAINER pMeshContainerBase){
    UINT iBone, cBones;
    D3DXFRAME_DERIVED *pFrame;

    D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;

	//蒙皮动画,则设置骨骼的变换矩阵
	//存在蒙皮数据,取出骨骼矩阵,放入矩阵表ppBoneMatrixPtrs中
    if (pMeshContainer->pSkinInfo != NULL){
        cBones = pMeshContainer->pSkinInfo->GetNumBones();

        pMeshContainer->ppBoneMatrixPtrs = new D3DXMATRIX*[cBones];	//创建骨骼
        if (pMeshContainer->ppBoneMatrixPtrs == NULL)
            return E_OUTOFMEMORY;

        for (iBone = 0; iBone < cBones; iBone++){
			//找到骨骼所在的Frame
            pFrame = (D3DXFRAME_DERIVED*)D3DXFrameFind(m_pFrameRoot, 
				pMeshContainer->pSkinInfo->GetBoneName(iBone));

            if (pFrame == NULL)
                return E_FAIL;
			//初始化矩阵
            pMeshContainer->ppBoneMatrixPtrs[iBone] = &pFrame->CombinedTransformationMatrix;
        }
    }

    return S_OK;
}

VOID Game_SkinMesh::Render(float fElapsedAppTime,D3DXVECTOR3 vPos,float angle,float scale,bool change){
	if(m_BoundingBox){
		D3DXVECTOR3 vMin,vMax;
		vMin=m_vMin;
		vMax=m_vMax;
		GetBoundingBox(&vMin,&vMax);
		RenderAABB(&vMin,&vMax);//画出盒子
	}
   // if( 0.00f == fElapsedAppTime )    return;
	m_fElapsedTime = fElapsedAppTime;
	D3DXMATRIXA16 matWorld,matWorld2,matWorld1;
	if(change){
		D3DXMatrixRotationZ(&matWorld2,angle+D3DX_PI);
		D3DXMatrixScaling(&matWorld,scale,scale,scale);
		D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
		D3DXMatrixRotationX(&matWorld2,4.7f);
		D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
		D3DXMatrixRotationY(&matWorld2,1.5f);
		D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
		D3DXMatrixTranslation( &matWorld2,vPos.x,vPos.y,vPos.z);
		D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
	}
	else{
		D3DXMatrixRotationY(&matWorld2,angle+D3DX_PI);
		D3DXMatrixScaling(&matWorld,scale,scale,scale);

		D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);

		D3DXMatrixTranslation( &matWorld2, vPos.x, vPos.y,vPos.z );

		D3DXMatrixMultiply(&matWorld,&matWorld,&matWorld2);
	}

	m_matWorld=matWorld;

	if(m_pAnimController){
		if (m_bMoving)

#if (D3D_SDK_VERSION &31)
			m_pAnimController->SetTime(m_pAnimController->GetTime()+m_fElapsedTime );
		else
			m_pAnimController->SetTime(0);
			
#else 
			m_pAnimController->AdvanceTime(m_fElapsedTime,NULL); 
		else
			m_pAnimController->ResetTime();
#endif

	}
	
    UpdateFrameMatrices(m_pFrameRoot, &matWorld);
	DrawFrame(m_pFrameRoot);
}




VOID Game_SkinMesh::DrawFrame(LPD3DXFRAME pFrame){
    LPD3DXMESHCONTAINER pMeshContainer;
	
    pMeshContainer = pFrame->pMeshContainer;
    while (pMeshContainer != NULL){
        DrawMeshContainer(pMeshContainer, pFrame);
        pMeshContainer = pMeshContainer->pNextMeshContainer;
    }
	
    if (pFrame->pFrameSibling != NULL){
        DrawFrame(pFrame->pFrameSibling);
    }
	
    if (pFrame->pFrameFirstChild != NULL){
        DrawFrame(pFrame->pFrameFirstChild);
    }
}

VOID Game_SkinMesh::DrawMeshContainer(LPD3DXMESHCONTAINER pMeshContainerBase, LPD3DXFRAME pFrameBase){
	D3DXMESHCONTAINER_DERIVED *pMeshContainer = (D3DXMESHCONTAINER_DERIVED*)pMeshContainerBase;
	D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED*)pFrameBase;
	UINT iMaterial;
	UINT NumBlend;
	UINT iAttrib;
	DWORD AttribIdPrev;
	LPD3DXBONECOMBINATION pBoneComb;

	UINT iMatrixIndex;
	UINT iPaletteEntry;
	D3DXMATRIXA16 matTemp;

	if (pMeshContainer->pSkinInfo != NULL){
		if (m_SkinningMethod == D3DNONINDEXED){
			AttribIdPrev = UNUSED32; 
			pBoneComb = reinterpret_cast<LPD3DXBONECOMBINATION>(pMeshContainer->pBoneCombinationBuf->GetBufferPointer());

			for (iAttrib = 0; iAttrib < pMeshContainer->NumAttributeGroups; iAttrib++){
				NumBlend = 0;
				for (DWORD i = 0; i < pMeshContainer->NumInfl; ++i){
					if (pBoneComb[iAttrib].BoneId[i] != UINT_MAX){
						NumBlend = i;
					}

⌨️ 快捷键说明

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