simpleSolverNode.cpp
#include <maya/MIOStream.h>
#include <maya/MPxIkSolverNode.h>
#include <maya/MString.h>
#include <maya/MFnPlugin.h>
#include <maya/MObject.h>
#include <maya/MIkHandleGroup.h>
#include <maya/MFnIkHandle.h>
#include <maya/MDagPath.h>
#include <maya/MVector.h>
#include <maya/MPoint.h>
#include <maya/MDoubleArray.h>
#define MAX_ITERATIONS 1
#define kSolverType "simpleSolverNode"
class simpleSolverNode : public MPxIkSolverNode {
public:
                                        simpleSolverNode();
    virtual                     ~simpleSolverNode();
        virtual MStatus doSolve();
        virtual MString solverTypeName() const;
        static  void*   creator();
        static  MStatus         initialize();
        static  MTypeId id;
private:
        MStatus                 doSimpleSolver();
};
MTypeId simpleSolverNode::id( 0x80100 );
simpleSolverNode::simpleSolverNode()
        : MPxIkSolverNode()
{
        
}
simpleSolverNode::~simpleSolverNode() {}
void* simpleSolverNode::creator()
{
        return new simpleSolverNode;
}
MStatus simpleSolverNode::initialize()
{ 
        return MS::kSuccess;
}
MString simpleSolverNode::solverTypeName() const
{
        return MString( kSolverType );
}
MStatus simpleSolverNode::doSolve()
{
        doSimpleSolver();
        return MS::kSuccess;
}
MStatus simpleSolverNode::doSimpleSolver()
{
        MStatus stat;
        
        
        MIkHandleGroup * handle_group = handleGroup();
        if (NULL == handle_group) {
                return MS::kFailure;
        }
        MObject handle = handle_group->handle( 0 );
        MDagPath handlePath = MDagPath::getAPathTo( handle );
        MFnIkHandle fnHandle(handlePath, &stat);
        
        
        MDagPath end_effector;
        fnHandle.getEffector(end_effector);
        MFnTransform tran( end_effector );
        MPoint effector_position = tran.rotatePivot( MSpace::kWorld );
        
        
        MPoint handle_position = fnHandle.rotatePivot( MSpace::kWorld );
        
        
        MDagPath start_joint;
        fnHandle.getStartJoint( start_joint );
        MFnTransform start_transform( start_joint );
        MPoint start_position = start_transform.rotatePivot( MSpace::kWorld );
        
        
        MVector v1 = start_position - effector_position;
        MVector v2 = start_position - handle_position;
        double angle = v1.angle( v2 );
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        #define CW               rot = -1.0 * angle;    // clockwise
        #define CCW              rot = angle;                   // counter-clockwise
        double rot = 0.0;       
        
        
        MVector U = effector_position - start_position;
        U.normalize();
        
        
        
        MVector zAxis( 0.0, 0.0, 1.0 );
        MVector N = U ^ zAxis;  
        N.normalize();
        
        
        MVector P = handle_position - effector_position;
        
        
        double PdotN = P[0]*N[0] + P[1]*N[1];
        if ( PdotN < 0 ) {
                CCW;
        } else {
                CW;
        }
        
        
        MDoubleArray jointAngles;
        if ( getJointAngles( jointAngles ) ) {
                jointAngles.set( jointAngles[0] + rot, 0 );
                setJointAngles( jointAngles );
        }
        return MS::kSuccess;
}
MStatus initializePlugin( MObject obj )
{
        MStatus                 status;
        MFnPlugin       plugin( obj, PLUGIN_COMPANY, "3.0", "Any");
        status = plugin.registerNode("simpleSolverNode", 
                                                                 simpleSolverNode::id,
                                                                 &simpleSolverNode::creator,
                                                                 &simpleSolverNode::initialize,
                                                                 MPxNode::kIkSolverNode);
        if (!status) {
                status.perror("registerNode");
                return status;
        }
        return status;
}
MStatus uninitializePlugin( MObject obj )
{
        MStatus                 status;
        MFnPlugin       plugin( obj );
        status = plugin.deregisterNode(simpleSolverNode::id);
        if (!status) {
                status.perror("deregisterNode");
                return status;
        }
        return status;
}