3DXI Mesh

The IGameMesh object provides complete access to all the mesh relevant data including normals, mapping channels, tangents and binormals, vertex information, and texture coordinates. It also takes care of such things as mirroring, which is again something that can cause unexpected results when exporting as the normals will appear to be flipped.

Once you have an IGameMesh pointer, you can use its various methods to extract the data. Most face data (except mapping channel data) is provided in an extended face class called FaceEx. This is an extension to the 3ds Max class Face and includes additional indexing for vertex color, alpha, illumination and normals. Mapping channels are dealt with separately.

The following example shows how to extract the vertices and face data of the given mesh. The other data types are extracted in a similar way.

int numVerts = gm->GetNumberOfVerts();
for(int i = 0;i<numVerts;i++)
{
    TSTR data;
    Point3 v;
    if(gm->GetVertex(i,v))
    {
        //use the data here
    }
}

int numFaces = gm->GetNumberOfFaces();
for(int f=0;f<numFaces;f++)
{
    FaceEx * face = gm->GetFace(f);
    // use data here
} 

IGameMesh also provides access to Face data based on smoothing groups. For any particular smoothing group, a list of faces can be returned. This also applies to faces on a per material ID basis, with material lookup into the global material list based on the material ID from the face. This type of access is important for real-time display of the data as hardware has no concept of a multi-material, so the mesh needs to be split into smaller chunks based on the material at the face.

Mapping data found on the object is collected and stored. You simply query which channels have data and then access them in a similar manner to other data channels. Typically, you call GetMapFace() and GetMapFaceIndex() to access all the data. The following code is an example:

//gm is a pointer to IGameMesh
if(exportMappingChannel)
{
    Tab<int> mapNums = gm->GetActiveMapChannelNum();
    int mapCount = mapNums.Count();
    for(int i=0;i < mapCount;i++)
        int vCount = gm->GetNumberOfMapVerts(mapNums[i]);
    buf.printf("%d",vCount);
    for(int j=0;j<vCount;j++)
    {
        vert = NULL;
        Point3 v;
        if(gm->GetMapVertex(mapNums[i],j,v))
        {
             //use data here
        }
    }
    int fCount = gm->GetNumberOfFaces();
    for(int k=0;k<fCount;k++)
    {
        DWORD v[3];
        gm->GetMapFaceIndex(mapNums[i],k,v);
        //use data here
    }
}