Matrix based constraint
Tools & Techart Topics
Recently I have been looking into new ways to add scale information into rigs, not just universal scaling and also in a way that there is no need for a secondary scale joint in order to keep the hierarchy working correctly. the bigest problem that I found with the current setup using constraints in maya is the rotation breaking when the parent of the constrained joint is not scaled universally.
the setup above uses a parentConstraint and a scaleConstraint from the locator on to the child joint. basic translate, rotate and universal scale works perfectly but once you start scaling in a single axis you can see that the rotation does not match with the driver locator. the same thing happens when the segmentScaleCompensation is turned off but then the object even starts to shear.
In order to make this setup work in all different usecases I started looking at one of my matrix constraint plugins, but debugging in c++ can be quite dificult and takes a lot of time. so I converted the base setup into simple maya nodes. This is for debugging purposes only, as the node tax will make this setup quite slow on a rig its best to convert this to a plugin based setup.
the nodegraph above uses in total 3 inputs to drive the output joint: (1) the current driver, the locator (2) the joint orientation on the driven joint (we multiple these into the setup in order to keep the same orientation) (3) the parent joint (in the constraint setup this would be the inverseParentMatrix of the driven joint)
in order to get the joint orient Mixed in, we convert it to quaternions and seperate this from the matrix math (4), the quaterions will calculate the output rotation from the current setup as our new rotation
the worldMatrix of the driver is then used and multiplied with the inverse world matrix of the parent object (5) we only use this for scale and translation
and in order to make sure that the parents scale is not breaking the orientations of the child when non-uniform scale is applied we make sure that the parent matrix is calculated without scale (6), the worldmatrix is decomposed to translate rotate and scale of wich the scale will not be used in the matrix math but applied onto the translation afterwards. this way the child joint will stay in place but will only take the scale information from the driver.
this setup requires a lot of nodes to setup correctly, but can be easily converted to a single node. the setup above works perfectly on jointchains that have segmentScaleCompensate turned on (default in Maya). it can also work with the setting turned off but the math is a bit different. I currently cheated the setup a bit by having the inverse scale calculated and pluged into the offsetParentMatrix of the child joint, but once I have the time again I will try to implement the math into the same setup so it only has to output translate rotate and scale