Home Website Youtube GitHub

Wing Rigging [Question]

Hi everyone,

What would be the best approach to rig wings/feathers using mGear?

Haven’t found any documentation or tutorial about it.


What approach do you currently use for wings/feathers?

I am just doing RnD for an upcoming project and thought I could use chain net component but I am not sure.

I am still working on my bird template. Maybe this will help you get started?
I am using Chain Net components. But you can see that I could swap some out with a normal chain component.

I used a hydraulic component to pin the base of the wing to the body. Using it as a parent for the Scapula Master.

I hope you come back to the forum and share your results.



This is awesome. Thanks!

I just didn’t understand the hydraulic component part.

I’m using the hydraulic as a parent to the scapulaMaster. Using the Tip Reference Array to keep the tip constrained to the base of the spine. This keeps the base of the wing connected to the body of the bird.

Hi, I’m trying to get a full wing made on MGear, but I’m struggling with somes things.
All of my chain_net have an extra control at the end very weird, but not on my primaryMid.

My scapulaMaster isn’t following my arm on the X rotation. How can I change that ?
An other thing, how did you create every controllers for each feather, and how did you assign the influence between the main controllers ?
Thanks in advance and have a nice day !

Sorry to revive this but where do you parent your tertial, secondary and primary chains?

Hello Hakan,

I uploaded my current repo to github so you can grab my bird template.

This is my postScript:

import maya.cmds as cmds

# L Wing tertial master constraint
lTirMstr = 'wing_L0_div6_loc|tertialMaster_L0_root'
if cmds.objExists(lTirMstr):
	lTirBlnd = cmds.createNode('transform', n='tertialMasterBlend_L0_drv', p='wing_L0_div6_loc', ss=True)
	cmds.parentConstraint('wing_L0_5_jnt', 'wing_L0_7_jnt', lTirBlnd, st=["x","y","z"])
	cmds.parentConstraint('wing_L0_6_jnt', lTirBlnd, sr=["x","y","z"])
	cmds.parentConstraint(lTirBlnd, lTirMstr, st=["x","z"], mo=True)

# R Wing tertial master constraint
rTirMstr = 'wing_R0_div6_loc|tertialMaster_R0_root'
if cmds.objExists(rTirMstr):
	rTirBlnd = cmds.createNode('transform', n='tertialMasterBlend_R0_drv', p='wing_R0_div6_loc', ss=True)
	cmds.parentConstraint('wing_R0_5_jnt', 'wing_R0_7_jnt', rTirBlnd, st=["x","y","z"])
	cmds.parentConstraint('wing_R0_6_jnt', rTirBlnd, sr=["x","y","z"])
	cmds.parentConstraint(rTirBlnd, rTirMstr, st=["x","z"], mo=True)

Here is a function to create a nurbs surface for the wings and tail. I use the nurbs surface to deform the feathers.

