struct FaceVertex
{
int m_Index; //表示該頂點在原mesh里的索引值
int m_FaceIndex; //表示該頂點所屬的面在原mesh里的索引值
int m_TriIndex; //表示該頂點在所屬三角形里的索引值,值為0,1,2
bool operator == (const FaceVertex &refVertex)
{
if ( m_Index == refVertex.m_Index )
{
return true;
}
else
{
return false;
}
}
};
class MaxDivideMesh
{
public:
vector<FaceVertex> m_VertexArray;
vector<int> m_IndexArray;
};
void MyTreeEnum::CreateMutilMesh( INode *pNode, Mesh *pMesh, Mtl *pMtl )
{
vector <int> MeshMtls; //該Mesh用到的子材質的數量,用來計算子Mesh的劃分
//每個元素表示一個材質ID。
for( int i=0; i<pMesh->getNumFaces(); i++ )
{
/*計算子Mesh數量,通過計算所有面使用的非重復材質數量而得*/
int MatID = pMesh->getFaceMtlIndex(i);
vector<int>::iterator MatIndex = find( MeshMtls.begin(), MeshMtls.end(), MatID );
if ( MatIndex == MeshMtls.end() )
{
MeshMtls.push_back(MatID );//該材質未在MeshMtls里出現過,說明是個
//新材質
}
}
//DivideMeshArray,計算Mesh劃分的拓撲信息
vector<MaxDivideMesh> DivideMeshArray;
DivideMeshArray.resize( MeshMtls.size() );//指定劃分數量
//
//此處有內存的分配
//GMeshD3D是我自己設計的一個類型,用來表示一個子Mesh
//GTextureD3D用來表示Texture
GMeshD3D *pMeshArray = new GMeshD3D[MeshMtls.size()];
GTextureD3D *pTextureArray = new GTextureD3D[MeshMtls.size()];
GObjectMAXD3D tempObj; //GObjectMAXD3D表示一個模型,有n個mesh和texture組成
tempObj.SetMeshNum( MeshMtls.size() );
tempObj.SetTextureNum( MeshMtls.size() );
for ( int i=0; i<MeshMtls.size(); i++ )
{
if ( pMtl!=NULL )
{
Mtl *pSubMtl = pMtl->GetSubMtl( MeshMtls[i] );
Texmap *pTexMap = pSubMtl->GetSubTexmap(ID_DI); //獲取漫反射材質的貼//圖
BitmapTex *pBMPTex = (BitmapTex *) pTexMap;
if ( pBMPTex )
{
char *MapName = pBMPTex->GetMapName(); //獲取漫反射貼圖名稱
if ( MapName!=NULL )
{
pTextureArray[i].SetMapName(MapName);
}
}
pMeshArray[i].m_MatID = i;
tempObj.SetTexture( &pTextureArray[i], i );
}
}
/*這里開始對原有mesh進行重新劃分*/
for( int i=0; i<pMesh->getNumFaces(); i++ )
{
int MatID = pMesh->getFaceMtlIndex(i); //計算該面的材質ID
vector<int>::iterator MatIndex = find( MeshMtls.begin(), MeshMtls.end(), MatID );
int MeshID = MatIndex - MeshMtls.begin(); //計算該MatID在TextureArray的紋理索引,使MeshID從0開始編號
for ( int j=0; j<3; j++)
{
int Index = pMesh->faces[i].v[j];//Index表示在全局頂點數組里的索引
FaceVertex tempVertex;
tempVertex.m_Index = Index;
vector<FaceVertex>::iterator VertexIter = find( DivideMeshArray[MeshID].m_VertexArray.begin(),
DivideMeshArray[MeshID].m_VertexArray.end(), tempVertex );
if ( VertexIter == DivideMeshArray[MeshID].m_VertexArray.end() )
//在DivideMeshArray里尋找頂點索引值相同的頂點,如果沒找到該頂點,表示//要添加該頂點
{
int VertexIndex = VertexIter - DivideMeshArray[MeshID].m_VertexArray.begin();
FaceVertex tempFVertex;
tempFVertex.m_Index = Index;
tempFVertex.m_FaceIndex = i;
tempFVertex.m_TriIndex = j;
DivideMeshArray[MeshID].m_VertexArray.push_back( tempFVertex );
}
}
}
/*計算頂點在每個子mesh中的索引*/
for( int i=0; i<pMesh->getNumFaces(); i++ )
{
int MatID = pMesh->getFaceMtlIndex(i);
vector<int>::iterator MatIndex = find( MeshMtls.begin(), MeshMtls.end(), MatID );
int MeshID = MatIndex - MeshMtls.begin(); //計算該MatID的紋理索引
for ( int j=0; j<3; j++)
{
int Index = pMesh->faces[i].v[j];
FaceVertex tempVertex;
tempVertex.m_Index = Index;
//若在子mesh里能找到該點,則計算該點在子mesh的索引
vector<FaceVertex>::iterator VertexIter = find( DivideMeshArray[MeshID].m_VertexArray.begin(), DivideMeshArray[MeshID].m_VertexArray.end(), tempVertex );
if ( VertexIter != DivideMeshArray[MeshID].m_VertexArray.end() )
{
int VertexIndex = VertexIter - DivideMeshArray[MeshID].m_VertexArray.begin();//VertexIndex表//示該頂點在子Mesh的索引
DivideMeshArray[MeshID].m_IndexArray.push_back( VertexIndex );
}
}
}
/*余下部分開始到處頂點信息*/
for ( int i=0; i<MeshMtls.size(); i++ )
{
pMeshArray[i].SetFVF( GFVF );
pMeshArray[i].SetVerticeNum( DivideMeshArray[i].m_VertexArray.size() );
int VerticesNum;
pMeshArray[i].GetVerticeNum( VerticesNum );
for ( int j=0; j<VerticesNum; j++ )
{
GVertex tempVertex;
Point3 Coord,Normal,TCoord;
if( pMesh->getNumVerts()>0 ) //導出頂點坐標
{
int index = DivideMeshArray[i].m_VertexArray[j].m_Index;
Coord = pMesh->getVert(
DivideMeshArray[i].m_VertexArray[j].m_Index );
tempVertex.PosCoord = D3DXVECTOR3( Coord.x, Coord.y, -Coord.z );
}
if ( pMesh->faces ) //導出法線向量
{
Normal = pMesh->getNormal( DivideMeshArray[i].m_VertexArray[j].m_Index );
tempVertex.NormalVector = D3DXVECTOR3( Normal.x, Normal.y, Normal.z );
}
if ( pMesh->getNumTVerts()>0 )//導出紋理坐標
{
FaceVertex tempFVertex = DivideMeshArray[i].m_VertexArray[j];
TCoord = pMesh->tVerts[pMesh->tvFace[tempFVertex.m_FaceIndex].getTVert(tempFVertex.m_TriIndex)] ;
int TCoordIndex = pMesh->tvFace[tempFVertex.m_FaceIndex].getTVert(tempFVertex.m_TriIndex);
_cprintf( "TextureCoord Index%d"n", TCoordIndex );
tempVertex.TexCoord = D3DXVECTOR2( TCoord.x, TCoord.y );
}
DWORD VColor = 0xffffffff;
tempVertex.Color = VColor;
pMeshArray[i].SetVertex( tempVertex, j );
}
pMeshArray[i].SetFaceNum( DivideMeshArray[i].m_IndexArray.size()/3 );
WORD FaceNum;
pMeshArray[i].GetFaceNum( FaceNum );
for ( int j=0; j<FaceNum; j++ )
{
pMeshArray[i].SetIndex( DivideMeshArray[i].m_IndexArray[j*3], j*3 );
pMeshArray[i].SetIndex( DivideMeshArray[i].m_IndexArray[j*3+2], j*3+1 );
pMeshArray[i].SetIndex( DivideMeshArray[i].m_IndexArray[j*3+1], j*3+2 );
}
}
tempObj.WritetoFile();
delete []pMeshArray;
delete []pTextureArray;
}
|