/* =========================================================================== Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code"). Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 Source Code. If not, see . In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #define MAYA_DEFAULT_CAMERA "camera1" #define ANIM_TX BIT( 0 ) #define ANIM_TY BIT( 1 ) #define ANIM_TZ BIT( 2 ) #define ANIM_QX BIT( 3 ) #define ANIM_QY BIT( 4 ) #define ANIM_QZ BIT( 5 ) typedef enum { WRITE_MESH, WRITE_ANIM, WRITE_CAMERA } exportType_t; typedef struct { idCQuat q; idVec3 t; } jointFrame_t; typedef struct { idCQuat q; idVec3 t; float fov; } cameraFrame_t; /* ============================================================================================== idTokenizer ============================================================================================== */ class idTokenizer { private: int currentToken; idStrList tokens; public: idTokenizer() { Clear(); }; void Clear( void ) { currentToken = 0; tokens.Clear(); }; int SetTokens( const char *buffer ); const char *NextToken( const char *errorstring = NULL ); bool TokenAvailable( void ) { return currentToken < tokens.Num(); }; int Num( void ) { return tokens.Num(); }; void UnGetToken( void ) { if ( currentToken > 0 ) { currentToken--; } }; const char *GetToken( int index ) { if ( ( index >= 0 ) && ( index < tokens.Num() ) ) { return tokens[ index ]; } else { return NULL; } }; const char *CurrentToken( void ) { return GetToken( currentToken ); }; }; /* ============================================================================================== idExportOptions ============================================================================================== */ class idNamePair { public: idStr from; idStr to; }; class idAnimGroup { public: idStr name; idStrList joints; }; class idExportOptions { private: idTokenizer tokens; void Reset( const char *commandline ); public: idStr commandLine; idStr src; idStr dest; idStr game; idStr prefix; float scale; exportType_t type; bool ignoreMeshes; bool clearOrigin; bool clearOriginAxis; bool ignoreScale; int startframe; int endframe; int framerate; float xyzPrecision; float quatPrecision; idStr align; idList renamejoints; idList remapjoints; idStrList keepjoints; idStrList skipmeshes; idStrList keepmeshes; idList exportgroups; idList groups; float rotate; float jointThreshold; int cycleStart; idExportOptions( const char *commandline, const char *ospath ); bool jointInExportGroup( const char *jointname ); }; /* ============================================================================== idExportJoint ============================================================================== */ class idExportJoint { public: idStr name; idStr realname; idStr longname; int index; int exportNum; bool keep; float scale; float invscale; MFnDagNode *dagnode; idHierarchy mayaNode; idHierarchy exportNode; idVec3 t; idMat3 wm; idVec3 idt; idMat3 idwm; idVec3 bindpos; idMat3 bindmat; int animBits; int firstComponent; jointFrame_t baseFrame; int depth; idExportJoint(); idExportJoint &operator=( const idExportJoint &other ); }; /* ============================================================================== misc structures ============================================================================== */ typedef struct { idExportJoint *joint; float jointWeight; idVec3 offset; } exportWeight_t; typedef struct { idVec3 pos; idVec2 texCoords; int startweight; int numWeights; } exportVertex_t; typedef struct { int indexes[ 3 ]; } exportTriangle_t; typedef struct { idVec2 uv[ 3 ]; } exportUV_t; ID_INLINE int operator==( exportVertex_t a, exportVertex_t b ) { if ( a.pos != b.pos ) { return false; } if ( ( a.texCoords[ 0 ] != b.texCoords[ 0 ] ) || ( a.texCoords[ 1 ] != b.texCoords[ 1 ] ) ) { return false; } if ( ( a.startweight != b.startweight ) || ( a.numWeights != b.numWeights ) ) { return false; } return true; } /* ======================================================================== .MD3 triangle model file format ======================================================================== */ #define MD3_IDENT (('3'<<24)+('P'<<16)+('D'<<8)+'I') #define MD3_VERSION 15 // limits #define MD3_MAX_LODS 4 #define MD3_MAX_TRIANGLES 8192 // per surface #define MD3_MAX_VERTS 4096 // per surface #define MD3_MAX_SHADERS 256 // per surface #define MD3_MAX_FRAMES 1024 // per model #define MD3_MAX_SURFACES 32 // per model #define MD3_MAX_TAGS 16 // per frame // vertex scales #define MD3_XYZ_SCALE (1.0/64) // surface geometry should not exceed these limits #define SHADER_MAX_VERTEXES 1000 #define SHADER_MAX_INDEXES (6*SHADER_MAX_VERTEXES) // the maximum size of game reletive pathnames #define MAX_Q3PATH 64 typedef struct md3Frame_s { idVec3 bounds[2]; idVec3 localOrigin; float radius; char name[16]; } md3Frame_t; typedef struct md3Tag_s { char name[MAX_Q3PATH]; // tag name idVec3 origin; idVec3 axis[3]; } md3Tag_t; /* ** md3Surface_t ** ** CHUNK SIZE ** header sizeof( md3Surface_t ) ** shaders sizeof( md3Shader_t ) * numShaders ** triangles[0] sizeof( md3Triangle_t ) * numTriangles ** st sizeof( md3St_t ) * numVerts ** XyzNormals sizeof( md3XyzNormal_t ) * numVerts * numFrames */ typedef struct { int ident; // char name[MAX_Q3PATH]; // polyset name int flags; int numFrames; // all surfaces in a model should have the same int numShaders; // all surfaces in a model should have the same int numVerts; int numTriangles; int ofsTriangles; int ofsShaders; // offset from start of md3Surface_t int ofsSt; // texture coords are common for all frames int ofsXyzNormals; // numVerts * numFrames int ofsEnd; // next surface follows } md3Surface_t; typedef struct { char name[MAX_Q3PATH]; int shaderIndex; // for in-game use } md3Shader_t; typedef struct { int indexes[3]; } md3Triangle_t; typedef struct { float st[2]; } md3St_t; typedef struct { short xyz[3]; short normal; } md3XyzNormal_t; typedef struct { int ident; int version; char name[MAX_Q3PATH]; // model name int flags; int numFrames; int numTags; int numSurfaces; int numSkins; int ofsFrames; // offset for first frame int ofsTags; // numFrames * numTags int ofsSurfaces; // first surface, others follow int ofsEnd; // end of file } md3Header_t; /* ============================================================================== idExportMesh ============================================================================== */ class idExportMesh { public: idStr name; idStr shader; bool keep; idList verts; idList tris; idList weights; idList uv; idExportMesh() { keep = true; }; void ShareVerts( void ); void GetBounds( idBounds &bounds ) const; void Merge( idExportMesh *mesh ); }; /* ============================================================================== idExportModel ============================================================================== */ class idExportModel { public: idExportJoint *exportOrigin; idList joints; idHierarchy mayaHead; idHierarchy exportHead; idList cameraCuts; idList camera; idList bounds; idList jointFrames; idList frames; int frameRate; int numFrames; int skipjoints; int export_joints; idList meshes; idExportModel(); ~idExportModel(); idExportJoint *FindJointReal( const char *name ); idExportJoint *FindJoint( const char *name ); bool WriteMesh( const char *filename, idExportOptions &options ); bool WriteAnim( const char *filename, idExportOptions &options ); bool WriteCamera( const char *filename, idExportOptions &options ); }; /* ============================================================================== Maya ============================================================================== */ class idMayaExport { private: idExportModel model; idExportOptions &options; void FreeDagNodes( void ); float TimeForFrame( int num ) const; int GetMayaFrameNum( int num ) const; void SetFrame( int num ); void GetBindPose( MObject &jointNode, idExportJoint *joint, float scale ); void GetLocalTransform( idExportJoint *joint, idVec3 &pos, idMat3 &mat ); void GetWorldTransform( idExportJoint *joint, idVec3 &pos, idMat3 &mat, float scale ); void CreateJoints( float scale ); void PruneJoints( idStrList &keepjoints, idStr &prefix ); void RenameJoints( idList &renamejoints, idStr &prefix ); bool RemapParents( idList &remapjoints ); MObject FindShader( MObject& setNode ); void GetTextureForMesh( idExportMesh *mesh, MFnDagNode &dagNode ); idExportMesh *CopyMesh( MFnSkinCluster &skinCluster, float scale ); void CreateMesh( float scale ); void CombineMeshes( void ); void GetAlignment( idStr &alignName, idMat3 &align, float rotate, int startframe ); const char *GetObjectType( MObject object ); float GetCameraFov( idExportJoint *joint ); void GetCameraFrame( idExportJoint *camera, idMat3 &align, cameraFrame_t *cam ); void CreateCameraAnim( idMat3 &align ); void GetDefaultPose( idMat3 &align ); void CreateAnimation( idMat3 &align ); public: idMayaExport( idExportOptions &exportOptions ) : options( exportOptions ) { }; ~idMayaExport(); void ConvertModel( void ); void ConvertToMD3( void ); };