#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MPxCustomEvaluator.h>
#include <maya/MCustomEvaluatorClusterNode.h>
#include <maya/MFnDependencyNode.h>
#include <maya/MPlug.h>
#include <maya/MProfiler.h>
#include <maya/MGraphNodeIterator.h>
#include <maya/MFnMatrixData.h>
#include <maya/MPlugArray.h>
#include <maya/MPxTransform.h>
#include <maya/MObjectHandle.h>
#include <map>
namespace
{
}
{
public:
typedef std::map<unsigned int, MObject> TargetMapHash;
virtual ~constraintEvaluator();
virtual const char* evaluatorName();
static void* creator();
void reset();
TargetMapHash fTransformTargetHash;
};
void constraintEvaluator::reset()
{
fTransformTargetHash.clear();
}
{
MObject thisNode = node->dependencyNode(&stat);
if (stat == MS::kSuccess)
{
MString nodeName = depNodeFn.name();
if (depNodeFn.typeName() == "transform")
{
MPlug translateXPlug = depNodeFn.findPlug(
"translateX", &stat);
if (stat != MS::kSuccess) return false;
translateXPlug.
connectedTo(sources,
true ,
false , &stat);
if (stat != MS::kSuccess) return false;
if (sources.
length() != 1)
return false;
MPlug rotateXPlug = depNodeFn.findPlug(
"rotateX", &stat);
if (stat != MS::kSuccess) return false;
rotateXPlug.
connectedTo(sources,
true ,
false , &stat);
if (stat != MS::kSuccess) return false;
if (sources.
length() > 1)
return false;
MPlug pointConstraintTargetTranslatePlug = pointConstraintNode.findPlug(
"targetTranslate",
true, &stat);
if (stat != MS::kSuccess) return false;
if (stat != MS::kSuccess) return false;
MString targetNodeName = sourceNode.name();
MPlug orientConstraintTargetRotatePlug = orientConstraintNode.findPlug(
"targetRotate",
true, &stat);
if (stat != MS::kSuccess) return false;
stat = sourceNode.setObject(orientConstraintTargetRotatePlug.
source().
node());
if (stat != MS::kSuccess) return false;
if (targetNodeName != sourceNode.name()) return false;
return true;
}
else if ((depNodeFn.typeName() == "pointConstraint") || (depNodeFn.typeName() == "orientConstraint"))
{
return true;
}
}
return false;
}
{
}
{
MProfilingScope profilingScope(_profilerCategory, MProfiler::kColorD_L1,
"Evaluate constraint cluster");
if (stat == MS::kSuccess)
{
while (!iterator.isDone())
{
iterator.next(&stat);
MObject currObject = currEvalNode.dependencyNode(&stat);
{
currEvalNode.datablock(&stat).isClean(worldMatrixForPreEval);
{
MProfilingScope profilingScopeParent(_profilerCategory, MProfiler::kColorD_L1,
"Get parent inverse matrix");
MArrayDataHandle parentInverseMatrixArrayHandle = currEvalNode.datablock(&stat).inputArrayValue(parentInverseMatrixPlug.attribute());
if ((stat != MS::kSuccess) || (parentInverseMatrixArrayHandle.
elementCount() == 0))
continue;
if (stat != MS::kSuccess) continue;
if (stat != MS::kSuccess) continue;
MObject parentInverseMatrixData = elementHandle.
data();
if (stat != MS::kSuccess) continue;
piMatrix = fnMatrixData.
matrix(&stat);
}
{
MProfilingScope profilingScopeTarget(_profilerCategory, MProfiler::kColorD_L1,
"Get target matrix");
if (stat != MS::kSuccess) continue;
if (stat != MS::kSuccess) continue;
MObject targetWorldMatrixData = targetWorldMatrixHandle.
data();
MFnMatrixData fnTargetWorldMatrixData(targetWorldMatrixData, &stat);
if (stat != MS::kSuccess) continue;
wMatrix = fnTargetWorldMatrixData.
matrix(&stat);
}
{
MProfilingScope profilingScopeDestination(_profilerCategory, MProfiler::kColorD_L1,
"Compute and write TR");
MMatrix currLocalMatrix = wMatrix * piMatrix;
if (stat != MS::kSuccess) continue;
double rotateVals[3];
stat = transformer.getRotation(rotateVals, ro);
if (stat != MS::kSuccess) continue;
MDataBlock currDataBlock = currEvalNode.datablock(&stat);
if (stat != MS::kSuccess) continue;
currTranslateHandle.
set3Double(translate.
x, translate.
y, translate.
z);
currRotateHandle.
set3Double(rotateVals[0], rotateVals[1], rotateVals[2]);
tPlug.setValue(currTranslateHandle);
rPlug.setValue(currRotateHandle);
}
{
MProfilingScope profilingScopeUpdate(_profilerCategory, MProfiler::kColorD_L1,
"Finalize evaluation and render update");
}
}
}
}
if(stat != MS::kSuccess)
{
MProfilingScope profilingScopeFallback(_profilerCategory, MProfiler::kColorD_L2,
"Fall back to native");
}
}
{
reset();
}
void* constraintEvaluator::creator()
{
constraintEvaluator* newEval = new constraintEvaluator();
newEval->reset();
return ((void*) newEval);
}
const char* constraintEvaluator::evaluatorName()
{
return "ConstraintEvaluator";
}
constraintEvaluator::~constraintEvaluator()
{
}
{
MFnPlugin plugin( obj, PLUGIN_COMPANY,
"3.0",
"Any");
status = plugin.registerEvaluator("ConstraintEvaluator", 42, constraintEvaluator::creator);
if (!status)
{
status.
perror(
"registerEvaluator");
return status;
}
return status;
}
{
status = plugin.deregisterEvaluator( "ConstraintEvaluator" );
if (!status)
{
status.
perror(
"deRegisterEvaluator");
return status;
}
return status;
}