Tag: mel

Pose library

Having a break in the job on hands, I find I need a few more others tools beyond my autorig script to ease my work. Years ago I modified the poseMan script and used it for a while. Actually there are some popular free alternatives with fancy GUI but I like how straight forward it look and use. With time I may rewrite it before messing up the original codes too much.


Work in Progress

Couple of busy weeks again continuing the rigging of a few characters for a TV commercial. It could be a long page of ideas to share but I’m in a hurry to finish the tasks on hand. Here captured my most recent autorig tool, if someone is interested to see.


Weight Painting Tool

I’m trying to do weight painting suggested in the tutorial : Expressive Facial Rigging by Josh Sobel. His workflow involves selection of target vertices, adding weight of 1 to target joint, and applying proper smoothing with unneeded joints locked. Maya’s paint skin weights tool is barely enough so I want more.

  1. Better view of weight assignment.
  2. Quick switching between paint mode and selection mode.
  3. Sliders for quick test on translation / rotation.
  4. Working mirroring even with joints translated / rotated.
  5. Working mirroring even with RHS vertices assigned to LHS joints.
  6. Nice weight relaxation on selected vertices.

The last two weeks I’ve been creating and testing one, with the above (1) to (4) working. The initial idea was from the script sdd_weightTools ( by leifeng ). Feature (5) and (6) are actually nicely done in the script ngSkinTools ( by Viktoras Makauskas ). These two are harder to implement since they may involve python API. Hoping to learn it one day and have these integrated. I already have tons of tools messing around !


Soft IK

If you haven’t heard of soft IK before, please read http://www.softimageblog.com/archives/108. Andy Nicholas explains the problem very clearly. Essentially it adds a “soft” distance and slow down the movement causing the pop with a formula. Andy showed this in Softimage but the idea works anywhere.

Below are some lines of expression showing the ideas in maya. They are running node-based in my final rig but making the setup works in expression first is faster for me.

// -----------------------------------------------------------
//     $d : current distance betw ends
//     $D : initial distance betw ends
//     $S : IK softness
//     softJ_start & softJ_end
//         a 2-joint chain with it's IK parented under e.g. foot ctrl
//         the main IK is point constrainted to softJ_end
// -----------------------------------------------------------

float $S = ctrl.soft;
float $D_soft = $D - $S;
float $new_d = $d;

if ( $d > $D_soft ) {
    float $x = $d - $D_soft;
    $new_d = $D_soft + $S *( 1-exp(-$x) );

softJ_end.ty = $new_d;

Pole vector maths

In my old rig, the lower limbs rotate in single plane only. That simplifies the story. Just put a locator under the FK lower limb, having the same world position as the pvCtrl at initial pose. Snapping to FK means snapping the pvCtrl to this locator because the rotate plane is always correct.

But I want rig like Stewart, where the lower limbs can rotate sideway. This involves simple vector maths.

global proc vector calcPvWPos( string $P1, string $P2, string $P3 ) {
     vector $a = `xform -q -ws -t $P1`;
     vector $b = `xform -q -ws -t $P2`;
     vector $c = `xform -q -ws -t $P3`;
     vector $AC = $c - $a;
     vector $AB = $b - $a;
     // projV = (|b|cos@) ^AC = (a.b/|a|) ^AC
     vector $projV = ( dotProduct($AC,$AB,0) / mag($AC) ) * `unit $AC`;
     vector $pvDirV = unit($AB - $projV);
     // move it out a bit
     return ( $b + mag($AB) * $pvDirV );

Pose mirror/flipping

I have seen a few “intelligent” scripts which are able to mirror/flip controls of arbitrary setup. They are great if you have to use other people’s rig. I’m now making my own rig so I prefer a simpler way.

I add a string attribute named “mirrorCode” to every control to be mirrored/flipped. e.g. “100011”. The order is for tx ty tz rx ry rz and a “1” means negation. My scripts can scan through this attribute and know which axis to negate. Nothing to detect and easy to debug !

global proc float[] getMirrorXform ( string $ctrl, string $code ) {
    vector $t = `getAttr ($ctrl + ".t")`;
    vector $r = `getAttr ($ctrl + ".r")`;
    float $tr[] = { $t.x, $t.y, $t.z, $r.x, $r.y, $r.z };
    for ($i=1; $i<=6; $i++) {
       if (`substring $code $i $i` == 1) {
          $tr[$i-1] *= -1;
    return $tr;

Better space switching

I learned about space switching years ago. I did’t think there was problem until recently …

How about having a prop control, that can drive the hand or the other way round ?

Of course I’m not setting each other as their “space” target. The evil cycle warning still shows because the target is having connections to all the space groups, no matter active or not. My solution is to add an extra loop of SetDrivenKey in space switching codes, setting nodeState of unused space groups to “block“.

// ----------------------------------------------
//   Block unused space groups
// ----------------------------------------------
for ($i=0; $i<`size $space`; $i++) {
     for ($j=0; $j<`size $spaceG`; $j++) {
         string $state = ($i == $j) ? 0 : 2;
         setDrivenKeyframe -cd "ctrl.space" -dv $i -at "nodeState" -v $state $spaceG[$j];