Tools are very important in game production, especially when you are working with someone who cannot write code. In my project, I worked with 2 artists, so I need to write some tools to export their models to my engine. There are different choices to export the models, you can parse.obj file format(for static model only), reading .fbx file using FBX SDK, reading COLLADA files… But I choose to extract it directly from the modeling package that the artists use – Writing Maya plugin to extract the model data.

To write Maya plugin for exporting models, we should know how data are stored in Maya first. Basically, Maya stores most of its data (e.g. meshes, transformation…) in a Directed Acyclic Graphic(DAG). In my case, I just need to locate those DAG nodes that store the mesh data. We can traverse the DAG using the iterator MItDag like this:

  1. MStatus status;
  2. MItDag dagIter( MItDag::kDepthFirst, MFn::kInvalid, &status );
  3. MDagPathArray meshPath;    // store the DAG nodes that contains mesh
  4. for ( ; !dagIter.isDone(); dagIter.next())
  5. {
  6.     MDagPath dagPath;
  7.     status = dagIter.getPath( dagPath );
  8.     if ( status )
  9.     {
  10.         MFnDagNode dagNode( dagPath, &status );
  11.         // Filter out the DAG nodes that do not contain mesh
  12.         if ( dagNode.isIntermediateObject()) continue;
  13.         if ( !dagPath.hasFn( MFn::kMesh )) continue;
  14.         if ( dagPath.hasFn( MFn::kTransform )) continue;
  15.         meshPath.append(dagPath);
  16.     }
  17. }

then, we can get the mesh data in the DAG nodes using the MFnMesh like this:

  1. for(int i=0; i< meshPath.length(); ++i)
  2. {
  3.     MDagPath dagPath= meshPath[i];
  4.     MFnMesh  fnMesh( dagPath );
  5.     MPointArray meshPoints;// store the position of vertices
  6.     fnMesh.getPoints( meshPoints, MSpace::kWorld );
  7.     // get more mesh data such as normals, UV…
  8. }

For the details of getting the mesh data, you may refer to MAYA API How-To and Maya Exporter Factfile. After getting the mesh data you can export them by creating a sub-class of the MPxFileTranslator and overwrite the writer() function. You can find some useful sample code provided by Maya inside the Maya directory (/Applications/Autodesk/maya2010/devkit/plugin-ins/ on Mac platform) such as the maTranslator.cpp and objExport.cpp.

Another reason I choose to write plugin instead of parsing .fbx/COLLADA is because of extracting the animation data. In my project, I just need to export some simple animations which linear interpolates between key frames, and I would like to get the key frames defined by artists in Maya. I have tried using the FBX SDK but when exporting animation data, it bakes all the animation frames as key frames… Using COLLADA get even worse because I cannot find a good exporter for Maya on the Mac platform… So writing Maya plugin can get rid of all these problems and get the data I want. I can also write a script for artists to set the animation clip data:

After exporting the mesh data, I think it would be nice to edit the collision geometry inside Maya, so I have written another plugin to define the collision shapes of the models:

This plugin works similar to the Dynamica Plugin (In fact, I learnt a lot from it.), except mine can just define simple shapes with only spheres, boxes and capsule shapes. And my plugin cannot do physics simulation inside Maya, it is just for defining the collision shapes. Those collision shapes (sphere/box/capsule) are just sub-class of MPxLocatorNode by overriding the draw() methods with some openGL calls to render the corresponding shapes.

In conclusions, extracting mesh data directly from Maya is not that hard. We can get all the data such as vertex normals, UV sets and key frame data from Maya and do not need to worry about the data loss during export through another formats, especially animation data. Also Maya provides a convenient API to get those data and it is easy to learn. After familiar with the Maya API, I can also write another plugin to define the collision shapes. Next time when you need to export mesh data, you may consider to extract them directly from the modeling package rather than parsing a file format.

Reference:
[1] MAYA API How-To: http://ewertb.soundlinker.com/api/api.018.php
[2] Maya Exporter Factfile: http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/research/index.htm
[3] Rob The Bloke: http://nccastaff.bournemouth.ac.uk/jmacey/RobTheBloke/www/
[4] http://www.vfxoverflow.com/questions/add-remove-framelayouts-in-a-window-using-mel
[5] http://bulletphysics.org/mediawiki-1.5.8/index.php/Maya_Dynamica_Plugin