Home Website Youtube GitHub

Lowpo Sagat_work in progress

The picker is nearly complete, I just need to add an IK/FK match once I know how to do it.

  • Orange controls are FK, yellow are IK.
  • The light blue buttons with a plus sign select the entire limb.
  • The hands are separated and moved to the side as I find this much more efficient especially in TV series where the hands are often done last and often mirrored.

Those days I don’t bother adding a picture of the character since I like to reuse my pickers for other characters and having a background picture is not “scalable” on a larger production when done manually.

You can find an article I wrote about Pickers a while back and you might find it interesting:

Turn on the mGear Viewport Menu. Then if you right click on any control you get a right-click menu. On any limb control, you can “Select host”. Or just select the host directly. Once the host is selected, you can right-click “Switch arm to Ik” or “Switch arm to Fk”. There is also seamless space switching for any component’s spaces.

There is also a picker template file that has some code examples for seamless switching.

screenshot_2022-09-08_10-37-05

Yes that is the code I am looking for. Thanks Chris, I will look for it.

Cheers

hum ok I found the code but it seems to be looking for some variables probably fed by the mGear picker and I have no clue how to adapt this to my situation :frowning:

This is the code found on the mGear Animpicker:

from mgear.core import anim_utils

if not __INIT__:
    anim_utils. ikFkMatch_with_namespace(__NAMESPACE__,
                                        "arm_blend",
                                        "armUI_L0_ctl",
                                        ["arm_L0_fk0_ctl", "arm_L0_fk1_ctl", "arm_L0_fk2_ctl"],
                                        "arm_L0_ik_ctl",
                                        "arm_L0_upv_ctl",
                                        ik_rot="arm_L0_ikRot_ctl")```

If you’re outside the context of the Picker, just remove __INIT__ and then you’ll have to define or find your own namespace.

Also, in this code all the control names are hard-coded. Some of these controls might be able to be found procedurally through connections and attributes stored on the host. But I can’t help with that today.

This is just an example that gets the namespace from the first thing you have selected, assuming you have the limb or hostUI selected. If you are in the context of the mGear Picker, you should be able to use the __NAMESPACE__ variable. If you use your own picker tool, you’ll have to store or derive it some other way.

import pymel.core as pm
from mgear.core import anim_utils

# Get the namespace from the thing you have selected.
controlNamespace = pm.selected()[0].namespace()

anim_utils. ikFkMatch_with_namespace(
        controlNamespace,
        "arm_blend",
        "armUI_L0_ctl",
        ["arm_L0_fk0_ctl", "arm_L0_fk1_ctl", "arm_L0_fk2_ctl"],
        "arm_L0_ik_ctl",
        "arm_L0_upv_ctl",
        ik_rot="arm_L0_ikRot_ctl")
1 Like

Oh, thanks a lot Chris!! I just had to change the ik_rot hard coded name! Cheers!!!

ik_rot=“arm_L0_ikRot_ctl”
to
ik_rot=“arm_L0_ik_ctl”

                                       
import pymel.core as pm
from mgear.core import anim_utils

# Get the namespace from the thing you have selected.
controlNamespace = pm.selected()[0].namespace()

anim_utils. ikFkMatch_with_namespace(
        controlNamespace,
        "arm_blend",
        "armUI_L0_ctl",
        ["arm_L0_fk0_ctl", "arm_L0_fk1_ctl", "arm_L0_fk2_ctl"],
        "arm_L0_ik_ctl",
        "arm_L0_upv_ctl",
        ik_rot="arm_L0_ik_ctl")```

So this is how I am setting up my FK neck for the project. I made a little video explaining the process.

Basically I am using a control_01 for the first FK neck control then a modified shoulder_01 aka mighty_neck_01 for the second FK neck control and finally a control_01 for the head control.

The world to parent orient switches for the head are setup using the mighty_neck_01 reference array which can then be accessed through the host.

[placeholder for the component download link]

I just realised there is an issue at the moment with the orientation of the neck_01 control!

The way I am showing it in the video, a forward rotation will be -RY instead of -RX (like the spine FK controls) so to keep a consistency in the behaviour of the rig and keep the animators happy, I will instead rotate neck_C1_root by RZ -90 and parent the head_C0_root to the neck_C1_root instead of the Neck_C1_tip.

