Category Archives: mel

make stretchy IK


As promised…

Here’s a link to the stretchy IK tool I’ve just created, I hope people will find some good uses for it.  It creates a stretchy ik chain for both RP and SC solvers and is not limited by joint numbers.  It is also node based, so no expressions, so faster for animators…one hopes!

I’ve kept it pretty basic, so if anyone wanted to go in and meddle with finished result they can.  I tend to try and use my tools to get my as far to the end goal as possible, then I just hack at the rig until it does what I want….

I could add a  feature to switch the stretching and on and off….

….but I wont!

….Off to watch Monstors University tonight…. Here’s nk_makeStretchyIK_RPSC

Happy first Wednesday of the week folks!

Here’s a Python script that creates a stretchy joint chain, I’ll aim to incorporate this into a more user friendly GUI soon…

It works on RotatePlane and Single Chain solvers. Enjoy.

import maya.cmds as mc

def nk_makeStretchyIK_RPSC(ikH = "ikHandle1", prefix="prefix", StretchCondition=True):
    Makes an ik handle stretchy.  works on RP or SC solvers.


    * Declare ikHandle, give it a prefix run script

    * This creates a grp with all the distance locators, parent these to the parent of the first joint in the chain.
    ... So if the first joint is an upper arm, parent the Distance grp to the clav joint(assuming that is the parent)

    *   Stretchy all the time.
    *   Introduced an an option to only stretch when extended beyond the full length of the chain.

    * Add an option for inverse scale


    ## --- Get the joints ---
    joints = mc.ikHandle(ikH, q=True, jl=True)
    # Since the joingList query does not return the end joint
    # ...We also need to get the end joint and append it to the list joints[]
    # ...We can do this by getting the last joint in the list, and querying its child
    lastJointinList = joints[(len(joints)-1)]
    endJoint = mc.listRelatives(lastJointinList, c=True, type="joint")

    ## ---Get the Distance---
    measureGrp, n=prefix+'_distanceLocators_grp')
    distLocators = []
    #Get the position of each joint
    for jnt in joints:
        jointPostion = mc.xform(jnt, q=True, ws=True, t=True)
        #Create distance Locators
        distLocator = mc.spaceLocator(n=(prefix+'_'+jnt+'_'+'distLoc'))
        #Position Locators
        mc.xform(distLocator, t = (jointPostion[0], jointPostion[1], jointPostion[2]))
        #parent to grp
        #add locators to list

    #Empty List to store Distance Between Noded
    distanceBetweenNodes = []
    #Measure the distance and the dbNodes to the list
    for i in range(len(distLocators)-1):
        distanceNode = nk_measure2Points(distLocators[i], distLocators[i+1],(distLocators[i]+'_to_'+distLocators[i+1]+'_dbNode'))

    ## --- Setup Scale ---
    ## NewDistance/Original scale = StretchScale
    ## OriginalScale/NewDistance = InvScale

    #Add the distance -- create plus minus average --
    pmaNode = mc.shadingNode("plusMinusAverage", asUtility=True, n=(prefix+"_stretch_pma"))

    for i in range(len(distanceBetweenNodes)):

        print distanceBetweenNodes[i]
        print (pmaNode + '.input1[{i}]'.format(i=i))
        mc.connectAttr(('{db}.distance'.format(db=distanceBetweenNodes[i])), (pmaNode + '.input1D[{i}]'.format(i=i)))

    # -- get the Ik distance --
    ##Create a locator point constrain to ikHandle and add to grp
    ikDistanceLoc = mc.spaceLocator(n=(prefix +'_' + ikH + '_distLoc'))

    mc.parent(ikDistanceLoc[0], measureGrp)
    mc.pointConstraint(ikH, ikDistanceLoc[0])
    ikDistanceNode = nk_measure2Points(distLocators[0],ikDistanceLoc[0], (ikDistanceLoc[0]+'_dbNode'))

    # -- Stretch Condition --
    if StretchCondition == True:
        # If the Ik Handle stretches beyond the length of the total length, then the condtion will output the ikDistance to the mdNode
        # ... The scale factor will == ikDistance/OrginalDistance(orThe full Length of the joint chain)
        # If the ik Distance is less than the OrigDistance, the condition will output the OrginalDistance
        # ... The scale factor will == OrigDistance/OrigDistance. So the value of scale will be 1.

        condtionNode = mc.shadingNode("condition", asUtility=True, n=prefix+"_stretchScale_Cond")
        mc.setAttr (('{condtionNode}.operation'.format(condtionNode=condtionNode)), 3)
        mc.connectAttr (('{ikDistanceNode}.distance'.format(ikDistanceNode=ikDistanceNode)) ,('{condtionNode}.firstTerm'.format(condtionNode=condtionNode)))
        mc.connectAttr (('{ikDistanceNode}.distance'.format(ikDistanceNode=ikDistanceNode)) ,('{condtionNode}.colorIfTrueR'.format(condtionNode=condtionNode)))

        mc.connectAttr (('{pmaNode}.output1D'.format(pmaNode=pmaNode)),('{condtionNode}.secondTerm'.format(condtionNode=condtionNode)))
        mc.connectAttr (('{pmaNode}.output1D'.format(pmaNode=pmaNode)), ('{condtionNode}.colorIfFalseR'.format(condtionNode=condtionNode)))

        #create multiply divide node
        stretch_mdNode = mc.shadingNode("multiplyDivide", asUtility=True, n=prefix+"_stretchScale_md")
        # Divide ik distance by OrigDistance
        #mc.connectAttr ikDistanceNode > to mdi1x
        mc.connectAttr ('{condtionNode}.outColorR'.format(condtionNode=condtionNode), ('{stretch_mdNode}.input1X').format(stretch_mdNode=stretch_mdNode))
        mc.connectAttr (('{pmaNode}.output1D'.format(pmaNode=pmaNode)), ('{stretch_mdNode}.input2X'.format(stretch_mdNode=stretch_mdNode)))

    if StretchCondition == False:
        # If the user does not require a condtion, the ikHandle will stretch when extended and when shortened

        #create multiply divide node
        stretch_mdNode = mc.shadingNode("multiplyDivide", asUtility=True, n=prefix+"_stretchScale_md")
        # Divide ik distance by OrigDistance
        #mc.connectAttr ikDistanceNode > to mdi1x
        mc.connectAttr ('{ikDistanceNode}.distance'.format(ikDistanceNode=ikDistanceNode), ('{stretch_mdNode}.input1X').format(stretch_mdNode=stretch_mdNode))
        mc.connectAttr (('{pmaNode}.output1D'.format(pmaNode=pmaNode)), ('{stretch_mdNode}.input2X'.format(stretch_mdNode=stretch_mdNode)))

    # we dont wat to attach to the last joint, so loop through the joints and connect except the last one
    jntCnt = len(joints)-1
    for i in range(jntCnt):

        mc.connectAttr((stretch_mdNode + '.outputX'), (joints[i]+ '.scaleX'), force = True )

    ##For some reason the ikHandle seems to not hold in Place if it is in worldSpace
    #...or not parented to a transform
    #...As such, we just need to pop it back to it's oirginal position it just snaps back to the last locator