def buildMembraine():
    if not cmds.objExists('wingFeatherBuilder'):
        cmds.createNode('transform', n='wingFeatherBuilder', ss=True)
    memDictL = {'scapulaMaster_L0_0_jnt': '.cv[0][0]',
                'scapulaMaster_L0_1_jnt': '.cv[0][1]',
                'scapulaMaster_L0_2_jnt': '.cv[0][2]',
                'scapulaMaster_L0_3_jnt': '.cv[0][3]',
                'tertialMaster_L0_0_jnt': '.cv[1][0]',
                'tertialMaster_L0_1_jnt': '.cv[1][1]',
                'tertialMaster_L0_2_jnt': '.cv[1][2]',
                'tertialMaster_L0_3_jnt': '.cv[1][3]',
                'secondaryMaster_L0_0_jnt': '.cv[2][0]',
                'secondaryMaster_L0_1_jnt': '.cv[2][1]',
                'secondaryMaster_L0_2_jnt': '.cv[2][2]',
                'secondaryMaster_L0_3_jnt': '.cv[2][3]',
                'primaryMid_L0_0_jnt': '.cv[3][0]',
                'primaryMid_L0_1_jnt': '.cv[3][1]',
                'primaryMid_L0_2_jnt': '.cv[3][2]',
                'primaryMid_L0_3_jnt': '.cv[3][3]',
                'primaryMaster_L0_0_jnt': '.cv[4][0]',
                'primaryMaster_L0_1_jnt': '.cv[4][1]',
                'primaryMaster_L0_2_jnt': '.cv[4][2]',
                'primaryMaster_L0_3_jnt': '.cv[4][3]',

    memDictR = {'scapulaMaster_R0_0_jnt': '.cv[0][0]',
                'scapulaMaster_R0_1_jnt': '.cv[0][1]',
                'scapulaMaster_R0_2_jnt': '.cv[0][2]',
                'scapulaMaster_R0_3_jnt': '.cv[0][3]',
                'tertialMaster_R0_0_jnt': '.cv[1][0]',
                'tertialMaster_R0_1_jnt': '.cv[1][1]',
                'tertialMaster_R0_2_jnt': '.cv[1][2]',
                'tertialMaster_R0_3_jnt': '.cv[1][3]',
                'secondaryMaster_R0_0_jnt': '.cv[2][0]',
                'secondaryMaster_R0_1_jnt': '.cv[2][1]',
                'secondaryMaster_R0_2_jnt': '.cv[2][2]',
                'secondaryMaster_R0_3_jnt': '.cv[2][3]',
                'primaryMid_R0_0_jnt': '.cv[3][0]',
                'primaryMid_R0_1_jnt': '.cv[3][1]',
                'primaryMid_R0_2_jnt': '.cv[3][2]',
                'primaryMid_R0_3_jnt': '.cv[3][3]',
                'primaryMaster_R0_0_jnt': '.cv[4][0]',
                'primaryMaster_R0_1_jnt': '.cv[4][1]',
                'primaryMaster_R0_2_jnt': '.cv[4][2]',
                'primaryMaster_R0_3_jnt': '.cv[4][3]',

    memDictC = {'tail_R0_0_jnt': '.cv[0][0]',
                'tail_R0_1_jnt': '.cv[0][1]',
                'tail_R0_2_jnt': '.cv[0][2]',
                'tail_R0_3_jnt': '.cv[0][3]',
                'tail_C0_0_jnt': '.cv[1][0]',
                'tail_C0_1_jnt': '.cv[1][1]',
                'tail_C0_2_jnt': '.cv[1][2]',
                'tail_C0_3_jnt': '.cv[1][3]',
                'tail_L0_0_jnt': '.cv[2][0]',
                'tail_L0_1_jnt': '.cv[2][1]',
                'tail_L0_2_jnt': '.cv[2][2]',
                'tail_L0_3_jnt': '.cv[2][3]',


    for dic, side in zip([memDictL, memDictR, memDictC], ['L', 'R', 'C']):
        if cmds.objExists(list(dic.keys())[0]): #If rig (joint) is present
            #Create Nurbs
            if dic == memDictC: #tail
                n1 =cmds.nurbsPlane(ch=1, d=1, v=3, p=(0, 0, 0), u=2, w=0.1, ax=(0, 1, 0), lr=1)[0]
                n1 = cmds.nurbsPlane(ch=0, d=1, v=3, p=(0, 0, 0), u=4, w=0.1, ax=(0, 1, 0), lr=1)[0]
            #Move cv's to match joint pos
            for k,v in dic.items():
                pos = cmds.xform(k, q=True, t=True, ws=True)
                cmds.xform(n1+v, t=pos, ws=True)

            #Set skinweights to 100% per jnt
            cmds.skinCluster(list(dic.keys()), n1, mi=2, bm=0, sm=0, dr=4, wd=0, tsb=1, n='wing_'+side+'0_membraineN1_skn')
            for k,v in dic.items():
                cmds.skinPercent('wing_'+side+'0_membraineN1_skn', n1+v, transformValue=[(k, 1.0)])

            #Convert to smooth nurbs
            n2 = cmds.rebuildSurface(n1, rt=0, kc=0, fr=0, ch=1, end=1, sv=0, su=0, kr=0, dir=2, kcp=1, tol=0.01, dv=2, du=2, rpo=0)[0]
            cmds.delete(n2, ch=True)
            cmds.skinCluster(list(dic.keys()), n2, mi=2, bm=0, sm=0, dr=4, wd=0, tsb=1, n='wing_'+side+'0_membraineN2_skn')
            for k,v in dic.items():
                cmds.skinPercent('wing_'+side+'0_membraineN1_skn', n1+v, transformValue=[(k, 1.0)])

            #Clean up
            cmds.parent(n1, n2, 'wingFeatherBuilder')
            cmds.setAttr(n1+'.v', 0)
            cmds.rename(n1, 'wing_'+side+'0_membraineN1_drv')
            cmds.rename(n2, 'wing_'+side+'0_membraineN2_drv')
            cmds.warning('Rig is not present? Cannot build a membraine')


I just tried importing your guides to the scene but I am getting an error :confused:

= GEAR RIG SYSTEM ======component base directory not found  for ui_host_01
# Error: RuntimeError: file C:\Program Files\Autodesk\Maya2022\Python27\lib\site-packages\pymel\internal\pmcmds.py line 130: Maya command error #

Ah yes. I created a UI Host component. You can either grab it from my repo. Or change the UI host components back to a control_01.

You mean rename them? I can’t import the .sgt files, I get that error immediately.

I tried adding your mgear_4_0_7-main directory to Maya.env like this but mGear menu didn’t show up


I’ve managed to make it work after editing the .sgt file raw, seems like you have bunch of custom components. Renaming them to default mGear ones worked, I got it built now. Thank you very much. I was just wondering how did you manage to make the chain_net on the elbow stay in the middle between elbow and shoulder, do you use constraint? If so, which control should I constraint on the chain_net? Because seems like control itself is being driven by the logic of chains and if I constraint, it’ll destroy the automation, right?

Aha, looks like I will need an arm component with a support elbow joint, I was using arm_2jnt_01 and even though I my chain to the elbow guide, it would still be parented under arm root joint. Tried using an arm component with a support joint, it worked. But we don’t use support joints in our engine :confused: Would be nice if there is a way to make it behave the same so it stays oriented in the middle when I bend the arm…

@Miquel @Jerome @chrislesage

I have a question. I want to use an “arm_2jnt_01” component (because it’s the component that I adjusted to the studio), then parent a chain to the elbow guide. When I build, it parents the chain under arm root instead of elbow support joint, this isn’t the case for other arm components, if you parent anything under elbow guide, they get parented under elbow support joint so they always stay in the middle.

It would be nice to know which part of the code I should edit in order to get the thing parented under elbow guide to be actually parented under support elbow joint when I build.

This is the section of the component init file where the connections are defined.


Thank you bunch!! :slight_smile:

Thanks @izze for helping @Lethendris :smiley:

Would you happen to have the updated .sgt with said changes? i’m running into the same issue but i’m not savey enough to be able to edit the file correctly :frowning:

i tired editing the raw file after i removed all the custom references with basic mGear ones. i still get this error at the end that i have no clue what to do with :

#Error: ValueError: file C:\Program Files\Autodesk\Maya2020\bin\python27.zip\json\decoder.py line 367: Extra data: line 50160 column 2 - line 100319 column 2 (char 1735242 - 3470484) #