1 Like

There has been few changes today.

###### Intense feature update #####

One of them was the import of .shp files as a Post Step for my Eye patch. Here is how I went about it.

Ideally I should get rid of the full hard path at some stage but that should help people.

    pm.blendShape ( 'eyePatch_geo', name = 'bsMightyInput' )
    pm.blendShape('bsMightyInput',e = True, ip = 'Z:/3d/Rigs/Sagat/Scenes/data/deformers/bs_face_intense.shp')
    pm.addAttr( 'head_C0_ctl', longName='Intense', defaultValue=0.0, minValue=0.0, maxValue= 1 )
    pm.setAttr( 'head_C0_ctl.Intense', keyable = 1 )
    pm.connectAttr ( 'head_C0_ctl.Intense', 'bsMightyInput.bs_face_intense_geo' )

Other than that, here is where I am tonight. The rig is nearly complete!

Massive set-back today, I thought I was done with my rig but my files don’t open anymore.

Currently I am using Maya 2019.2 and mGear 4.03 on Windows.

Several of my work files, all the latest ones and the incremental saves, hard crash Maya as soon as I open the files either by double clicking on the file names in the explorer or through Maya’s “open file” menu.

I will open a new thread since this seem to be a recurring problem for other people too.

Variation!

and extra limbs for strobbing effects. Is there a component like a simple FK chain with squash and stretch or should I create my limbs based on lite_chain_01? I just need simple FK chains, no need for IK.

Some nice updates today.

I updated my “cleaning pre step” based on Chris example found on the forum.

Something I felt a really strong need for is to clean my materials. I am surprised no one mentionned it. Everytime I build my rig, the materials get duplicated.

I left some lines commented out for now since I don’t really use them,

import os
import mgear.shifter.custom_step as cstp
import pymel.core as pm

######## delete all materials in scene ########
MaterialsInScene = pm.ls(mat=True)
pm.delete ( MaterialsInScene )

######## delete various groups ########
# pm.delete(pm.PyNode('rig'))


### From Chris ########
pm.delete(pm.ls(type='createColorSet'))
pm.delete(pm.ls(type='hyperView'))
allGeo = [mesh.getTransform() for mesh in pm.ls(type='mesh')]
pm.delete(allGeo)
### Delete all tag controllers. They build up the file size over time.
pm.delete(pm.ls(type='controller'))

### Delete all ngSkin nodes. If you delete the rig, they remain and cause large file sizes.
# NOTE: This means that you must not use ngSkin layers in your rig guide!!! You can use them in your built rig, of course.
# pm.delete(pm.ls(type='ngSkinLayerData'))

# These nodes inflate the scene size and cause the scenes to take WAY longer to open.
# (20 seconds instead of 0.9 seconds to open the model files, for example.)

# For some reason, sometimes dagPoses get polluted into the guide scene.
# I *think* it would be safe just to delete all dagNodes, but just in case, I'm only deleting ones who
# are on the buffer controls under controllers_org. Someone might choose to custom rig a hack inside a guide on purpose.
# buffers = pm.PyNode('controllers_org')
# for each in pm.ls(type='dagPose'):
    # check if the transform inputs of the dagPose are the buffer controls.
#    if any([x.hasParent(buffers) for x in each.inputs(type='transform')]):
#        pm.delete(each)

# pm.select(pm.PyNode('guide'))

I also tackled something I wanted to do for a long time. The autoloading of an animation file as soon as the rig builds. The script is built upon the one shared by Toke Stuart Jepsen. I am not sure exactly how I got it to work but the difference is to have the Studio Library animation file in the /data/anim subfolder with a default name. This should allow me to scale to other characters too. For some reason I had to comment out the Paste option.

import os
import pymel.core as pm
import studiolibrary

from studiolibrarymaya import animitem

directory = os.path.dirname(pm.sceneName())

anim_folder = ( directory + '/data/anim/ROM.anim' )

item = ( os.path.join(directory, anim_folder ))
print ( ' item is ' + item )

