Thursday, June 24, 2010

On the elegance of remap nodes....

Typically when I rig I hack the heck out of stuff using expressions and what not. For example, this had been my expression driving lid movement...

//Left Lid connections
eyeRigAttributeHolder.blink_center_left = clamp (0,1, -blink_left_anim.translateY);
eyeRigAttributeHolder.blink_inner_left = clamp (0,1, -blink_left_anim.translateY);
eyeRigAttributeHolder.blink_outer_left = clamp (0,1, -blink_left_anim.translateY);

eyeRigAttributeHolder.upperLid_center_left = clamp (-27, 35, -uprLid_left_anim.translateY * 35);
eyeRigAttributeHolder.upperLid_outer_left = clamp (-25, 25, -outer_uprLid_left_anim.translateY * 25);
eyeRigAttributeHolder.upperLid_inner_left = clamp (-8, 20, -inner_uprLid_left_anim.translateY * 20);

eyeRigAttributeHolder.lowerLid_center_left = clamp ( -12, 21, -lwrLid_left_anim.translateY * 21);
eyeRigAttributeHolder.lowerLid_outer_left = clamp ( -14, 12, -outer_lwrLid_left_anim.translateY * 20);
eyeRigAttributeHolder.lowerLid_inner_left = clamp ( -5, 12, -inner_lwrLid_left_anim.translateY * 12);

//adds rotation on the center eyelid skin joints for bend in the eyelid and is then negated by the blink so things seal up
left_uprLid_skin_jnt.rotateZ = uprLid_left_anim.rotateZ - (uprLid_left_anim.rotateZ * -blink_left_anim.translateY);
left_lwrLid_skin_jnt.rotateZ = lwrLid_left_anim.rotateZ - (lwrLid_left_anim.rotateZ * -blink_left_anim.translateY);

//left eyelid group follows the eye
eyelid_left_rig_grp.rotateY = left_eye_skin_jnt.rotateY * .2;
uprEyelid_left_rig_grp.rotateX = clamp (-35, 10, left_eye_skin_jnt.rotateX + (eyeRigAttributeHolder.blink_center_left * 35)) ;

//joint following
//left_uprFan_jnt.rotateX = left_uprLid_jnt.rotateX * .7;
//left_outerUprLid_jnt.rotateX = left_uprLid_jnt.rotateX * .7;
That's a bit of a mess and a major pain to edit for the user and wanting to follow in Shleifer's Animator Friendly rigging principles I looked into a bit of a more elegant solution and learned to love remap nodes in the process.

So with a bid of elbow grease and heavily modifying Doublestein's eyelid joint setup by adding new attributes and some new doodads everything connects in one nice little script.

Here's a chunk of that code...
//connecteding eyelid controls -jb
string $uprLidMovementRemap = `createNode remapValue -n ("remapUprLidMovement"+$location+$side)`;
setAttr ( $uprLidMovementRemap+".inputMin") -1;
connectAttr ($uprLidControl+".ty") ($uprLidMovementRemap+".inputValue");
connectAttr ($uprLidUprLimit) ($uprLidMovementRemap+".outputMax");
connectAttr ($uprLidLwrLimit) ($uprLidMovementRemap+".outputMin");
connectAttr ($uprLidMovementRemap+".outValue") ($uprLidMover);

string $lwrLidMovementRemap = `createNode remapValue -n ("remapLwrLidMovement"+$location+$side)`;
setAttr ( $lwrLidMovementRemap+".inputMin") -1;
connectAttr ($lwrLidControl+".ty") ($lwrLidMovementRemap+".inputValue");
connectAttr ($lwrLidUprLimit) ($lwrLidMovementRemap+".outputMax");
connectAttr ($lwrLidLwrLimit) ($lwrLidMovementRemap+".outputMin");
connectAttr ($lwrLidMovementRemap+".outValue") ($lwrLidMover);

//Blink setup - jb
string $blinkmdNode = `createNode multiplyDivide -n ("BlinkmdNode"+$location+$side)`;
connectAttr ($blinkControl+".ty") ($blinkmdNode+".input1X");
setAttr ($blinkmdNode+".input2X") -1;
connectAttr ($blinkmdNode+".outputX") ($blinkMover);
It's also pretty cool in that there's now attributes sitting on a control that you can mess with to tweak the range of the lid movement by the controls. Pretty nifty.

Now I'd really like to buckle down and learn some python but if I'm gonna finish Morphy anytime soon, it'll have to wait.


Virgil said...

duuuuuuuuuude, don't use expressions :P there are far simpler ways for automatic eyelid movement and fleshiness. anyway, look for the fastest way. nodes are not that hard to work with. also, as far as deformers go, keep things as simple as possible. I see that you're having wrap deformers for the brows. not ideal. you could initially wrap deform them, and export those deformations to blendshapes. but yeah, it depends on what you want from your rig. but if you'll have the rig completely driven by sliders, and no freeform stuff, you should consider the above :P

Josh said...

Hey man,

This post is from ages ago, what are you doing down here? :)...pretty much everything is changed over to nodes now. I agree that expressions aren't the fastest end setup. However, I find them a lot easier to mess with when I'm trying things out. Just comment out sections you wanna unhook and rehook it up when you want.

Blendshapes for the eyebrows wouldn't work. Download the deformation beta rig and I think it'll be clear why. Much of the customization is freeform.

All the stuff on this site is 2000 - by Josh Burton...unless otherwise noted. All rights reserved.