16 September, 2012

Resetting skin deformation for joints

There are times when you need to update the bind transforms for joints after applying the skinCluster deformer. Maya provides a tool called "Move Skinned Joints Tool" for doing the same. It works great if you want to move joints that are not constrained. But if you want to move a skinned joint that is constrained to a surface this tool does not work well. Here is a small function that will reset skin deformation for given skinned joints. First move/rotate all the skinned joints in desired position then run this function. This will reset the skinned mesh to its non-deformed state while keeping the joints in place.

def resetSkinnedJoints(joints):
    """ Reset skin deformation for selected joint(s) """
    for joint in joints:
        # Get connected skinCluster nodes
        skinClusterPlugs = mc.listConnections(joint + ".worldMatrix[0]", type="skinCluster", p=1)
        if skinClusterPlugs:
            # for each skinCluster connection
            for skinClstPlug in skinClusterPlugs:
                index = skinClstPlug[ skinClstPlug.index("[")+1 : -1 ]
                skinCluster = skinClstPlug[ : skinClstPlug.index(".") ]
                curInvMat = mc.getAttr(joint + ".worldInverseMatrix")
                mc.setAttr( skinCluster + ".bindPreMatrix[{0}]".format(index), type="matrix", *curInvMat )
        else:
            print "No skinCluster attached to {0}".format(joint)

09 September, 2012

Muscle using single chain stretchy IK

One way to create a simplified muscle movement is to have two joints in a single chain act as origin and insertion points. These joints are orient constrained such that they always aim at each other in a fixed axis. So when we move either of the joints the chain should stretch/squash and orient themselves pointing at each other. One of the ways to achieve this is using a single chain IK solver. Here is a script to do that.

def makeSingleChainStretchyIK(prefix, joint1, joint2, settings=None):
    ikHandle, effector = mc.ikHandle(n=prefix+"_ikHandle", sj=joint1, ee=joint2, sol="ikSCsolver")
    distNode = mc.createNode("distanceBetween", n=prefix+"_jntDist")
    mc.connectAttr(joint1+".translate", distNode+".point1")
    mc.connectAttr(ikHandle+".translate", distNode+".point2")
    mc.connectAttr(distNode+".distance", joint2+".tx")

06 September, 2012

Bottom-up rigging approach & Decoupling rigs

The general approach for rigging a character is to start building skeleton, define how it will move (control system) and then dive into deformation(enveloping process). This approach assumes that the target bind skeleton driven by the control rig is going to produce good deformation. Usually one should do some deformation tests first to make sure bind skeleton would deform the character nicely and then build the control rig. However if this is not done thoughtfully then you could get stuck with a rig that does not deform well. Of course we have tools at our disposal to correct the deformation if required, however this could significantly lengthen the skinning process and make it tedious.

Another approach is to start thinking about deformation and do the skinning first then build its control rig. I am working on a realistic character model for studying deformation based on musculature. Hence the focus is on getting the deformation looking as good as possible. The first stage is to built the bind skeleton and add most of the secondary deformation joints along with the enveloping process. This should give a better idea of how the skeleton would deform the mesh. We can go on refining the bind skeleton and deformation weights until we get a solid base. My goal here is actually go get the skinning closer to the final look and hook up the control rig afterwards that is created based on the bind skeleton.

Regardless of the approach we take, the goal should be to be able to focus on both deformation and control rigs while keeping them independent processes. By keeping control rig and deformation rig separate we can focus on one task without worrying about the other and work on them in parallel. Generally there will be some dependency between both rigs, for example matching the pivots for the movement and deformation or a joint driven by a surface that is deforming the mesh . But we can still decouple both the systems to a good extent. Also, it is possible to keep the pose based deformation independent of control rig reducing the coupling further.

In programming it's a good practice to keep the objects of the system independent so that changing one does not require to change the others. This is highly applicable to Rigging as well. If you are more into programming you should read Design Patterns by the Gang of Four. It's an excellent read.