#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();
~noise3() override;
SchedulingType
schedulingType()
const override {
return SchedulingType::kParallel; }
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) );
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);
return MS::kSuccess;
}
#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;
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))
return MS::kUnknownParameter;
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;
return MS::kSuccess;
}
{
const MString UserClassify(
"texture/3d" );
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"4.5",
"Any");
&noise3::creator, &noise3::initialize,
return MS::kSuccess;
}
{
return MS::kSuccess;
}