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

# renderAccessNode.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.
    // ==========================================================================
    //+

    // Install the plugin and create a renderAccessNode.  Set the
    // ptWorld attribute to set the point to be converted from world
    // space to screen space.

    #include <maya/MIOStream.h>
    #include <stdlib.h>

    #include <maya/MString.h>
    #include <maya/MTypeId.h>

    #include <maya/MGlobal.h>
    #include <maya/MFnPlugin.h>
    #include <maya/MPxNode.h>

    #include <maya/MPlug.h>
    #include <maya/MDataBlock.h>
    #include <maya/MDataHandle.h>

    #include <maya/MFnNumericAttribute.h>

    #include <maya/MFloatPoint.h>

    #include <maya/MRenderData.h>
    #include <maya/MRenderShadowData.h>
    #include <maya/MRenderUtil.h>
    #include <maya/MRenderCallback.h>

    class myCallback2 : public MRenderCallback
    {
        public:
        myCallback2() {;}
        ~myCallback2() {;}
        void setObj(MObject &obj) { nodeObj = obj;}

        virtual bool shadowCastCallback( const MRenderShadowData &data );
        virtual bool renderCallback( const MRenderData &data );
        virtual bool postProcessCallback( const MRenderData &data );

        private:
        MObject nodeObj;
    };

    // Main Class //

    class renderAccessNode : public MPxNode
    {
        myCallback2 callback;

        public: // Methods

        renderAccessNode();
        virtual         ~renderAccessNode();
        void            postConstructor();

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

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

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

        public:

        // Input
        static MObject     aSamples;
        static MObject     aDist;
        static MObject     aInColor;
        static MObject     aPointWorld;

        static MObject     aOutput;

    };

    // To get 3 float values from the node attribute
    //
    static void getFloat3(MObject node, MObject attr, MFloatPoint & val)
    {
        // Get the attr to use
        //
        MObject object;
        MStatus status;
        MPlug   plug(node, attr);

        CHECK_MSTATUS(plug.getValue(object));

        MFnNumericData data(object, &status);
        CHECK_MSTATUS(status);

        CHECK_MSTATUS(data.getData(val[0], val[1], val[2]));
    }

    bool myCallback2::renderCallback( const MRenderData &data )
    {
        MFloatPoint wp;
        getFloat3( nodeObj, renderAccessNode::aPointWorld, wp );

        fprintf( stderr, "\n*** Render Callback\n\n" );
        fprintf( stderr, "Image: %d %d\n", data.resX, data.resY );
        fprintf( stderr, "region rect: %d %d %d %d\n",
            data.left,
            data.bottom,
            data.right,
            data.top
        );
        return 0;
    }

    bool myCallback2::shadowCastCallback( const MRenderShadowData &data )
    {
        MFloatPoint wp;
        getFloat3( nodeObj, renderAccessNode::aPointWorld, wp );

        fprintf( stderr, "\n*** Shadow cast Callback\n\n" );
        fprintf( stderr, "Light Position (%2.2f, %2.2f, %2.2f), size (%dx%d)\n",
            data.lightPosition.x,
            data.lightPosition.y,
            data.lightPosition.z,
            data.shadowResX,
            data.shadowResY );

        fprintf( stderr, "Light type: %d, perspective: %d\n",
            data.lightType, data.perspective );

        MFloatPoint zp;
        data.worldToZbuffer( wp, zp );

        fprintf( stderr, "World Point( %g, %g, %g) = shadowmap (%g, %g, %g)\n\n",
            wp.x, wp.y, wp.z,
            zp.x, zp.y, zp.z );

        data.zbufferToWorld( zp, wp );

        fprintf( stderr, "shadowmap( %g, %g, %g ) = World Point( %g, %g, %g)\n\n",
            zp.x, zp.y, zp.z,
            wp.x, wp.y, wp.z );

        return 0;
    }

    bool myCallback2::postProcessCallback( const MRenderData &data )
    {
        MFloatPoint wp;
        getFloat3( nodeObj, renderAccessNode::aPointWorld, wp );

        float screenZ;
        MPlug   plug(nodeObj, renderAccessNode::aDist );
        plug.getValue( screenZ );

        fprintf( stderr, "\n*** Post process Callback\n\n" );
        fprintf( stderr, "Image: %d %d\n", data.resX, data.resX );
        fprintf( stderr, "region rect: %d %d %d %d\n",
            data.left,
            data.bottom,
            data.right,
            data.top
        );
        fprintf( stderr, "Data size: %d x %d (%d)\n", data.xsize, data.ysize, data.bytesPerChannel );

        float r, g, b, a;

        r = 0.0;
        g = 255.0;
        b = 255.0;
        a = 255.0;

        //
        // modify rgba and depth values
        //

        short x, y;
        unsigned char *addr;

        for ( y = 0; y < data.ysize/2; y+= 3 )
        {
            for ( x = 0; x < data.xsize/2; x+= 3 )
            {
                addr = data.rgbaArr + ((data.xsize*y+x)*4*data.bytesPerChannel);
                if ( data.bytesPerChannel == 1 )
                {
                    addr[0] = (char)a;  // a
                    addr[1] = (char)b;  // b
                    addr[2] = (char)g;  // g
                    addr[3] = (char)r;  // r
                }
                else
                {
                    addr[0] = (char)a;
                    addr[1] = (char)(((a - (int)(a)) * 256.0));
                    addr[2] = (char)b;
                    addr[3] = (char)(((b - (int)(b)) * 256.0));
                    addr[4] = (char)g;
                    addr[5] = (char)(((g - (int)(g)) * 256.0));
                    addr[6] = (char)r;
                    addr[7] = (char)(((r - (int)(r)) * 256.0));

                }
                data.depthArr[ data.xsize*y+x ] = -0.25;
            }
        }
        MFloatPoint sp;

        data.worldToScreen( wp, sp );

        fprintf( stderr, "\nWorld point: ( %2.2f, %2.2f, %2.2f ) = Screen (%2.2f, %2.2f) depth: %2.2f\n\n",
            wp.x, wp.y, wp.z,
            sp.x, sp.y, sp.z );

        data.screenToWorld( sp, wp );

        fprintf( stderr, "Screen point: ( %2.2f, %2.2f, %2.2f ) = World (%2.2f, %2.2f, %2.2f)\n",
            sp.x, sp.y, sp.z,
            wp.x, wp.y, wp.z );

        fprintf( stderr, "\n" );
        return 0;
    }

    // attribute information

    MTypeId renderAccessNode::id( 0x81018 );

    // input

    MObject     renderAccessNode::aSamples;
    MObject     renderAccessNode::aDist;
    MObject     renderAccessNode::aInColor;
    MObject     renderAccessNode::aPointWorld;

    MObject     renderAccessNode::aOutput;

    renderAccessNode::renderAccessNode()
    {}

    renderAccessNode::~renderAccessNode()
    {
        MRenderCallback::removeCallback( &callback );
    }

    void renderAccessNode::postConstructor()
    {
        MObject obj = thisMObject();
        callback.setObj( obj );
        MRenderCallback::addCallback( &callback, 255 );
    }

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

    // initializes attribute information
    MStatus renderAccessNode::initialize()
    {
        MFnNumericAttribute nAttr;

        // samples

        aSamples = nAttr.create( "samples", "spl", MFnNumericData::kShort, 0 );
        nAttr.setMin(0);
        CHECK_MSTATUS(addAttribute( aSamples ));

        // distance

        aDist = nAttr.create( "distance", "dis", MFnNumericData::kFloat, 0 );
        CHECK_MSTATUS(addAttribute( aDist ));

        // inColor

        aInColor = nAttr.createColor( "inColor", "ic" );
        nAttr.setStorable(false);
        CHECK_MSTATUS(addAttribute( aInColor ));

        // pointWorld

        aPointWorld = nAttr.createPoint( "worldPoint", "wp" );
        nAttr.setStorable(false);
        nAttr.setWritable(true);
        CHECK_MSTATUS(addAttribute( aPointWorld ));

        // Output

        aOutput = nAttr.create( "output", "out", MFnNumericData::kFloat, 1.0 );
        CHECK_MSTATUS(addAttribute( aOutput ));

        attributeAffects( aPointWorld, aOutput );
        attributeAffects( aInColor, aOutput );

        return MS::kSuccess;
    }

    MStatus renderAccessNode::compute( const MPlug& plug, MDataBlock& data)
    {
        if ( plug == renderAccessNode::aOutput )
        {
            MDataHandle outHandle = data.outputValue( aOutput );
            float& of = outHandle.asFloat();
            of = 1.0f;

            outHandle.setClean();
        }

        return MS::kSuccess;
    }

    //
    //
    //

    MStatus initializePlugin( MObject obj )
    {
       const MString UserClassify( "utility/general" );

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

       return MS::kSuccess;

    }

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

        return MS::kSuccess;
    }