Tuesday, 8 June 2021

Unique Properties of Joints

Joints are very important, very unique objects in Maya. Through the skin cluster deformer they serve as a foundational component of most deforming rigs. But there are a few ways in which they don't behave exactly like other transformable objects. And once you know about these quirks, you'll find you have a few more options than you thought you did when it comes to using joints.

Let's start with the most integral to understand:

Joint Orientation

Joints kind of have... two sets of rotation attributes. That really is the best way to think about it. Joints have the usual rotate X, Y, and Z, visible in the channel box and in the attribute editor. But then, only visible in the attribute editor, under the 'joint' section is another trio of attributes: joint orient X, Y, and Z.

Play around with these attributes and you'll see they really do just appear to be another avenue to rotate the joint. What gives? What's the point?

As useless as it may seem, you will use joint orient constantly while rigging.
In any given rig you almost always want to able to put your joints into rotated starting positions ('bind pose') but still have clean rotate values.

Couldn't I have just put the joint inside a group and offset the group's rotation?
Well... yes. And you still could. I guess Autodesk was just trying to streamline that notion for joints.

The joint orient attributes are evaluated before the rotation of the joint, so you can use joint orient to rotate a joint without changing the values in the rotate attributes. And these can be used in conjunction. Input 45 into the joint orient X and 45 into the rotate X, and the joint's rotation in reference to its parent will be 90 degrees.
Oh, and if you ever find yourself scratching your head wondering why a joint appears to be rotated in a hierarchy without it being reflected in the rotate fields, make sure to check the joint orient in the attribute editor. 9 times out of 10, that's your culprit.

Inverse Scale

Let's start with familiar territory. Let's make a row of three cubes, from left to right, A, B, and C. Parent C to B, and B to A. Almost like the segments of a finger (I'm going to reshape mine a bit to keep with that analogy, but you don't have to).
If we mess with A's scale, cubes B and C will follow suit. Just like you'd expect. After all each cube exists in the space inherited from its parent.

Now let's try a similar scenario with joints. Parent all three of those cubes back to the world.
Make a joint chain, joints 1, 2, and 3, in the positions of those cubes. Bind each cube to its corresponding joints via skin cluster.
Now the joints don't inherit anything from eachother, because they're no longer parented to eachother, but they do follow the joint chain, and the joints are parented to eachother. So if we mess with joint 1's scale, you'd expect to see the same sort of thing as before, right?
And yet...

What is this? You dare defy me, Maya??
Here's what's going on. Select those joints and graph them in your node editor and you'll notice connections running between each parent/child joint pairing.
Odd. The node editor doesn't usually give us any visual indicator of parentage.
Take a closer look and you'll see the connections are going from the parent joint's scale attribute into the child joint's 'inverse scale' attribute.

Inverse scale is an attribute unique to joints, and when you parent one joint to another, this connection is automatically made. What it's essentially doing is taking the scale of the parent joint and feeding inverse values to the child joint on top of the child joint's own scale values. The result is that while the child joint still moves when the parent is scaled  - because its local space is still scaling with the parent - any scaling it might have inherited is nullified.

This is the default scaling behaviour of parented joints, but its by no means your only option. If you're in a situation (such situations do happen) where you'd prefer the joints tp behave like other transform objects, it's simply a matter of severing that connection from scale to inverse scale.

(You can cut connections easily like this by holding shift+alt and click dragging through the connection)
Now scaling is inherited like usual.

You might think its a lot of extra bother to have to opt out of this behaviour, but it's actually a good thing. You will in fact want this unique behaviour on your joints the majority of the time. Suppose we were driving these joints with a chain of controls, with each joint constrained to its corresponding control, and those controls were also parented to eachother in a chain. If each joint were getting its scale from its control via scale constraint and also trying to inherit scale from its parent joint, we'd get double the intended scaling.
But know that you have the option and its as simple as removing a few connections.

Radius

Lastly is the shape of the joints.
If you scale a joint up, it might look like nothing's happening. It's only if something is parented or skinned to it that you can see the effects.
So the shape of the joint doesn't get any bigger or smaller when you scale it, but the transformation is happening.
If its the shape of the joint you want to scale, that's what the joint's unique 'radius' attribute is for.

Most objects in Maya that can be seen in the viewport and transformed are in fact two nodes. A shape node, which itself cannot be transformed but is responsible for the renderable aspect of that object, and that is parented to a transform node, which itself has no renderable qualities, but possesses attributes like translation, rotation, and scale.
Joints are unique in that they are transform node and shape node in one.
I guess Autodesk decided for this reason to split into two attributes the scale of the joint's transform and that of the joint's shape. And it's a good thing too; there are many times you'd want to change the size of how the joint appears in the viewport without actually messing with the scale values.
Most commonly, if two joints are right on top of eachother (which happens a lot) it's hard to select one over the other in the viewport. Giving them different radii makes them visually distinguishable.

Draw Style

While we're on the subject. What if you want to hide a joint, but no any of the joint's children.
If we had an object parented under a locator for instance, and we wanted that locator to be hidden, but not the child object, we couldn't hide the locator's translate, because then that hidden status would be inherited by the child geo. No drama, we'd just hide the locator's shape node instead.
But as I said, joints don't have shape nodes. They are transform and shape all in one. It's perhaps for this reason that Autodesk gave joints yet another unique attribute: draw style.


It can be accessed under the 'joints' section in the attribute editor and your options are bone, multi-child as box, and none.

Bone is the default.
Multi-Child as Box will cause joints with multiple joint children to take a weird box shape... it's an odd addition, I've never known any one to use it.
And None will simply cause the joint not to render in the viewport. This is how you'd hide the joint's shape without switching off its visibility and effecting its children.

No comments:

Post a Comment