Home Youtube GitHub

Hand custom attributes - Curl, Bend, Spread etc


#1

Hi!
Wonder if you have a way to handle custom attributes for hand for example.
I’m learning to use mGear and couldn’t find that option in Shifter, please correct me if I’m wrong.

I’m used to attributes like Curl / Lean / Twist / Spread (I see that Meta01 is for spread) - sometimes I need to add an extra layer to control each FK Bend and its influences. It’s done that way in Rapidrig modular - not sure if you’re familiar, so I’ll attach screens from the setup I did a while ago based on that.

Ideally would be if I have control over each finger (in one host) and then the second host to control the whole hand.

If I need to do it manually in my custom rigs, I’m mainly using multipliDivide nodes, then add values from both parameters and then connect this to extra transform node before the FK Control.

Should I try to rebuild this using post scripts, or maybe do you have a clever way to do this?


(plusMinus nodes takes values from both setups and then send it to CtrlSdkGrps)

Cheers,
Krzysztof


#2

Hi Krzysztof,

As far as I know, there are no built-in modules that have any finger curl attrs. I use a Post script in my rigs. You could also build a custom finger or hand module.

Also, you might want to check out the remapValue node. It’s a great way to drive simple relationships like this. It takes an input range, and outputs an output range, and you can control a basic curve (linear by default).


#3

I do have one trick I use though. I use Python’s defaultdict

from collections import defaultdict

This is a dictionary that can specify a default value, if a key doesn’t exist. So when I want to customize my finger spread attrs for a character, I add a matching key, based on the character name from the guide.

    def rig_finger_curls(self, charName):
        def default_finger_spread():
            return [-32.0, -12.0, 0.0, -0.8, 6.0, 0.0, -22.0, -8.4, 19.0, 35.0]

        def default_finger_bend():
            return [65.5, 94.5, 87.8]

        def default_thumb_bend():
            return [360, 360]

        spreadValues = defaultdict(default_finger_spread)
        # if a key doesn't exist, it returns the default callable object you specify. (See the docs for defaultdict)
        spreadValues['billy'] = [-30.0, -12.0, 0.0, -0.8, 7.0, 0.5, -21.0, -8.8, 19.0, 35.0]
        spreadValues['sarah'] = [-28.0, -11.0, 0.0, -0.8, 6.0, 0.0, -22.0, -7.2, 17.0, 32.0]

        # Then in the code, I check which character I'm running.
        # charName = pm.PyNode('guide').rig_name.get()
        for each in spreadValues[charName]:
            foo...

#4

Thank you! I will give it a try this afternoon. Do you think that remapValue would be a better and more efficient way to solve this than multiplyDivide + plusMinus nodes? This way I have control over the influence values for each joint and this allows me to create a second layer for the fingers. It’s pretty fast to animate in tight deadlines :slight_smile:

The values you have in that dicts are default values for a key? So when you run a script, it’s binding a pose to the fingers - if I understand it correctly?

Maybe I should try to set this as a postscript, not sure how to edit the modules yet.


#5

remapValue is not better or worse. I personally prefer it. It is slightly more efficient and stable than a driven key. It also automatically clamps to the ranges you specify, and you can get curve effects that you can’t get with multiplyDivide. (Though 90% of the time, you just want a simple linear relationship.)

It wouldn’t replace your use of plusMinusAverage to combine inputs.

Yeah sort of a pose. Those defaultdicts I use are the values I’ll eventually use for how much I want the fingers to rotate when the curve attributes are used by the animators. I’ll plug those values into my remapValue nodes, so I can more precisely find the perfect fist pose, for example.