//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ //////////////////////////////////////////////////////////////////////// // // Translate selected objects // //////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef M_PI #define M_PI 3.14159265358979323846 /* pi */ #endif class sampleParticles : public MPxCommand { public: sampleParticles() {}; virtual ~sampleParticles(); MStatus doIt( const MArgList& args ); static void* creator(); }; sampleParticles::~sampleParticles() {} void* sampleParticles::creator() { return new sampleParticles(); } /* emits particles with color sampled from specified shading node/shading engine */ MStatus sampleParticles::doIt( const MArgList& args ) { unsigned int i; bool shadow = 0; bool reuse = 0; for ( i = 0; i < args.length(); i++ ) if ( args.asString(i) == MString("-shadow") || args.asString(i) == MString("-s") ) shadow = 1; else if ( args.asString(i) == MString("-reuse") || args.asString(i) == MString("-r") ) reuse = 1; else break; if ( args.length() - i < 5 ) { displayError( "Usage: sampleParticles [-shadow|-reuse] particleName resX resY scale\n" " Example: sampleParticles -shadow particle1 phong1SG 64 64 10;\n" " Example: sampleParticles particle1 file1.outColor 128 128 5;\n" ); return MS::kFailure; } if ( reuse && !shadow ) // can only reuse if shadow is turned on reuse = 0; MString particleName = args.asString( i ); MString node = args.asString( i+1 ); short resX = args.asInt( i+2 ); short resY = args.asInt( i+3 ); double scale = args.asDouble( i+4 ); if ( scale <= 0.0 ) scale = 1.0; MFloatArray uCoord, vCoord; MFloatPointArray points; MFloatVectorArray normals, tanUs, tanVs; if ( resX <= 0 ) resX = 1; if ( resY <= 0 ) resY = 1; MString command( "emit -o " ); command += particleName; char tmp[2048]; float stepU = (float) (1.0 / resX); float stepV = (float) (1.0 / resY); // stuff sample data by iterating over grid // Y is set to arch along the X axis int x, y; for ( y = 0; y < resY; y++ ) for ( x = 0; x < resX; x++ ) { uCoord.append( stepU * x ); vCoord.append( stepV * y ); float curY = (float) (sin( stepU * (x) * M_PI )*2.0); MFloatPoint curPt( (float) (stepU * x * scale), curY, (float) (stepV * y * scale )); MFloatPoint uPt( (float) (stepU * (x+1) * scale), (float) (sin( stepU * (x+1) * M_PI )*2.0), (float) (stepV * y * scale )); MFloatPoint vPt( (float) (stepU * (x) * scale), curY, (float) (stepV * (y+1) * scale )); MFloatVector du, dv, n; du = uPt-curPt; dv = vPt-curPt; n = dv^du; // normal is based on dU x dV n = n.normal(); normals.append( n ); du.normal(); dv.normal(); tanUs.append( du ); tanVs.append( dv ); points.append( curPt ); } // get current camera's world matrix MDagPath cameraPath; M3dView::active3dView().getCamera( cameraPath ); MMatrix mat = cameraPath.inclusiveMatrix(); MFloatMatrix cameraMat( mat.matrix ); MFloatVectorArray colors, transps; if ( MS::kSuccess == MRenderUtil::sampleShadingNetwork( node, points.length(), shadow, reuse, cameraMat, &points, &uCoord, &vCoord, &normals, &points, &tanUs, &tanVs, NULL, // don't need filterSize colors, transps ) ) { fprintf( stderr, "%u points sampled...\n", points.length() ); for ( i = 0; i < uCoord.length(); i++ ) { sprintf( tmp, " -pos %g %g %g -at velocity -vv %g %g %g -at rgbPP -vv %g %g %g", points[i].x, points[i].y, points[i].z, normals[i].x, normals[i].y, normals[i].z, colors[i].x, colors[i].y, colors[i].z ); command += MString( tmp ); // execute emit command once every 512 samples if ( i % 512 == 0 ) { fprintf( stderr, "%u...\n", i ); MGlobal::executeCommand( command, false, false ); command = MString( "emit -o " ); command += particleName; } } if ( i % 512 ) MGlobal::executeCommand( command, true, true ); } else { displayError( node + MString(" is not a shading engine! Specify node.attr or shading group node." ) ); } 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, PLUGIN_COMPANY, "3.0", "Any"); status = plugin.registerCommand( "sampleParticles", sampleParticles::creator ); if (!status) { status.perror("registerCommand"); return status; } return status; } MStatus uninitializePlugin( MObject obj) { MStatus status; MFnPlugin plugin( obj ); status = plugin.deregisterCommand( "sampleParticles" ); if (!status) { status.perror("deregisterCommand"); return status; } return status; }