|
#include <string.h> |
|
|
|
#include <maya/MPxNode.h> |
|
|
|
#include <maya/MFnNumericAttribute.h> |
|
#include <maya/MFnMatrixAttribute.h> |
|
#include <maya/MFnUnitAttribute.h> |
|
#include <maya/MFnPlugin.h> |
|
|
|
#include <maya/MTypeId.h> |
|
#include <maya/MPlug.h> |
|
#include <maya/MVector.h> |
|
#include <maya/MTransformationMatrix.h> |
|
#include <maya/MMatrix.h> |
|
#include <maya/MDataBlock.h> |
|
#include <maya/MDataHandle.h> |
|
#include <maya/MStreamUtils.h> |
|
|
|
#define Print MStreamUtils::stdErrorStream |
|
|
|
class initialStateNode : public MPxNode { |
|
public: |
|
initialStateNode(); |
|
~initialStateNode() override; |
|
|
|
MStatus compute(const MPlug& plug, MDataBlock& data) override; |
|
MStatus computeOutputTranslate(const MPlug& plug, MDataBlock& data); |
|
|
|
static void* creator() { return new initialStateNode(); } |
|
static MStatus initialize(); |
|
|
|
bool isPassiveOutput(const MPlug& plug) const; |
|
|
|
public: |
|
static MTypeId id; |
|
|
|
// Attributes |
|
static MObject aInWorldMatrix; |
|
static MObject aStartTime; |
|
static MObject aCurrentTime; |
|
static MObject aOutputTranslate; |
|
static MObject aOutputTranslateX; |
|
static MObject aOutputTranslateY; |
|
static MObject aOutputTranslateZ; |
|
|
|
private: |
|
MMatrix _restMatrix; |
|
}; |
|
|
|
|
|
MTypeId initialStateNode::id(0x80012); |
|
MObject initialStateNode::aInWorldMatrix; |
|
MObject initialStateNode::aOutputTranslate; |
|
MObject initialStateNode::aOutputTranslateX; |
|
MObject initialStateNode::aOutputTranslateY; |
|
MObject initialStateNode::aOutputTranslateZ; |
|
MObject initialStateNode::aStartTime; |
|
MObject initialStateNode::aCurrentTime; |
|
|
|
initialStateNode::initialStateNode() {} |
|
initialStateNode::~initialStateNode() {} |
|
|
|
bool initialStateNode::isPassiveOutput(const MPlug& plug) const { |
|
if (plug == aOutputTranslate || |
|
plug == aOutputTranslateX || |
|
plug == aOutputTranslateY || |
|
plug == aOutputTranslateZ) { |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
MStatus initialStateNode::initialize() { |
|
MStatus status; |
|
MFnNumericAttribute numFn; |
|
MFnMatrixAttribute matFn; |
|
MFnUnitAttribute uniFn; |
|
|
|
aStartTime = uniFn.create("startTime", "stti", MFnUnitAttribute::kTime, 0.0, &status); |
|
aCurrentTime = uniFn.create("currentTime", "cuti", MFnUnitAttribute::kTime, 0.0, &status); |
|
|
|
aInWorldMatrix = matFn.create("inWorldMatrix", "inwm"); |
|
|
|
aOutputTranslateX = numFn.create("outputTranslateX", "outx", MFnNumericData::kDouble, 0.0, &status); |
|
aOutputTranslateY = numFn.create("outputTranslateY", "outy", MFnNumericData::kDouble, 0.0, &status); |
|
aOutputTranslateZ = numFn.create("outputTranslateZ", "outz", MFnNumericData::kDouble, 0.0, &status); |
|
aOutputTranslate = numFn.create("outputTranslate", "outr", aOutputTranslateX, aOutputTranslateY, aOutputTranslateZ); |
|
numFn.setWritable(false); |
|
numFn.setStorable(false); |
|
|
|
addAttribute(aStartTime); |
|
addAttribute(aCurrentTime); |
|
addAttribute(aInWorldMatrix); |
|
addAttribute(aOutputTranslate); |
|
|
|
attributeAffects(aCurrentTime, aOutputTranslate); |
|
|
|
return MS::kSuccess; |
|
} |
|
|
|
|
|
MStatus initialStateNode::computeOutputTranslate(const MPlug& plug, MDataBlock& datablock) { |
|
MStatus status { MS::kUnknownParameter }; |
|
|
|
MTransformationMatrix tm { _restMatrix }; |
|
MVector translate = tm.translation(MSpace::kTransform); |
|
|
|
MDataHandle tx = datablock.outputValue(aOutputTranslateX), |
|
ty = datablock.outputValue(aOutputTranslateY), |
|
tz = datablock.outputValue(aOutputTranslateZ); |
|
|
|
tx.set(translate.x); |
|
ty.set(translate.y); |
|
tz.set(translate.z); |
|
|
|
datablock.setClean(plug); |
|
|
|
return status; |
|
} |
|
|
|
|
|
MStatus initialStateNode::compute(const MPlug& plug, MDataBlock& datablock) { |
|
MStatus status { MS::kUnknownParameter }; |
|
|
|
const bool isStartTime = datablock.inputValue(aStartTime).asTime() == |
|
datablock.inputValue(aCurrentTime).asTime(); |
|
|
|
if (plug == aOutputTranslate || |
|
plug == aOutputTranslateX || |
|
plug == aOutputTranslateY || |
|
plug == aOutputTranslateZ) { |
|
|
|
if (isStartTime) { |
|
Print() << "Updating Rest Matrix, but aren't outputting anything.\n"; |
|
_restMatrix = datablock.inputValue(aInWorldMatrix).asMatrix(); |
|
} |
|
else { |
|
Print() << "Outputting new translate values\n"; |
|
status = computeOutputTranslate(plug, datablock); |
|
} |
|
} |
|
|
|
return status; |
|
} |
|
|
|
|
|
MStatus initializePlugin(MObject obj) { |
|
MStatus status; |
|
MFnPlugin plugin(obj, PLUGIN_COMPANY, "3.0", "Any"); |
|
|
|
status = plugin.registerNode("initialStateNode", |
|
initialStateNode::id, |
|
initialStateNode::creator, |
|
initialStateNode::initialize); |
|
if (!status) { |
|
status.perror("registerNode"); |
|
return status; |
|
} |
|
|
|
Print() << "==============\n"; |
|
Print() << "Initialising\n"; |
|
|
|
return status; |
|
} |
|
|
|
|
|
MStatus uninitializePlugin(MObject obj) { |
|
MStatus status; |
|
MFnPlugin plugin(obj); |
|
|
|
status = plugin.deregisterNode(initialStateNode::id); |
|
if (!status) { |
|
status.perror("deregisterNode"); |
|
return status; |
|
} |
|
|
|
Print() << "Deinitialising.\n"; |
|
Print() << "==============\n"; |
|
|
|
return status; |
|
} |