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;
}