Last active
October 15, 2024 03:21
-
-
Save gregoiredehame/1af94cce663a844243fe5319fd41b489 to your computer and use it in GitHub Desktop.
c++ plugin for joint parent matrix, that maintain 0.0.0 rotations angles on joints.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <maya/MPxNode.h> | |
| #include <maya/MFnMatrixAttribute.h> | |
| #include <maya/MFnUnitAttribute.h> | |
| #include <maya/MFnNumericAttribute.h> | |
| #include <maya/MFnEnumAttribute.h> | |
| #include <maya/MTransformationMatrix.h> | |
| #include <maya/MGlobal.h> | |
| #include <maya/MQuaternion.h> | |
| #include <maya/MMatrix.h> | |
| #include <maya/MFnPlugin.h> | |
| #include <maya/MVector.h> | |
| #include <maya/MEulerRotation.h> | |
| class ParentJointMatrix : public MPxNode | |
| { | |
| public: | |
| ParentJointMatrix() {} | |
| virtual ~ParentJointMatrix() {} | |
| static void* creator() { return new ParentJointMatrix(); } | |
| static MStatus initialize(); | |
| virtual MStatus compute(const MPlug& plug, MDataBlock& data) override; | |
| static MTypeId id; | |
| // Attributes | |
| static MObject inputMatrix; | |
| static MObject offsetMatrix; | |
| static MObject parentMatrix; | |
| static MObject jointOrient; | |
| static MObject inputRotateOrder; | |
| static MObject outputMatrix; | |
| static MObject outputTranslate; | |
| static MObject outputRotate; | |
| static MObject outputScale; | |
| static MObject outputShear; | |
| }; | |
| MTypeId ParentJointMatrix::id(0x00124dfe); | |
| MObject ParentJointMatrix::inputMatrix = MObject::kNullObj; | |
| MObject ParentJointMatrix::offsetMatrix = MObject::kNullObj; | |
| MObject ParentJointMatrix::parentMatrix = MObject::kNullObj; | |
| MObject ParentJointMatrix::jointOrient = MObject::kNullObj; | |
| MObject ParentJointMatrix::inputRotateOrder = MObject::kNullObj; | |
| MObject ParentJointMatrix::outputMatrix = MObject::kNullObj; | |
| MObject ParentJointMatrix::outputTranslate = MObject::kNullObj; | |
| MObject ParentJointMatrix::outputRotate = MObject::kNullObj; | |
| MObject ParentJointMatrix::outputScale = MObject::kNullObj; | |
| MObject ParentJointMatrix::outputShear = MObject::kNullObj; | |
| MStatus ParentJointMatrix::initialize() | |
| { | |
| MFnMatrixAttribute fnMatrix; | |
| MFnUnitAttribute fnUnit; | |
| MFnNumericAttribute fnNumeric; | |
| MFnEnumAttribute fnEnum; | |
| // INPUTS | |
| inputMatrix = fnMatrix.create("inputMatrix", "im"); | |
| fnMatrix.setStorable(true); | |
| fnMatrix.setKeyable(true); | |
| addAttribute(inputMatrix); | |
| offsetMatrix = fnMatrix.create("offsetMatrix", "ofm"); | |
| addAttribute(offsetMatrix); | |
| parentMatrix = fnMatrix.create("jointParentMatrix", "jpm"); | |
| addAttribute(parentMatrix); | |
| MObject jointOrientX = fnUnit.create("jointOrientX", "jox", MFnUnitAttribute::kAngle, 0.0); | |
| MObject jointOrientY = fnUnit.create("jointOrientY", "joy", MFnUnitAttribute::kAngle, 0.0); | |
| MObject jointOrientZ = fnUnit.create("jointOrientZ", "joz", MFnUnitAttribute::kAngle, 0.0); | |
| jointOrient = fnNumeric.create("jointOrient", "jo", jointOrientX, jointOrientY, jointOrientZ); | |
| addAttribute(jointOrient); | |
| inputRotateOrder = fnEnum.create("inputRotateOrder", "iro", 0); | |
| fnEnum.addField("xyz", 0); | |
| fnEnum.addField("yzx", 1); | |
| fnEnum.addField("zxy", 2); | |
| fnEnum.addField("xzy", 3); | |
| fnEnum.addField("yxz", 4); | |
| fnEnum.addField("zyx", 5); | |
| addAttribute(inputRotateOrder); | |
| // OUTPUTS | |
| outputMatrix = fnMatrix.create("outputMatrix", "om"); | |
| fnMatrix.setStorable(false); | |
| fnMatrix.setWritable(false); | |
| addAttribute(outputMatrix); | |
| MObject outputTranslateX = fnUnit.create("outputTranslateX", "otx", MFnUnitAttribute::kDistance, 0.0); | |
| MObject outputTranslateY = fnUnit.create("outputTranslateY", "oty", MFnUnitAttribute::kDistance, 0.0); | |
| MObject outputTranslateZ = fnUnit.create("outputTranslateZ", "otz", MFnUnitAttribute::kDistance, 0.0); | |
| outputTranslate = fnNumeric.create("outputTranslate", "ot", outputTranslateX, outputTranslateY, outputTranslateZ); | |
| addAttribute(outputTranslate); | |
| MObject outputRotateX = fnUnit.create("outputRotateX", "orx", MFnUnitAttribute::kAngle, 0.0); | |
| MObject outputRotateY = fnUnit.create("outputRotateY", "ory", MFnUnitAttribute::kAngle, 0.0); | |
| MObject outputRotateZ = fnUnit.create("outputRotateZ", "orz", MFnUnitAttribute::kAngle, 0.0); | |
| outputRotate = fnNumeric.create("outputRotate", "or", outputRotateX, outputRotateY, outputRotateZ); | |
| addAttribute(outputRotate); | |
| MObject outputScaleX = fnNumeric.create("outputScaleX", "osx", MFnNumericData::kDouble, 1.0); | |
| MObject outputScaleY = fnNumeric.create("outputScaleY", "osy", MFnNumericData::kDouble, 1.0); | |
| MObject outputScaleZ = fnNumeric.create("outputScaleZ", "osz", MFnNumericData::kDouble, 1.0); | |
| outputScale = fnNumeric.create("outputScale", "os", outputScaleX, outputScaleY, outputScaleZ); | |
| addAttribute(outputScale); | |
| MObject outputShearX = fnNumeric.create("outputShearX", "oshx", MFnNumericData::kDouble, 0.0); | |
| MObject outputShearY = fnNumeric.create("outputShearY", "oshy", MFnNumericData::kDouble, 0.0); | |
| MObject outputShearZ = fnNumeric.create("outputShearZ", "oshz", MFnNumericData::kDouble, 0.0); | |
| outputShear = fnNumeric.create("outputShear", "osh", outputShearX, outputShearY, outputShearZ); | |
| addAttribute(outputShear); | |
| // Attribute Affects | |
| attributeAffects(inputMatrix, outputMatrix); | |
| attributeAffects(inputMatrix, outputTranslate); | |
| attributeAffects(inputMatrix, outputRotate); | |
| attributeAffects(inputMatrix, outputScale); | |
| attributeAffects(inputMatrix, outputShear); | |
| attributeAffects(offsetMatrix, outputMatrix); | |
| attributeAffects(offsetMatrix, outputTranslate); | |
| attributeAffects(offsetMatrix, outputRotate); | |
| attributeAffects(offsetMatrix, outputScale); | |
| attributeAffects(offsetMatrix, outputShear); | |
| attributeAffects(parentMatrix, outputMatrix); | |
| attributeAffects(parentMatrix, outputTranslate); | |
| attributeAffects(parentMatrix, outputRotate); | |
| attributeAffects(parentMatrix, outputScale); | |
| attributeAffects(parentMatrix, outputShear); | |
| attributeAffects(jointOrient, outputMatrix); | |
| attributeAffects(jointOrient, outputTranslate); | |
| attributeAffects(jointOrient, outputRotate); | |
| attributeAffects(jointOrient, outputScale); | |
| attributeAffects(jointOrient, outputShear); | |
| attributeAffects(inputRotateOrder, outputMatrix); | |
| attributeAffects(inputRotateOrder, outputTranslate); | |
| attributeAffects(inputRotateOrder, outputRotate); | |
| attributeAffects(inputRotateOrder, outputScale); | |
| attributeAffects(inputRotateOrder, outputShear); | |
| return MS::kSuccess; | |
| } | |
| MStatus ParentJointMatrix::compute(const MPlug& plug, MDataBlock& data) | |
| { | |
| if (plug == outputMatrix || plug == outputTranslate || plug == outputRotate || plug == outputScale || plug == outputShear) | |
| { | |
| MMatrix inputMat = data.inputValue(inputMatrix).asMatrix(); | |
| MMatrix parentMat = data.inputValue(parentMatrix).asMatrix(); | |
| MMatrix offsetMat = data.inputValue(offsetMatrix).asMatrix(); | |
| // Create the orient matrix based on jointOrient | |
| MTransformationMatrix orientMat; | |
| MVector jointOrientVal = data.inputValue(jointOrient).asVector(); | |
| MEulerRotation jointOrientEuler(jointOrientVal.x, jointOrientVal.y, jointOrientVal.z); | |
| orientMat.rotateBy(jointOrientEuler.asQuaternion(), MSpace::kTransform); | |
| // Calculate the output matrix with joint orientation considered | |
| MTransformationMatrix outputMat(offsetMat * inputMat * parentMat.inverse()); | |
| MTransformationMatrix offsetOrientMat(inputMat * (orientMat.asMatrix() * parentMat).inverse()); | |
| // Replace the rotation of outputMat with offsetOrientMat rotation | |
| MQuaternion offsetRotation = offsetOrientMat.rotation(); | |
| outputMat.setRotationQuaternion(offsetRotation.x, offsetRotation.y, offsetRotation.z, offsetRotation.w); | |
| // Set output matrix | |
| MDataHandle outputMatrixHandle = data.outputValue(outputMatrix); | |
| outputMatrixHandle.setMMatrix(outputMat.asMatrix()); | |
| // Set output translate | |
| MDataHandle outputTranslateHandle = data.outputValue(outputTranslate); | |
| MVector translation = outputMat.getTranslation(MSpace::kTransform); | |
| outputTranslateHandle.set3Double(translation.x, translation.y, translation.z); | |
| // Set output rotate | |
| MDataHandle outputRotateHandle = data.outputValue(outputRotate); | |
| MQuaternion quatRotation = outputMat.rotation(); | |
| MEulerRotation eulerRotation = quatRotation.asEulerRotation(); | |
| outputRotateHandle.set3Double(eulerRotation.x, eulerRotation.y, eulerRotation.z); | |
| // Set output scale | |
| MDataHandle outputScaleHandle = data.outputValue(outputScale); | |
| double scale[3] = { 1.0, 1.0, 1.0 }; | |
| outputMat.getScale(scale, MSpace::kTransform); | |
| outputScaleHandle.set3Double(scale[0], scale[1], scale[2]); | |
| // Set output shear | |
| MDataHandle outputShearHandle = data.outputValue(outputShear); | |
| double shear[3] = { 0.0, 0.0, 0.0 }; | |
| outputMat.getShear(shear, MSpace::kTransform); | |
| outputShearHandle.set3Double(shear[0], shear[1], shear[2]); | |
| // Mark the plug as clean | |
| data.setClean(plug); | |
| } | |
| return MS::kSuccess; | |
| } | |
| MStatus initializePlugin(MObject obj) | |
| { | |
| MFnPlugin plugin(obj, "Gregoire Dehame", "1.0", "Any"); | |
| return plugin.registerNode("parentJointMatrix", ParentJointMatrix::id, ParentJointMatrix::creator, ParentJointMatrix::initialize); | |
| } | |
| MStatus uninitializePlugin(MObject obj) | |
| { | |
| MFnPlugin plugin(obj); | |
| return plugin.deregisterNode(ParentJointMatrix::id); | |
| } |
Author
gregoiredehame
commented
Oct 15, 2024

Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment