//- // ========================================================================== // Copyright (C) 1995 - 2005 Alias Systems Corp. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files are provided by Alias // Systems Corp. ("Alias") and/or its licensors for the exclusive use of the // Customer (as defined in the Alias Software License Agreement that // accompanies this Alias software). Such Customer has the right to use, // modify, and incorporate the Data into other products and to distribute such // products for use by end-users. // // THE DATA IS PROVIDED "AS IS". ALIAS HEREBY DISCLAIMS ALL WARRANTIES // RELATING TO THE DATA, INCLUDING, WITHOUT LIMITATION, ANY AND ALL EXPRESS OR // IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND/OR FITNESS FOR A // PARTICULAR PURPOSE. IN NO EVENT SHALL ALIAS BE LIABLE FOR ANY DAMAGES // WHATSOEVER, WHETHER DIRECT, INDIRECT, SPECIAL, OR PUNITIVE, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, OR IN EQUITY, // ARISING OUT OF ACCESS TO, USE OF, OR RELIANCE UPON THE DATA. // ========================================================================== //+ // Description: // // Traces the position of an animated object // and create a curve showing the object's path. // // Usage: // // Animate an object. // Select the object. // Run 'motionTrace;' in the command window. // See the object's path drawn as a curve. // // Options: // // -s The start frame. Default to 1. // -e The end frame. Default to 60. // -b The by frame. Default to 1. // // See also: // // node_info.cc for how to get object attributes // helix.cc for how to create a curve #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include /////////////////////////////////////////////////// // // Command class declaration // /////////////////////////////////////////////////// class motionTrace : public MPxCommand { public: motionTrace(); virtual ~motionTrace(); MStatus doIt( const MArgList& args ); MStatus redoIt(); static void* creator(); private: void printType( MObject node, MString & prefix ); double start, end, by; // frame range }; /////////////////////////////////////////////////// // // Command class implementation // /////////////////////////////////////////////////// motionTrace::motionTrace() {} void* motionTrace::creator() { return new motionTrace(); } motionTrace::~motionTrace() { } MStatus motionTrace::doIt( const MArgList& args ) // // Description // This method is called from MEL when this command is called. // It should set up any class data necessary for redo/undo, // parse any given arguments, and then call redoIt. // { start = 1.0; end = 60.0; by = 1.0; MStatus stat; double tmp; unsigned i; // Parse the arguments. for ( i = 0; i < args.length(); i++ ) { if ( MString( "-s" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) start = tmp; } else if ( MString( "-e" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) end = tmp; } else if ( MString( "-b" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) by = tmp; } } stat = redoIt(); return stat; } /* ----------------------------------------- Make a degree 1 curve from the given CVs. ----------------------------------------- */ static void jMakeCurve( MPointArray cvs ) { MStatus stat; unsigned int deg = 1; MDoubleArray knots; unsigned int i; for ( i = 0; i < cvs.length(); i++ ) knots.append( (double) i ); // Now create the curve // MFnNurbsCurve curveFn; MObject curve = curveFn.create( cvs, knots, deg, MFnNurbsCurve::kOpen, false, false, MObject::kNullObj, &stat ); if ( MS::kSuccess != stat ) printf("Error creating curve.\n"); } MStatus motionTrace::redoIt() // // Description // This method performs the action of the command. // // This method iterates over all selected items and // prints out connected plug and dependency node type // information. // { MStatus stat; // Status code MObjectArray picked; MObject dependNode; // Selected dependency node // Create a selection list iterator // MSelectionList slist; MGlobal::getActiveSelectionList( slist ); MItSelectionList iter( slist, MFn::kInvalid,&stat ); // Iterate over all selected dependency nodes // and save them in a list // for ( ; !iter.isDone(); iter.next() ) { // Get the selected dependency node // if ( MS::kSuccess != iter.getDependNode( dependNode ) ) { cerr << "Error getting the dependency node" << endl; continue; } picked.append( dependNode ); } // array of arrays for object position MPointArray *pointArrays = new MPointArray [ picked.length() ]; unsigned int i; double time; // Sample the animation using start, end, by values for ( time = start; time <= end; time+=by ) { MTime timeval(time); MGlobal::viewFrame( timeval ); // Iterate over selected dependency nodes // for ( i = 0; i < picked.length(); i++ ) { // Get the selected dependency node // dependNode = picked[i]; // Create a function set for the dependency node // MFnDependencyNode fnDependNode( dependNode ); // Get the translation attribute values MObject txAttr; txAttr = fnDependNode.attribute( MString("translateX"), &stat ); MPlug txPlug( dependNode, txAttr ); double tx; stat = txPlug.getValue( tx ); MObject tyAttr; tyAttr = fnDependNode.attribute( MString("translateY"), &stat ); MPlug tyPlug( dependNode, tyAttr ); double ty; stat = tyPlug.getValue( ty ); MObject tzAttr; tzAttr = fnDependNode.attribute( MString("translateZ"), &stat ); MPlug tzPlug( dependNode, tzAttr ); double tz; stat = tzPlug.getValue( tz ); #if 0 fprintf( stderr, "Time = %2.2lf, XYZ = ( %2.2lf, %2.2lf, %2.2lf )\n\n", time, tx, ty, tz ); #endif pointArrays[i].append( MPoint( tx, ty, tz )) ; } } // make a path curve for each selected object for ( i = 0; i < picked.length(); i++ ) jMakeCurve( pointArrays[i] ); delete [] pointArrays; return MS::kSuccess; } ///////////////////////////////////////////////////////////////// // // The following routines are used to register/unregister // the command we are creating within Maya // ///////////////////////////////////////////////////////////////// MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, "Alias", "3.0", "Any"); status = plugin.registerCommand( "motionTrace", motionTrace::creator ); if (!status) { status.perror("registerCommand"); return status; } return status; } MStatus uninitializePlugin( MObject obj) { MStatus status; MFnPlugin plugin( obj ); status = plugin.deregisterCommand( "motionTrace" ); if (!status) { status.perror("registerCommand"); return status; } return status; }