solidCheckerShader/solidCheckerShader.cpp
 
 
 
solidCheckerShader/solidCheckerShader.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/MGlobal.h>
#include <maya/MPxNode.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/MFnMatrixAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFloatPoint.h>
#include <maya/MFloatMatrix.h>
#include <maya/MFnPlugin.h>

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

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

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

        //  Id tag for use with binary file format
        static const MTypeId id;

        private:

        // Input attributes
        static MObject aColor1;
        static MObject aColor2;
        static MObject aPlaceMat;
        static MObject aPointWorld;
    static MObject aBias;

        // Output attributes
        static MObject aOutColor;
        static MObject aOutAlpha;
};


// Static data
const MTypeId mySChecker::id( 0x8100b );

// Attributes
MObject        mySChecker::aColor1;
MObject        mySChecker::aColor2;
MObject        mySChecker::aPlaceMat;
MObject        mySChecker::aPointWorld;
MObject        mySChecker::aBias;
 
MObject        mySChecker::aOutColor;
MObject        mySChecker::aOutAlpha;

#define MAKE_INPUT(attr)                                                                \
    attr.setKeyable(true);  attr.setStorable(true);             \
    attr.setReadable(true); attr.setWritable(true);

#define MAKE_OUTPUT(attr)                                                               \
    attr.setKeyable(false); attr.setStorable(false);    \
    attr.setReadable(true); attr.setWritable(false);

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

mySChecker::mySChecker()
{
}

mySChecker::~mySChecker()
{
}

// creates an instance of the node
void * mySChecker::creator()
{
    return new mySChecker();
}

// initializes attribute information
MStatus mySChecker::initialize()
{
    MFnMatrixAttribute mAttr; 
    MFnNumericAttribute nAttr; 
        MObject x, y, z;

        aColor1 = nAttr.createColor("color1", "c1");
        MAKE_INPUT(nAttr);
        nAttr.setDefault(0., .58824, .644);             // Light blue

        aColor2 = nAttr.createColor("color2", "c2");
        MAKE_INPUT(nAttr);
        nAttr.setDefault(1., 1., 1.);                   // White

    aBias = nAttr.create( "bias", "b", MFnNumericData::k3Float);
        MAKE_INPUT(nAttr);
    nAttr.setMin(0.0f);
    nAttr.setMax(1.0f);
    nAttr.setDefault(0.5f, 0.5f, 0.5f);

    aPlaceMat = mAttr.create("placementMatrix", "pm",
                                                         MFnMatrixAttribute::kFloat);
    MAKE_INPUT(mAttr);

        // Internal shading attribute, implicitely connected.
    aPointWorld = nAttr.createPoint("pointWorld", "pw");
        MAKE_INPUT(nAttr);
    nAttr.setHidden(true);

        // Create output attributes
    aOutColor = nAttr.createColor("outColor", "oc");
        MAKE_OUTPUT(nAttr);

    aOutAlpha = nAttr.create( "outAlpha", "oa", MFnNumericData::kFloat);
        MAKE_OUTPUT(nAttr);

    // Add the attributes here
    addAttribute(aColor1);
    addAttribute(aColor2);
    addAttribute(aPointWorld);
    addAttribute(aPlaceMat);
    addAttribute(aBias);

    addAttribute(aOutColor);
    addAttribute(aOutAlpha);

    // all input affect the output color and alpha
    attributeAffects (aColor1, aOutColor);
    attributeAffects (aColor1, aOutAlpha);

    attributeAffects (aColor2, aOutColor);
    attributeAffects (aColor2, aOutAlpha);

    attributeAffects (aPointWorld, aOutColor);
    attributeAffects (aPointWorld, aOutAlpha);

    attributeAffects (aPlaceMat, aOutColor);
    attributeAffects (aPlaceMat, aOutAlpha);

    attributeAffects (aBias, aOutColor);
    attributeAffects (aBias, aOutAlpha);

    return MS::kSuccess;
}


//
// This function gets called by Maya to evaluate the texture.
//
MStatus mySChecker::compute(const MPlug& plug, MDataBlock& block) 
{
        // outColor or individial R, G, B channel, or alpha
    if((plug != aOutColor) && (plug.parent() != aOutColor) && 
           (plug != aOutAlpha))
                return MS::kUnknownParameter;

        MFloatVector resultColor;
        float3 & worldPos = block.inputValue(aPointWorld).asFloat3();
        MFloatMatrix& mat = block.inputValue(aPlaceMat).asFloatMatrix();
    float3 & bias = block.inputValue(aBias).asFloat3();

        MFloatPoint pos(worldPos[0], worldPos[1], worldPos[2]);
        pos *= mat;                                                             // Convert into solid space

    // normalize the point
    int count = 0;
        if (pos.x - floor(pos.x) < bias[0]) count++;
        if (pos.y - floor(pos.y) < bias[1]) count++;
        if (pos.z - floor(pos.z) < bias[2]) count++;

    if (count & 1)
                resultColor = block.inputValue(aColor2).asFloatVector();
        else
                resultColor = block.inputValue(aColor1).asFloatVector();

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

    // Set ouput alpha attribute
        MDataHandle outAlphaHandle = block.outputValue( aOutAlpha );
        float& outAlpha = outAlphaHandle.asFloat();
        outAlpha = ( count & 1) ? 1.0f : 0.0f;
        outAlphaHandle.setClean();

    return MS::kSuccess;
}


MStatus initializePlugin( MObject obj )
{
    const MString UserClassify( "texture/3d" );

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

    return MS::kSuccess;
}

MStatus uninitializePlugin( MObject obj )
{
    MFnPlugin plugin( obj );
    plugin.deregisterNode( mySChecker::id );

    return MS::kSuccess;
}