Monday 29 November 2010

Using upper arm roll_01 to help deltoid deformation

In this post I'm going to expand the function of the upper arm roll joint system I posted about here.
The aim is to improve the deltoid deformation as the arm is raised from this

...to this, simply by driving the translateX and rotateZ channels of l_arm_roll_01 via the defDriver_l_arm_roll_01_twistMod joint that makes part of the upper arm roll system.




First off, you need to grab this awesome script. siPoseDeformer is a useful tool I found on HighEnd3d for driving something based on the position of a joint rather than rotation values.

There are two key elements, the nurbs sphere with a greyscale colour ramp and a locator that follows the orientation of the joint you are using as the 'driver' (in this case l_arm). As the arm is rotated the locator position relative to the sphere changes. Using a closestPointOnSurface node, the uvs of the surface at the locator position are extracted and then used to query the colour value of the ramp at that position. This gives a 0-1 value as the arm moves relative to the sphere, 0 for black and 1 for white.


 Setting up the delt deformation

Source the deformer script, select the arm with it in a horizontal position and run si_poseDeformer;
It should create a group called posePositionGRP01. You may need to scale it up to see the sphere (poseFallOffSphere1), set display smoothness to 3 and show textures.
posePositionGRP01 will be parent constrained to the parent of the selected joint, in this case l_shoulder. The locator (poseLocator1) will be orient constrained to l_arm, but I like to replace this with an aim constraint to (in this case) l_elbow as it is much more stable. The up vector of the aim constraint is not important, so you can set it to scene up.
 
Rotate poseFallOffSphere1 90 degrees in Z and open up the attribute editor. Click right until you come to poseFallOffRamp.  Set interpolation to linear, set the white colour position to 0.555 and black colour position to 0.125.

So you can see what's happening, open the attribute editor for poseLocator1 and copy the tab so it remains open when you select the arm. Expand the Extra Attributes frame so you can see the Weight attribute in yellow. Now, as you rotate the arm around you should see this value change from 0 to 1 as poseLocator1 moves relative to the colour ramp on poseFallOffSphere1.

Now it's a simple task to use this weight value to drive some extra attributes on the roll system I covered earlier to improve deltoid deformation.
In the Hypershade, import poseLocator1 and defDriver_l_arm_roll_twistMod to the graph. Create two remap nodes called l_arm_deltLift_tX and l_arm_deltLift_rZ. The first of these will convert the 0 to 1 weight range to translateX, and the second to rotateZ.

Connect poseLocator1.weight to l_arm_deltLift_tX.inputValue and l_arm_deltLift_rZ.inputValue.
Set  l_arm_deltLift_tX.outputMax to -4.0 and l_arm_deltLift_rZ.outputMax to -15. Connect l_arm_deltLift_tX.outValue to defDriver_l_arm_roll_twistMod.translateX and l_arm_deltLift_rZ.outValue defDriver_l_arm_roll_twistMod.rotateZ.
Now, as the arm approaches a horizontal position, the roll joint should raise slightly and rotate in Z and drop down again to its original position as the arm is lowered.

You might need to play around with the remap node values to get the desired effect for your character, and generally I find that I need to tweak the skin weighting for l_arm_roll_01 a little after I've set this up. Also please note that if your joint orientations are different to mine you might need to connect them to different axis.
Here is a quick capture of it working. The right arm is not set up, so you can see the difference in deformation quality.
 
 

3 comments:

  1. Thank you.
    Very clever.

    ReplyDelete
  2. The "this awesome script" link to siPoseDeformer in the third sentence was down but I found this (si_poseDeformer) here: https://www.highend3d.com/maya/script/pose-space-deformer-for-maya

    ReplyDelete