#include <maya/MPxNode.h>
#include <maya/MFnPlugin.h>
#include <maya/MIOStream.h>
#include <maya/MDrawRegistry.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MRenderUtil.h>
#include "simpleNoiseShaderOverride.h"
class SimpleNoiseShader : 
public MPxNode 
{
public:
    static void* creator();
    static const MString drawDbClassification;
 
    static const MString classification;
 
    SimpleNoiseShader();
    virtual ~SimpleNoiseShader();
private:
    
    
};
const MTypeId SimpleNoiseShader::id(0x00080FFE);
 
const MString SimpleNoiseShader::nodeName(
"simpleNoise");
 
const MString SimpleNoiseShader::drawDbClassification(
"drawdb/shader/texture/2d/" + SimpleNoiseShader::nodeName);
 
const MString SimpleNoiseShader::classification(
"texture/2d:" + drawDbClassification);
 
MObject SimpleNoiseShader::aOutColor;
 
MObject SimpleNoiseShader::aOutAlpha;
 
MObject SimpleNoiseShader::aUVCoord;
 
MObject SimpleNoiseShader::aFilterSize;
 
MObject SimpleNoiseShader::aAmplitude;
 
MObject SimpleNoiseShader::aDepthMax;
 
MObject SimpleNoiseShader::aFrequency;
 
MObject SimpleNoiseShader::aFrequencyRatio;
 
MObject SimpleNoiseShader::aNumWaves;
 
#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 SimpleNoiseShader::postConstructor()
{
    setMPSafe(true);
}
SimpleNoiseShader::SimpleNoiseShader()
{
}
SimpleNoiseShader::~SimpleNoiseShader()
{
}
void* SimpleNoiseShader::creator()
{
    return new SimpleNoiseShader();
}
MStatus SimpleNoiseShader::initialize()
 
{
    
    aOutColor = nAttr.
create(
"outColor", 
"oc", outcR, outcG, outcB);
    MAKE_OUTPUT(nAttr);
    MAKE_OUTPUT(nAttr);
    
    aUVCoord = nAttr.
create(
"uvCoord", 
"uv", child1, child2);
    MAKE_INPUT(nAttr);
    aFilterSize = nAttr.
create(
"uvFilterSize", 
"fs", child1, child2);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    
    
}
{
    
    if (plug != aOutColor && plug.
parent() != aOutColor && plug != aOutAlpha)
 
    {
    }
    float resultAlpha = 1.0f;
    
    
    static const float fM_PI = (float)M_PI;
    static const float M_2PI = 2.0f*fM_PI;
    const float timeRatio = sqrt(frequencyRatio);
    float uvX = uv[0] * frequency;
    float uvY = uv[1] * frequency;
    float cosine = 0.0f;
    float noise = 0.0f;
    unsigned int depthId = 0;
    unsigned int waveId = 0;
    unsigned int seedOffset = 0;
    while (depthId<depthMax && waveId<numWaves)
    {
        const unsigned int step = depthId;
        const unsigned int seed = 50*step;
        const float norm = sqrtf(dirX*dirX + dirY*dirY);
        if (norm <= 0.0f) continue;
        dirX /= norm;
        dirY /= norm;
        noise += cosf(
            dirX*uvX*M_2PI +
            dirY*uvY*M_2PI +
            time*fM_PI);
        ++waveId;
        if (waveId < numWaves) continue;
        noise /= float(numWaves);
        uvX *= frequencyRatio;
        uvY *= frequencyRatio;
        time *= timeRatio;
        cosine += amplitude * noise;
        amplitude *= ratio;
        noise = 0.0f;
        waveId = 0;
        seedOffset = 0;
        ++depthId;
    }
    cosine = 0.5f*cosine + 0.5f;
    const float noiseVal = (cosine > 1.0f) ? 1.0f : cosine;
    
    resultColor[0] = resultColor[1] = resultColor[2] = noiseVal;
    resultAlpha = noiseVal;
    
    if (plug == aOutColor || plug.
parent() == aOutColor)
 
    {
        
        
        outColor = resultColor;
    }
    
    if (plug == aOutAlpha)
    {
        
        float& outAlpha = outAlphaHandle.
asFloat();
 
        
        outAlpha = resultAlpha;
    }
}
static const MString sRegistrantId(
"simpleNoiseShaderPlugin");
 
{
    MFnPlugin plugin(obj, PLUGIN_COMPANY, 
"1.0", 
"Any");
 
        SimpleNoiseShader::nodeName,
        SimpleNoiseShader::id,
        SimpleNoiseShader::creator,
        SimpleNoiseShader::initialize,
        &SimpleNoiseShader::classification));
            SimpleNoiseShader::drawDbClassification,
            sRegistrantId,
            simpleNoiseShaderOverride::creator));
}
{
            SimpleNoiseShader::drawDbClassification,
            sRegistrantId));
}