slopeShader/slopeShaderNode.cpp
 
 
 
slopeShader/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;
}