#include <math.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/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
{
    public:
                      BackNode();
    virtual           ~BackNode();
    static void *     creator();
    
    private:
    static MObject  aDiffuseReflectivity;
 
    static MObject  aLightShadowFraction;
 
    static MObject  aPreShadowIntensity;
 
};
MObject  BackNode::aTranslucenceCoeff;
 
MObject  BackNode::aDiffuseReflectivity;
 
MObject  BackNode::aLightShadowFraction;
 
MObject  BackNode::aPreShadowIntensity;
 
#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 BackNode::postConstructor( )
{
    setMPSafe(true);
}
BackNode::BackNode()
{
}
BackNode::~BackNode()
{
}
void * BackNode::creator()
{
    return new BackNode();
}
{
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    aIncandescence = nAttr.
createColor( 
"incandescence",
"ic" );
    MAKE_INPUT(nAttr);
    aTranslucenceCoeff = nAttr.
create(
"translucenceCoeff", 
"tc", 
    MAKE_INPUT(nAttr);
    aDiffuseReflectivity = nAttr.
create(
"diffuseReflectivity", 
"drfl",
    MAKE_INPUT(nAttr);
    
    MAKE_OUTPUT(nAttr);
    aPointCamera = nAttr.
createPoint( 
"pointCamera", 
"pc" );
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    aNormalCamera = nAttr.
createColor( 
"normalCamera", 
"n" );
    MAKE_INPUT(nAttr);
    aLightDirection = nAttr.
createPoint( 
"lightDirection", 
"ld" );
    aLightIntensity = nAttr.
createColor( 
"lightIntensity", 
"li" );
    aLightAmbient = nAttr.
create( 
"lightAmbient", 
"la",
    aLightDiffuse = nAttr.
create( 
"lightDiffuse", 
"ldf",
    aLightSpecular = nAttr.
create( 
"lightSpecular", 
"ls", 
    aLightShadowFraction = nAttr.
create(
"lightShadowFraction", 
"lsf",
    aPreShadowIntensity = nAttr.
create(
"preShadowIntensity", 
"psi",
    aLightBlindData = nAttr.
createAddr(
"lightBlindData", 
"lbld");
    aLightData = lAttr.
create( 
"lightDataArray", 
"ltd", 
                               aLightDirection, aLightIntensity, aLightAmbient, 
                               aLightDiffuse, aLightSpecular, aLightShadowFraction,
                               aPreShadowIntensity, aLightBlindData);
    CHECK_MSTATUS( lAttr.
setDefault(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 
true, 
true, 
false, 0.0f, 1.0f, NULL) );
 
    
    
    
    CHECK_MSTATUS( attributeAffects (aTranslucenceCoeff, aOutColor) );
 
    CHECK_MSTATUS( attributeAffects (aDiffuseReflectivity, aOutColor) );
 
    CHECK_MSTATUS( attributeAffects (aLightShadowFraction, aOutColor) );
 
    CHECK_MSTATUS( attributeAffects (aPreShadowIntensity, aOutColor) );
 
}
{
    
    if ((plug != aOutColor) && (plug.
parent() != aOutColor))
 
    
    
  
    
    float specularR, specularG, specularB;
    float diffuseR, diffuseG, diffuseB;
    float BackR, BackG, BackB;
    diffuseR = diffuseG = diffuseB = specularR = specularG = specularB = 0.0;
    BackR = BackG = BackB = 0.0;
    
    
    for( int count=1; count <= numLights; count++ )
    {
        
        
            diffuseR += lightIntensity[0];
            diffuseG += lightIntensity[1];
            diffuseB += lightIntensity[2];
        }
        
        {
            float cosln = lightDirection * surfaceNormal;
    
            if( cosln > 0.0f )  
            {
                 diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity );
                 diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity );
                 diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity );
            }
            if (((cosln > 0.0) && (cosln <= threshold)) ||
                 (cosln <= 0.0))
            {
                float interp;
                if (threshold != 0.0) {
                    interp = ((1.0f / (-1 - threshold)) * cosln) +
                        (threshold / (threshold + 1));
                }
                else
                {
                    interp = fabsf(cosln);
                }
                BackR += (BackLightColor[0] * interp);
                BackG += (BackLightColor[1] * interp);
                BackB += (BackLightColor[2] * interp);
            }
            if( cosln > 0.0f ) 
            {
                float RV = ( ( (2*surfaceNormal) * cosln ) - lightDirection ) * cameraPosition;
                if( RV < 0.0 ) RV = -RV;
                if ( power < 0 ) power = -power;
                float s = spec * powf( RV, power );
                specularR += lightIntensity[0] * s; 
                specularG += lightIntensity[1] * s; 
                specularB += lightIntensity[2] * s; 
            }
       }
       if( !lightData.
next() ) 
break;
 
    }
    
    resultColor[0] = ( diffuseR * surfaceColor[0] ) + specularR + incandescence[0] + (BackR * Boost);
    resultColor[1] = ( diffuseG * surfaceColor[1] ) + specularG + incandescence[1] + (BackG * Boost);
    resultColor[2] = ( diffuseB * surfaceColor[2] ) + specularB + incandescence[2] + (BackB * Boost);
    
    outColor = resultColor;
}
{ 
   const MString UserClassify( 
"shader/surface" );
 
   MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"4.5", 
"Any");
 
   CHECK_MSTATUS( plugin.registerNode( 
"backFillShader", BackNode::id, 
 
                         BackNode::creator, BackNode::initialize,
}
{
}