//- // ========================================================================== // 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. // ========================================================================== //+ #include #include #include #include #include #include #include #include #include #include #include #include DeclareSimpleCommand( volumeLight, "Alias", "5.0"); #define EQUAL(a,b) ( (((a-b) > -0.00001) && ((a-b) < 0.00001)) ? 1 : 0 ) MStatus volumeLight::doIt( const MArgList& args ) { MStatus stat; double arc = 180.0f; double coneEndRadius = 0.0f; MFnVolumeLight::MLightDirection volumeLightDirection = MFnVolumeLight::kOutward; MFnVolumeLight::MLightShape lightShape = MFnVolumeLight::kConeVolume; bool emitAmbient = true; unsigned i; // Parse the arguments. for ( i = 0; i < args.length(); i++ ) { if ( MString( "-a" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { double tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) arc = tmp; } else if ( MString( "-c" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { double tmp = args.asDouble( ++i, &stat ); if ( MS::kSuccess == stat ) coneEndRadius = tmp; } else if ( MString( "-e" ) == args.asString( i, &stat ) && MS::kSuccess == stat) { bool tmp = args.asBool( ++i, &stat ); if ( MS::kSuccess == stat ) emitAmbient = tmp; } } MFnVolumeLight light; light.create( true, &stat); printf ("What's up?"); if ( MS::kSuccess != stat ) { printf("Error creating light.\n"); return stat; } stat = light.setArc ((float)arc); if ( MS::kSuccess != stat ) { printf("Error setting \"arc\" attribute.\n"); return stat; } stat = light.setVolumeLightDirection (volumeLightDirection); if ( MS::kSuccess != stat ) { printf("Error setting \"volumeLightDirection\" attribute.\n"); return stat; } stat = light.setConeEndRadius ((float)coneEndRadius); if ( MS::kSuccess != stat ) { printf("Error setting \"coneEndRadius\" attribute.\n"); return stat; } stat = light.setEmitAmbient (emitAmbient); if ( MS::kSuccess != stat ) { printf("Error setting \"emitAmbient\" attribute.\n"); return stat; } stat = light.setLightShape (lightShape); if ( MS::kSuccess != stat ) { printf("Error setting \"lightShape\" attribute.\n"); return stat; } double arcGet = light.arc (&stat); if ( MS::kSuccess != stat || arcGet != arc) { printf("Error getting \"arc\" attribute.\n"); return stat; } short volumeLightDirectionGet = light.volumeLightDirection (&stat); if ( MS::kSuccess != stat || volumeLightDirectionGet != volumeLightDirection) { printf("Error getting \"volumeLightDirection\" attribute.\n"); return stat; } double coneEndRadiusGet = light.coneEndRadius (&stat); if ( MS::kSuccess != stat || coneEndRadiusGet != coneEndRadius) { printf("Error getting \"coneEndRadius\" attribute.\n"); return stat; } bool emitAmbientGet = light.emitAmbient (&stat); if ( MS::kSuccess != stat || emitAmbientGet != emitAmbient) { printf("Error getting \"emitAmbient\" attribute.\n"); return stat; } short lightShapeGet = light.lightShape (&stat); if ( MS::kSuccess != stat || lightShapeGet != lightShape) { printf("Error getting \"lightShape\" attribute.\n"); return stat; } // Get reference to the penumbra ramp. MRampAttribute ramp = light.penumbraRamp (&stat); if ( MS::kSuccess != stat ) { printf("Error getting \"penumbraRamp\" attribute.\n"); return stat; } MFloatArray a, b; MIntArray c,d; // Get the entries in the ramp ramp.getEntries (d, a, b, c, &stat); if ( MS::kSuccess != stat ) { printf("Error getting entries from \"penumbraRamp\" attribute.\n"); return stat; } // There should be 2 entries by default. if (d.length() != 2) { printf("Invalid number of entries in \"penumbraRamp\" attribute.\n"); return stat; } MFloatArray a1, b1; MIntArray c1; // Prepare an array of entries to add. // In this case we are just adding 1 more entry // at position 0.5 with a curve value of 0.25 and a linear interpolation. a1.append (0.5f); b1.append (0.25f); c1.append (MRampAttribute::kLinear); // Add it to the curve ramp ramp.addEntries (a1, b1, c1, &stat); if ( MS::kSuccess != stat) { printf("Error adding entries to \"penumbraRamp\" attribute.\n"); return stat; } // Get the entries to make sure that the above add actually worked. MFloatArray a2, b2; MIntArray c2,d2; ramp.getEntries (d2, a2, b2, c2, &stat); if ( MS::kSuccess != stat ) { printf("Error getting entries from \"penumbraRamp\" attribute.\n"); return stat; } if ( a.length() + a1.length() != a2.length()) { printf("Invalid number of entries in \"penumbraRamp\" attribute.\n"); return stat; } // Now try to interpolate the value at a point float newVal = -1; ramp.getValueAtPosition(.3f, newVal, &stat); if ( MS::kSuccess != stat ) { printf("Error interpolating value from \"penumbraRamp\" attribute.\n"); return stat; } if ( !EQUAL(newVal, .15f)) { printf("Invalid interpolation in \"penumbraRamp\" expected .15 got %g .\n", newVal); } // Try to delete an entry in an incorrect manner. // This delete will work because there is an entry at 0, // However we should never do it this way, because the entries // array can become sparse, so trying to delete an entry without // checking whether an entry exists at that index can cause a failure. MIntArray entriesToDelete; entriesToDelete.append (0); ramp.deleteEntries (entriesToDelete, &stat); if ( MS::kSuccess != stat ) { printf("Error deleting entries from \"penumbraRamp\" attribute.\n"); return stat; } // Check to see whether the above delete worked. // As mentioned earlier it did work, but we shouldn't do it this way. // To illustrate why we shouldn't do it this way, we'll try to delete // entry at index 0 ( this no longer exists) ramp.getEntries (d2, a2, b2, c2, &stat); if ( a2.length() != 2) { printf("Invalid number of entries in \"penumbraRamp\" attribute.\n"); return stat; } // Trying to delete entry at 0. entriesToDelete.clear(); entriesToDelete.append (0); ramp.deleteEntries (entriesToDelete, &stat); // It will fail because no entry exists. if ( MS::kSuccess == stat) { printf("Error deleting entries from \"penumbraRamp\" attribute.\n"); return stat; } if ( a2.length() != 2) { printf("Invalid number of entries in \"penumbraRamp\" attribute.\n"); return stat; } // The proper way to delete is to retrieve the index by calling "getEntries" ramp.getEntries (d2, a2, b2, c2, &stat); entriesToDelete.clear(); entriesToDelete.append (d2[0]); // Delete the first logical entry in the entry array. ramp.deleteEntries (entriesToDelete, &stat); if ( MS::kSuccess != stat) { printf("Error deleting entries from \"penumbraRamp\" attribute.\n"); return stat; } // There should be only 1 entry left. ramp.getEntries (d2, a2, b2, c2, &stat); if ( MS::kSuccess != stat) { printf("Error getting entries from \"penumbraRamp\" attribute.\n"); return stat; } entriesToDelete.clear(); entriesToDelete.append (d2[0]); // Can't delete the last entry, should return failure. ramp.deleteEntries (entriesToDelete, &stat); if ( MS::kSuccess == stat) { printf("Error deleting entries from \"penumbraRamp\" attribute.\n"); return stat; } ramp.setPositionAtIndex (0.0f, d2[0], &stat); if ( MS::kSuccess != stat) { printf("Error setting position at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]); return stat; } ramp.setValueAtIndex (1.0f, d2[0], &stat); if ( MS::kSuccess != stat) { printf("Error setting value at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]); return stat; } ramp.setInterpolationAtIndex (MRampAttribute::kNone, d2[0], &stat); if ( MS::kSuccess != stat) { printf("Error setting interpolation at index: %d, of \"penumbraRamp\" attribute.\n", d2[0]); return stat; } MRampAttribute ramp2 = light.colorRamp (&stat); if ( MS::kSuccess != stat) { printf("Error getting \"colorRamp\" attribute.\n"); return stat; } MFloatArray a3; MColorArray b3; MIntArray c3,d3; // Get the entries in the ramp ramp2.getEntries (d3, a3, b3, c3, &stat); if ( MS::kSuccess != stat) { printf("Error getting entries from \"colorRamp\" attribute.\n"); return stat; } // There should be 2 entries by default. if ( d3.length() != 2) { printf("Invalid number of entries in \"colorRamp\" attribute.\n"); return stat; } MFloatArray a4; MColorArray b4; MIntArray c4; // Prepare an array of entries to add. // In this case we are just adding 1 more entry // at position 0.5 withe curve value of 0.5 and a linear interpolation. a4.append (0.5f); b4.append (MColor (0.0f, 0.0f, 0.75f)); c4.append (MRampAttribute::kLinear); // Add it to the curve ramp ramp2.addEntries (a4, b4, c4, &stat); if ( MS::kSuccess != stat) { printf("Error adding entries to \"colorRamp\" attribute.\n"); return stat; } // Get the entries to make sure that the above add actually worked. MFloatArray a5; MColorArray b5; MIntArray c5,d5; ramp2.getEntries (d5, a5, b5, c5, &stat); if ( MS::kSuccess != stat) { printf("Error getting entries from \"colorRamp\" attribute.\n"); return stat; } if ( a3.length() + a4.length() != a5.length()) { printf("Invalid number of entries in \"colorRamp\" attribute.\n"); return stat; } // Now try to interpolate the color at a point MColor newCol(0.0, 0.0, 0.0); ramp2.getColorAtPosition(.3f, newCol, &stat); if ( MS::kSuccess != stat ) { printf("Error interpolating color from \"penumbraRamp\" attribute.\n"); return stat; } if ( !EQUAL(newCol[2], .45)) { printf("Invalid color interpolation in \"colorRamp\" expected .45 got %g.\n", newCol[2]); } MColor clr (0.5, 0.5, 0.0); ramp2.setColorAtIndex (clr, d5[0], &stat); if ( MS::kSuccess != stat) { printf("Error setting color at index: %d, of \"colorRamp\" attribute.\n", d5[0]); return stat; } ramp2.setInterpolationAtIndex (MRampAttribute::kSpline, d5[1], &stat); if ( MS::kSuccess != stat) { printf("Error setting interpolation at index: %d, of \"colorRamp\" attribute.\n", d5[1]); return stat; } return stat; }