29 #include "../idlib/precompiled.h"
32 #include "Maya5.0/maya.h"
40 #define DEFAULT_ANIM_EPSILON 0.125f
41 #define DEFAULT_QUAT_EPSILON ( 1.0f / 8192.0f )
43 #define SLOP_VERTEX 0.01f // merge xyz coordinates this far apart
44 #define SLOP_TEXCOORD 0.001f // merge texture coordinates this far apart
63 va_start( argptr, fmt );
75 #define MAX_PRINT_MSG 4096
76 static int WriteFloatString( FILE *file,
const char *fmt, ... ) {
85 va_start( argPtr, fmt );
94 while ( (*fmt >=
'0' && *fmt <=
'9') ||
95 *fmt ==
'.' || *fmt ==
'-' || *fmt ==
'+' || *fmt ==
'#') {
105 f = va_arg( argPtr,
double );
106 if ( format.
Length() <= 2 ) {
111 index += fprintf( file,
"%s", tmp.
c_str() );
114 index += fprintf( file, format.
c_str(),
f );
119 i = va_arg( argPtr,
long );
120 index += fprintf( file, format.
c_str(),
i );
123 u = va_arg( argPtr,
unsigned long );
124 index += fprintf( file, format.
c_str(), u );
127 u = va_arg( argPtr,
unsigned long );
128 index += fprintf( file, format.
c_str(), u );
131 u = va_arg( argPtr,
unsigned long );
132 index += fprintf( file, format.
c_str(), u );
135 u = va_arg( argPtr,
unsigned long );
136 index += fprintf( file, format.
c_str(), u );
139 i = va_arg( argPtr,
long );
140 index += fprintf( file, format.
c_str(), (char) i );
143 str = va_arg( argPtr,
char * );
144 index += fprintf( file, format.
c_str(), str );
147 index += fprintf( file, format.
c_str() );
150 MayaError(
"WriteFloatString: invalid format %s", format.
c_str() );
159 index += fprintf( file,
"\t" );
162 index += fprintf( file,
"\n" );
164 MayaError(
"WriteFloatString: unknown escape character \'%c\'", *fmt );
170 index += fprintf( file,
"%c", *fmt );
204 if ( base ==
NULL && strlen(game) > 0 ) {
206 base = s = (
char *)strstr( osPath, game );
208 while( s = strstr( s, game ) ) {
210 if ( s[0] ==
'/' || s[0] ==
'\\' ) {
217 s = strstr( base,
"/" );
219 s = strstr( base,
"\\" );
227 common->
Printf(
"OSPathToRelativePath failed on %s\n", osPath );
241 mat[ 0 ][ 0 ] = idmat[ 0 ][ 0 ];
242 mat[ 0 ][ 2 ] = -idmat[ 0 ][ 1 ];
243 mat[ 0 ][ 1 ] = idmat[ 0 ][ 2 ];
245 mat[ 1 ][ 0 ] = idmat[ 1 ][ 0 ];
246 mat[ 1 ][ 2 ] = -idmat[ 1 ][ 1 ];
247 mat[ 1 ][ 1 ] = idmat[ 1 ][ 2 ];
249 mat[ 2 ][ 0 ] = idmat[ 2 ][ 0 ];
250 mat[ 2 ][ 2 ] = -idmat[ 2 ][ 1 ];
251 mat[ 2 ][ 1 ] = idmat[ 2 ][ 2 ];
279 idmat[ 0 ][ 0 ] = mat[ 0 ][ 0 ];
280 idmat[ 0 ][ 1 ] = -mat[ 0 ][ 2 ];
281 idmat[ 0 ][ 2 ] = mat[ 0 ][ 1 ];
283 idmat[ 1 ][ 0 ] = mat[ 1 ][ 0 ];
284 idmat[ 1 ][ 1 ] = -mat[ 1 ][ 2 ];
285 idmat[ 1 ][ 2 ] = mat[ 1 ][ 1 ];
287 idmat[ 2 ][ 0 ] = mat[ 2 ][ 0 ];
288 idmat[ 2 ][ 1 ] = -mat[ 2 ][ 2 ];
289 idmat[ 2 ][ 2 ] = mat[ 2 ][ 1 ];
315 return idVec3( point[ 0 ], point[ 1 ], point[ 2 ] );
324 return idVec3( matrix[ 3 ][ 0 ], matrix[ 3 ][ 1 ], matrix[ 3 ][ 2 ] );
336 for( j = 0; j < 3; j++ ) {
337 for( k = 0; k < 3; k++ ) {
338 mat[
j ][ k ] = matrix[
j ][ k ];
352 MObject parentObject;
354 parentObject = joint->parent( 0, &status );
355 if ( !status && status.statusCode() == MStatus::kInvalidParameter ) {
359 while( !parentObject.hasFn( MFn::kTransform ) ) {
360 MFnDagNode parentNode( parentObject, &status );
365 parentObject = parentNode.parent( 0, &status );
366 if ( !status && status.statusCode() == MStatus::kInvalidParameter ) {
371 MFnDagNode *parentNode;
373 parentNode =
new MFnDagNode( parentObject, &status );
404 while( *cmd && isspace( *cmd ) ) {
413 while( *cmd && !isspace( *cmd ) ) {
498 Reset( commandline );
501 if ( token ==
"mesh" ) {
503 }
else if ( token ==
"anim" ) {
505 }
else if ( token ==
"camera" ) {
515 if ( token ==
"-force" ) {
517 }
else if ( token ==
"-game" ) {
521 }
else if ( token ==
"-rename" ) {
523 joints.
from =
tokens.
NextToken(
"Missing joint name for -rename. Usage: -rename [joint name] [new name]" );
524 joints.
to =
tokens.
NextToken(
"Missing new name for -rename. Usage: -rename [joint name] [new name]" );
527 }
else if ( token ==
"-prefix" ) {
530 }
else if ( token ==
"-parent" ) {
532 joints.
from =
tokens.
NextToken(
"Missing joint name for -parent. Usage: -parent [joint name] [new parent]" );
533 joints.
to =
tokens.
NextToken(
"Missing new parent for -parent. Usage: -parent [joint name] [new parent]" );
536 }
else if ( !token.
Icmp(
"-sourcedir" ) ) {
538 sourceDir =
tokens.
NextToken(
"Missing filename for -sourcedir. Usage: -sourcedir [directory]" );
540 }
else if ( !token.
Icmp(
"-destdir" ) ) {
542 destDir =
tokens.
NextToken(
"Missing filename for -destdir. Usage: -destdir [directory]" );
544 }
else if ( token ==
"-dest" ) {
548 }
else if ( token ==
"-range" ) {
550 token =
tokens.
NextToken(
"Missing start frame for -range. Usage: -range [start frame] [end frame]" );
552 token =
tokens.
NextToken(
"Missing end frame for -range. Usage: -range [start frame] [end frame]" );
556 MayaError(
"Start frame is greater than end frame." );
559 }
else if ( !token.
Icmp(
"-cycleStart" ) ) {
561 token =
tokens.
NextToken(
"Missing cycle start frame for -cycleStart. Usage: -cycleStart [first frame of cycle]" );
564 }
else if ( token ==
"-scale" ) {
566 token =
tokens.
NextToken(
"Missing scale amount for -scale. Usage: -scale [scale amount]" );
567 scale = atof( token );
569 }
else if ( token ==
"-align" ) {
573 }
else if ( token ==
"-rotate" ) {
575 token =
tokens.
NextToken(
"Missing value for -rotate. Usage: -rotate [yaw]" );
578 }
else if ( token ==
"-nomesh" ) {
581 }
else if ( token ==
"-clearorigin" ) {
585 }
else if ( token ==
"-clearoriginaxis" ) {
588 }
else if ( token ==
"-ignorescale" ) {
591 }
else if ( token ==
"-xyzprecision" ) {
593 token =
tokens.
NextToken(
"Missing value for -xyzprecision. Usage: -xyzprecision [precision]" );
596 MayaError(
"Invalid value for -xyzprecision. Must be >= 0" );
599 }
else if ( token ==
"-quatprecision" ) {
601 token =
tokens.
NextToken(
"Missing value for -quatprecision. Usage: -quatprecision [precision]" );
604 MayaError(
"Invalid value for -quatprecision. Must be >= 0" );
607 }
else if ( token ==
"-jointthreshold" ) {
609 token =
tokens.
NextToken(
"Missing weight for -jointthreshold. Usage: -jointthreshold [minimum joint weight]" );
612 }
else if ( token ==
"-skipmesh" ) {
613 token =
tokens.
NextToken(
"Missing name for -skipmesh. Usage: -skipmesh [name of mesh to skip]" );
616 }
else if ( token ==
"-keepmesh" ) {
617 token =
tokens.
NextToken(
"Missing name for -keepmesh. Usage: -keepmesh [name of mesh to keep]" );
620 }
else if ( token ==
"-jointgroup" ) {
621 token =
tokens.
NextToken(
"Missing name for -jointgroup. Usage: -jointgroup [group name] [joint1] [joint2]...[joint n]" );
623 for( i = 0; i <
groups.
Num(); i++, group++ ) {
624 if ( group->
name == token ) {
637 if ( token[ 0 ] ==
'-' ) {
644 }
else if ( token ==
"-group" ) {
648 if ( token[ 0 ] ==
'-' ) {
654 for( i = 0; i <
groups.
Num(); i++, group++ ) {
655 if ( group->
name == token ) {
666 }
else if ( token ==
"-keep" ) {
670 if ( token[ 0 ] ==
'-' ) {
685 src.AppendPath( token );
694 src.BackSlashesToSlashes();
698 MayaError(
"Can't use -keepmesh and -skipmesh together." );
720 for( j = 0; j < group->
joints.
Num(); j++ ) {
721 if ( group->
joints[ j ] == jointname ) {
808 for( i = 0; i <
tris.
Num(); i++ ) {
809 for( j = 0; j < 3; j++ ) {
810 vert = v[
tris[
i ].indexes[
j ] ];
814 for( k = 0; k <
verts.
Num(); k++ ) {
832 tris[
i ].indexes[
j ] = k;
853 for( i = 0; i < mesh->
verts.
Num(); i++ ) {
861 for( i = 0; i < mesh->
tris.
Num(); i++ ) {
862 tris[ numtris +
i ].indexes[ 0 ] = mesh->
tris[
i ].indexes[ 0 ] + numverts;
863 tris[ numtris +
i ].indexes[ 1 ] = mesh->
tris[
i ].indexes[ 1 ] + numverts;
864 tris[ numtris +
i ].indexes[ 2 ] = mesh->
tris[
i ].indexes[ 2 ] + numverts;
877 for( i = 0; i < mesh->
uv.
Num(); i++ ) {
878 uv[ numuvs +
i ] = mesh->
uv[
i ];
893 for( i = 0; i <
verts.
Num(); i++, vert++ ) {
896 for( j = 0; j < vert->
numWeights; j++, weight++ ) {
938 for( i = 0; i <
joints.
Num(); i++, joint++ ) {
952 for( i = 0; i <
joints.
Num(); i++, joint++ ) {
953 if ( joint->
name == name ) {
969 const char *parentName;
973 file = fopen( filename,
"w" );
979 jointList.
Append( joint );
982 for( i = 0; i < jointList.
Num(); i++ ) {
983 joint = jointList[
i ];
1003 if (
meshes[ i ]->keep ) {
1011 WriteFloatString( file,
"commandline \"%s\"\n\n", options.
commandLine.
c_str() );
1014 WriteFloatString( file,
"numJoints %d\n", jointList.
Num() );
1015 WriteFloatString( file,
"numMeshes %d\n\n", numMeshes );
1017 WriteFloatString( file,
"joints {\n" );
1018 for( i = 0; i < jointList.
Num(); i++ ) {
1019 joint = jointList[
i ];
1030 WriteFloatString( file,
"\t\"%s\"\t%d ( %f %f %f ) ( %f %f %f )\t\t// %s\n", joint->
name.
c_str(), parentNum,
1033 WriteFloatString( file,
"}\n" );
1038 if ( !mesh->
keep ) {
1042 WriteFloatString( file,
"\nmesh {\n" );
1043 WriteFloatString( file,
"\t// meshes: %s\n", mesh->
name.
c_str() );
1044 WriteFloatString( file,
"\tshader \"%s\"\n", mesh->
shader.
c_str() );
1046 WriteFloatString( file,
"\n\tnumverts %d\n", mesh->
verts.
Num() );
1047 for( j = 0; j < mesh->
verts.
Num(); j++ ) {
1048 WriteFloatString( file,
"\tvert %d ( %f %f ) %d %d\n", j, mesh->
verts[ j ].texCoords[ 0 ], mesh->
verts[ j ].texCoords[ 1 ],
1049 mesh->
verts[ j ].startweight, mesh->
verts[ j ].numWeights );
1052 WriteFloatString( file,
"\n\tnumtris %d\n", mesh->
tris.
Num() );
1053 for( j = 0; j < mesh->
tris.
Num(); j++ ) {
1054 WriteFloatString( file,
"\ttri %d %d %d %d\n", j, mesh->
tris[ j ].indexes[ 2 ], mesh->
tris[ j ].indexes[ 1 ], mesh->
tris[ j ].indexes[ 0 ] );
1057 WriteFloatString( file,
"\n\tnumweights %d\n", mesh->
weights.
Num() );
1062 WriteFloatString( file,
"\tweight %d %d %f ( %f %f %f )\n", j,
1066 WriteFloatString( file,
"}\n" );
1081 int numAnimatedComponents;
1084 file = fopen( filename,
"w" );
1090 jointList.
Append( joint );
1093 for( i = 0; i < jointList.
Num(); i++ ) {
1094 joint = jointList[
i ];
1111 numAnimatedComponents = 0;
1112 for( i = 0; i < jointList.
Num(); i++ ) {
1113 joint = jointList[
i ];
1137 if ( ( joint->
animBits & 63 ) == 63 ) {
1143 for( j = 0; j < 6; j++ ) {
1145 numAnimatedComponents++;
1153 WriteFloatString( file,
"commandline \"%s\"\n\n", options.
commandLine.
c_str() );
1155 WriteFloatString( file,
"numFrames %d\n",
numFrames );
1156 WriteFloatString( file,
"numJoints %d\n", jointList.
Num() );
1157 WriteFloatString( file,
"frameRate %d\n",
frameRate );
1158 WriteFloatString( file,
"numAnimatedComponents %d\n", numAnimatedComponents );
1161 WriteFloatString( file,
"\nhierarchy {\n" );
1162 for( i = 0; i < jointList.
Num(); i++ ) {
1163 joint = jointList[
i ];
1172 WriteFloatString( file,
"\n" );
1174 WriteFloatString( file,
" ( " );
1175 for( j = 0; j < 6; j++ ) {
1180 WriteFloatString( file,
")\n" );
1183 WriteFloatString( file,
"}\n" );
1186 WriteFloatString( file,
"\nbounds {\n" );
1190 WriteFloatString( file,
"}\n" );
1193 WriteFloatString( file,
"\nbaseframe {\n" );
1194 for( i = 0; i < jointList.
Num(); i++ ) {
1195 joint = jointList[
i ];
1199 WriteFloatString( file,
"}\n" );
1203 WriteFloatString( file,
"\nframe %d {\n", i );
1204 for( j = 0; j < jointList.
Num(); j++ ) {
1205 joint = jointList[
j ];
1208 WriteFloatString( file,
"\t" );
1210 WriteFloatString( file,
" %f", frame->
t[ 0 ] );
1213 WriteFloatString( file,
" %f", frame->
t[ 1 ] );
1216 WriteFloatString( file,
" %f", frame->
t[ 2 ] );
1219 WriteFloatString( file,
" %f", frame->
q[ 0 ] );
1222 WriteFloatString( file,
" %f", frame->
q[ 1 ] );
1225 WriteFloatString( file,
" %f", frame->
q[ 2 ] );
1227 WriteFloatString( file,
"\n" );
1230 WriteFloatString( file,
"}\n" );
1242 file = fopen( filename,
"w" );
1249 WriteFloatString( file,
"commandline \"%s\"\n\n", options.
commandLine.
c_str() );
1251 WriteFloatString( file,
"numFrames %d\n",
camera.
Num() );
1252 WriteFloatString( file,
"frameRate %d\n",
frameRate );
1256 WriteFloatString( file,
"\ncuts {\n" );
1258 WriteFloatString( file,
"\t%d\n",
cameraCuts[ i ] );
1260 WriteFloatString( file,
"}\n" );
1263 WriteFloatString( file,
"\ncamera {\n" );
1265 for( i = 0; i <
camera.
Num(); i++, frame++ ) {
1266 WriteFloatString( file,
"\t( %f %f %f ) ( %f %f %f ) %f\n", frame->
t.
x, frame->
t.
y, frame->
t.
z, frame->
q[ 0 ], frame->
q[ 1 ], frame->
q[ 2 ], frame->
fov );
1268 WriteFloatString( file,
"}\n" );
1293 MFileIO::newFile(
true );
1305 time.setUnit( MTime::kFilm );
1306 time.setValue( num );
1307 return time.as( MTime::kSeconds );
1353 time.setUnit( MTime::kFilm );
1354 time.setValue( frameNum );
1355 MGlobal::viewFrame( time );
1373 if ( !keepjoints.
Num() && !prefix.
Length() ) {
1384 mesh->
weights[
j ].joint->keep =
true;
1390 for( i = 0; i < keepjoints.
Num(); i++ ) {
1402 if ( mesh->
weights[ j ].joint->keep ) {
1404 }
else if ( prefix.
Length() && !mesh->
weights[
j ].joint->realname.Cmpn( prefix, prefix.
Length() ) ) {
1406 mesh->
weights[
j ].joint->keep =
true;
1421 if ( !joint->
keep ) {
1429 if ( parent->
keep ) {
1434 if ( parent !=
NULL ) {
1444 if ( !joint->
keep ) {
1449 if ( ( joint2 != joint ) && ( joint2->
name == joint->
name ) ) {
1477 MFnDependencyNode fnJoint( jointNode );
1478 MObject aBindPose = fnJoint.attribute(
"bindPose", &status );
1483 if ( MS::kSuccess == status ) {
1485 unsigned jointIndex;
1486 unsigned connLength;
1487 MPlugArray connPlugs;
1488 MPlug pBindPose( jointNode, aBindPose );
1490 pBindPose.connectedTo( connPlugs,
false,
true );
1491 connLength = connPlugs.length();
1492 for( ii = 0; ii < connLength; ++ii ) {
1493 if ( connPlugs[ ii ].node().apiType() == MFn::kDagPose ) {
1494 MObject aMember = connPlugs[ ii ].attribute();
1495 MFnAttribute fnAttr( aMember );
1497 if ( fnAttr.name() ==
"worldMatrix" ) {
1498 jointIndex = connPlugs[ ii ].logicalIndex();
1500 MFnDependencyNode nDagPose( connPlugs[ ii ].node() );
1503 MObject aWorldMatrix = nDagPose.attribute(
"worldMatrix" );
1504 MPlug pWorldMatrix( connPlugs[ ii ].node(), aWorldMatrix );
1506 pWorldMatrix.selectAncestorLogicalIndex( jointIndex, aWorldMatrix );
1509 MObject worldMatrix;
1510 MStatus status = pWorldMatrix.getValue( worldMatrix );
1511 if ( MS::kSuccess != status ) {
1516 MFnMatrixData dMatrix( worldMatrix );
1517 MMatrix wMatrix = dMatrix.matrix( &status );
1524 joint->
bindmat[ 0 ].Normalize();
1525 joint->
bindmat[ 1 ].Normalize();
1526 joint->
bindmat[ 2 ].Normalize();
1552 status = joint->
dagnode->getPath( dagPath );
1557 MObject transformNode = dagPath.transform( &status );
1558 if ( !status && ( status.statusCode () == MStatus::kInvalidParameter ) ) {
1562 MFnDagNode
transform( transformNode, &status );
1567 pos =
idVec( transform.transformationMatrix() );
1568 mat =
idMat( transform.transformationMatrix() );
1590 pos = parentpos + ( parentmat * ( pos * parent->
scale ) );
1591 mat = mat * parentmat;
1607 MFnDagNode *parentNode;
1612 MItDag dagIterator( MItDag::kDepthFirst, MFn::kTransform, &status );
1613 for ( ; !dagIterator.isDone(); dagIterator.next() ) {
1614 status = dagIterator.getPath( dagPath );
1616 MayaError(
"CreateJoints: MItDag::getPath failed (%s)", status.errorString().asChar() );
1622 joint->
dagnode =
new MFnDagNode( dagPath, &status );
1624 MayaError(
"CreateJoints: MFnDagNode constructor failed (%s)", status.errorString().asChar() );
1652 if (
model.
joints[ j ].dagnode->name() == parentNode->name() ) {
1672 joint->
scale = joint->
wm[ 0 ].Length();
1676 if ( joint->
scale != 0 ) {
1683 joint->
dagnode->getPath( dagPath );
1709 for( i = 0; i < renamejoints.
Num(); i++ ) {
1712 joint->
name = renamejoints[
i ].to;
1729 for( i = 0; i < remapjoints.
Num(); i++ ) {
1734 MayaError(
"Couldn't find joint '%s' to reparent\n", remapjoints[ i ].from.c_str() );
1741 MayaError(
"Couldn't find joint '%s' to be new parent for '%s'\n", remapjoints[ i ].to.c_str(), remapjoints[
i ].from.c_str() );
1755 origin->
name =
"origin";
1764 origin->
keep =
true;
1770 if ( joint != origin ) {
1788 MFnDependencyNode fnNode( setNode );
1791 shaderPlug = fnNode.findPlug(
"surfaceShader" );
1792 if ( !shaderPlug.isNull() ) {
1793 MPlugArray connectedPlugs;
1796 shaderPlug.connectedTo( connectedPlugs, asDst, asSrc, &status );
1798 if ( connectedPlugs.length() != 1 ) {
1799 MayaError(
"FindShader: Error getting shader (%s)", status.errorString().asChar() );
1801 return connectedPlugs[ 0 ].node();
1805 return MObject::kNullObj;
1822 status = dagNode.getPath( path );
1827 path.extendToShape();
1833 if ( path.isInstanced() ) {
1834 instanceNum = path.instanceNumber();
1840 MFnMesh fnMesh( path );
1843 status = fnMesh.getConnectedSetsAndMembers( instanceNum, sets, comps,
true );
1845 MayaError(
"GetTextureForMesh: MFnMesh::getConnectedSetsAndMembers failed (%s)", status.errorString().asChar() );
1852 for ( i = 0; i < (
int )sets.length(); i++ ) {
1853 MObject set = sets[
i];
1854 MObject comp = comps[
i];
1856 MFnSet fnSet( set, &status );
1857 if ( status == MS::kFailure ) {
1858 MayaError(
"GetTextureForMesh: MFnSet constructor failed (%s)", status.errorString().asChar() );
1863 MItMeshPolygon piter(path, comp, &status);
1864 if (status == MS::kFailure) {
1874 if ( shaderNode == MObject::kNullObj ) {
1878 MPlug colorPlug = MFnDependencyNode(shaderNode).findPlug(
"color", &status);
1879 if ( status == MS::kFailure ) {
1883 MItDependencyGraph dgIt(colorPlug, MFn::kFileTexture,
1884 MItDependencyGraph::kUpstream,
1885 MItDependencyGraph::kBreadthFirst,
1886 MItDependencyGraph::kNodeLevel,
1889 if ( status == MS::kFailure ) {
1893 dgIt.disablePruningOnFilter();
1897 if ( dgIt.isDone() ) {
1903 MObject textureNode = dgIt.thisNode();
1904 MPlug filenamePlug = MFnDependencyNode( textureNode ).findPlug(
"fileTextureName" );
1905 MString textureName;
1906 filenamePlug.getValue( textureName );
1923 MObjectArray objarray;
1924 MObjectArray outputarray;
1932 status = skinCluster.getInputGeometry( objarray );
1934 MayaError(
"CopyMesh: Error getting input geometry (%s)", status.errorString().asChar() );
1938 nGeom = objarray.length();
1939 for( i = 0; i < nGeom; i++ ) {
1940 MFnDagNode dagNode( objarray[ i ], &status );
1942 common->
Printf(
"CopyMesh: MFnDagNode Constructor failed (%s)", status.errorString().asChar() );
1946 MFnMesh fnmesh( objarray[ i ], &status );
1952 status = skinCluster.getOutputGeometry( outputarray );
1954 common->
Printf(
"CopyMesh: Error getting output geometry (%s)", status.errorString().asChar() );
1958 if ( outputarray.length() < 1 ) {
1962 name = fnmesh.name().asChar();
1973 pos = name.
Find(
"ShapeOrig" );
1978 MFnDagNode dagNode2( outputarray[ 0 ], &status );
1980 common->
Printf(
"CopyMesh: MFnDagNode Constructor failed (%s)", status.errorString().asChar() );
1985 MObject parent = fnmesh.parent( 0, &status );
1987 MFnDagNode parentNode( parent, &status );
1989 altname = parentNode.name().asChar();
1997 if ( altname != name ) {
1998 common->
Printf(
"Skipping mesh '%s' ('%s')\n", name.
c_str(), altname.
c_str() );
2000 common->
Printf(
"Skipping mesh '%s'\n", name.
c_str() );
2007 common->
Printf(
"Skipping mesh '%s' ('%s')\n", name.
c_str(), altname.
c_str() );
2014 if ( altname.
Length() ) {
2015 mesh->
name = altname;
2021 int v = fnmesh.numVertices( &status );
2024 MFloatPointArray vertexArray;
2026 fnmesh.getPoints( vertexArray, MSpace::kPreTransform );
2028 for( j = 0; j <
v; j++ ) {
2029 memset( &mesh->
verts[ j ], 0,
sizeof( mesh->
verts[ j ] ) );
2033 MIntArray vertexList;
2036 p = fnmesh.numPolygons( &status );
2042 status = fnmesh.getCurrentUVSetName( setName );
2044 MayaError(
"CopyMesh: MFnMesh::getCurrentUVSetName failed (%s)", status.errorString().asChar() );
2047 for( j = 0; j <
p; j++ ) {
2048 fnmesh.getPolygonVertices( j, vertexList );
2049 if ( vertexList.length() != 3 ) {
2050 MayaError(
"CopyMesh: Too many vertices on a face (%d)\n", vertexList.length() );
2053 for( k = 0; k < 3; k++ ) {
2054 mesh->
tris[
j ].indexes[ k ] = vertexList[ k ];
2056 status = fnmesh.getPolygonUV( j, k, uv_u, uv_v, &setName );
2058 MayaError(
"CopyMesh: MFnMesh::getPolygonUV failed (%s)", status.errorString().asChar() );
2061 mesh->
uv[
j ].uv[ k ][ 0 ] = uv_u;
2062 mesh->
uv[
j ].uv[ k ][ 1 ] = uv_v;
2082 unsigned int nGeoms;
2085 MItDependencyNodes iter( MFn::kSkinClusterFilter );
2087 for ( ; !iter.isDone(); iter.next() ) {
2088 MObject
object = iter.item();
2093 MFnSkinCluster skinCluster(
object, &status );
2095 MayaError(
"%s: Error getting skin cluster (%s)",
object.apiTypeStr(), status.errorString().asChar() );
2098 mesh =
CopyMesh( skinCluster, scale );
2104 unsigned int nInfs = skinCluster.influenceObjects(infs, &status);
2106 MayaError(
"Mesh '%s': Error getting influence objects (%s)", mesh->
name.
c_str(), status.errorString().asChar() );
2114 nGeoms = skinCluster.numOutputConnections();
2115 for (
size_t ii = 0; ii < nGeoms; ++ii) {
2116 unsigned int index = skinCluster.indexForOutputConnection(ii,&status);
2119 MayaError(
"Mesh '%s': Error getting geometry index (%s)", mesh->
name.
c_str(), status.errorString().asChar() );
2124 status = skinCluster.getPathAtIndex(index,skinPath);
2126 MayaError(
"Mesh '%s': Error getting geometry path (%s)", mesh->
name.
c_str(), status.errorString().asChar() );
2130 MItGeometry gIter( skinPath );
2138 for (
size_t kk = 0; kk < nInfs; ++kk) {
2142 s = infs[kk].partialPathName();
2152 for ( ; !gIter.isDone(); gIter.next() ) {
2153 MObject comp = gIter.component( &status );
2155 MayaError(
"Mesh '%s': Error getting component (%s)", mesh->
name.
c_str(), status.errorString().asChar() );
2161 status = skinCluster.getWeights(skinPath,comp,wts,infCount);
2163 MayaError(
"Mesh '%s': Error getting weights (%s)", mesh->
name.
c_str(), status.errorString().asChar() );
2165 if (0 == infCount) {
2169 int num = gIter.index();
2173 float totalweight = 0.0f;
2176 int numNonZeroWeights = 0;
2178 for ( jj = 0; jj < (
int)infCount ; ++jj ) {
2179 float w = (
float )wts[ jj ];
2181 numNonZeroWeights++;
2184 weight.
joint = joints[ jj ];
2200 if ( numNonZeroWeights ) {
2203 MayaError(
"Error on mesh '%s': Vertex %d doesn't have any joint weights.", mesh->
name.
c_str(),
num );
2205 }
else if ( !totalweight ) {
2222 MayaError(
"CreateMesh: No skinClusters found in this scene.\n" );
2244 for( i = 0; i < oldmeshes.
Num(); i++ ) {
2245 mesh = oldmeshes[
i ];
2246 if ( !mesh->
keep ) {
2260 combine->
Merge( mesh );
2273 common->
Printf(
"Merged %d meshes\n", count );
2289 if ( alignName.
Length() ) {
2294 MayaError(
"could not find joint '%s' to align model to.\n", alignName.
c_str() );
2299 align[ 0 ][ 0 ] = mat[ 2 ][ 0 ];
2300 align[ 0 ][ 1 ] = -mat[ 2 ][ 2 ];
2301 align[ 0 ][ 2 ] = mat[ 2 ][ 1 ];
2303 align[ 1 ][ 0 ] = mat[ 0 ][ 0 ];
2304 align[ 1 ][ 1 ] = -mat[ 0 ][ 2 ];
2305 align[ 1 ][ 2 ] = mat[ 0 ][ 1 ];
2307 align[ 2 ][ 0 ] = mat[ 1 ][ 0 ];
2308 align[ 2 ][ 1 ] = -mat[ 1 ][ 2 ];
2309 align[ 2 ][ 2 ] = mat[ 1 ][ 1 ];
2314 }
else if ( rotate ) {
2329 if(
object.isNull() ) {
2334 MFnDependencyNode dgNode;
2337 stat = dgNode.setObject(
object );
2338 typeName = dgNode.typeName( &stat );
2339 if( MS::kSuccess != stat ) {
2344 return typeName.asChar();
2358 const char *n1, *n2;
2359 MFnDagNode *dagnode;
2364 MObject cameraNode = dagnode->object();
2365 childCount = dagnode->childCount();
2368 for( j = 0; j < childCount; j++ ) {
2369 MObject childNode = dagnode->child( j );
2373 if ( ( !
strcmp(
"transform", n1 ) ) && ( !
strcmp(
"camera", n2 ) ) ) {
2374 MFnCamera camera( childNode );
2375 focal = camera.focalLength();
2376 horiz = camera.horizontalFilmAperture();
2377 fov =
RAD2DEG( 2 * atan( ( horiz * 0.5 ) / ( focal / 25.4 ) ) );
2403 mat[ 0 ] = -axis[ 2 ];
2404 mat[ 1 ] = -axis[ 0 ];
2405 mat[ 2 ] = axis[ 1 ];
2429 MFnEnumAttribute cameraAttribute;
2444 common->
Printf(
" start time = %f\n end time = %f\n total time = %f\n", start, end, end - start );
2446 if ( start > end ) {
2447 MayaError(
"Start frame is greater than end frame." );
2451 if ( refCam ==
NULL ) {
2454 MObject cameraNode = refCam->
dagnode->object();
2455 MFnDependencyNode cameraDG( cameraNode, &status );
2456 if( MS::kSuccess != status ) {
2457 MayaError(
"Can't find 'refcam' dependency node." );
2461 MObject attr = cameraDG.attribute( MString(
"Camera" ), &status );
2462 if( MS::kSuccess != status ) {
2463 MayaError(
"Can't find 'Camera' attribute on 'refcam'." );
2467 plug = MPlug( cameraNode, attr );
2468 status = cameraAttribute.setObject( attr );
2469 if( MS::kSuccess != status ) {
2470 MayaError(
"Bad 'Camera' attribute on 'refcam'." );
2478 status = plug.getValue( v );
2479 currentCam = cameraAttribute.fieldName( v, &status ).asChar();
2480 if( MS::kSuccess != status ) {
2495 time.setUnit( MTime::kSeconds );
2496 time.setValue( start + ( (
float )frameNum / (
float )
options.
framerate ) );
2497 MGlobal::viewFrame( time );
2505 if ( refCam !=
NULL ) {
2506 status = plug.getValue( v );
2507 newCam = cameraAttribute.fieldName( v, &status ).asChar();
2508 if( MS::kSuccess != status ) {
2512 if ( newCam != currentCam ) {
2516 currentCam = newCam;
2549 common->
Printf(
" default pose time = %f\n", start );
2560 frame[ joint->
index ].t.Zero();
2561 frame[ joint->
index ].q.Set( 0.0
f, 0.0
f, 0.0
f );
2573 joint->
idwm = jointaxis;
2574 joint->
idt = jointpos;
2581 }
else if ( joint->
name ==
"origin" ) {
2590 frame[ joint->
index ].t = jointpos;
2597 frame[ joint->
index ].t.Zero();
2602 jointpos = frame[ joint->
index ].t;
2603 jointaxis = frame[ joint->
index ].q.ToQuat().ToMat3();
2607 joint->
idwm = jointaxis * parent->
idwm;
2608 joint->
idt = parent->
idt + jointpos * parent->
idwm;
2610 joint->
idwm = jointaxis;
2611 joint->
idt = jointpos;
2648 common->
Printf(
" start time = %f\n end time = %f\n total time = %f\n", start, end, end - start );
2650 if ( start > end ) {
2651 MayaError(
"Start frame is greater than end frame." );
2691 joint->
idwm = jointaxis;
2692 joint->
idt = jointpos;
2699 }
else if ( joint->
name ==
"origin" ) {
2708 frame[ joint->
index ].
t = jointpos;
2722 totalDelta = frame[ joint->
index ].
t - origin;
2729 bool shiftorigin =
false;
2739 if ( joint && shiftorigin ) {
2751 frame[ joint->
index ].
t -= origin;
2761 jointpos = frame[ joint->
index ].
t;
2766 joint->
idwm = jointaxis * parent->
idwm;
2767 joint->
idt = parent->
idt + jointpos * parent->
idwm;
2769 joint->
idwm = jointaxis;
2770 joint->
idt = jointpos;
2814 MFileIO::newFile(
true );
2817 common->
Printf(
"Loading file...\n" );
2818 status = MFileIO::open( filename,
NULL,
true );
2820 MayaError(
"Error loading '%s': '%s'\n", filename.asChar(), status.errorString().asChar() );
2828 MGlobal::viewFrame( MAnimControl::maxTime() );
2829 MGlobal::viewFrame( MAnimControl::minTime() );
2848 common->
Printf(
"Creating joints...\n" );
2851 common->
Printf(
"Creating meshes...\n" );
2853 common->
Printf(
"Renaming joints...\n" );
2855 common->
Printf(
"Remapping parents...\n" );
2857 common->
Printf(
"Pruning joints...\n" );
2859 common->
Printf(
"Combining meshes...\n" );
2863 common->
Printf(
"Align model...\n" );
2868 common->
Printf(
"Grabbing default pose:\n" );
2870 common->
Printf(
"Writing file...\n" );
2877 common->
Printf(
"Creating animation frames:\n" );
2879 common->
Printf(
"Writing file...\n" );
2886 common->
Printf(
"Creating camera frames:\n" );
2889 common->
Printf(
"Writing file...\n" );
2896 common->
Printf(
"done\n\n" );
2924 common->
Printf(
"R_LoadMD3: %s has wrong version (%i should be %i)\n",
2929 mod->type = MOD_MESH;
2931 mod->dataSize +=
size;
2932 mod->md3[lod] = ri.Hunk_Alloc( size );
2936 LL(mod->md3[lod]->ident);
2937 LL(mod->md3[lod]->version);
2938 LL(mod->md3[lod]->numFrames);
2939 LL(mod->md3[lod]->numTags);
2940 LL(mod->md3[lod]->numSurfaces);
2941 LL(mod->md3[lod]->ofsFrames);
2942 LL(mod->md3[lod]->ofsTags);
2943 LL(mod->md3[lod]->ofsSurfaces);
2944 LL(mod->md3[lod]->ofsEnd);
2946 if ( mod->md3[lod]->numFrames < 1 ) {
2947 common->
Printf(
"R_LoadMD3: %s has no frames\n", mod_name );
2952 frame = (
md3Frame_t *) ( (
byte *)mod->md3[lod] + mod->md3[lod]->ofsFrames );
2953 for ( i = 0 ; i < mod->md3[lod]->numFrames ; i++, frame++) {
2955 for ( j = 0 ; j < 3 ; j++ ) {
2963 tag = (
md3Tag_t *) ( (
byte *)mod->md3[lod] + mod->md3[lod]->ofsTags );
2964 for ( i = 0 ; i < mod->md3[lod]->numTags * mod->md3[lod]->numFrames ; i++, tag++) {
2965 for ( j = 0 ; j < 3 ; j++ ) {
2974 surf = (
md3Surface_t *) ( (
byte *)mod->md3[lod] + mod->md3[lod]->ofsSurfaces );
2975 for ( i = 0 ; i < mod->md3[lod]->numSurfaces ; i++) {
2990 ri.Error (ERR_DROP,
"R_LoadMD3: %s has more than %i verts on a surface (%i)",
2994 ri.Error (ERR_DROP,
"R_LoadMD3: %s has more than %i triangles on a surface (%i)",
2999 surf->
ident = SF_MD3;
3002 Q_strlwr( surf->
name );
3006 j = strlen( surf->
name );
3007 if ( j > 2 && surf->
name[j-2] ==
'_' ) {
3008 surf->
name[j-2] = 0;
3013 for ( j = 0 ; j < surf->
numShaders ; j++, shader++ ) {
3016 sh = R_FindShader( shader->
name, LIGHTMAP_NONE, qtrue );
3017 if ( sh->defaultShader ) {
3034 for ( j = 0 ; j < surf->
numVerts ; j++, st++ ) {
3073 errorMessage.
Clear();
3088 errorMessage =
"Ok";
3098 errorMessage = exception.
error;
3111 if ( !common || !sys ) {
3127 common->
Printf(
"Error initializing Maya exporter: DLL version %d different from .exe version %d\n",
MD5_VERSION, version );
3134 status = MLibrary::initialize(
GAME_NAME,
true );
3136 common->
Printf(
"Error calling MLibrary::initialize (%s)\n", status.errorString().asChar() );
bool RemapParents(idList< idNamePair > &remapjoints)
bool TokenAvailable(void)
bool AddBounds(const idBounds &a)
int SetTokens(const char *buffer)
bool Compare(const idVec3 &a) const
idList< idExportJoint > joints
idList< idAnimGroup > groups
int Cmp(const char *text) const
idMat3 idMat(const MMatrix &matrix)
void GetBindPose(MObject &jointNode, idExportJoint *joint, float scale)
const exporterShutdown_t ValidateShutdown
#define DEFAULT_QUAT_EPSILON
idExportJoint * FindJointReal(const char *name)
const char * componentNames[6]
void MayaError(const char *fmt,...)
GLenum GLsizei GLenum format
idExportJoint & operator=(const idExportJoint &other)
const char * Maya_ConvertModel(const char *ospath, const char *commandline)
void SetNum(int newnum, bool resize=true)
void CreateMesh(float scale)
idMat3 ToMat3(void) const
void GetLocalTransform(idExportJoint *joint, idVec3 &pos, idMat3 &mat)
void MakeSiblingAfter(idHierarchy &node)
bool Compare(const idVec2 &a) const
GLenum GLenum GLenum GLenum GLenum scale
idMat3 Transpose(void) const
idList< idAnimGroup * > exportgroups
void StripTrailing(const char c)
void GetAlignment(idStr &alignName, idMat3 &align, float rotate, int startframe)
bool WriteAnim(const char *filename, idExportOptions &options)
#define MD5_VERSION_STRING
idList< idBounds > bounds
void SetOwner(type *object)
void Set(float x, float y, float z)
GLuint GLuint GLsizei GLenum type
idMat3 ConvertFromIdSpace(const idMat3 &idmat)
bool dllEntry(int version, idCommon *common, idSys *sys)
idExportOptions(const char *commandline, const char *ospath)
void ParentTo(idHierarchy &node)
idExportMesh * CopyMesh(MFnSkinCluster &skinCluster, float scale)
#define SHADER_MAX_VERTEXES
bool OSPathToRelativePath(const char *osPath, idStr &qpath, const char *game)
bool ParentedBy(const idHierarchy &node) const
int Cmpn(const char *text, int n) const
bool WriteCamera(const char *filename, idExportOptions &options)
void GetDefaultPose(idMat3 &align)
const char * GetObjectType(MObject object)
const exporterInterface_t ValidateConvert
int Icmp(const char *text) const
void RemoveFromHierarchy(void)
idExportJoint * FindJoint(const char *name)
idStr & BackSlashesToSlashes(void)
idCVarSystem * cvarSystem
idList< cameraFrame_t > camera
idList< idNamePair > remapjoints
bool jointInExportGroup(const char *jointname)
idList< exportWeight_t > weights
bool AddPoint(const idVec3 &v)
GLuint GLuint GLsizei count
idExportOptions & options
static class idFileSystem * fileSystem
void GetTextureForMesh(idExportMesh *mesh, MFnDagNode &dagNode)
GLubyte GLubyte GLubyte GLubyte w
void Merge(idExportMesh *mesh)
idStr & StripFileExtension(void)
void RenameJoints(idList< idNamePair > &renamejoints, idStr &prefix)
idList< exportTriangle_t > tris
idList< exportVertex_t > verts
const char * NextToken(const char *errorstring=NULL)
float GetCameraFov(idExportJoint *joint)
idList< idNamePair > renamejoints
#define SHADER_MAX_INDEXES
idList< idExportMesh * > meshes
type * Find(type const &obj) const
MObject FindShader(MObject &setNode)
void DeleteContents(bool clear)
void CreateCameraAnim(idMat3 &align)
static idCVar * staticVars
const char * Right(int len, idStr &result) const
int Find(const char c, int start=0, int end=-1) const
bool WriteMesh(const char *filename, idExportOptions &options)
type * GetNext(void) const
float TimeForFrame(int num) const
idCQuat ToCQuat(void) const
virtual void Printf(const char *fmt,...) id_attribute((format(printf
void PruneJoints(idStrList &keepjoints, idStr &prefix)
void CreateAnimation(idMat3 &align)
void AppendPath(const char *text)
idMat3 & OrthoNormalizeSelf(void)
#define DEFAULT_ANIM_EPSILON
void ProjectVector(const idVec3 &src, idVec3 &dst) const
idList< jointFrame_t > jointFrames
idHierarchy< idExportJoint > mayaNode
idVec3 idVec(const MFloatPoint &point)
bool(* exporterDLLEntry_t)(int version, idCommon *common, idSys *sys)
idExportJoint * exportOrigin
#define MAYA_DEFAULT_CAMERA
short LittleShort(short l)
int Append(const type &obj)
void GetBounds(idBounds &bounds) const
type * GetChild(void) const
int GetMayaFrameNum(int num) const
idMat3 ConvertToIdSpace(const idMat3 &mat)
idList< jointFrame_t * > frames
void GetCameraFrame(idExportJoint *camera, idMat3 &align, cameraFrame_t *cam)
idHierarchy< idExportJoint > exportHead
type * GetSibling(void) const
static int static int vsnPrintf(char *dest, int size, const char *fmt, va_list argptr)
int AddUnique(const type &obj)
void Reset(const char *commandline)
idHierarchy< idExportJoint > mayaHead
char error[MAX_STRING_CHARS]
void(* exporterShutdown_t)(void)
idQuat ToQuat(void) const
void GetWorldTransform(idExportJoint *joint, idVec3 &pos, idMat3 &mat, float scale)
idMat3 ToMat3(void) const
type * GetParent(void) const
MFnDagNode * GetParent(MFnDagNode *joint)
idHierarchy< idExportJoint > exportNode
static class idCVarSystem * cvarSystem
idQuat ToQuat(void) const
const exporterDLLEntry_t ValidateEntry
const char * c_str(void) const
float LittleFloat(float l)
GLuint GLenum GLenum transform
void CreateJoints(float scale)
const char *(* exporterInterface_t)(const char *ospath, const char *commandline)
int sprintf(idStr &string, const char *fmt,...)
bool StripLeadingOnce(const char *string)
static class idCommon * common
idMat3 & TransposeSelf(void)