//- // ========================================================================== // 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 #include #include #include class noise3 : public MPxNode { public: noise3(); virtual ~noise3(); virtual MStatus compute( const MPlug&, MDataBlock& ); virtual void postConstructor(); static void * creator(); static MStatus initialize(); // Id tag for use with binary file format static MTypeId id; private: static void init(); static float pnoise3( MFloatPoint& vec ); static float pnoise3( float vx, float vy, float vz ); // Input attributes static MObject aColor1; static MObject aColor2; static MObject aScale; static MObject aBias; static MObject aPlaceMat; static MObject aPointWorld; // Output attributes static MObject aOutColor; static MObject aOutAlpha; }; // Static data MTypeId noise3::id( 0x8100a ); // Attributes MObject noise3::aColor1; MObject noise3::aColor2; MObject noise3::aPlaceMat; MObject noise3::aPointWorld; MObject noise3::aScale; MObject noise3::aBias; MObject noise3::aOutColor; MObject noise3::aOutAlpha; #define MAKE_INPUT(attr) \ CHECK_MSTATUS ( attr.setKeyable(true) ); \ CHECK_MSTATUS ( attr.setStorable(true) ); \ CHECK_MSTATUS ( attr.setReadable(true) ); \ CHECK_MSTATUS ( attr.setWritable(true) ); #define MAKE_OUTPUT(attr) \ CHECK_MSTATUS ( attr.setKeyable(false) ); \ CHECK_MSTATUS ( attr.setStorable(false) ); \ CHECK_MSTATUS ( attr.setReadable(true) ); \ CHECK_MSTATUS ( attr.setWritable(false) ); void noise3::postConstructor( ) { setMPSafe(true); } noise3::noise3() { } noise3::~noise3() { } // creates an instance of the node void * noise3::creator() { return new noise3(); } // initializes attribute information MStatus noise3::initialize() { MFnMatrixAttribute mAttr; MFnNumericAttribute nAttr; // Create input attributes aColor1 = nAttr.createColor("color1", "c1"); MAKE_INPUT(nAttr); CHECK_MSTATUS ( nAttr.setDefault(0., .58824, .644) ); // Light blue aColor2 = nAttr.createColor("color2", "c2"); MAKE_INPUT(nAttr); CHECK_MSTATUS ( nAttr.setDefault(1., 1., 1.) ); // White aScale = nAttr.create( "scale", "s", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS ( nAttr.setDefault( 1. ) ); aBias = nAttr.create( "bias", "b", MFnNumericData::kFloat); MAKE_INPUT(nAttr); aPlaceMat = mAttr.create("placementMatrix", "pm", MFnMatrixAttribute::kFloat); MAKE_INPUT(mAttr); // Implicit shading network attributes aPointWorld = nAttr.createPoint("pointWorld", "pw"); MAKE_INPUT(nAttr); CHECK_MSTATUS ( nAttr.setHidden(true) ); // Create output attributes aOutColor = nAttr.createColor("outColor", "oc"); MAKE_OUTPUT(nAttr); aOutAlpha = nAttr.create( "outAlpha", "oa", MFnNumericData::kFloat); MAKE_OUTPUT(nAttr); // Add the attributes here CHECK_MSTATUS ( addAttribute(aColor1) ); CHECK_MSTATUS ( addAttribute(aColor2) ); CHECK_MSTATUS ( addAttribute(aScale) ); CHECK_MSTATUS ( addAttribute(aBias) ); CHECK_MSTATUS ( addAttribute(aPointWorld) ); CHECK_MSTATUS ( addAttribute(aPlaceMat) ); CHECK_MSTATUS ( addAttribute(aOutColor) ); CHECK_MSTATUS ( addAttribute(aOutAlpha) ); // All input affect the output color and alpha CHECK_MSTATUS ( attributeAffects (aColor1, aOutColor) ); CHECK_MSTATUS ( attributeAffects (aColor1, aOutAlpha) ); CHECK_MSTATUS ( attributeAffects (aColor2, aOutColor) ) ; CHECK_MSTATUS ( attributeAffects (aColor2, aOutAlpha) ); CHECK_MSTATUS ( attributeAffects (aScale, aOutAlpha) ); CHECK_MSTATUS ( attributeAffects (aScale, aOutColor) ); CHECK_MSTATUS ( attributeAffects (aBias, aOutAlpha) ); CHECK_MSTATUS ( attributeAffects (aBias, aOutColor) ); CHECK_MSTATUS ( attributeAffects (aPointWorld, aOutColor) ); CHECK_MSTATUS ( attributeAffects (aPointWorld, aOutAlpha) ); CHECK_MSTATUS ( attributeAffects (aPlaceMat, aOutColor) ); CHECK_MSTATUS ( attributeAffects (aPlaceMat, aOutAlpha) ); return MS::kSuccess; } /* Ken Perlin */ #define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) #define B 256 static int p[B +B +2]; static float g[B + B + 2][3]; static int start = 1; #define setup(i,b0,b1,r0,r1) t = i + 10000.0f; b0 = ((int)t) & (B-1); b1 = (b0+1) & (B-1); r0 = t - (int)t; r1 = r0 - 1.0f; inline float noise3::pnoise3( MFloatPoint& vec ) { return pnoise3( vec.x, vec.y, vec.z ); } float noise3::pnoise3(float vx, float vy, float vz) { int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v; register int i, j; if (start) { start = 0; init(); } setup(vx, bx0,bx1, rx0,rx1); setup(vy, by0,by1, ry0,ry1); setup(vz, bz0,bz1, rz0,rz1); i = p[ bx0 ]; j = p[ bx1 ]; b00 = p[ i + by0 ]; b10 = p[ j + by0 ]; b01 = p[ i + by1 ]; b11 = p[ j + by1 ]; #define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) #define s_curve(t) ( t * t * (3.0f - 2.0f * t) ) #define lerp(t, a, b) ( a + t * (b - a) ) sx = s_curve(rx0); sy = s_curve(ry0); sz = s_curve(rz0); q = g[ b00 + bz0 ] ; u = at(rx0,ry0,rz0); q = g[ b10 + bz0 ] ; v = at(rx1,ry0,rz0); a = lerp(sx, u, v); q = g[ b01 + bz0 ] ; u = at(rx0,ry1,rz0); q = g[ b11 + bz0 ] ; v = at(rx1,ry1,rz0); b = lerp(sx, u, v); c = lerp(sy, a, b); // interpolate in y at lo x q = g[ b00 + bz1 ] ; u = at(rx0,ry0,rz1); q = g[ b10 + bz1 ] ; v = at(rx1,ry0,rz1); a = lerp(sx, u, v); q = g[ b01 + bz1 ] ; u = at(rx0,ry1,rz1); q = g[ b11 + bz1 ] ; v = at(rx1,ry1,rz1); b = lerp(sx, u, v); d = lerp(sy, a, b); // interpolate in y at hi x return 1.5f * lerp(sz, c, d); // interpolate in z } void noise3::init() { int i, j, k; float v[3], s; // Create an array of random gradient vectors uniformly on the // unit sphere srandom(1); for (i = 0 ; i < B ; i++) { do { // Choose uniformly in a cube for (j=0 ; j<3 ; j++) v[j] = (float)((random() % (B + B)) - B) / B; s = DOT(v,v); } while (s > 1.0); // If not in sphere try again s = sqrtf(s); for (j = 0 ; j < 3 ; j++) // Else normalize g[i][j] = v[j] / s; } // Create a pseudorandom permutation of [1..B] for (i = 0 ; i < B ; i++) p[i] = i; for(i=B ;i >0 ;i -=2) { k = p[i]; p[i] = p[j = random() % B]; p[j] = k; } // Extend g and p arrays to allow for faster indexing for(i=0 ;i 1.) val = 1.; resultColor = col1 * val + col2*(1-val); // Set output color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); MDataHandle outAlphaHandle = block.outputValue( aOutAlpha ); float& outAlpha = outAlphaHandle.asFloat(); outAlpha = val; outAlphaHandle.setClean(); return MS::kSuccess; } MStatus initializePlugin( MObject obj ) { const MString UserClassify( "texture/3d" ); MFnPlugin plugin( obj, "Alias", "4.5", "Any"); CHECK_MSTATUS ( plugin.registerNode( "solidNoise", noise3::id, &noise3::creator, &noise3::initialize, MPxNode::kDependNode, &UserClassify ) ); return MS::kSuccess; } MStatus uninitializePlugin( MObject obj ) { MFnPlugin plugin( obj ); CHECK_MSTATUS ( plugin.deregisterNode( noise3::id ) ); return MS::kSuccess; }