Friday, April 18, 2014

Tutorial : Volume preservation using joint and some node connections.

    I would like to share with you guys some trick I just learned about volume preservation on a bounded mesh. There are many ways to correct bad deformation, corrective blendshapes, helper joint with SDK, pose space deformer and etc. This is a simple way using joints and nodes to kinda 'push' out to restore the lost volume. This trick applys for any bend area. I tried it on elbow, finger, wrist, upper leg, worked just fine.

This is what we usually get...

With a couple of extra joints,
I ended up with this.

    To automate the push motion of the extra joint, I did a little node connection instead of set driven key, which of course, can be easily scripted. The idea is to have the extra joint properly aimed out from the bending spot.

The node connection.
On your far left is the upper arm(parent) joint. Next is the elbow(bend) joint.
On your far right is the extra joint and its parent group.

1. Duplicate the bend_jnt(in this case: elbow_jnt). Will call this 'corrective_jnt'. 
2. Create 2 empty groups. 1. cons_grp' 2.'zero_grp .
   Snap the zero_grp to the elbow_joint (both translate and rotate).
   Parent the cons_grp under zero_grp.
3. Move the corrective_jnt over a little in the direction you want it to push the mesh out so it does not
   stays exactly at where the bend joint is. Depends on your joint orientation and your mesh, in my case,
   I moved transalteZ 0.3.
4. Parent the corrective_jnt to the cons_grp.
5. Point constraint the cons_grpto the parent_jnt(shoulder_jnt).
6. Orient constraint the cons_grp to both the parent_jnt and the bend_jnt with maintain offset checked.
7. Add a float attribute called 'multiplier' with the minimum value of 0 at the bend_jnt. This attribute is
   there to tweak how far the 'push' will go.
8. Create 3 multDoubleLinear nodes. 1.devideDegree_mdl 2.multiplier_mdl 3.inverseValue_mdl
9. Connect bend_jnt.roateX(in this case the axis is X) to the multiplider_mdl.input1.
10. Connect bend_jnt.multiplier to the devideDegree_mdl.input1 and set its input2 to 1/360(0.002778).
11 Connect devideDegree_mdl.output to multiplier_mdl.input2.
12 Connect multiplier_mdl output to inverseValue_mdlinput 1 and set its input2 to -1
13 Create a condition node set its second term to 0 and operation to 'less than'.
14 Connect multipliler_mdl.output to the conditon's firstTerm and colorIfFalseR.
15. Connect inverseValue_mdl.output to the condition node's colorIfTrueR.
16. Create a addDoubleLiner node, call it addTranslate_adl. Set its input2 to whatever value the
    corrective_jnt.translateZ(in this case the axis is Z) currently is.
17. Connect the conditon node's outColorR to addTranslate_adl.input1.
18. Connect addTranslate_adl.output to corrective_jnt.translateZ.

    We're done. Try adding the corrective_jnt to influence the mesh and tweak some weights. You can control how far the joint will push the mesh out by tweaking the multiplier attribute you added on the bend_jnt.
    You will end up with only one group which is the corrective_jnt parent group which should be parented under all mover control to move and scale with the whole rig. It's my personal preference to have this extra joint separated from the main joint heirachy.
    I'm planing on doing a little adjustment to have the joint push motion kick in exponentialy. Maybe add some limit to it(clamp?).


That's it! Have fun.
If you have any question, feel free to put them in the comment below.

1 comment:

  1. Hello Nattapong Nilprohm! amazing tutorial, congrats. Could you please answer me a question? Is this set up made especially for video games or for film? I am rigger junior and I am learning about helper joints!