offsetNode.cpp
#include <string.h>
#include <maya/MIOStream.h>
#include <math.h>
#include <maya/MPxDeformerNode.h> 
#include <maya/MItGeometry.h>
#include <maya/MPxLocatorNode.h> 
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MFnMatrixData.h>
#include <maya/MFnPlugin.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MTypeId.h> 
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MPoint.h>
#include <maya/MVector.h>
#include <maya/MMatrix.h>
#include <maya/MDagModifier.h>
class offset : public MPxDeformerNode
{
public:
                                                offset();
        virtual                         ~offset();
        static  void*           creator();
        static  MStatus         initialize();
        
        
    virtual MStatus                     deform(MDataBlock&              block,
                                                                           MItGeometry&         iter,
                                                                           const MMatrix&       mat,
                                                                           unsigned int         multiIndex);
        
        
        virtual MObject&                        accessoryAttribute() const;
        
        
        virtual MStatus                         accessoryNodeSetup(MDagModifier& cmd);
public:
        
        static  MObject     offsetMatrix;       
        
        static  MTypeId         id;
private:
};
MTypeId     offset::id( 0x8000c );
MObject         offset::offsetMatrix;
offset::offset() {}
offset::~offset() {}
void* offset::creator()
{
        return new offset();
}
MStatus offset::initialize()
{
        
        MFnMatrixAttribute  mAttr;
        offsetMatrix=mAttr.create( "locateMatrix", "lm");
            mAttr.setStorable(false);
                mAttr.setConnectable(true);
        
        addAttribute( offsetMatrix);
        attributeAffects( offset::offsetMatrix, offset::outputGeom );
        return MStatus::kSuccess;
}
MStatus
offset::deform( MDataBlock& block,
                                MItGeometry& iter,
                                const MMatrix& ,
                                unsigned int multiIndex)
{
        MStatus returnStatus;
        
        
        
        
        MDataHandle envData = block.inputValue(envelope, &returnStatus);
        if (MS::kSuccess != returnStatus) return returnStatus;
        float env = envData.asFloat();  
        
        
        
        MDataHandle matData = block.inputValue(offsetMatrix, &returnStatus );
        if (MS::kSuccess != returnStatus) return returnStatus;
        MMatrix omat = matData.asMatrix();
        MMatrix omatinv = omat.inverse();
        
        
        for ( ; !iter.isDone(); iter.next()) {
                MPoint pt = iter.position();
                pt *= omatinv;
                
                float weight = weightValue(block,multiIndex,iter.index());
                
                
                
                pt.y = pt.y + env*weight;
                
                
                pt *= omat;
                iter.setPosition(pt);
        }
        return returnStatus;
}
MObject&
offset::accessoryAttribute() const
{
        return offset::offsetMatrix;
}
MStatus
offset::accessoryNodeSetup(MDagModifier& cmd)
{
        MStatus result;
        
        
        MObject objLoc = cmd.createNode(MString("locator"),
                                                                        MObject::kNullObj,
                                                                        &result);
        if (MS::kSuccess == result) {
                MFnDependencyNode fnLoc(objLoc);
                MString attrName;
                attrName.set("matrix");
                MObject attrMat = fnLoc.attribute(attrName);
                result = cmd.connect(objLoc,attrMat,this->thisMObject(),offset::offsetMatrix);
        }
        return result;
}
MStatus initializePlugin( MObject obj )
{
        MStatus result;
        MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
        result = plugin.registerNode( "offset", offset::id, offset::creator, 
                                                                  offset::initialize, MPxNode::kDeformerNode );
        return result;
}
MStatus uninitializePlugin( MObject obj)
{
        MStatus result;
        MFnPlugin plugin( obj );
        result = plugin.deregisterNode( offset::id );
        return result;
}