Thursday, 10 February 2011

Setting up a forearm roll joint - method 1 of 2

The problem with roll joints is always one of driving them, and that comes down to being able to separate out the twist rotation from the source joint (upper arm/wrist etc. etc.).
The upper arm is pretty tricky in this respect due to the large range of movement and so requires a more complex set up. The forearm, however, is quite a lot easier because the rotation range of the wrist joint within its local coordinate system (of the elbow) is reasonably small.


There are two ways you could set up the twist system. The first is super-quick and 99% stable (but is completely dependent on your wrist joint rotation order for it to work), the second is just as quick but completely stable and doesn't rely on you having optimal wrist rotation orders set.

Actually, if you want to set up a forearm roll joint system I'd definitely do it this way.
The main aim for this post is that it serves as a really great way of exploring rotation orders and the implications they have for your rig. It's quick-to-make practical example of how different orders can affect stability and useablility of the rig and also your own sanity when building more complex systems.



First method:

So, here you can see l_wrist and the local rotation axis for this joint. Here, as with all my skeletons, I have the Y axis pointing down the joint making this my twist rotation. The X axis is the curl rotation, and the Z is the least-used axis being side-to-side rotation.

The aim with any roll system is to somehow extract a stable twist rotation value from the source joint (in this case the wrist) which we can then use to drive our roll joints. In this example I'm going to use the rotateY attribute of the wrist directly, but first we need to set the rotation order of the wrist joint so that this attribute is as stable as possible (more on rotation orders here).

What we want is it set so that whenever the wrist rotates in X and Z that the Y axis is always pointing down the joint. By ensuring that this is the case you give yourself a stable rotateY attribute that you can use to drive your roll joint. You can check whether this is the case or not by setting the rotate tool to gimbal mode and rotating in the X and Z axis and seeing what happens to the Y axis.

In this first video the rotation order is set to the default xyz. Initially as I rotate in gimbal mode you can see that the Y axis does not follow when rotated in X. Setting the rotate tool back to local mode you can see what happens to the rotate attributes when rotating using the Y axis of the rotate tool away from the rest position - all three attributes change. Clearly there is no prospect of using the rotateY channel to drive a roll joint.

So, now we change the rotation order of the wrist joint to yzx. Rotating in gimbal mode you can see that the Y axis follows when rotating in X and Z. Essentially this means that no matter the rotation applied when in local mode, the Y axis shown corresponds directly to the actual Y axis of the joint (it's important to remember that axis displayed with the rotate tool in any mode other than gimbal are not the actual axis of the joint).

The effect of this is that when rotating the Y axis in local mode has the effect of changing the rotateY attribute only. This means that we now have a sufficiently stable attribute from which to drive the forearm roll joints.

To set the roll driver up is extremely simple. Start off, as usual, by duplicating the skinned roll joints and prefixing them with driver_. Create a group called l_foreArm_roll_grp and parent constrain with no offset to l_elbow. Parent both your driver roll joints to this group. Your skinned roll joints should be constrained to these driver joints.

I'm using two roll joints here, it's pretty much the standard I'd use for in-game characters but if you're not concerned about joint budgets or influences per vert I'd go with three or more. In this case l_foreArm_roll_01 represents the mid point of the fore arm, and l_foreArm_roll_02 the area immediately adjacent to the wrist joint. I want l_foreArm_roll_02 to take all of the Y rotation from the wrist and l_foreArm_roll_01 to take half of this.

You can see the skin weighting here, from top to bottom l_elbow, l_foreArm_roll_01, l_foreArm_roll_02 and l_wrist.

Connect l_wrist.rotateY to driver_l_foreArm_roll_02.rotateY. Create a multiplyDivide node called foreArm_roll_divide. Set operation to divide and input2x to 2. Connect l_wrist.rotateY to foreArm_roll_divide.input1X and foreArm_roll_divide.outputX to l_foreArm_roll_01.rotateY.
Now the first roll joint takes half the wrist twist rotation and the second takes all of it.

Once the roll joints are being driven you'll probably want to go back and tweak the skinning a little. This is a capture of the above set up working.


The second method (using aim constrainst) will follow shortly!

No comments:

Post a Comment