- Main Page
- Related Pages
- Modules
- Classes
- Examples

# slopeShaderNode.cpp

    //-
    // ==========================================================================
    // Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
    //
    // Use of this software is subject to the terms of the Autodesk
    // license agreement provided at the time of installation or download,
    // or which otherwise accompanies this software in either electronic
    // or hard copy form.
    // ==========================================================================
    //+

    #include <math.h>

    #include <slopeShaderNode.h>
    #include <maya/MDataBlock.h>
    #include <maya/MDataHandle.h>
    #include <maya/MFloatVector.h>
    #include <maya/MFnNumericAttribute.h>
    #include <maya/MFnMatrixAttribute.h>
    #include <maya/MFnTypedAttribute.h>
    #include <maya/MFnGenericAttribute.h>

    #define AWdegreesToRadians 0.0174532925199432957692369076848f

    MTypeId slopeShaderNode::id( 0x81005 );

    //Input values
    //
    MObject slopeShaderNode::aAngle;
    MObject slopeShaderNode::aColor1;
    MObject slopeShaderNode::aColor2;

    //Rendering attributes
    //
    MObject slopeShaderNode::aTriangleNormalCamera;
    MObject slopeShaderNode::aMatrixEyeToWorld;

    //Output color
    //
    MObject slopeShaderNode::aOutColor;

    //Dummy plug for forcing
    //an evaluation of this node
    //
    MObject slopeShaderNode::aDirtyShaderAttr;

    slopeShaderNode::slopeShaderNode()
    //
    //  Description:
    //      Constructor
    //
    {
    }

    void slopeShaderNode::postConstructor( )
    //
    //  Description:
    //      postConstructor
    //
    {
        setMPSafe(true);
    }

    slopeShaderNode::~slopeShaderNode()
    //
    //  Description:
    //      Descructor
    //
    {
    }

    void* slopeShaderNode::creator()
    //
    //  Description:
    //      Returns a new instance of this class
    //
    {
        return new slopeShaderNode();
    }

    MStatus slopeShaderNode::initialize()
    //
    //  Description:
    //      Initializes the attributes for this node.
    //
    {
         MFnNumericAttribute nAttr;
         MFnMatrixAttribute nMAttr;
         MFnTypedAttribute nTAttr;
         MFnGenericAttribute nGAttr;

        // Input Attributes
        //
        aAngle = nAttr.create( "angle", "ang", MFnNumericData::kFloat);
        nAttr.setDefault(30.0f);
        nAttr.setMin(0.0f);
        nAttr.setMax(100.0f);
        nAttr.setKeyable(true);
        nAttr.setStorable(true);
        nAttr.setReadable(true);
        nAttr.setWritable(true);

        aColor1 = nAttr.createColor( "walkableColor", "w" );
        nAttr.setDefault(0.0f, 1.0f, 0.0f);
        nAttr.setKeyable(true);
        nAttr.setStorable(true);
        nAttr.setUsedAsColor(true);
        nAttr.setReadable(true);
        nAttr.setWritable(true);

        aColor2 = nAttr.createColor( "nonWalkableColor", "nw" );
        nAttr.setDefault(1.0f, 0.0f, 0.0f);
        nAttr.setKeyable(true);
        nAttr.setStorable(true);
        nAttr.setUsedAsColor(true);
        nAttr.setReadable(true);
        nAttr.setWritable(true);

        // Surface Normal supplied by the render sampler
        //
        aTriangleNormalCamera = nAttr.createPoint( "triangleNormalCamera", "n" );
        nAttr.setStorable(false);
        nAttr.setHidden(true);
        nAttr.setReadable(true);
        nAttr.setWritable(true);

        //View matrix from the camera into world space
        //
        aMatrixEyeToWorld = nMAttr.create( "matrixEyeToWorld", "mew",
                                           MFnMatrixAttribute::kFloat );
        nAttr.setHidden(true);
        nMAttr.setWritable(true);

        // Output Attributes
        //
        aOutColor  = nAttr.createColor( "outColor", "oc" );
        nAttr.setStorable(false);
        nAttr.setHidden(false);
        nAttr.setReadable(true);
        nAttr.setWritable(false);

        //dummy plug for forcing evaluation
        //
        aDirtyShaderAttr = nGAttr.create( "dirtyShaderPlug", "dsp");
        nGAttr.setArray(true);
        nGAttr.setHidden(false);
        nGAttr.setUsesArrayDataBuilder(true);
        nGAttr.setReadable(false);
        nGAttr.setStorable(true);
        nGAttr.setIndexMatters(false);
        nGAttr.addAccept(MFnData::kMesh);

        //Add attribues
        addAttribute(aAngle);
        addAttribute(aColor1);
        addAttribute(aColor2);
        addAttribute(aTriangleNormalCamera);
        addAttribute(aOutColor);
        addAttribute(aMatrixEyeToWorld);
        addAttribute(aDirtyShaderAttr);

        attributeAffects (aAngle,  aOutColor);
        attributeAffects (aColor1, aOutColor);
        attributeAffects (aColor2, aOutColor);
        attributeAffects (aTriangleNormalCamera,  aOutColor);
        attributeAffects (aDirtyShaderAttr, aOutColor);

        return MS::kSuccess;
    }

    MStatus slopeShaderNode::compute(const MPlug & plug, MDataBlock & block )
    //
    //  Description:
    //      Computes a color value
    //  from a surface noraml angle.
    //
    {
        if ((plug != aOutColor) && (plug.parent() != aOutColor))
            return MS::kUnknownParameter;

        MFloatVector resultColor;

        MFloatVector&  walkable = block.inputValue( aColor1 ).asFloatVector();
        MFloatVector&  nonWalkable = block.inputValue( aColor2 ).asFloatVector();
        MFloatVector&  surfaceNormal = block.inputValue( aTriangleNormalCamera ).asFloatVector();
        MFloatMatrix&  viewMatrix = block.inputValue( aMatrixEyeToWorld ).asFloatMatrix();
        float angle = block.inputValue( aAngle ).asFloat();

        // Normalize the view vector
        //
        surfaceNormal.normalize();
        MFloatVector WSVector = surfaceNormal * viewMatrix;

        // find dot product
        //
        float scalarNormal = WSVector * MFloatVector(0, 1, 0);

        // take the absolute value
        //
        if (scalarNormal < 0.0) scalarNormal *= -1.0;

        if(cos(angle*AWdegreesToRadians) < scalarNormal)
            resultColor = walkable;
        else
            resultColor = nonWalkable;

        // set ouput color attribute
        //
        MDataHandle outColorHandle = block.outputValue( aOutColor );
        MFloatVector& outColor = outColorHandle.asFloatVector();
        outColor = resultColor;
        outColorHandle.setClean();

        return MS::kSuccess;
    }