#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/MFloatVector.h>
#include <maya/MFloatPoint.h>
#include <maya/MFnPlugin.h>
float Noise(float, float, float);
void Noise_init();
static float Omega(int i, int j, int k, float t[3]);
static float omega(float);
static double turbulence(double u,double v,double w,int octaves);
#define PI 3.14159265358979323846
#ifdef FLOOR
#undef FLOOR
#endif
#define FLOOR(x) ((int)floorf(x))
#define TABLELEN 512
#define TLD2 256 // TABLELEN
static int Phi[TABLELEN];
static char fPhi[TABLELEN];
static float G[TABLELEN][3];
{
public:
Flame3D();
~Flame3D() override;
SchedulingType
schedulingType()
const override {
return SchedulingType::kParallel; }
static void * creator();
private:
};
#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));
Flame3D::Flame3D()
{
}
Flame3D::~Flame3D()
{
}
void * Flame3D::creator()
{
return new Flame3D();
}
{
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
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;
}
{
if((plug != aOutColor) && (plug.
parent() != aOutColor) &&
(plug != aOutAlpha))
return MS::kUnknownParameter;
q *= mat;
float rise_distance = -1.0f * rise_speed * frame;
float u,v,w;
u = q.x + ( rise_distance * axis[0]);
v = q.y + ( rise_distance * axis[1]);
w = q.z + ( rise_distance * axis[2]);
float dist = flicker_speed * frame;
float au, av, aw;
au = u + dist;
av = v + dist;
aw = w + dist;
float ascale = Noise(au,av,aw);
u += ascale * dscale;
v += ascale * dscale;
w += ascale * dscale;
float scalar = (float) (turbulence(u, v, w, 3) + 0.5);
if (power != 1) scalar = powf (scalar, power);
if (scalar >= 1)
resultColor = cFlame;
else if (scalar < 0)
resultColor = cBase;
else
resultColor = ((cFlame-cBase)*scalar) + cBase;
outColor = resultColor;
return MS::kSuccess;
}
{
const MString UserClassify(
"texture/3d" );
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any" );
Flame3D::creator, Flame3D::initialize,
Noise_init();
return MS::kSuccess;
}
{
return MS::kSuccess;
}
float Noise(float u, float v, float w)
{
int i;
int j;
int k;
int ul;
int vl;
int wl;
float ans;
float t[3];
ans = 0.0;
ul = FLOOR(u);
vl = FLOOR(v);
wl = FLOOR(w);
for(i = ul + 1; i >= ul; i--)
{
t[0] = u - i;
for(j = vl + 1; j >= vl; j--)
{
t[1] = v - j;
for(k = wl + 1; k >= wl; k--)
{
t[2] = w - k;
ans += Omega(i, j, k, t);
}
}
}
return ans;
}
static float Omega(int i, int j, int k, float t[3])
{
int ct;
ct = Phi[((i +
Phi[((j +
Phi[(k%TLD2)+TLD2]) % TLD2) + TLD2]) % TLD2) + TLD2];
return omega(t[0]) * omega(t[1]) * omega(t[2]) *
( G[ct][0]*t[0] + G[ct][1]*t[1] + G[ct][2]*t[2] );
}
static float omega(float t)
{
t = fabsf(t);
return (t * (t * (t * (float)2.0 - (float)3.0))) + (float)1.0;
}
void Noise_init()
{
int i;
float u, v, w, s, len;
static int first_time = 1;
if (first_time)
first_time = 0;
else
return;
(void)srand48(0l);
for(i = 0; i < TABLELEN; i++)
fPhi[i] = 0;
for(i = 0; i < TABLELEN; i++) {
Phi[i] = lrand48() % TABLELEN;
if (fPhi[Phi[i]])
i--;
else
fPhi[Phi[i]] = 1;
}
for(i = 0; i < TABLELEN; i++) {
u = (float) (2.0 * drand48() - 1.0);
v = (float) (2.0 * drand48() - 1.0);
w = (float) (2.0 * drand48() - 1.0);
if((s = u*u + v*v + w*w) > 1.0)
{ i--;
continue;
}
else
if (s == 0.0)
{ i--;
continue;
}
len = 1.0f / sqrtf(s);
G[i][0] = u * len;
G[i][1] = v * len;
G[i][2] = w * len;
}
}
static double turbulence(double u,double v,double w,int octaves)
{
double s,t;
s = 1.0;
t = 0.0;
while (octaves--) {
t += Noise((float)u, (float)v, (float)w)*s;
s *= 0.5;
u*=2.0; v*=2.0; w*=2.0;
}
return t;
}