item = animitem.AnimItem(os.path.join(directory, anim_folder))

print ( item )
item.load(
    objects=[],
    namespaces=[],
#    option=animitem.PasteOption.ReplaceCompletely,
    connect=False,
    currentTime=False
    )

##### Range of motion animation loaded ########
print ( '\n###############         Range of motion animation loaded      ##################\n' )

and finally I converted my Publish script from .mel to Python. What that script does is to save and move a copy of my mGear work file as a publish file after deleting the guides. I should probably also have the procedure export the guides as a separate file… Here is the link to the script from my Github page:

Dam today was supposed to be my long run sunday but I got too excited with this project and just didn’t find the time!!!

Hopefully you will find this interesting.

ah and I also started to create a “rig_initialisation” post script:

# My bits and bobs to prepare the rig for animation

# Hide joints
pm.setAttr ( 'rig.jnt_vis', 0 )

# Parent the rig node under Sagat
pm.parent ( 'rig', 'Sagat' )

# Rotation orders
pm.setAttr ( 'head_C0_ctl.rotateOrder', 2 )
pm.setAttr ( 'jaw_C0_ctl.rotateOrder', 5 )
pm.setAttr ( 'neck_C0_ctl.rotateOrder', 2 )
pm.setAttr ( 'COG_C0_ctl.rotateOrder', 2 )
pm.setAttr ( 'hip_C0_ctl.rotateOrder', 3 )

# Set pole vectors to World
pm.setAttr ( 'legUI_L0_ctl.leg_upvref', 2 )
pm.setAttr ( 'legUI_R0_ctl.leg_upvref', 2 )
pm.setAttr ( 'armUI_L0_ctl.arm_upvref', 1 )
pm.setAttr ( 'armUI_L0_ctl.arm_upvref', 1 )

Good progress for the day. Using the shoulder_01 and my customised mighty_Neck_01 wasn’t usable in the end as I couldn’t get neck rotation consistent with the rest of the body. After a ton of testing and upgrading to mGear 3.7.11, I finally understood how to go about it simply by using a series of control_01!!

I will open a new thread and post a tutorial to explain.

I also tested the orientation offset method but I couldn’t understand how it worked.

Currently I am stuck with the metas as explained on the following thread.

And here is what I have left on my plate to call the rig done!

image

Ok so here is where we are now that I have upgraded to mGear 4 and redone the metacarpals using the technique in the thread mentionned in my previous post.

Actually… it is bizarre, it still says mGear 3.7?!? I must be on a different version since the original meta controls are gone.

image

Other than that, I also modified my setup for the FK neck with space switches following the technique highlighted here :

and managed to rename the “nice name” of the Head host using a post script with the following code, yeah you have to use the addAttr function but in conjunction with the edit flag:

# Rename the Head space switches on the Head host
cmds.addAttr( 'headUI_C0_ctl.control_ikref', e=True, nn='Head space' )

This way it will be more intuitive for the animators.

image

Unfortunately, the Right Mouse menu still displays “Parent control ik”. From what I read, it is not possible to change this. :confused:

image

And now I am stuck again as this new version of mGear has changed the behavior of the Epic arms so my upper-arms are rotating in an unwanted manner so this will need some tinkering again. grrrrr

That’s annoying as I was really hoping to move to the next milestone :confused:

Okay, I am finally back to mGear and this project.

After updating to mGear 4.0.9 my issue with the Epic FK arms seems to have been fixed.

Today I was testing the chain_spring_01. It wasn’t part of my original plan but it looked too good not to give it a try. Now I just need to understand how to bake the animation.

We are getting there !!!

1 Like

Hehe yeah there was a little bit of trickery to get the chain_spring_01 component to react in the viewport :slight_smile:

To achieve that, I locked the camera and titles to the root control which I animated in +X and a bit of +Z then to create the variation to simulate the wind, I simply made the “root offset” (global) control vibrate a bit.

I will bake the “simulation” in a next pass and record a tutorial for the process.

2 Likes

Final render for my rig’s teaser and tribute to everyone’s favourite Jean-Claude Van Damme movie :slight_smile:

I am having a lot of fun with this project!

4 Likes