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

# displacementShader.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 <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/MFnNumericAttribute.h>
    #include <maya/MFloatVector.h>
    #include <maya/MFnPlugin.h>

    //
    // DESCRIPTION:

    class DispNode : public MPxNode
    {
        public:
                      DispNode();
        virtual      ~DispNode();

        virtual MStatus compute( const MPlug&, MDataBlock& );
        virtual void    postConstructor();

        static  void *  creator();
        static  MStatus initialize();

        static  MTypeId id;

        private:

        static MObject aColor;
        static MObject aInputValue;
        static MObject aOutColor;
        static MObject aOutTransparency;
        static MObject aOutDisplacement;
    };

    MTypeId DispNode::id( 0x81011 );

    MObject DispNode::aColor;
    MObject DispNode::aInputValue;
    MObject DispNode::aOutColor;
    MObject DispNode::aOutTransparency;
    MObject DispNode::aOutDisplacement;

    void DispNode::postConstructor( )
    {
        setMPSafe(true);
    }

    //
    // DESCRIPTION:
    DispNode::DispNode()
    {
    }

    //
    // DESCRIPTION:
    DispNode::~DispNode()
    {
    }

    //
    // DESCRIPTION:
    void* DispNode::creator()
    {
        return new DispNode();
    }

    //
    // DESCRIPTION:
    MStatus DispNode::initialize()
    {
        MFnNumericAttribute nAttr;

        // Inputs
        aColor = nAttr.createColor( "color", "c" );
        CHECK_MSTATUS(nAttr.setKeyable(true));
        CHECK_MSTATUS(nAttr.setStorable(true));
        CHECK_MSTATUS(nAttr.setDefault(1.0f, 1.0f, 1.0f));

        aInputValue = nAttr.create( "factor", "f", MFnNumericData::kFloat);
        CHECK_MSTATUS(nAttr.setKeyable(true));
        CHECK_MSTATUS(nAttr.setStorable(true));
        CHECK_MSTATUS(nAttr.setDefault(1.0f));

        // Outputs

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

        aOutTransparency  = nAttr.createColor( "outTransparency", "ot" );
        CHECK_MSTATUS(nAttr.setStorable(false));
        CHECK_MSTATUS(nAttr.setHidden(false));
        CHECK_MSTATUS(nAttr.setReadable(true));
        CHECK_MSTATUS(nAttr.setWritable(false));

        aOutDisplacement = nAttr.create( "displacement", "od",
                                         MFnNumericData::kFloat);
        CHECK_MSTATUS(nAttr.setStorable(false));
        CHECK_MSTATUS(nAttr.setHidden(false));
        CHECK_MSTATUS(nAttr.setReadable(true));
        CHECK_MSTATUS(nAttr.setWritable(false));

        CHECK_MSTATUS(addAttribute(aColor));
        CHECK_MSTATUS(addAttribute(aInputValue));
        CHECK_MSTATUS(addAttribute(aOutColor));
        CHECK_MSTATUS(addAttribute(aOutTransparency));
        CHECK_MSTATUS(addAttribute(aOutDisplacement));

        CHECK_MSTATUS(attributeAffects (aColor, aOutColor));
        CHECK_MSTATUS(attributeAffects (aColor, aOutDisplacement));

        return MS::kSuccess;
    }

    //
    // DESCRIPTION:
    MStatus DispNode::compute(
    const MPlug&      plug,
          MDataBlock& block )
    {
        if ((plug == aOutColor) || (plug.parent() == aOutColor) ||
            (plug == aOutDisplacement))
        {
            MFloatVector resultColor(0.0,0.0,0.0);

            MFloatVector&  InputColor = block.inputValue( aColor ).asFloatVector();
            float MultValue = block.inputValue( aInputValue ).asFloat();

            resultColor = InputColor;

            float scalar = resultColor[0] + resultColor[1] + resultColor[2];
            if (scalar != 0.0) {
                scalar /= 3.0;
                scalar *= MultValue;
            }

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

            MDataHandle outDispHandle = block.outputValue( aOutDisplacement );
            float& outDisp = outDispHandle.asFloat();
            outDisp = scalar;
            outDispHandle.setClean( );
        }
        else if ((plug == aOutTransparency) || (plug.parent() == aOutTransparency))
        {
            // set output transparency to be opaque
            MFloatVector transparency(0.0,0.0,0.0);
            MDataHandle outTransHandle = block.outputValue( aOutTransparency );
            MFloatVector& outTrans = outTransHandle.asFloatVector();
            outTrans = transparency;
            outTransHandle.setClean( );
        }
        else
            return MS::kUnknownParameter;

        return MS::kSuccess;
    }

    //
    // DESCRIPTION:
    MStatus initializePlugin( MObject obj )
    {
       const MString UserClassify( "shader/displacement" );

       MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any");
       CHECK_MSTATUS( plugin.registerNode( "dispNodeExample", DispNode::id,
                             DispNode::creator, DispNode::initialize,
                             MPxNode::kDependNode, &UserClassify ) );

       return MS::kSuccess;
    }

    //
    // DESCRIPTION:
    MStatus uninitializePlugin( MObject obj )
    {
       MFnPlugin plugin( obj );
       CHECK_MSTATUS( plugin.deregisterNode( DispNode::id ) );

       return MS::kSuccess;
    }