//----------------------------------------------------------------------------- // Get the starting list of objects to export //----------------------------------------------------------------------------- MStatus CVstSmdIOCmd::GetOptSelection( const MArgDatabase &mArgDatabase, MSelectionList &mSelectionList ) { if ( mArgDatabase.isFlagSet( kOptSelection ) ) { // Get the user's specified selection of stuff to export if ( !mArgDatabase.getObjects( mSelectionList ) ) { MGlobal::displayError( "Cannot get list of specified objects to export" ); return MS::kFailure; } else if ( mSelectionList.isEmpty() ) { MGlobal::displayError( "-export -selection specified but nothing is selected" ); return MS::kFailure; } } else { MDagPath mDagPath; const bool exportInvisible( mArgDatabase.isFlagSet( kOptExportInvisible ) ); for ( MItDag dagIt( MItDag::kBreadthFirst, MFn::kDagNode ); !dagIt.isDone() && dagIt.depth() <= 1; dagIt.next() ) { if ( dagIt.depth() == 1) { if ( dagIt.getPath( mDagPath ) ) { if ( exportInvisible || ValveMaya::IsPathVisible( mDagPath ) ) { mSelectionList.add( mDagPath, MObject::kNullObj, true ); } } } } } if ( mSelectionList.isEmpty() ) { MGlobal::displayError( "Cannot find anything to export" ); return MS::kFailure; } return MS::kSuccess; }
//----------------------------------------------------------------------------- // Purpose: Export the specified bits of the maya scene into the specified file // Input : mArgDatabase The command line arguments as passed // Output : MS::kSuccess if ok, MS::kFailure otherwise //----------------------------------------------------------------------------- MStatus CVstSmdIOCmd::DoImport( const MArgDatabase &mArgDatabase ) { MString optFilename; if ( mArgDatabase.getFlagArgument( kOptFilename, 0, optFilename ) != MS::kSuccess || optFilename.length() == 0 ) { MGlobal::displayError( "No filename specified for import" ); return MS::kFailure; } MString optGame; if ( mArgDatabase.isFlagSet( kOptGame ) ) { mArgDatabase.getFlagArgument( kOptGame, 0, optGame ); } MString optTextureArchive; if ( mArgDatabase.isFlagSet( kOptTextureArchive ) ) { mArgDatabase.getFlagArgument( kOptTextureArchive, 0, optTextureArchive ); } CQcData qcData; char fullPath[ MAX_PATH ]; if ( !_fullpath( fullPath, optFilename.asChar(), sizeof( fullPath ) ) ) { strncpy( fullPath, optFilename.asChar(), sizeof( fullPath ) ); } qcData.GetQcData( fullPath ); if ( mArgDatabase.isFlagSet( kOptUpAxis ) ) { MString upAxis; mArgDatabase.getFlagArgument( kOptUpAxis, 0, upAxis ); switch ( *upAxis.asChar() ) { case 'x': case 'X': qcData.m_upAxis = 0; break; case 'y': case 'Y': qcData.m_upAxis = 1; break; case 'z': case 'Z': default: qcData.m_upAxis = 2; break; } } CSmdImport smdImport( optGame.asChar(), optTextureArchive.asChar() ); if ( mArgDatabase.isFlagSet( kOptImportSkeleton ) && !mArgDatabase.isFlagSet( kOptVmf ) ) { mArgDatabase.getFlagArgument( kOptImportSkeleton, 0, smdImport.m_optImportSkeleton ); } smdImport.SetNodeAddPrefix( GetNodeAddPrefix( mArgDatabase ) ); smdImport.SetNodeDelPrefix( GetNodeDelPrefix( mArgDatabase ) ); if ( mArgDatabase.isFlagSet( kOptImportType ) ) { MString optImportType; if ( mArgDatabase.getFlagArgument( kOptImportType, 0, optImportType ) && ( *optImportType.asChar() == 'a' || *optImportType.asChar() == 'A' || *optImportType.asChar() == 's' || *optImportType.asChar() == 'S' ) ) { MSelectionList mSelectionList; mArgDatabase.getObjects( mSelectionList ); MDagPath rootDagPath; if ( mSelectionList.length() && mSelectionList.getDagPath( 0, rootDagPath ) ) { return smdImport.ImportAnimation( optFilename.asChar(), rootDagPath, qcData, m_undo ); } else { merr << "Cannot import animation without the root of the skeleton is selected or specified" << std::endl; return MS::kFailure; } } } MTransformationMatrix topLevel; if ( mArgDatabase.isFlagSet( kOptOrigin ) ) { MVector o; mArgDatabase.getFlagArgument( kOptOrigin, 0, o.x ); mArgDatabase.getFlagArgument( kOptOrigin, 1, o.y ); mArgDatabase.getFlagArgument( kOptOrigin, 2, o.z ); topLevel.setTranslation( o, MSpace::kObject ); } if ( mArgDatabase.isFlagSet( kOptAngles ) ) { MVector a; if ( mArgDatabase.isFlagSet( kOptVmf ) ) { // The angles are specified in Yaw Pitch Roll order ( YZX ) // but they're still an XYZ rotation mArgDatabase.getFlagArgument( kOptAngles, 0, a.y ); mArgDatabase.getFlagArgument( kOptAngles, 1, a.z ); mArgDatabase.getFlagArgument( kOptAngles, 2, a.x ); } else { mArgDatabase.getFlagArgument( kOptAngles, 0, a.x ); mArgDatabase.getFlagArgument( kOptAngles, 1, a.y ); mArgDatabase.getFlagArgument( kOptAngles, 2, a.z ); } const MEulerRotation e( a.x / 180.0 * M_PI, a.y / 180.0 * M_PI, a.z / 180.0 * M_PI, MEulerRotation::kXYZ ); topLevel.rotateBy( e.asQuaternion(), MSpace::kObject ); } if ( mArgDatabase.isFlagSet( kOptVmf ) ) { if ( qcData.m_upAxis == 1U ) { topLevel.rotateBy( MEulerRotation( 90.0 / 180.0 * M_PI, 0.0, 90.0 / 180.0 * M_PI ).asQuaternion(), MSpace::kObject ); } else { topLevel.rotateBy( MEulerRotation( 0.0, 0.0, 90.0 / 180.0 * M_PI ).asQuaternion(), MSpace::kObject ); } } else { switch ( qcData.m_upAxis ) { case 0U: // X Up if ( MGlobal::isYAxisUp() ) { topLevel.rotateBy( MEulerRotation( -M_PI / 2.0, M_PI / 2.0, 0.0 ).asQuaternion(), MSpace::kObject ); } else { topLevel.rotateBy( MEulerRotation( 0.0, M_PI / 2.0, 0.0 ).asQuaternion(), MSpace::kObject ); } break; case 1U: // Y Up if ( MGlobal::isZAxisUp() ) { topLevel.rotateBy( MEulerRotation( M_PI / 2.0, 0.0, 0.0 ).asQuaternion(), MSpace::kObject ); } break; default: case 2U: // Z Up if ( MGlobal::isYAxisUp() ) { topLevel.rotateBy( MEulerRotation( -M_PI / 2.0, 0.0, 0.0 ).asQuaternion(), MSpace::kObject ); } break; } } MDagPath mDagPath( smdImport.DoIt( optFilename.asChar(), qcData, topLevel, m_undo ) ); if ( mDagPath.isValid() && mDagPath.length() ) { if ( mArgDatabase.isFlagSet( kOptVmf ) ) { MFnNumericAttribute nFn; MObject aObj( nFn.create( "yUp", "yUp", MFnNumericData::kBoolean, false ) ); MDagPath sDagPath( mDagPath ); sDagPath.extendToShapeDirectlyBelow( 0 ); m_undo.DagModifier().addAttribute( sDagPath.node(), aObj ); m_undo.DagModifierDoIt(); MPlug aP( sDagPath.node(), aObj ); if ( qcData.m_upAxis == 1U ) { aP.setValue( true ); } else { aP.setValue( false ); } } m_undo.SaveCurrentSelection(); MGlobal::select( mDagPath, MObject::kNullObj, MGlobal::kReplaceList ); setResult( mDagPath.partialPathName() ); m_undo.SaveCurrentSelection(); return MS::kSuccess; } m_undo.Undo(); return MS::kFailure; }
//----------------------------------------------------------------------------- // Creates a vstAttachment Locator //----------------------------------------------------------------------------- MStatus CVstAttachmentCmd::DoCreate() { MDagModifier *mDagModifier( new MDagModifier ); if ( !mDagModifier ) { merr << "Can't create new MDagModifier" << std::endl; return MS::kFailure; } MString optName( "vstAttachment" ); if ( m_mArgDatabase->isFlagSet( kOptName ) ) { m_mArgDatabase->getFlagArgument( kOptName, 0, optName ); } // Create the helper bone locator's transform MObject xObj = mDagModifier->createNode( "transform" ); mDagModifier->doIt(); if ( xObj.isNull() ) { merr << "Can't create new transform node" << std::endl; return MS::kFailure; } // name the shape & the transform the same thing mDagModifier->renameNode( xObj, optName ); mDagModifier->doIt(); MObject vstAttachmentObj = mDagModifier->createNode( "vstAttachment", xObj ); if ( vstAttachmentObj.isNull() ) { merr << "Can't create new vstAttachment node" << std::endl; mDagModifier->undoIt(); return MS::kFailure; } // name the shape & the transform the same thing mDagModifier->renameNode( vstAttachmentObj, MFnDependencyNode( xObj ).name() ); mDagModifier->doIt(); m_undoable = true; m_mDagModifier = mDagModifier; if ( m_mArgDatabase->isFlagSet( kOptParent ) ) { MSelectionList mSelectionList; m_mArgDatabase->getObjects( mSelectionList ); for ( MItSelectionList sIt( mSelectionList, MFn::kDagNode ); !sIt.isDone(); sIt.next() ) { MDagPath mDagPath; if ( sIt.getDagPath( mDagPath ) ) { m_mDagModifier->reparentNode( xObj, mDagPath.node() ); m_mDagModifier->doIt(); break; } } } // Save the current selection just in case we want to undo stuff MGlobal::getActiveSelectionList( m_mSelectionList ); MDagPath xDagPath; MDagPath::getAPathTo( xObj, xDagPath ); MGlobal::select( xDagPath, MObject::kNullObj, MGlobal::kReplaceList ); setResult( xDagPath.partialPathName() ); return MS::kSuccess; }
//----------------------------------------------------------------------------- // Purpose: Export the specified bits of the maya scene into the specified file // Input : i_mArgDatabase The command line arguments as passed // Output : MS::kSuccess if ok, MS::kFailure otherwise //----------------------------------------------------------------------------- MStatus CVstSmdIOCmd::DoExport( const MArgDatabase &mArgDatabase ) { MString optFilename; if ( mArgDatabase.getFlagArgument( kOptFilename, 0, optFilename ) != MS::kSuccess || optFilename.length() == 0 ) { MGlobal::displayError( "No filename specified for export" ); return MS::kFailure; } MSelectionList optSelectionList; if ( GetOptSelection( mArgDatabase, optSelectionList ) != MS::kSuccess ) return MS::kFailure; const uint exportType( GetExportType( mArgDatabase ) ); const uint exportFlags( GetExportFlags( mArgDatabase ) ); const uint version( mArgDatabase.isFlagSet( kOptRelativeMaterials ) && exportType & ( CSmdExport::kModel | CSmdExport::kPhysModel | CSmdExport::kVertexAnimation ) ? 2 : 1 ); CSmdExport smdExport( exportType, exportFlags, version ); smdExport.SetNodeAddPrefix( GetNodeAddPrefix( mArgDatabase ) ); smdExport.SetNodeDelPrefix( GetNodeDelPrefix( mArgDatabase ) ); if ( exportType & CSmdExport::kAnimation ) { double fs( 0.0 ); double fe( 0.0 ); double fi( 1.0 ); GetExportFrameRange( mArgDatabase, fs, fe, fi ); smdExport.SetFrameRange( fs, fe, fi ); } MStringArray result; if ( smdExport.DoIt( optFilename, optSelectionList, result ) != MS::kSuccess ) return MS::kFailure; if ( result.length() ) { result.append( "smd" ); result.append( optFilename ); } else { result.append( MString( "Exported to " ) + optFilename ); } if ( mArgDatabase.isFlagSet( kOptQci ) ) { MString optQci; mArgDatabase.getFlagArgument( kOptQci, 0, optQci ); MSelectionList qciSelectionList; if ( mArgDatabase.isFlagSet( kOptSelection ) ) { mArgDatabase.getObjects( qciSelectionList ); } MStringArray qciResult; CQciExport qciExport; if ( qciExport.DoIt( optQci, qciSelectionList, qciResult ) && qciResult.length() ) { for ( uint i( 0 ); i != qciResult.length(); ++i ) { result.append( qciResult[ i ] ); } } } setResult( result ); return MS::kSuccess; }
MStatus CVstAimCmd::redoIt() { MStatus mStatus; if ( !mStatus ) { setResult( MString( "Cannot parse command line" ) + mStatus.errorString() ); return MS::kFailure; } if ( m_mArgDatabase->isFlagSet( kHelp ) ) { PrintHelp(); } else { // See if there are two object specified MDagPath mDagPath; MSelectionList optSelectionList; // Validate specified items to whole dag nodes { MSelectionList tmpSelectionList; m_mArgDatabase->getObjects( tmpSelectionList ); for ( MItSelectionList sIt( tmpSelectionList, MFn::kDagNode ); !sIt.isDone(); sIt.next() ) { if ( sIt.getDagPath( mDagPath ) ) { optSelectionList.add( mDagPath, MObject::kNullObj, true ); } } } if ( m_mArgDatabase->isFlagSet( "create" ) || optSelectionList.length() >= 2 && m_mArgDatabase->numberOfFlagsUsed() == 0 ) { // Error if there aren't at least two if ( optSelectionList.length() < 2 ) { displayError( GetName() + " needs at least two objects specified or selected when -create is used" ); return MS::kFailure; } // Get name command line arg MString optName; if ( m_mArgDatabase->isFlagSet( "name" ) ) { m_mArgDatabase->getFlagArgument( "name", 0, optName ); } m_undoable = true; m_mDagModifier = new MDagModifier; MObject vstAimObj( m_mDagModifier->MDGModifier::createNode( GetName() ) ); if ( m_mDagModifier->doIt() != MS::kSuccess ) { displayError( MString( "Couldn't create " ) + GetName() + " node" ); m_mDagModifier->undoIt(); delete m_mDagModifier; m_mDagModifier = NULL; m_undoable = false; return MS::kFailure; } m_mDagModifier->renameNode( vstAimObj, optName.length() ? optName : GetName() ); if ( m_mDagModifier->doIt() != MS::kSuccess ) { if ( optName.length() ) { displayWarning( MString( "Couldn't rename newly created vstNode \"" ) + optName + "\"" ); } } // Set options on the newly create vstAim node MFnDependencyNode vstAimFn( vstAimObj ); MPlug sP; MPlug dP; if ( m_mArgDatabase->isFlagSet( kAim ) ) { MVector aim; m_mArgDatabase->getFlagArgument( kAim, 0, aim.x ); m_mArgDatabase->getFlagArgument( kAim, 1, aim.y ); m_mArgDatabase->getFlagArgument( kAim, 2, aim.z ); sP = vstAimFn.findPlug( "aimX" ); sP.setValue( aim.x ); sP = vstAimFn.findPlug( "aimY" ); sP.setValue( aim.y ); sP = vstAimFn.findPlug( "aimZ" ); sP.setValue( aim.z ); } if ( m_mArgDatabase->isFlagSet( kUp ) ) { MVector up; m_mArgDatabase->getFlagArgument( kUp, 0, up.x ); m_mArgDatabase->getFlagArgument( kUp, 1, up.y ); m_mArgDatabase->getFlagArgument( kUp, 2, up.z ); sP = vstAimFn.findPlug( "upX" ); sP.setValue( up.x ); sP = vstAimFn.findPlug( "upY" ); sP.setValue( up.y ); sP = vstAimFn.findPlug( "upZ" ); sP.setValue( up.z ); } // Now connect up the newly created vstAim node MDagPath toAim; optSelectionList.getDagPath( 1, toAim ); const MFnDagNode toAimFn( toAim ); if ( toAim.hasFn( MFn::kJoint ) ) { MPlug joP( toAimFn.findPlug( "jointOrient" ) ); if ( !joP.isNull() ) { MAngle jox, joy, joz; joP.child( 0 ).getValue( jox ); joP.child( 1 ).getValue( joy ); joP.child( 2 ).getValue( joz ); if ( abs( jox.value() ) > FLT_EPSILON || abs( joy.value() ) > FLT_EPSILON || abs( joz.value() ) > FLT_EPSILON ) { mwarn << "Joint orient on node being constrained is non-zero ( " << jox.asDegrees() << " " << joy.asDegrees() << " " << joz.asDegrees() << " ), setting to 0" << std::endl; joP.child( 0 ).setValue( MAngle( 0.0 ) ); joP.child( 1 ).setValue( MAngle( 0.0 ) ); joP.child( 2 ).setValue( MAngle( 0.0 ) ); } } } if ( toAim.hasFn( MFn::kTransform ) ) { MPlug mP( toAimFn.findPlug( "rotateAxis" ) ); if ( !mP.isNull() ) { MAngle rx, ry, rz; mP.child( 0 ).getValue( rx ); mP.child( 1 ).getValue( ry ); mP.child( 2 ).getValue( rz ); if ( abs( rx.value() ) > FLT_EPSILON || abs( ry.value() ) > FLT_EPSILON || abs( rz.value() ) > FLT_EPSILON ) { mwarn << "Rotate Axis on node being constrained is non-zero ( " << rx.asDegrees() << " " << ry.asDegrees() << " " << rz.asDegrees() << " ), setting to 0" << std::endl; mP.child( 0 ).setValue( MAngle( 0.0 ) ); mP.child( 1 ).setValue( MAngle( 0.0 ) ); mP.child( 2 ).setValue( MAngle( 0.0 ) ); } } } MDagPath aimAt; optSelectionList.getDagPath( 0, aimAt ); const MFnDagNode aimAtFn( aimAt ); // toAim.rotateOrder -> vstAim.rotateOrder sP = toAimFn.findPlug( "rotateOrder" ); dP = vstAimFn.findPlug( "rotateOrder" ); m_mDagModifier->connect( sP, dP ); // toAim.translate -> vstAim.translate sP = toAimFn.findPlug( "translate" ); dP = vstAimFn.findPlug( "translate" ); m_mDagModifier->connect( sP, dP ); // toAim.parentMatrix[ instance ] -> vstAim.parentSpace sP = toAimFn.findPlug( "parentMatrix" ); sP = sP.elementByLogicalIndex( toAim.instanceNumber() ); dP = vstAimFn.findPlug( "parentSpace" ); m_mDagModifier->connect( sP, dP ); // aimAt.worldMatrix[ instance ] -> vstAim.aimSpace sP = aimAtFn.findPlug( "worldMatrix" ); sP = sP.elementByLogicalIndex( aimAt.instanceNumber() ); dP = vstAimFn.findPlug( "aimSpace" ); m_mDagModifier->connect( sP, dP ); // vstAim.rotation -> toAim.rotation // These have to be connected individually because Maya plays stupid tricks // with rotateOrder if they aren't sP = vstAimFn.findPlug( "rotateX" ); dP = toAimFn.findPlug( "rotateX" ); m_mDagModifier->connect( sP, dP ); sP = vstAimFn.findPlug( "rotateY" ); dP = toAimFn.findPlug( "rotateY" ); m_mDagModifier->connect( sP, dP ); sP = vstAimFn.findPlug( "rotateZ" ); dP = toAimFn.findPlug( "rotateZ" ); m_mDagModifier->connect( sP, dP ); if ( m_mDagModifier->doIt() != MS::kSuccess ) { displayWarning( MString( GetName() ) + ": Couldn't connect everything when creating" ); } // Save the current selection just in case we want to undo stuff MGlobal::getActiveSelectionList( m_mSelectionList ); MGlobal::select( vstAimObj, MGlobal::kReplaceList ); setResult( vstAimFn.name() ); } else if ( m_mArgDatabase->isFlagSet( "select" ) ) { MSelectionList mSelectionList; MDagPath mDagPath; for ( MItDag dagIt; !dagIt.isDone(); dagIt.next() ) { if ( MFnDependencyNode( dagIt.item() ).typeName() == GetName() ) { dagIt.getPath( mDagPath ); mSelectionList.add( mDagPath, MObject::kNullObj, true ); } } if ( mSelectionList.length() ) { m_undoable = true; // Save the current selection just in case we want to undo stuff MGlobal::getActiveSelectionList( m_mSelectionList ); MGlobal::setActiveSelectionList( mSelectionList, MGlobal::kReplaceList ); } } else { displayError( GetName() + ": No valid operation specified via command line arguments\n" ); } } return MS::kSuccess; }