#include <math.h>
#include <stdlib.h>
#include <maya/MPxNode.h>
#include <maya/MIOStream.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h> 
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MFloatPoint.h>
#include <maya/MFloatVector.h>
#include <maya/MFloatMatrix.h>
#include <maya/MFnPlugin.h>
{
    public:
    noise3();
    virtual ~noise3();
    static  void *  creator();
    
    private:
    static void init();
    static float pnoise3( float vx, float vy, float vz );
    
    
};
 
#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()
{
}
void * noise3::creator()
{
    return new noise3();
}
{
    
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    aPlaceMat = mAttr.
create(
"placementMatrix", 
"pm",
    MAKE_INPUT(mAttr);
    
    MAKE_INPUT(nAttr);
    
    MAKE_OUTPUT(nAttr);
    MAKE_OUTPUT(nAttr);
    
    
}
#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; 
{
    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);                     
    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);                     
    return 1.5f * lerp(sz, c, d);           
}
void noise3::init() 
{
    int i, j, k; 
    float v[3], s; 
 
    
    
    srandom(1); 
    for (i = 0 ; i < B ; i++) 
    { 
        do 
        { 
            
            for (j=0 ; j<3 ; j++) 
                v[j] = (float)((random() % (B + B)) - B) / B; 
            s = DOT(v,v); 
        } while (s > 1.0);                  
        s = sqrtf(s); 
        for (j = 0 ; j < 3 ; j++)           
            g[i][j] = v[j] / s; 
    } 
    
    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; 
    } 
    
    for(i=0 ;i <B +2 ;i++) 
    { 
        p[B + i] = p[i]; 
        for (j = 0 ; j < 3 ; j++) 
            g[B + i][j] = g[i][j]; 
    }
}
{
    
    if((plug != aOutColor) && (plug.
parent() != aOutColor) && 
 
       (plug != aOutAlpha))
    
    MFloatPoint solidPos(worldPos[0], worldPos[1], worldPos[2]);
 
    solidPos *= mat;                        
    float val = fabsf( pnoise3( solidPos ) * sc + bi );
    if (val < 0.) val = 0.;
    if (val > 1.) val = 1.;
    resultColor = col1 * val + col2*(1-val);
    
    outColor = resultColor;
    outColorHandle.setClean();
    float& outAlpha = outAlphaHandle.
asFloat();
 
    outAlpha = val;
}
{
    const MString UserClassify( 
"texture/3d" );
 
    MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"4.5", 
"Any");
 
                         &noise3::creator, &noise3::initialize,
}
{
}