//- // ========================================================================== // 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. // // ========================================================================== //+ // // File: latticeNoise.cc // // Description: // plugin registration code // #include "latticeNoise.h" #include #include #include MStatus initializePlugin( MObject obj ) { MStatus status; MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any"); // Register latticeNoise node // status = plugin.registerNode( "latticeNoise", latticeNoiseNode::id, latticeNoiseNode::creator, latticeNoiseNode::initialize); if (!status) { status.perror("registerNode"); return status; } // Register latticeNoise command // status = plugin.registerCommand( "latticeNoise", latticeNoiseCmd::creator ); if (!status) { plugin.deregisterNode( latticeNoiseNode::id ); status.perror("registerCommand"); return status; } return status; } MStatus uninitializePlugin( MObject obj) { MStatus status; MFnPlugin plugin( obj ); // Deregister latticeNoise node // status = plugin.deregisterNode( latticeNoiseNode::id ); if (!status) { status.perror("registerNode"); return status; } // Register latticeNoise command // status = plugin.deregisterCommand( "latticeNoise" ); if (!status) { status.perror("deregisterCommand"); return status; } return status; } // // Class: noise // // Description: // The noise class is used for generating pseudo-random continuous noise. // The noise values generated are always between 0 and 1. // // The technique used is a simple lattice noise algorithm based upon one // by Ken Perlin. This particular implementation is adapted from // Darwyn Peachey's (Texturing and Modeling: a Procedural Approach, S. Ebert // Editor, 1994). // #include #include const int kTableMask = TABLE_SIZE - 1; ////////////////////////////////////////////////////////////// // PUBLIC // ////////////////////////////////////////////////////////////// float noise::atValue( float x ) // // Description: // Get the noise value at the given point in 1-space. // // Arguments: // x - the point at which to calculate the noise // // Return Value: // the noise value at the point // { int ix; float fx; if ( !isInitialized ) { initTable( 23479015 ); isInitialized = 1; } ix = (int)floorf( x ); fx = x - (float)ix; return spline( fx, value( ix - 1 ), value( ix ), value( ix + 1 ), value( ix + 2 ) ); } float noise::atPoint( float x, float y, float z ) // // Description: // Get the noise value at the given point in 3-space. // // Arguments: // x - x component of point // y - x component of point // z - x component of point // // Return Value: // the noise value at the point // { int ix, iy, iz; int i, j, k; float fx, fy, fz; float xknots[4], yknots[4], zknots[4]; if ( !isInitialized ) { initTable( 23479015 ); } ix = (int)floorf( x ); fx = x - (float)ix; iy = (int)floorf( y ); fy = y - (float)iy; iz = (int)floorf( z ); fz = z - (float)iz; for ( k = -1; k <= 2; k++ ) { for ( j = -1; j <= 2; j++ ) { for ( i = -1; i <= 2 ; i++ ) { xknots[i+1] = value( ix + i, iy + j, iz + k ); } yknots[j+1] = spline( fx, xknots[0], xknots[1], xknots[2], xknots[3] ); } zknots[k+1] = spline( fy, yknots[0], yknots[1], yknots[2], yknots[3] ); } float val = spline( fz, zknots[0], zknots[1], zknots[2], zknots[3] ); return val; } pnt noise::atPointAndTime( float x, float y, float z, float t ) // // Description: // Get three noise values at the given point in 4-space. This is actually // a reasonably expensive operation. It requires 255 simple spline // interpolations. However, the noise function is continuous. // // Arguments: // x - x component of point // y - x component of point // z - x component of point // t - t component of point (time component) // // Return Value: // the noise value at the point // { pnt ret; int ix, iy, iz, it; int i, j, k, l; float fx, fy, fz, ft; float xknots[3][4], yknots[3][4], zknots[3][4], tknots[3][4]; if ( !isInitialized ) { initTable( 23479015 ); } ix = (int)floorf( x ); fx = x - (float)ix; iy = (int)floorf( y ); fy = y - (float)iy; iz = (int)floorf( z ); fz = z - (float)iz; it = (int)floorf( t); ft = t - (float)it; for ( l = -1; l <= 2; l++ ) { for ( k = -1; k <= 2; k++ ) { for ( j = -1; j <= 2; j++ ) { for ( i = -1; i <= 2 ; i++ ) { xknots[0][i+1] = value( ix + i, iy + j, iz + k, it + l, valueTable1 ); xknots[1][i+1] = value( ix + i, iy + j, iz + k, it + l, valueTable2 ); xknots[2][i+1] = value( ix + i, iy + j, iz + k, it + l, valueTable3 ); } yknots[0][j+1] = spline( fx, xknots[0][0], xknots[0][1], xknots[0][2], xknots[0][3] ); yknots[1][j+1] = spline( fx, xknots[1][0], xknots[1][1], xknots[1][2], xknots[1][3] ); yknots[2][j+1] = spline( fx, xknots[2][0], xknots[2][1], xknots[2][2], xknots[2][3] ); } zknots[0][k+1] = spline( fy, yknots[0][0], yknots[0][1], yknots[0][2], yknots[0][3] ); zknots[1][k+1] = spline( fy, yknots[1][0], yknots[1][1], yknots[1][2], yknots[1][3] ); zknots[2][k+1] = spline( fy, yknots[2][0], yknots[2][1], yknots[2][2], yknots[2][3] ); } tknots[0][l+1] = spline( fz, zknots[0][0], zknots[0][1], zknots[0][2], zknots[0][3] ); tknots[1][l+1] = spline( fz, zknots[1][0], zknots[1][1], zknots[1][2], zknots[1][3] ); tknots[2][l+1] = spline( fz, zknots[2][0], zknots[2][1], zknots[2][2], zknots[2][3] ); } ret.x = spline( ft, tknots[0][0], tknots[0][1], tknots[0][2], tknots[0][3] ); ret.y = spline( ft, tknots[1][0], tknots[1][1], tknots[1][2], tknots[1][3] ); ret.z = spline( ft, tknots[2][0], tknots[2][1], tknots[2][2], tknots[2][3] ); return ret; } void noise::initTable( long seed ) // // Description: // Initialize the table of random values with the given seed. // // Arguments: // seed - the new seed value // { srand48( seed ); for ( int i = 0; i < TABLE_SIZE; i++ ) { valueTable1[i] = (float)drand48(); valueTable2[i] = (float)drand48(); valueTable3[i] = (float)drand48(); } isInitialized = 1; } ////////////////////////////////////////////////////////////// // PRIVATE // ////////////////////////////////////////////////////////////// float noise::spline( float x, float knot0, float knot1, float knot2, float knot3 ) // // Description: // This is a simple version of a Catmull-Rom spline interpolation. // // Assumptions: // // 0 < x < 1 // // { float c0, c1, c2, c3; // Evaluate span of cubic at x using Horner's rule // c3 = (-0.5F * knot0 ) + ( 1.5F * knot1 ) + (-1.5F * knot2 ) + ( 0.5F * knot3 ); c2 = ( 1.0F * knot0 ) + (-2.5F * knot1 ) + ( 2.0F * knot2 ) + (-0.5F * knot3 ); c1 = (-0.5F * knot0 ) + ( 0.0F * knot1 ) + ( 0.5F * knot2 ) + ( 0.0F * knot3 ); c0 = ( 0.0F * knot0 ) + ( 1.0F * knot1 ) + ( 0.0F * knot2 ) + ( 0.0F * knot3 ); return ( ( c3 * x + c2 ) * x + c1 ) * x + c0;; } int noise::isInitialized = 0; int noise::permtable[256] = { 254, 91, 242, 186, 90, 204, 85, 133, 233, 50, 187, 49, 182, 224, 144, 166, 7, 51, 20, 179, 36, 203, 114, 156, 195, 40, 24, 60, 162, 84, 126, 102, 63, 194, 220, 161, 72, 94, 193, 229, 140, 57, 3, 189, 106, 54, 164, 198, 199, 44, 245, 235, 100, 87, 25, 41, 62, 111, 13, 70, 27, 82, 69, 53, 66, 247, 124, 67, 163, 125, 155, 228, 122, 19, 113, 143, 121, 9, 1, 241, 171, 200, 83, 244, 185, 170, 141, 115, 190, 154, 48, 32, 178, 127, 167, 56, 134, 15, 160, 238, 64, 6, 11, 196, 232, 26, 89, 0, 219, 112, 68, 30, 215, 227, 75, 132, 71, 239, 251, 92, 14, 104, 231, 29, 180, 150, 226, 191, 47, 73, 37, 183, 88, 105, 42, 22, 2, 38, 5, 119, 74, 249, 184, 52, 8, 55, 118, 255, 206, 173, 165, 78, 31, 123, 98, 212, 80, 139, 61, 138, 77, 177, 45, 137, 145, 28, 168, 128, 95, 223, 35, 205, 76, 211, 175, 81, 33, 207, 21, 131, 58, 152, 16, 240, 18, 96, 210, 109, 214, 216, 202, 148, 34, 146, 117, 176, 93, 246, 172, 97, 159, 197, 218, 65, 147, 253, 221, 217, 79, 101, 142, 23, 149, 99, 39, 12, 135, 110, 234, 108, 153, 129, 4, 169, 174, 116, 243, 130, 107, 222, 10, 43, 188, 46, 213, 252, 86, 157, 192, 236, 158, 120, 17, 103, 248, 225, 230, 250, 208, 181, 151, 237, 201, 59, 136, 209 }; float noise::valueTable1[256]; float noise::valueTable2[256]; float noise::valueTable3[256];