Sunday, December 18, 2005

Stretchiness, Scaling vs Translating

I recall a while back reading a forum which Goosh frequented where people were asking about stretchy limbs, discussing various techniques using joint scaling to make a leg or an arm grow longer. Goosh mentioned that he prefered translations over scaling, and that got me thinking.

First, I understood why he harshed on scaling. The problem with scaling joints is that they work well for anything skinned below the joint stretching it along the bone, but anything above the joint gets stretched backwards. This can be detrimental in areas such as the pelvis where the leg joins up with the hip. If you were to use scaling on the leg joints, any smooth weighting you might have above the pelvis joint will invert, pushing the skin up into the character ever so slightly. The more weight in that area, and the more scaling the joint does, the more it will invert, which can become quite noticable on very cartoony characters.

Second, I wondered what he even meant when he said translations. Did he mean using expressions to drive the world position of the joints, or perhaps using point constraints or parent constraints to wrangle the joints into the positions he wanted. After pondering this for a while I realized that he meant local translations down the joints. You'll notice that whenever you create a joint chain, each child joint has a translation offset, and you can't use Freeze Transformations to remove this offset either. This offset is what tells each child joint how far away from its parent it is. One thing to note about these offsets, in order to unify the offset into a single Translate channel, you MUST ORIENT THE JOINTS FIRST. Doing so will ensure that one of the local axis point down the joint, which is also the direction you want the joint to stretch in.

Using this offset, we can can simulate the effect of scale without the negative effects of the skin inverting above the joints. How? By piping our stretch percentages into the translate channels rather than the scale channels. Sounds pretty simple, but there's a drawback. Scaling works on the fact that it has an original size, and adjusting the scale is simply increasing or decreasing the size of the joint by a factor of that orginal size. Basically, scaling remembers how big it was.

The problem with this is that if you were to pipe the precentage values into the translate channels, when the joints arn't stretched at all, their percentage is zero. This would, in turn, set all the local translation offsets of the child joints to zero. The result being is that all your joints wouldn't be offset, they'd be all overlapping eachother at their local origins.

One of the easiest solutions I've found is to create a custom attribute for each of the joints you plan to stretch and call it "Original Length" or something to that effect. This attribute would be used to store a copy of, what else, the original length, aka: the translate value. You can then multiply the original length by your incoming stretch percentage and pipe that into your translate channel on your joints.

This was a real eye-opener when I first figured it out, I hope it helps anyone out there having to build a stretchy rig. There are lots of options for this sort of thing, and I've found the translation approach works best.

0 Comments:

Post a Comment

<< Home