#nk_makeStretchyIK_RPSC(ikH = "ikHandle2", prefix = "prefix")


def nk_measure2Points(itemA='itemA', itemB='itemA', distanceBetweenNodeName='dbNode'):

    dbNode = mc.createNode ('distanceBetween', name=distanceBetweenNodeName)



    return dbNode

The Seven Wonders – my part in its downfall!!!

So here are some highlights from my work on the Seven Wonders project.  My first time working in a game engine, and I must say despite a few small hurdles towards the beginning, I soon felt privileged to be using Cryengine 3, an amzing realtime rendering engine, with some fantastic cinematic features.

Here’s a quick breakdown of the shots I was responsible for.

  1. Nano suit macro close up.  Elements created in Maya and Z-Brush, animated in Maya, lit rendered using Cryengine.   A lot of mel scripting went in to these few seconds of animation, I’m aiming to do a little breakdown of the process soon, and will link it here as soon it’s up.
  2. Helicopters, New York intro.  All assets and FX created, animated and lit in engine
  3. Typhoon Gun chamber and bullet time(err…bullets!).  Again created in Engine.  Additional bullet effects created using engine based particles systems.
  4. Launch Trailer Text sequences.  Created Text models and textures using Maya and Photoshop.  All set dressing and lighting and FX again created using the engine’s magic.
  5. Brain fly-through.  Neuron assets created in Maya. Camera and FX animation all done using….Maya!  Just kidding, it was the Cryengine again.



I’ve won’t hail myself as the ultimate scripting wizard…I think I’m pretty average to be fair, but its always nice to make certain tasks a bit quicker.   Here’s a basic python script you can use to copy attributes between 2 selected objects.


”’import maya.cmds as mc”’




#get attributesfromfirst selected

cntrls = (sl=1, tr=1)

print cntrls

cnt = len(cntrls)

print cnt


#check if two items are selected

if cnt != 2 :



if cnt == 2:

#get attributes from master item

attrList = mc.listAttr (cntrls[0], v=1, k=1)

print attrList

#add attributes to next selected item

for attr in attrList :

mc.addAttr (cntrls[1], k=True, at=”float”, ln=attr)