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;
}
|