#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>
#include <maya/MDrawRegistry.h>
#include <maya/MRenderUtil.h>
#include "phongShaderOverride.h"
{
    public:
                      PhongNode();
    virtual           ~PhongNode();
    static void *     creator();
    private:
    static MObject aDiffuseReflectivity;
 
    static MObject aLightShadowFraction;
 
    static MObject aPreShadowIntensity;
 
    static MObject aTriangleNormalCamera;
 
};
MObject PhongNode::aTranslucenceCoeff;
 
MObject PhongNode::aDiffuseReflectivity;
 
MObject PhongNode::aLightDirection;
 
MObject PhongNode::aLightIntensity;
 
MObject PhongNode::aLightShadowFraction;
 
MObject PhongNode::aPreShadowIntensity;
 
MObject PhongNode::aLightBlindData;
 
MObject PhongNode::aTriangleNormalCamera;
 
#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 PhongNode::postConstructor( )
{
    setMPSafe(true);
}
PhongNode::PhongNode()
{
}
PhongNode::~PhongNode()
{
}
void * PhongNode::creator()
{
    return new PhongNode();
}
{
    aTranslucenceCoeff = nAttr.
create(
"translucenceCoeff", 
"tc",
    MAKE_INPUT(nAttr);
    aDiffuseReflectivity = nAttr.
create(
"diffuseReflectivity", 
"drfl",
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    aIncandescence = nAttr.
createColor( 
"incandescence", 
"ic" );
    MAKE_INPUT(nAttr);
    MAKE_OUTPUT(nAttr);
    aPointCamera = nAttr.
createPoint( 
"pointCamera", 
"pc" );
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    MAKE_INPUT(nAttr);
    aNormalCamera = nAttr.
createPoint( 
"normalCamera", 
"n" );
    MAKE_INPUT(nAttr);
    aTriangleNormalCamera = nAttr.
createPoint( 
"triangleNormalCamera", 
"tn" );
    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);
                     false, 0.0f, 1.0f, NULL) );
    
    aRayOrigin = nAttr.
create( 
"rayOrigin", 
"rog", RayX, RayY, RayZ );
    
    aRayDirection = nAttr.
create( 
"rayDirection", 
"rad", RayX, RayY, RayZ );
    
    
    aRaySampler = nAttr.
createAddr(
"raySampler", 
"rtr");
    
    CHECK_MSTATUS ( attributeAffects (aTranslucenceCoeff, aOutColor));
 
    CHECK_MSTATUS ( attributeAffects (aDiffuseReflectivity, aOutColor));
 
    CHECK_MSTATUS ( attributeAffects (aTriangleNormalCamera, 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;
    diffuseR = diffuseG = diffuseB = specularR = specularG = specularB = 0.0;
    
    
    for( int count=1; count <= numLights; count++ )
    {
        
        void*& blindData = currentLight.
child( aLightBlindData ).
asAddr();
 
        
            diffuseR += lightIntensity[0];
            diffuseG += lightIntensity[1];
            diffuseB += lightIntensity[2];
        }
        if ( blindData == NULL )
        {
            
            {
                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.0f ) 
                {
                    float RV = ( ( (2*surfaceNormal) * cosln ) - lightDirection ) * cameraPosition;
                    if( RV > 0.0 ) RV = 0.0;
                    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;
                }
            }
        }
        else
        {
            if( cosln > 0.0f )  
            {
                 diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity );
                 diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity );
                 diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity );
            }
            {
                float lightAttenuation = 1.0;
                                        lightDirection, point, surfaceNormal, direction );
                
                if ( specLightDirection * surfaceNormal > 0.0f )
                {
                    MFloatVector rv = 2 * surfaceNormal * ( surfaceNormal * direction ) - direction;
 
                    float s = spec * powf( rv * specLightDirection, power2 );
                    specularR += lightIntensity[0] * s * lightAttenuation;
                    specularG += lightIntensity[1] * s * lightAttenuation;
                    specularB += lightIntensity[2] * s * lightAttenuation;
                }
             }
       }
       if( !lightData.
next() ) 
break;
 
    }
    
    resultColor[0] = ( diffuseR * surfaceColor[0] ) + specularR + incandescence[0];
    resultColor[1] = ( diffuseG * surfaceColor[1] ) + specularG + incandescence[1];
    resultColor[2] = ( diffuseB * surfaceColor[2] ) + specularB + incandescence[2];
    
    if (reflectGain > 0.0) {
        
        
        
        void*& samplerPtr = samplerH.
asAddr();
 
        
        float dot = l * normal;
        if( dot < 0.0 ) dot = -dot;
        float dotRef = refVector * triangleNormal;
        if( dotRef < 0.0 ) {
            const float s = 0.01f;
            refVector = mVec + s * triangleNormal;
        }
                point,      
                refVector,  
                objId,      
                samplerPtr, 
                depth,      
                reflectColor,   
                reflectTransparency);
        
        resultColor[0] += reflectGain * (reflectColor[0]);
        resultColor[1] += reflectGain * (reflectColor[1]);
        resultColor[2] += reflectGain * (reflectColor[2]);
    }
    
    outColor = resultColor;
}
static const MString sRegistrantId(
"phongShaderPlugin");
 
{
   const MString UserClassify( 
"shader/surface:drawdb/shader/surface/phongNode" );
 
   MFnPlugin plugin( obj, PLUGIN_COMPANY, 
"4.5", 
"Any");
 
                         PhongNode::creator, PhongNode::initialize,
            "drawdb/shader/surface/phongNode",
            sRegistrantId,
            phongShaderOverride::creator));
}
{
        "drawdb/shader/surface/phongNode", sRegistrantId));
}