Maya "inverseScale" without joints?

For fingers and most FK ctrls I want the ability to scale a ctrl, which would push the next ctrls away rather than scaling or scewing anything (to avoid counter scaling when animating and having individual control over e.g. uparm & lowarm length)

With joints; super easy; since they automatically hook up the parentjoint’s local scale to the childjoints inverseScale.

I want that same behaviour with my NURBS ctrl chain! But they don’t seem to have this inverseScale input anywhere. Is there an easy way to hook that up?

I tried hacking it by driving the offsetParentMatrix of the child FK ctrl but I run into shearing. (if there is a rotation offset on the child ctrl like on the elbow)

Currently I’m generating a joint as a child per fk_ctrl to plug the ctrl’s scale into the joint’s inverseScale (joint has same orient as parent & position of child ctrl)


TeachArtistForum
TeachArtistForum2

Get the parentInverse transform of the control and apply the scale component to its child (the joint)

-c

With joints; super easy; since they automatically hook up the parentjoint’s local scale to the childjoints inverseScale.

They do, but the reason you’re seeing that behavior on joints is because of the segment scale compensation setting, which uses that inverseScale plug and is enabled by default on joints. The purpose of it is to remove shearing from joints without affecting their position.

To mimic the behavior of segment-scale-compensated joints, you want the scale that has been propagated to the child removed so there is no shearing, but you still need the parent scale to propagate in some way or otherwise the child will appear not to move, because you need the scale to affect the child’s position.

The simplest way to do this is to allow scale to propagate through parenting, then remove the scale from the child’s local scale channels at the end by only applying the scale component of its parent inverse matrix. You can get that by decomposing the matrix.

(It helps to think of “inverse matrix” as meaning “undo matrix”)

I wasn’t able to get exactly what I want from your suggestion with that simple connection but you sparked an idea with the “undo mtx” and I think I got something that seems to work:

I want all the channels of fkctrl2 to be 0, that’s why there’s the offset matrix. And I found out it was crucial to split the rotation and translation of the offset in order to apply the inverseScale from the parent in between.


i.e. OPM = rotationOffset * invScale * translationOffset


in my script I will not need the offset matrix nodes and will just setAttr() on the OPM node instead. They are static matrixes. Only the scale from the parent is a live connection.


I was not able to get the correct scaleMatrix from the parent using the inverseMatrix output. Because the rotation causes shearing that I can’t remove with a pickMatrix. That’s why I composeMtx and invert it instead.

Does this make sense? Is there a better way to do it?

That sounds right. Doing this operation in code would look pretty similar. You have to build the matrix in that particular order to get the behavior you want without scale affecting anything else.

Alternatively, if you didn’t want to use matrices or wanted to simplify it for scripting purposes then you could insert a group above the child, add a locator in world-space (outside of the control hierarchy) and scale-constrain the inserted group to the locator.

Or, if the “child” wasn’t actually a hierarchical child of the parent, you could point + orient-constrain it to a locator that is a hierarchical child of the parent.