Files
2025-05-18 13:04:45 +08:00

8099 lines
389 KiB
Python

#Author: Jeremy Ernst
#Date: 4.9.13
import maya.cmds as cmds
import maya.mel as mel
import os, ast
import Modules.ART_UpperLegIKTwist as uplegik
import Modules.ART_rigUtils as utils
reload(uplegik)
class AutoRigger():
def __init__(self, handCtrlSpace, progressBar):
self.handCtrlSpace = handCtrlSpace
#get access to our maya tools
toolsPath = cmds.internalVar(usd = True) + "mayaTools.txt"
if os.path.exists(toolsPath):
f = open(toolsPath, 'r')
self.mayaToolsDir = f.readline()
f.close()
#create a progress window to track the progress of the rig build
self.progress = 0
cmds.progressBar(progressBar, edit = True, progress=self.progress, status='Creating Spine Rig')
#build the core of the rig
import Modules.ART_Core
coreNodes = Modules.ART_Core.RigCore()
#BODY CONTROL
self.buildHips()
"""
#create the rig settings node
"Rig_Settings" = cmds.group(empty = True, name = "Rig_Settings")
cmds.setAttr("Rig_Settings" + ".tx", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".ty", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".tz", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".rx", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".ry", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".rz", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".sx", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".sy", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".sz", lock = True, keyable = False)
cmds.setAttr("Rig_Settings" + ".v", lock = True, keyable = False)
#build the spine rigs
self.createDriverSkeleton()
self.buildCoreComponents()
"""
#to be replaced by modules
fkControls = self.buildFKSpine()
ikControls = self.buildIKSpine(fkControls)
#build the leg rigs
#first determine the leg style
legStyle = cmds.getAttr("SkeletonSettings_Cache.legStyle")
if legStyle == "Standard Biped":
cmds.progressBar(progressBar, edit = True, progress = 20, status='Creating Leg Rigs')
self.buildFKLegs()
self.buildIKLegs()
self.finishLegs()
cmds.progressBar(progressBar, edit = True, progress = 30, status='Creating Toe Rigs')
self.buildToes()
cmds.progressBar(progressBar, edit = True, progress = 40, status='Creating Auto Hips and Spine')
self.buildAutoHips()
self.autoSpine()
if legStyle == "Hind Leg":
pass
#build the arms
cmds.progressBar(progressBar, edit = True, progress = 50, status='Creating Arm Rigs')
spineBones = self.getSpineJoints()
lastSpine = "driver_" + spineBones[-1]
print lastSpine
import Modules.ART_Arm
reload(Modules.ART_Arm)
Modules.ART_Arm.Arm(True, "", None, "l", lastSpine, 6, True)
Modules.ART_Arm.Arm(True, "", None, "r", lastSpine, 13, True)
"""
self.buildFKArms()
self.buildIkArms()
"""
cmds.progressBar(progressBar, edit = True, progress = 60, status='Creating Finger Rigs')
self.buildFingers()
#build the neck and head rig
cmds.progressBar(progressBar, edit = True, progress = 70, status='Creating Neck and Head Rigs')
self.buildNeckAndHead()
#rig extra joints
cmds.progressBar(progressBar, edit = True, progress = 80, status='Creating Rigs for Custom Joints')
createdControls = self.rigLeafJoints()
createdJiggleNodes = self.rigJiggleJoints()
createdChainNodes = self.rigCustomJointChains()
#clean up the hierarchy
cmds.progressBar(progressBar, edit = True, progress = 90, status='Cleaning up Scene')
bodyGrp = cmds.group(empty = True, name = "body_grp")
for obj in ["spine_splineIK_curve", "splineIK_spine_01_splineIK", "body_anim_space_switcher_follow"]:
if cmds.objExists(obj):
cmds.parent(obj, bodyGrp)
if cmds.objExists("autoHips_sys_grp"):
cmds.parent("autoHips_sys_grp", "body_anim")
rigGrp = "ctrl_rig"
cmds.parent([bodyGrp, "leg_sys_grp"], rigGrp)
"""
rigGrp = cmds.group(empty = True, name = "ctrl_rig")
cmds.parent([bodyGrp, "leg_sys_grp", "Rig_Settings"], rigGrp)
cmds.parent(rigGrp, "offset_anim")
"""
#Arms
"""
if cmds.objExists("arm_rig_master_grp_l"):
cmds.setAttr("Rig_Settings.lArmMode", 1)
if cmds.objExists("lowerarm_l_roll_grp"):
cmds.parent("lowerarm_l_roll_grp", "arm_rig_master_grp_l")
cmds.parent("arm_rig_master_grp_l", "ctrl_rig")
if cmds.objExists("arm_rig_master_grp_r"):
cmds.setAttr("Rig_Settings.rArmMode", 1)
if cmds.objExists("lowerarm_r_roll_grp"):
cmds.parent("lowerarm_r_roll_grp", "arm_rig_master_grp_r")
cmds.parent("arm_rig_master_grp_r", "ctrl_rig")
if cmds.objExists("arm_rig_master_grp_r") and cmds.objExists("arm_rig_master_grp_l"):
armSysGrp = cmds.group(empty = True, name = "arm_sys_grp")
cmds.parent(armSysGrp, "ctrl_rig")
cmds.parent(["arm_rig_master_grp_r", "arm_rig_master_grp_l", "ik_wrist_l_anim_space_switcher_follow", "ik_wrist_r_anim_space_switcher_follow"], armSysGrp)
#arm twists
if cmds.objExists("upperarm_twist_grp_l"):
cmds.parent("upperarm_twist_grp_l", armSysGrp)
if cmds.objExists("upperarm_twist_grp_r"):
cmds.parent("upperarm_twist_grp_r", armSysGrp)
"""
if cmds.objExists("neck_01_fk_anim_grp"):
cmds.parent("neck_01_fk_anim_grp", "ctrl_rig")
#Fingers
if cmds.objExists("finger_sys_grp_l"):
cmds.parent("finger_sys_grp_l", "ctrl_rig")
if cmds.objExists("finger_sys_grp_r"):
cmds.parent("finger_sys_grp_r", "ctrl_rig")
#Custom Joints (leaf, jiggle, chain)
if len(createdControls) > 0:
for each in createdControls:
cmds.parent(each, "ctrl_rig")
if len(createdJiggleNodes) > 0:
for each in createdJiggleNodes:
cmds.parent(each, "ctrl_rig")
if len(createdChainNodes) > 0:
for each in createdChainNodes:
cmds.parent(each, "ctrl_rig")
cmds.parent("head_sys_grp", "ctrl_rig")
#finish grouping everything under 1 character grp
if cmds.objExists("Proxy_Geo_Skin_Grp"):
try:
cmds.parent("Proxy_Geo_Skin_Grp", "rig_grp")
except:
pass
if cmds.objExists("dynHairChain"):
try:
cmds.parent("dynHairChain", "rig_grp")
except:
pass
#add world spaces to each space switch control
self.addSpaces()
#Hide all joints
joints = cmds.ls(type = 'joint')
for joint in joints:
if cmds.getAttr(joint + ".v", settable = True):
cmds.setAttr(joint + ".v", 0)
cmds.progressBar(progressBar, edit = True, progress = 100, status='Cleaning up Scene')
#delete the joint mover
cmds.select("root_mover_grp", r = True, hi = True)
cmds.select("Skeleton_Settings", add = True)
nodes = cmds.ls(sl = True, transforms = True)
cmds.select(clear = True)
for node in nodes:
cmds.lockNode(node, lock = False)
cmds.lockNode("JointMover", lock = False)
cmds.delete("JointMover")
#find and delete junk nodes/clean scene
for obj in ["invis_legs_Rig_Settings", "invis_legs_Rig_Settings1", "invis_legs_spine_splineIK_curve", "invis_legs_spine_splineIK_curve1","invis_legs_master_anim_space_switcher_follow", "invis_legs_master_anim_space_switcher_follow1"]:
try:
cmds.select("*" + obj + "*")
selection = cmds.ls(sl = True)
for each in selection:
if cmds.objExists(each):
cmds.delete(each)
except:
pass
cmds.select(all = True)
selection = cmds.ls(sl = True)
for each in selection:
if each.find("invis_") == 0:
try:
parent = cmds.listRelatives(each, parent = True)
if parent == None:
cmds.delete(each)
except:
pass
#set default rotate Orders
self.setDefaultRotateOrders()
#end progress window
cmds.select(clear = True)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def setDefaultRotateOrders(self):
cmds.setAttr("body_anim.rotateOrder", 5)
cmds.setAttr("hip_anim.rotateOrder", 5)
if cmds.objExists("mid_ik_anim"):
cmds.setAttr("mid_ik_anim.rotateOrder", 5)
cmds.setAttr("chest_ik_anim.rotateOrder", 5)
cmds.setAttr("head_fk_anim.rotateOrder", 5)
for control in ["neck_01_fk_anim", "neck_02_fk_anim", "neck_03_fk_anim"]:
if cmds.objExists(control):
cmds.setAttr(control + ".rotateOrder", 5)
for control in ["spine_01_anim", "spine_02_anim", "spine_03_anim", "spine_04_anim", "spine_05_anim"]:
if cmds.objExists(control):
cmds.setAttr(control + ".rotateOrder", 5)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def addSpaces(self):
cmds.select("*_space_switcher_follow")
nodes = cmds.ls(sl = True)
spaceSwitchers = []
for node in nodes:
if node.find("invis") != 0:
spaceSwitchers.append(node)
for node in spaceSwitchers:
#create a 'world' locator to constrain to
worldLoc = cmds.spaceLocator(name = node + "_world_pos")[0]
cmds.setAttr(worldLoc + ".v", 0)
#position world loc to be in same place as node
constraint = cmds.parentConstraint(node, worldLoc)[0]
cmds.delete(constraint)
#add the constraint between worldLoc and node
if node == "spine_01_space_switcher_follow":
constraint = cmds.orientConstraint(worldLoc, node)[0]
else:
constraint = cmds.parentConstraint(worldLoc, node)[0]
#add the attr to the space switcher node for that space
spaceSwitchNode = node.rpartition("_follow")[0]
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_world", minValue = 0, maxValue = 1, dv = 0, keyable = True)
#connect that attr to the constraint
cmds.connectAttr(spaceSwitchNode + ".space_world", constraint + "." + worldLoc + "W0")
#parent worldLoc under the offset_anim
if worldLoc.find("master_anim") == 0:
cmds.parent(worldLoc, "rig_grp")
else:
cmds.parent(worldLoc, "offset_anim")
#SETUP SPECIAL CASES
for node in spaceSwitchers:
if node == "chest_ik_anim_space_switcher_follow":
#create a locator named world aligned
spaceLoc = cmds.spaceLocator(name = "chest_ik_world_aligned")[0]
cmds.setAttr(spaceLoc + ".v",0)
#constrain it to the chest ik anim
constraint = cmds.pointConstraint("chest_ik_anim", spaceLoc)[0]
cmds.delete(constraint)
#duplicate the locator
worldOrientLoc = cmds.duplicate(spaceLoc, name = "chest_ik_world_orient")[0]
#orient constrain the space loc to the world orient loc
cmds.orientConstraint(worldOrientLoc, spaceLoc, mo = True)
#parent the space loc under the hip anim
cmds.parent(spaceLoc, "body_anim")
#parent the worldOrientLoc under the master anim
cmds.parent(worldOrientLoc, "master_anim")
#add attr to the space switcher node
spaceSwitchNode = node.rpartition("_follow")[0]
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_chest_ik_world_aligned", minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceLoc, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(len(targets)):
if targets[i].find(spaceLoc) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_chest_ik_world_aligned", constraint + "." + spaceLoc + "W" + str(weight))
if node == "ik_wrist_l_anim_space_switcher_follow":
spaceList = ["body_anim", "head_fk_anim"]
if cmds.objExists("chest_ik_anim"):
spaceList.append("chest_ik_anim")
for spaceObj in spaceList:
spaceSwitchNode = node.rpartition("_follow")[0]
#add attr to the space switcher node
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_" + spaceObj, minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceObj, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(len(targets)):
if targets[i].find(spaceObj) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_" + spaceObj, constraint + "." + spaceObj + "W" + str(weight))
if node == "ik_wrist_r_anim_space_switcher_follow":
spaceList = ["body_anim", "head_fk_anim"]
if cmds.objExists("chest_ik_anim"):
spaceList.append("chest_ik_anim")
for spaceObj in spaceList:
spaceSwitchNode = node.rpartition("_follow")[0]
#add attr to the space switcher node
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_" + spaceObj, minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceObj, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(len(targets)):
if targets[i].find(spaceObj) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_" + spaceObj, constraint + "." + spaceObj + "W" + str(weight))
if node == "ik_elbow_l_anim_space_switcher_follow":
spaceList = ["body_anim"]
if cmds.objExists("chest_ik_anim"):
spaceList.append("chest_ik_anim")
for spaceObj in spaceList:
spaceSwitchNode = node.rpartition("_follow")[0]
#add attr to the space switcher node
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_" + spaceObj, minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceObj, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(len(targets)):
if targets[i].find(spaceObj) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_" + spaceObj, constraint + "." + spaceObj + "W" + str(weight))
if node == "ik_elbow_r_anim_space_switcher_follow":
spaceList = ["body_anim"]
if cmds.objExists("chest_ik_anim"):
spaceList.append("chest_ik_anim")
for spaceObj in spaceList:
spaceSwitchNode = node.rpartition("_follow")[0]
#add attr to the space switcher node
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_" + spaceObj, minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceObj, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(int(len(targets))):
if targets[i].find(spaceObj) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_" + spaceObj, constraint + "." + spaceObj + "W" + str(weight))
if node == "ik_foot_anim_l_space_switcher_follow":
for spaceObj in ["body_anim"]:
spaceSwitchNode = node.rpartition("_follow")[0]
#add attr to the space switcher node
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_" + spaceObj, minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceObj, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(int(len(targets))):
if targets[i].find(spaceObj) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_" + spaceObj, constraint + "." + spaceObj + "W" + str(weight))
if node == "ik_foot_anim_r_space_switcher_follow":
for spaceObj in ["body_anim"]:
spaceSwitchNode = node.rpartition("_follow")[0]
#add attr to the space switcher node
cmds.select(spaceSwitchNode)
cmds.addAttr(ln = "space_" + spaceObj, minValue = 0, maxValue = 1, dv = 0, keyable = True)
#add constraint to the new object on the follow node
constraint = cmds.parentConstraint(spaceObj, node, mo = True)[0]
#hook up connections
targets = cmds.parentConstraint(constraint, q = True, targetList = True)
weight = 0
for i in range(int(len(targets))):
if targets[i].find(spaceObj) != -1:
weight = i
cmds.connectAttr(spaceSwitchNode + ".space_" + spaceObj, constraint + "." + spaceObj + "W" + str(weight))
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildCoreComponents(self):
#builds the master, the root, the hips/body
#BODY CONTROL
self.buildHips()
#MASTER CONTROL
masterControl = self.createControl("circle", 150, "master_anim")
constraint = cmds.pointConstraint("root", masterControl)[0]
cmds.delete(constraint)
cmds.makeIdentity(masterControl, apply = True)
cmds.setAttr(masterControl + ".overrideEnabled", 1)
cmds.setAttr(masterControl + ".overrideColor", 18)
spaceSwitchFollow = cmds.group(empty = True, name = masterControl + "_space_switcher_follow")
constraint = cmds.parentConstraint("root", spaceSwitchFollow)[0]
cmds.delete(constraint)
spaceSwitcher = cmds.group(empty = True, name = masterControl + "_space_switcher")
constraint = cmds.parentConstraint("root", spaceSwitcher)[0]
cmds.delete(constraint)
cmds.parent(spaceSwitcher, spaceSwitchFollow)
cmds.parent(masterControl, spaceSwitcher)
cmds.makeIdentity(masterControl, apply = True)
#OFFSET CONTROL
offsetControl = self.createControl("square", 140, "offset_anim")
constraint = cmds.pointConstraint("root", offsetControl)[0]
cmds.delete(constraint)
cmds.parent(offsetControl, masterControl)
cmds.makeIdentity(offsetControl, apply = True)
cmds.setAttr(offsetControl + ".overrideEnabled", 1)
cmds.setAttr(offsetControl + ".overrideColor", 17)
#ROOT ANIM
rootControl = self.createControl("sphere", 10, "root_anim")
constraint = cmds.parentConstraint("driver_root", rootControl)[0]
cmds.delete(constraint)
cmds.parent(rootControl, masterControl)
cmds.makeIdentity(rootControl, apply = True)
cmds.parentConstraint(rootControl, "driver_root")
cmds.setAttr(rootControl + ".overrideEnabled", 1)
cmds.setAttr(rootControl + ".overrideColor", 30)
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(masterControl + attr, lock = True, keyable = False)
cmds.setAttr(offsetControl + attr, lock = True, keyable = False)
cmds.setAttr(rootControl + attr, lock = True, keyable = False)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildHips(self):
#create the grp and position and orient it correctly
bodyGrp = cmds.group(empty = True, name = "body_anim_grp")
bodyCtrl = self.createControl("square", 100, "body_anim")
constraint = cmds.parentConstraint("pelvis", bodyGrp)[0]
cmds.delete(constraint)
#world alignment
for attr in [".rx", ".ry", ".rz"]:
print cmds.getAttr(bodyGrp + attr)
if cmds.getAttr(bodyGrp + attr) < 45:
if cmds.getAttr(bodyGrp + attr) > 0:
cmds.setAttr(bodyGrp + attr, 0)
if cmds.getAttr(bodyGrp + attr) >= 80:
if cmds.getAttr(bodyGrp + attr) < 90:
cmds.setAttr(bodyGrp + attr, 90)
if cmds.getAttr(bodyGrp + attr) > 90:
if cmds.getAttr(bodyGrp + attr) < 100:
cmds.setAttr(bodyGrp + attr, 90)
if cmds.getAttr(bodyGrp + attr) <= -80:
if cmds.getAttr(bodyGrp + attr) > -90:
cmds.setAttr(bodyGrp + attr, -90)
if cmds.getAttr(bodyGrp + attr) > -90:
if cmds.getAttr(bodyGrp + attr) < -100:
cmds.setAttr(bodyGrp + attr, -90)
for attr in [".rx", ".ry", ".rz"]:
print cmds.getAttr(bodyGrp + attr)
#create space switcher
spaceSwitcherFollow = cmds.duplicate(bodyGrp, name = "body_anim_space_switcher_follow")[0]
spaceSwitcher = cmds.duplicate(bodyGrp, name = "body_anim_space_switcher")[0]
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(bodyGrp, spaceSwitcher)
#create temp duplicate and orient control to joint
tempDupe = cmds.duplicate(bodyCtrl)[0]
constraint = cmds.parentConstraint("pelvis", bodyCtrl)[0]
cmds.delete(constraint)
#parent control to grp
cmds.parent(bodyCtrl, bodyGrp)
constraint = cmds.orientConstraint(tempDupe, bodyCtrl)[0]
cmds.delete(constraint)
cmds.makeIdentity(bodyCtrl, t = 1, r = 1, s = 1, apply = True)
#clean up body control creation
cmds.delete(tempDupe)
#set control color
cmds.setAttr(bodyCtrl + ".overrideEnabled", 1)
cmds.setAttr(bodyCtrl + ".overrideColor", 17)
#lock attrs
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(bodyCtrl + attr, lock = True, keyable = False)
#build pelvis
self.buildPelvisControl()
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildPelvisControl(self):
#create the grp and position and orient it correctly
hipGrp = cmds.group(empty = True, name = "hip_anim_grp")
hipCtrl = self.createControl("circle", 60, "hip_anim")
constraint = cmds.parentConstraint("pelvis", hipGrp)[0]
cmds.delete(constraint)
#create temp duplicate and orient control to joint
tempDupe = cmds.duplicate(hipCtrl)[0]
constraint = cmds.parentConstraint("pelvis", hipCtrl)[0]
cmds.delete(constraint)
#parent control to grp
cmds.parent(hipCtrl, hipGrp)
constraint = cmds.orientConstraint(tempDupe, hipCtrl)[0]
cmds.delete(constraint)
cmds.makeIdentity(hipCtrl, t = 1, r = 1, s = 1, apply = True)
#parent the grp to the body anim
cmds.parent(hipGrp, "body_anim")
#clean up body control creation
cmds.delete(tempDupe)
#set control color
cmds.setAttr(hipCtrl + ".overrideEnabled", 1)
cmds.setAttr(hipCtrl + ".overrideColor", 18)
#lock attrs
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(hipCtrl + attr, lock = True, keyable = False)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildFKSpine(self):
#find the number of spine bones from the skeleton settings
spineJoints = self.getSpineJoints()
fkControls = []
parent = None
for joint in spineJoints:
if joint == "spine_01":
#add space switcher node to base of spine
spaceSwitcherFollow = cmds.group(empty = True, name = joint + "_space_switcher_follow")
constraint = cmds.parentConstraint(joint, spaceSwitcherFollow)[0]
cmds.delete(constraint)
spaceSwitcher = cmds.duplicate(spaceSwitcherFollow, name = joint + "_space_switcher")[0]
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
#create an empty group in the same space as the joint
group = cmds.group(empty = True, name = joint + "_anim_grp")
constraint = cmds.parentConstraint(joint, group)[0]
cmds.delete(constraint)
#create an additional layer of group that has zeroed attrs
offsetGroup = cmds.group(empty = True, name = joint + "_anim_offset_grp")
constraint = cmds.parentConstraint(joint, offsetGroup)[0]
cmds.delete(constraint)
cmds.parent(offsetGroup, group)
#create a control object in the same space as the joint
control = self.createControl("circle", 45, joint + "_anim")
tempDupe = cmds.duplicate(control)[0]
constraint = cmds.parentConstraint(joint, control)[0]
cmds.delete(constraint)
fkControls.append(control)
#parent the control object to the group
cmds.parent(control, offsetGroup)
constraint = cmds.orientConstraint(tempDupe, control, skip = ["x", "z"])[0]
cmds.delete(constraint)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#setup hierarchy
if parent != None:
cmds.parent(group, parent, absolute = True)
else:
cmds.parent(group, spaceSwitcher)
cmds.parent(spaceSwitcherFollow, "body_anim")
#set the parent to be the current spine control
parent = control
#clean up
cmds.delete(tempDupe)
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
#set the control's color
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
#create length attr on spine controls. need to find up axis for control first
upAxis = self.getUpAxis(control)
cmds.aliasAttr("length", control + ".translate" + upAxis)
return fkControls
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildIKSpine(self, fkControls):
numSpineBones = cmds.getAttr("Skeleton_Settings.numSpineBones")
if numSpineBones > 2:
#duplicate the spine joints we'll need for the spline IK
spineJoints = self.getSpineJoints()
print "SPINE JOINTS:"
print spineJoints
parent = None
rigJoints = []
for joint in spineJoints:
spineBone = cmds.duplicate(joint, parentOnly = True, name = "splineIK_" + joint)[0]
if parent != None:
cmds.parent(spineBone, parent)
else:
cmds.parent(spineBone, world = True)
parent = spineBone
rigJoints.append(str(spineBone))
for joint in rigJoints:
twistJoint = cmds.duplicate(joint, name = "twist_" + joint, parentOnly = True)[0]
cmds.parent(twistJoint, joint)
# find the driver top and mid joints
topDriverJoint = "driver_"+spineJoints[len(spineJoints) - 1]
print topDriverJoint
midDriverJoint = "driver_"+spineJoints[len(spineJoints) / 2]
print midDriverJoint
#create the spline IK
ikNodes = cmds.ikHandle(sj = str(rigJoints[0]), ee = str(rigJoints[len(rigJoints) - 1]), sol = "ikSplineSolver", createCurve = True, simplifyCurve = True, parentCurve = False, name = str(rigJoints[0]) + "_splineIK")
ikHandle = ikNodes[0]
ikCurve = ikNodes[2]
ikCurve = cmds.rename(ikCurve, "spine_splineIK_curve")
cmds.setAttr(ikCurve + ".inheritsTransform", 0)
cmds.setAttr(ikHandle + ".v", 0)
cmds.setAttr(ikCurve + ".v", 0)
#create the three joints to skin the curve to
botJoint = cmds.duplicate(rigJoints[0], name = "spine_splineIK_bottom_joint", parentOnly = True)[0]
topJoint = cmds.duplicate(rigJoints[len(rigJoints) - 1], name = "spine_splineIK_top_joint", parentOnly = True)[0]
midJoint = cmds.duplicate(topJoint, name = "spine_splineIK_mid_joint", parentOnly = True)[0]
cmds.parent([botJoint, topJoint,midJoint], world = True)
constraint = cmds.pointConstraint([botJoint, topJoint], midJoint)[0]
cmds.delete(constraint)
#skin the joints to the curve
cmds.select([botJoint, topJoint, midJoint])
skin = cmds.skinCluster( [botJoint, topJoint, midJoint], ikCurve, toSelectedBones = True )[0]
#skin weight the curve
curveShape = cmds.listRelatives(ikCurve, shapes = True)[0]
numSpans = cmds.getAttr(curveShape + ".spans")
degree = cmds.getAttr(curveShape + ".degree")
numCVs = numSpans + degree
#this should always be the case, but just to be safe
if numCVs == 4:
cmds.skinPercent(skin, ikCurve + ".cv[0]", transformValue = [(botJoint, 1.0)])
cmds.skinPercent(skin, ikCurve + ".cv[1]", transformValue = [(botJoint, 0.5), (midJoint, 0.5)])
cmds.skinPercent(skin, ikCurve + ".cv[2]", transformValue = [(midJoint, 0.5), (topJoint, 0.5)])
cmds.skinPercent(skin, ikCurve + ".cv[3]", transformValue = [(topJoint, 1.0)])
#create the controls
#TOP CTRL
topCtrl = self.createControl("circle", 50, "chest_ik_anim")
#set the control's color
cmds.setAttr(topCtrl + ".overrideEnabled", 1)
cmds.setAttr(topCtrl + ".overrideColor", 17)
#position the control
constraint = cmds.pointConstraint(topJoint, topCtrl)[0]
cmds.delete(constraint)
#create the control grp
topCtrlGrp = cmds.group(empty = True, name = topCtrl + "_grp")
constraint = cmds.parentConstraint(topJoint, topCtrlGrp)[0]
cmds.delete(constraint)
#create the top control driver group
topCtrlDriver = cmds.duplicate(topCtrlGrp, name = "chest_ik_anim_driver_grp")
#create the space switcher group
spaceSwitcherFollow = cmds.group(empty = True, name = topCtrl + "_space_switcher_follow")
constraint = cmds.parentConstraint(topCtrlGrp, spaceSwitcherFollow)[0]
cmds.delete(constraint)
spaceSwitcher = cmds.duplicate(spaceSwitcherFollow, parentOnly = True, name = topCtrl + "_space_switcher")[0]
#parent objects
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(topCtrlGrp, spaceSwitcher)
cmds.parent(topCtrlDriver, topCtrlGrp)
cmds.parent(topCtrl, topCtrlDriver)
cmds.makeIdentity(topCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.parent(topJoint, topCtrl)
#MID CTRL
midCtrl = self.createControl("circle", 45, "mid_ik_anim")
#set the control's color
cmds.setAttr(midCtrl + ".overrideEnabled", 1)
cmds.setAttr(midCtrl + ".overrideColor", 18)
#position the control
constraint = cmds.pointConstraint(midJoint, midCtrl)[0]
cmds.delete(constraint)
#create the control grp
midCtrlGrp = cmds.group(empty = True, name = midCtrl + "_grp")
constraint = cmds.parentConstraint(midJoint, midCtrlGrp)[0]
cmds.delete(constraint)
#mid control driver grp
midCtrlDriver = cmds.duplicate(midCtrlGrp, name = "mid_ik_anim_driver_grp")
midCtrlTranslateDriver = cmds.duplicate(midCtrlGrp, name = "mid_ik_anim_translate_driver_grp")
#parent objects
cmds.parent(midCtrl, midCtrlDriver)
cmds.parent(midCtrlDriver, midCtrlTranslateDriver)
cmds.parent(midCtrlTranslateDriver, midCtrlGrp)
cmds.makeIdentity(midCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.parent(midJoint, midCtrl)
cmds.parent(botJoint, "hip_anim")
#ADDING STRETCH
#add the attr to the top ctrl
cmds.select(topCtrl)
cmds.addAttr(longName='stretch', defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.addAttr(longName='squash', defaultValue=0, minValue=0, maxValue=1, keyable = True)
#create the curveInfo node#find
cmds.select(ikCurve)
curveInfoNode = cmds.arclen(cmds.ls(sl = True), ch = True )
originalLength = cmds.getAttr(curveInfoNode + ".arcLength")
#create the multiply/divide node that will get the scale factor
divideNode = cmds.shadingNode("multiplyDivide", asUtility = True)
divideNode_Inverse = cmds.shadingNode("multiplyDivide", asUtility = True)
cmds.setAttr(divideNode + ".operation", 2)
cmds.setAttr(divideNode + ".input2X", originalLength)
cmds.setAttr(divideNode_Inverse + ".operation", 2)
cmds.setAttr(divideNode_Inverse + ".input1X", originalLength)
#create the blendcolors node
blenderNode = cmds.shadingNode("blendColors", asUtility = True)
cmds.setAttr(blenderNode + ".color2R", 1)
blenderNode_Inverse = cmds.shadingNode("blendColors", asUtility = True)
cmds.setAttr(blenderNode_Inverse + ".color2R", 1)
#connect attrs
cmds.connectAttr(curveInfoNode + ".arcLength", divideNode + ".input1X")
cmds.connectAttr(curveInfoNode + ".arcLength", divideNode_Inverse + ".input2X")
cmds.connectAttr(divideNode + ".outputX", blenderNode + ".color1R")
cmds.connectAttr(divideNode_Inverse + ".outputX", blenderNode_Inverse + ".color1R")
cmds.connectAttr(topCtrl + ".stretch", blenderNode + ".blender")
cmds.connectAttr(topCtrl + ".squash", blenderNode_Inverse + ".blender")
upAxis = self.getUpAxis(topCtrl)
if upAxis == "X":
axisB = "Y"
axisC = "Z"
if upAxis == "Y":
axisB = "X"
axisC = "Z"
if upAxis == "Z":
axisB = "X"
axisC = "Y"
for i in range(len(rigJoints) - 2):
children = cmds.listRelatives(rigJoints[i], children = True)
for child in children:
if child.find("twist") != -1:
twistJoint = child
cmds.connectAttr(blenderNode_Inverse + ".outputR", twistJoint + ".scale" + axisB)
cmds.connectAttr(blenderNode_Inverse + ".outputR", twistJoint + ".scale" + axisC)
cmds.connectAttr(blenderNode + ".outputR", rigJoints[0] + ".scale" + upAxis)
#add twist amount attrs and setup
cmds.select(topCtrl)
cmds.addAttr(longName='twist_amount', defaultValue=1, minValue=0, keyable = True)
#find number of spine joints and divide 1 by numSpineJoints
num = len(spineJoints)
val = 1.0/float(num)
twistamount = val
locGrp = cmds.group(empty = True, name = "spineIK_twist_grp")
cmds.parent(locGrp, "body_anim")
for i in range(int(num - 1)):
#create a locator that will be orient constrained between the body and chest
locator = cmds.spaceLocator(name = spineJoints[i] + "_twistLoc")[0]
group = cmds.group(empty = True, name = spineJoints[i] + "_twistLocGrp")
constraint = cmds.parentConstraint(spineJoints[i], locator)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(spineJoints[i], group)[0]
cmds.delete(constraint)
cmds.parent(locator, group)
cmds.parent(group, locGrp)
cmds.setAttr(locator + ".v", 0, lock = True)
#duplicate the locator and parent it under the group. This will be the locator that takes the rotation x twist amount and gives us the final value
orientLoc = cmds.duplicate(locator, name = spineJoints[i] + "_orientLoc")[0]
#create constraints between body/chest
constraint = cmds.orientConstraint(["body_anim", topCtrl], locator)[0]
#set weights on constraint
firstValue = 1 - twistamount
secondValue = 1 - firstValue
cmds.setAttr(constraint + ".body_animW0", firstValue)
cmds.setAttr(constraint + "." + topCtrl + "W1", secondValue)
#factor in twist amount
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = spineJoints[i] + "_twist_amount")
#expose the twistAmount on the control as an attr
cmds.connectAttr(topCtrl + ".twist_amount", twistMultNode + ".input2X")
cmds.connectAttr(topCtrl + ".twist_amount", twistMultNode + ".input2Y")
cmds.connectAttr(topCtrl + ".twist_amount", twistMultNode + ".input2Z")
cmds.connectAttr(locator + ".rotate", twistMultNode + ".input1")
cmds.connectAttr(twistMultNode + ".output", orientLoc + ".rotate")
#constrain the spine joint to the orientLoc
if upAxis == "X":
skipped = ["y", "z"]
if upAxis == "Y":
skipped = ["x", "z"]
if upAxis == "Z":
skipped = ["x", "y"]
cmds.orientConstraint(orientLoc, "twist_splineIK_" + spineJoints[i], skip = skipped)
twistamount = twistamount + val
#parent the components to the body anim
cmds.parent(midCtrlGrp, "body_anim")
cmds.parent(midCtrl, world = True)
cmds.parent(midJoint, world = True)
for attr in [".rx", ".ry", ".rz"]:
cmds.setAttr(midCtrlGrp + attr, 0)
cmds.parent(midCtrl, midCtrlDriver)
cmds.makeIdentity(midCtrl, t = 1, r = 1, s = 0, apply = True)
cmds.parent(midJoint, midCtrl)
cmds.parent(spaceSwitcherFollow, "body_anim")
cmds.parent(rigJoints[0], "body_anim")
#world alignment
cmds.parent(topCtrl, world = True)
cmds.parent(topJoint, world = True)
for attr in [".rx", ".ry", ".rz"]:
if cmds.getAttr(spaceSwitcherFollow + attr) < 45:
if cmds.getAttr(spaceSwitcherFollow + attr) > 0:
cmds.setAttr(spaceSwitcherFollow + attr, 0)
if cmds.getAttr(spaceSwitcherFollow + attr) >= 80:
if cmds.getAttr(spaceSwitcherFollow + attr) < 90:
cmds.setAttr(spaceSwitcherFollow + attr, 90)
if cmds.getAttr(spaceSwitcherFollow + attr) > 90:
if cmds.getAttr(spaceSwitcherFollow + attr) < 100:
cmds.setAttr(spaceSwitcherFollow + attr, 90)
if cmds.getAttr(spaceSwitcherFollow + attr) <= -80:
if cmds.getAttr(spaceSwitcherFollow + attr) > -90:
cmds.setAttr(spaceSwitcherFollow + attr, -90)
if cmds.getAttr(spaceSwitcherFollow + attr) > -90:
if cmds.getAttr(spaceSwitcherFollow + attr) < -100:
cmds.setAttr(spaceSwitcherFollow + attr, -90)
cmds.parent(topCtrl, topCtrlDriver)
cmds.makeIdentity(topCtrl, t = 1, r = 1, s = 0, apply = True)
cmds.parent(topJoint, topCtrl)
#hookup spine driver joints
driverJoints = []
for joint in rigJoints:
driverJoint = joint.partition("splineIK_")[2]
driverJoint = "driver_" + driverJoint
driverJoints.append(driverJoint)
#hookup spine to driver
self.hookupSpine(rigJoints, fkControls)
#control driver joints
children = cmds.listRelatives(rigJoints[len(rigJoints) -1], children = True)
for child in children:
if child.find("twist") != -1:
twistJoint = child
topSpineJointConstraint = cmds.pointConstraint(topJoint, twistJoint, mo = True)[0]
topSpineBone = twistJoint.partition("twist_")[2]
cmds.pointConstraint(topSpineBone, twistJoint)[0]
#connect attr on top spine joint constraint
target = cmds.pointConstraint(topSpineJointConstraint, q = True, weightAliasList = True)[0]
cmds.connectAttr(topCtrl + ".stretch", topSpineJointConstraint + "." + target)
#create stretch meter attr
cmds.select(topCtrl)
cmds.addAttr(longName='stretchFactor',keyable = True)
cmds.connectAttr(divideNode + ".outputX", topCtrl + ".stretchFactor")
cmds.setAttr(topCtrl + ".stretchFactor", lock = True)
cmds.select(midCtrl)
cmds.addAttr(longName='stretchFactor',keyable = True)
cmds.connectAttr(topCtrl + ".stretchFactor", midCtrl + ".stretchFactor")
cmds.setAttr(midCtrl + ".stretchFactor", lock = True)
#lock and hide attrs that should not be keyable
for control in [topCtrl, midCtrl]:
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, keyable = False, lock = True)
# Create a couple nodes that can be used to make IK/FK matching work better.
chest_match_node = cmds.duplicate(topCtrl, po=True, name=topCtrl+"_MATCH")
cmds.parent(chest_match_node, topDriverJoint)
mid_match_node = cmds.duplicate(midCtrl, po=True, name=midCtrl+"_MATCH")
cmds.parent(mid_match_node, midDriverJoint)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildFKLegs(self):
#need to create the leg joints for each side based on the driver thigh, calf, and foot
for side in ["l", "r"]:
ball = False
#create joints
fkThighJoint = cmds.duplicate("driver_thigh_" + side, name = "fk_leg_thigh_" + side, parentOnly = True)[0]
fkCalfJoint = cmds.duplicate("driver_calf_" + side, name = "fk_leg_calf_" + side, parentOnly = True)[0]
fkFootJoint = cmds.duplicate("driver_foot_" + side, name = "fk_leg_foot_" + side, parentOnly = True)[0]
if cmds.objExists("driver_ball_" + side):
ball = True
fkBallJoint = cmds.duplicate("driver_ball_" + side, name = "fk_leg_ball_" + side, parentOnly = True)[0]
for joint in [fkThighJoint, fkCalfJoint, fkFootJoint]:
cmds.parent(joint, world = True)
if ball:
cmds.parent(fkBallJoint, fkFootJoint)
cmds.parent(fkFootJoint, fkCalfJoint)
cmds.parent(fkCalfJoint, fkThighJoint)
cmds.makeIdentity(fkThighJoint, t = 0, r = 1, s = 0, apply = True)
#create controls for each joint
#THIGH
fkThighCtrl = self.createControl("circle", 30, "fk_thigh_" + side + "_anim")
cmds.setAttr(fkThighCtrl + ".ry", -90)
cmds.makeIdentity(fkThighCtrl, r = 1, apply =True)
fkThighCtrlGrp = cmds.group(empty = True, name = "fk_thigh_" + side + "_anim_grp")
constraint = cmds.parentConstraint(fkThighJoint, fkThighCtrlGrp)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(fkThighJoint, fkThighCtrl)[0]
cmds.delete(constraint)
fkThighOrientGrp = cmds.duplicate(fkThighCtrlGrp, parentOnly = True, name = "fk_thigh_" + side + "_orient_grp")
fkThighWorldNode = cmds.duplicate(fkThighOrientGrp, parentOnly = True, name = "fk_thigh_" + side + "_world")
cmds.orientConstraint(fkThighWorldNode, fkThighOrientGrp)
cmds.parent(fkThighWorldNode, "body_anim")
cmds.parent(fkThighCtrl, fkThighCtrlGrp)
cmds.parent(fkThighCtrlGrp, fkThighOrientGrp)
#get the distance between the hip and knee
thighPos = cmds.xform("driver_thigh_" + side, q = True, ws = True, t = True)
kneePos = cmds.xform("driver_calf_" + side, q = True, ws = True, t = True)
dist = (thighPos[2] - kneePos[2]) / 2
#move the ctrl to the position of dist
upAxis = self.getUpAxis(fkThighCtrl)
if side == "l":
cmds.setAttr(fkThighCtrl + ".translate" + upAxis, dist * -1)
else:
cmds.setAttr(fkThighCtrl + ".translate" + upAxis, dist)
#get the pivot of the thigh and set the pivot of the ctrl to that position
piv = cmds.xform(fkThighJoint, q = True, ws = True, rotatePivot = True)
cmds.xform(fkThighCtrl, ws = True, piv = (piv[0], piv[1], piv[2]))
#lock attrs that should not be animated
cmds.setAttr(fkThighCtrl + ".tx", lock = True, keyable = False)
cmds.setAttr(fkThighCtrl + ".ty", lock = True, keyable = False)
cmds.setAttr(fkThighCtrl + ".tz", lock = True, keyable = False)
cmds.setAttr(fkThighCtrl + ".sx", lock = True, keyable = False)
cmds.setAttr(fkThighCtrl + ".sy", lock = True, keyable = False)
cmds.setAttr(fkThighCtrl + ".sz", lock = True, keyable = False)
cmds.setAttr(fkThighCtrl + ".v", lock = True, keyable = False)
#CALF
fkCalfCtrl = self.createControl("semiCircle", 5, "fk_calf_" + side + "_anim")
cmds.makeIdentity(fkCalfCtrl, s = 1, apply = True)
cmds.setAttr(fkCalfCtrl + ".sx", .5)
cmds.setAttr(fkCalfCtrl + ".sy", .75)
cmds.setAttr(fkCalfCtrl + ".rx", 180)
cmds.setAttr(fkCalfCtrl + ".ry", -90)
cmds.makeIdentity(fkCalfCtrl, s = 1, apply = True)
fkCalfCtrlGrp = cmds.group(empty = True, name = "fk_calf_" + side + "_anim_grp")
constraint = cmds.parentConstraint(fkCalfJoint, fkCalfCtrlGrp)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint(fkCalfJoint, fkCalfCtrl)[0]
cmds.delete(constraint)
cmds.parent(fkCalfCtrl, fkCalfCtrlGrp)
#get the pivot of the calf and set the pivot of the ctrl to that position
piv = cmds.xform(fkCalfJoint, q = True, ws = True, rotatePivot = True)
cmds.xform(fkCalfCtrl, ws = True, piv = (piv[0], piv[1], piv[2]))
#parent the fk ctrl grp to the thigh anim
cmds.parent(fkCalfCtrlGrp, fkThighCtrl)
cmds.makeIdentity(fkCalfCtrl, r = 1, apply = True)
#lock attrs that should not be animated
cmds.setAttr(fkCalfCtrl + ".tx", lock = True, keyable = False)
cmds.setAttr(fkCalfCtrl + ".ty", lock = True, keyable = False)
cmds.setAttr(fkCalfCtrl + ".tz", lock = True, keyable = False)
cmds.setAttr(fkCalfCtrl + ".sx", lock = True, keyable = False)
cmds.setAttr(fkCalfCtrl + ".sy", lock = True, keyable = False)
cmds.setAttr(fkCalfCtrl + ".sz", lock = True, keyable = False)
cmds.setAttr(fkCalfCtrl + ".v", lock = True, keyable = False)
#FOOT
fkFootCtrl = self.createControl("circle", 17, "fk_foot_" + side + "_anim")
cmds.setAttr(fkFootCtrl + ".ry", -90)
cmds.makeIdentity(fkFootCtrl, r = 1, apply =True)
fkFootCtrlGrp = cmds.group(empty = True, name = "fk_foot_" + side + "_anim_grp")
constraint = cmds.parentConstraint(fkFootJoint, fkFootCtrlGrp)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(fkFootJoint, fkFootCtrl)[0]
cmds.delete(constraint)
cmds.parent(fkFootCtrl, fkFootCtrlGrp)
#get the pivot of the thigh and set the pivot of the ctrl to that position
piv = cmds.xform(fkFootJoint, q = True, ws = True, rotatePivot = True)
cmds.xform(fkFootCtrl, ws = True, piv = (piv[0], piv[1], piv[2]))
#parent the fk ctrl grp to the thigh anim
cmds.parent(fkFootCtrlGrp, fkCalfCtrl)
#lock attrs that should not be animated
cmds.setAttr(fkFootCtrl + ".tx", lock = True, keyable = False)
cmds.setAttr(fkFootCtrl + ".ty", lock = True, keyable = False)
cmds.setAttr(fkFootCtrl + ".tz", lock = True, keyable = False)
cmds.setAttr(fkFootCtrl + ".sx", lock = True, keyable = False)
cmds.setAttr(fkFootCtrl + ".sy", lock = True, keyable = False)
cmds.setAttr(fkFootCtrl + ".sz", lock = True, keyable = False)
cmds.setAttr(fkFootCtrl + ".v", lock = True, keyable = False)
if ball:
#BALL
fkBallCtrl = self.createControl("arrowOnBall", 2, "fk_ball_" + side + "_anim")
if side == "l":
cmds.setAttr(fkBallCtrl + ".rx", -90)
cmds.makeIdentity(fkBallCtrl, t = 1, r = 1, s = 1, apply = True)
else:
cmds.setAttr(fkBallCtrl + ".rx", 90)
cmds.makeIdentity(fkBallCtrl, t = 1, r = 1, s = 1, apply = True)
fkBallCtrlGrp = cmds.group(empty = True, name = "fk_ball_" + side + "_anim_grp")
constraint = cmds.parentConstraint(fkBallJoint, fkBallCtrlGrp)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(fkBallJoint, fkBallCtrl)[0]
cmds.delete(constraint)
cmds.parent(fkBallCtrl, fkBallCtrlGrp)
#get the pivot of the thigh and set the pivot of the ctrl to that position
piv = cmds.xform(fkBallJoint, q = True, ws = True, rotatePivot = True)
cmds.xform(fkBallCtrl, ws = True, piv = (piv[0], piv[1], piv[2]))
#parent the fk ctrl grp to the thigh anim
cmds.parent(fkBallCtrlGrp, fkFootCtrl)
#lock attrs that should not be animated
cmds.setAttr(fkBallCtrl + ".tx", lock = True, keyable = False)
cmds.setAttr(fkBallCtrl + ".ty", lock = True, keyable = False)
cmds.setAttr(fkBallCtrl + ".tz", lock = True, keyable = False)
cmds.setAttr(fkBallCtrl + ".sx", lock = True, keyable = False)
cmds.setAttr(fkBallCtrl + ".sy", lock = True, keyable = False)
cmds.setAttr(fkBallCtrl + ".sz", lock = True, keyable = False)
cmds.setAttr(fkBallCtrl + ".v", lock = True, keyable = False)
#hook up leg joints to follow ctrls
cmds.orientConstraint(fkThighCtrl, fkThighJoint)
cmds.orientConstraint(fkCalfCtrl, fkCalfJoint)
cmds.orientConstraint(fkFootCtrl, fkFootJoint)
if ball:
cmds.orientConstraint(fkBallCtrl, fkBallJoint)
#color the controls
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(fkThighCtrl + ".overrideEnabled", 1)
cmds.setAttr(fkThighCtrl + ".overrideColor", color)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildIKLegs(self):
#need to create the leg joints for each side based on the driver thigh, calf, and foot
for side in ["l", "r"]:
#create joints
ikThighJoint = cmds.duplicate("driver_thigh_" + side, name = "ik_leg_thigh_" + side, parentOnly = True)[0]
ikCalfJoint = cmds.duplicate("driver_calf_" + side, name = "ik_leg_calf_" + side, parentOnly = True)[0]
ikFootJoint = cmds.duplicate("driver_foot_" + side, name = "ik_leg_foot_" + side, parentOnly = True)[0]
cmds.setAttr(ikThighJoint + ".v", 0)
for joint in [ikThighJoint, ikCalfJoint, ikFootJoint]:
cmds.parent(joint, world = True)
cmds.parent(ikFootJoint, ikCalfJoint)
cmds.parent(ikCalfJoint, ikThighJoint)
cmds.makeIdentity(ikThighJoint, t = 0, r = 1, s = 0, apply = True)
#create the 2 joint chain for the no flip setup
cmds.select(clear = True)
beginJoint = cmds.joint(name = "noflip_begin_joint_" + side)
cmds.select(clear = True)
endJoint = cmds.joint(name = "noflip_end_joint_" + side)
cmds.select(clear = True)
cmds.setAttr(beginJoint + ".v", 0)
beginPos = cmds.xform(ikThighJoint, q = True, ws = True, t = True)
cmds.xform(beginJoint, ws = True, t = (beginPos[0], 0, beginPos[2]))
endPos = cmds.xform(ikFootJoint, q = True, ws = True, t = True)
cmds.xform(endJoint, ws = True, relative = True, t = (endPos[0], 0, endPos[2]))
cmds.parent(endJoint, beginJoint)
cmds.makeIdentity(beginJoint, t = 0, r = 1, s = 0, apply = True)
#set preferred angle
cmds.setAttr(beginJoint + ".preferredAngleX", -90)
#apply a RP IK solver to the 2 bone chain
ikNodes = cmds.ikHandle(name = "noflip_chain_ikHandle_" + side, solver = "ikRPsolver", sj = beginJoint, ee = endJoint)
for node in ikNodes:
cmds.setAttr(node + ".v", 0)
#create a locator(target loc) and group it
targetLoc = cmds.spaceLocator(name = "noflip_target_loc_" + side)[0]
targetGrp = cmds.group(empty = True, name = "noflip_target_loc_grp_" + side)
cmds.setAttr(targetLoc + ".v", 0)
constraint = cmds.pointConstraint(beginJoint, targetGrp)[0]
cmds.delete(constraint)
cmds.parent(targetLoc, targetGrp)
constraint = cmds.pointConstraint(endJoint, targetLoc)
cmds.delete(constraint)
cmds.parent(ikNodes[0], targetLoc)
#create the foot control
footCtrl = self.createControl("foot", 1, ("ik_foot_anim_" + side))
footCtrlGrp = cmds.group(empty = True, name = "ik_foot_anim_grp_" + side)
constraint = cmds.pointConstraint(ikFootJoint, footCtrlGrp)[0]
cmds.delete(constraint)
#position the foot control
footCtrlPos = cmds.xform("ball_mover_" + side + "_grp", q = True, ws = True, t = True)
cmds.xform(footCtrl, ws = True, t = (footCtrlPos[0], 0, 0))
constraint = cmds.pointConstraint("ball_mover_" + side + "_grp", footCtrl)[0]
cmds.delete(constraint)
cmds.makeIdentity(footCtrl, t=1, r=1, s=1, apply = True)
if side == "r":
cmds.setAttr(footCtrl + ".sx", -1)
cmds.makeIdentity(footCtrl, t=1, r=1, s=1, apply = True)
cmds.xform(footCtrl, ws = True, piv = [endPos[0], endPos[1], endPos[2]])
footCtrlSpaceSwitcherFollow = cmds.duplicate(footCtrlGrp, po = True, name = "ik_foot_anim_" + side + "_space_switcher_follow")[0]
footCtrlSpaceSwitcher = cmds.duplicate(footCtrlGrp, po = True, name = "ik_foot_anim_" + side + "_space_switcher")[0]
cmds.parent(footCtrlSpaceSwitcher, footCtrlSpaceSwitcherFollow)
cmds.parent(footCtrlGrp, footCtrlSpaceSwitcher)
cmds.parent(footCtrl, footCtrlGrp)
cmds.makeIdentity(footCtrl, t=1, r=1, s=1, apply = True)
#create the noflip pole vector loc
scale = self.getScaleFactor()
noflipVectorLoc = cmds.spaceLocator(name = "noflip_pv_loc_" + side)[0]
noflipVectorGrp = cmds.group(name = "noflip_pv_loc_grp_" + side, empty = True)
constraint = cmds.pointConstraint([beginJoint, endJoint], noflipVectorLoc)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint(targetLoc, noflipVectorGrp)[0]
cmds.delete(constraint)
cmds.setAttr(noflipVectorLoc + ".v", 0)
noflipVectorLocPos = cmds.xform(footCtrl + "_end_loc", q = True, ws = True, t = True)
if side == "l":
cmds.setAttr(noflipVectorLoc + ".ty", noflipVectorLocPos[1])
else:
cmds.setAttr(noflipVectorLoc + ".ty", noflipVectorLocPos[1] * -1)
cmds.makeIdentity(noflipVectorLoc, t = 1, r = 1, s = 1, apply = True)
cmds.parent(noflipVectorLoc, noflipVectorGrp)
if side == "l":
cmds.setAttr(noflipVectorLoc + ".ty", (200 * scale))
else:
cmds.setAttr(noflipVectorLoc + ".ty", (-200 * scale))
cmds.makeIdentity(noflipVectorLoc, t = 1, r = 1, s = 1, apply = True)
cmds.parentConstraint(endJoint, noflipVectorGrp)
#duplicate the targetGrp to create our aim vector locator
aimGrp = cmds.duplicate(targetGrp, name = "noflip_aim_grp_" + side, parentOnly = True)[0]
aimSoftGrp = cmds.duplicate(targetGrp, name = "noflip_aim_soft_grp_" + side, parentOnly = True)[0]
aimLoc = cmds.duplicate(targetLoc, name = "noflip_aim_loc_" + side, parentOnly = True)[0]
cmds.parent(aimSoftGrp, aimGrp)
cmds.parent(aimLoc, aimSoftGrp)
cmds.setAttr(aimGrp + ".v", 0)
if side == "r":
cmds.setAttr(aimGrp + ".ry", 90)
else:
cmds.setAttr(aimGrp + ".ry", -90)
#connectAttrs of targetLoc and aimLoc
cmds.connectAttr(targetLoc + ".tx", aimLoc + ".tx")
cmds.connectAttr(targetLoc + ".tz", aimLoc + ".tz")
#pole vector constraint between aimLoc and ikNodes[0] (2bone chain ik handle)
cmds.poleVectorConstraint(aimLoc, ikNodes[0])
if side == "l":
cmds.setAttr(ikNodes[0] + ".twist", 180)
twistAmt = cmds.getAttr(beginJoint + ".rz")
cmds.setAttr(ikNodes[0] + ".twist", twistAmt * -1)
#create RP IK on the actual IK leg chain
#set preferred angle first
cmds.setAttr(ikThighJoint + ".preferredAngleZ", 90)
cmds.setAttr(ikCalfJoint + ".preferredAngleZ", 90)
ikNodesLeg = cmds.ikHandle(name = "foot_ikHandle_" + side, solver = "ikRPsolver", sj = ikThighJoint, ee = ikFootJoint)
footIK = ikNodesLeg[0]
cmds.setAttr(footIK + ".v", 0)
cmds.parent(footIK, targetLoc)
#create pole vector constraint between knee loc and full ik leg rp ik handle
cmds.poleVectorConstraint(noflipVectorLoc, footIK)
#set limits on the aimLoc in Z space
minTz = cmds.getAttr(aimLoc + ".tz")
maxTz = cmds.xform(aimGrp, q = True, ws = True, t = True)[0]
if side == "l":
maxTz = maxTz * -1
cmds.transformLimits(aimLoc, etz = (True, True), tz = (minTz, maxTz))
#create the twist control
kneeCtrl = self.createControl("arrow", 2, ("ik_knee_anim_" + side))
constraint = cmds.pointConstraint(ikCalfJoint, kneeCtrl)[0]
cmds.delete(constraint)
kneeCtrlGrp = cmds.group(name = "ik_knee_anim_grp_" + side, empty = True)
constraint = cmds.parentConstraint(ikCalfJoint, kneeCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(kneeCtrl, kneeCtrlGrp)
cmds.makeIdentity(kneeCtrl, t = 1, r = 1, s = 1, apply = True)
upAxis = self.getUpAxis(kneeCtrl)
cmds.pointConstraint(ikCalfJoint, kneeCtrlGrp, mo = True)
cmds.setAttr(kneeCtrl + ".overrideEnabled", 1)
cmds.setAttr(kneeCtrl + ".overrideDisplayType", 2)
#Create foot rig
#create joints for ball and toe in IK leg skeleton
cmds.select(clear = True)
ikBallJoint = cmds.joint(name = "ik_leg_ball_" + side)
cmds.select(clear = True)
ikToeJoint = cmds.joint(name = "ik_leg_toe_" + side)
cmds.select(clear = True)
#position joints
constraint = cmds.parentConstraint("ball_" + side + "_lra", ikBallJoint)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint("jointmover_toe_" + side + "_end", ikToeJoint)[0]
cmds.delete(constraint)
constraint = cmds.orientConstraint(ikBallJoint, ikToeJoint)[0]
cmds.delete(constraint)
#parent joints into IK leg hierarchy
cmds.parent(ikToeJoint, ikBallJoint)
cmds.parent(ikBallJoint, ikFootJoint)
cmds.makeIdentity(ikBallJoint, r = 1, apply = True)
#create SC IK for ankle to ball and ball to toe
ballIKNodes = cmds.ikHandle(name = "ikHandle_ball_" + side, solver = "ikSCsolver", sj = ikFootJoint, ee = ikBallJoint)
toeIKNodes = cmds.ikHandle(name = "ikHandle_toe_" + side, solver = "ikSCsolver", sj = ikBallJoint, ee = ikToeJoint)
cmds.setAttr(ballIKNodes[0] + ".v", 0)
cmds.setAttr(toeIKNodes[0] + ".v", 0)
#create the locators we need for all of the pivot points
toeTipPivot = cmds.spaceLocator(name = "ik_foot_toe_tip_pivot_" + side)[0]
insidePivot = cmds.spaceLocator(name = "ik_foot_inside_pivot_" + side)[0]
outsidePivot = cmds.spaceLocator(name = "ik_foot_outside_pivot_" + side)[0]
heelPivot = cmds.spaceLocator(name = "ik_foot_heel_pivot_" + side)[0]
toePivot = cmds.spaceLocator(name = "ik_foot_toe_pivot_" + side)[0]
ballPivot = cmds.spaceLocator(name = "ik_foot_ball_pivot_" + side)[0]
masterBallPivot = cmds.spaceLocator(name = "master_foot_ball_pivot_" + side)[0]
#create the controls
heelControl = self.createControl("arrowOnBall", 1.5, "heel_ctrl_" + side)
toeWiggleControl = self.createControl("arrowOnBall", 2, "toe_wiggle_ctrl_" + side)
toeControl = self.createControl("arrowOnBall", 1.5, "toe_tip_ctrl_" + side)
if side == "l":
cmds.setAttr(toeControl + ".rx", -90)
cmds.setAttr(toeControl + ".rz", -90)
cmds.makeIdentity(toeControl, t = 1, r = 1, s = 1, apply = True)
else:
cmds.setAttr(toeControl + ".rx", 90)
cmds.setAttr(toeControl + ".rz", -90)
cmds.makeIdentity(toeControl, t = 1, r = 1, s = 1, apply = True)
if side == "l":
cmds.setAttr(toeWiggleControl + ".rx", -90)
cmds.makeIdentity(toeWiggleControl, t = 1, r = 1, s = 1, apply = True)
else:
cmds.setAttr(toeWiggleControl + ".rx", 90)
cmds.makeIdentity(toeWiggleControl, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(heelControl + ".rx", -90)
cmds.makeIdentity(heelControl, t = 1, r = 1, s = 1, apply = True)
#position and orient controls
constraint = cmds.parentConstraint("jointmover_" + side + "_heel_loc", heelControl)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint("ball_" + side + "_lra", toeWiggleControl)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint("jointmover_toe_" + side + "_end", toeControl)[0]
cmds.delete(constraint)
constraint = cmds.orientConstraint(toeWiggleControl, toeControl)[0]
cmds.delete(constraint)
#position the pivots
constraint = cmds.pointConstraint(heelControl, heelPivot)[0]
cmds.delete(constraint)
constraint = cmds.orientConstraint(heelControl, heelPivot)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(toeWiggleControl, ballPivot)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(toeControl, toeTipPivot)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(toeControl, toePivot)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint("inside_pivot_" + side + "_mover", insidePivot)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint("outside_pivot_" + side + "_mover", outsidePivot)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(ballPivot, masterBallPivot)[0]
cmds.delete(constraint)
#create groups for each pivot and parent the pivot to the corresponding group
for piv in [heelPivot, ballPivot, toeTipPivot, toePivot, insidePivot, outsidePivot, masterBallPivot]:
pivGrp = cmds.group(empty = True, name = piv + "_grp")
constraint = cmds.parentConstraint(piv, pivGrp)[0]
cmds.delete(constraint)
cmds.parent(piv, pivGrp)
shape = cmds.listRelatives(piv, shapes = True)[0]
cmds.setAttr(shape + ".v", 0)
#create groups for each control and parent the control to the corresponding group
for ctrl in [heelControl, toeWiggleControl, toeControl]:
grp = cmds.group(empty = True, name = ctrl + "_grp")
constraint = cmds.parentConstraint(ctrl, grp)[0]
cmds.delete(constraint)
cmds.parent(ctrl, grp)
if side == "r":
if ctrl == heelControl:
cmds.setAttr(grp + ".rx", (cmds.getAttr(grp + ".rx")) *1)
cmds.setAttr(grp + ".ry", (cmds.getAttr(grp + ".ry")) *1)
#setup pivot hierarchy
cmds.parent(toeWiggleControl + "_grp", toePivot)
cmds.parent(ballPivot + "_grp", toePivot)
cmds.parent(toePivot + "_grp", heelPivot)
cmds.parent(heelPivot + "_grp", outsidePivot)
cmds.parent(outsidePivot + "_grp", insidePivot)
cmds.parent(insidePivot + "_grp", toeTipPivot)
#setup foot roll
cmds.setAttr(heelControl + ".rz", 0)
cmds.setAttr(heelPivot + ".rz", 0)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", 0)
cmds.setDrivenKeyframe([heelPivot + ".rz", toePivot + ".rz", ballPivot + ".rz"], cd = heelControl + ".rz", itt = "linear", ott = "linear")
if side == "l":
cmds.setAttr(heelControl + ".rz", -90)
cmds.setAttr(heelPivot + ".rz", 0)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", -90)
cmds.setDrivenKeyframe([heelPivot + ".rz", toePivot + ".rz", ballPivot + ".rz"], cd = heelControl + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(heelControl + ".rz", 90)
cmds.setAttr(heelPivot + ".rz", 90)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", 0)
cmds.setDrivenKeyframe([heelPivot + ".rz", toePivot + ".rz", ballPivot + ".rz"], cd = heelControl + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(heelControl + ".rz", 0)
cmds.setAttr(heelPivot + ".rz", 0)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", 0)
if side == "r":
cmds.setAttr(heelControl + ".rz", -90)
cmds.setAttr(heelPivot + ".rz", 0)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", -90)
cmds.setDrivenKeyframe([heelPivot + ".rz", toePivot + ".rz", ballPivot + ".rz"], cd = heelControl + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(heelControl + ".rz", 90)
cmds.setAttr(heelPivot + ".rz", 90)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", 0)
cmds.setDrivenKeyframe([heelPivot + ".rz", toePivot + ".rz", ballPivot + ".rz"], cd = heelControl + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(heelControl + ".rz", 0)
cmds.setAttr(heelPivot + ".rz", 0)
cmds.setAttr(toePivot + ".rz", 0)
cmds.setAttr(ballPivot + ".rz", 0)
#setup heel rotate X and Y
if side == "l":
cmds.connectAttr(heelControl + ".rx", ballPivot + ".ry")
if side == "r":
heelControlRXMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = heelControl + "_RX_MultNode")
cmds.connectAttr(heelControl + ".rx", heelControlRXMultNode + ".input1X")
cmds.setAttr(heelControlRXMultNode + ".input2X", -1)
cmds.connectAttr(heelControlRXMultNode + ".outputX", ballPivot + ".ry")
if side == "l":
heelControlRYMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = heelControl + "_RY_MultNode")
cmds.connectAttr(heelControl + ".ry", heelControlRYMultNode + ".input1X")
cmds.setAttr(heelControlRYMultNode + ".input2X", -1)
cmds.connectAttr(heelControlRYMultNode + ".outputX", ballPivot + ".rx")
else:
cmds.connectAttr(heelControl + ".ry", ballPivot + ".rx")
#setup toe control Y and Z rotates
cmds.connectAttr(toeControl + ".ry", toeTipPivot + ".ry")
cmds.connectAttr(toeControl + ".rz", toeTipPivot + ".rz")
#setup the toe control RX (side to side)
if side == "l":
cmds.setAttr(toeControl + ".rx", 0)
cmds.setAttr(insidePivot + ".rx", 0)
cmds.setAttr(outsidePivot + ".rx", 0)
cmds.setDrivenKeyframe([insidePivot + ".rx", outsidePivot + ".rx"], cd = toeControl + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(toeControl + ".rx", -90)
cmds.setAttr(insidePivot + ".rx", 0)
cmds.setAttr(outsidePivot + ".rx", -90)
cmds.setDrivenKeyframe([insidePivot + ".rx", outsidePivot + ".rx"], cd = toeControl + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(toeControl + ".rx", 90)
cmds.setAttr(insidePivot + ".rx", 90)
cmds.setAttr(outsidePivot + ".rx", 0)
cmds.setDrivenKeyframe([insidePivot + ".rx", outsidePivot + ".rx"], cd = toeControl + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(toeControl + ".rx", 0)
cmds.setAttr(insidePivot + ".rx", 0)
cmds.setAttr(outsidePivot + ".rx", 0)
if side == "r":
cmds.setAttr(toeControl + ".rx", 0)
cmds.setAttr(insidePivot + ".rx", 0)
cmds.setAttr(outsidePivot + ".rx", 0)
cmds.setDrivenKeyframe([insidePivot + ".rx", outsidePivot + ".rx"], cd = toeControl + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(toeControl + ".rx", -90)
cmds.setAttr(insidePivot + ".rx", 0)
cmds.setAttr(outsidePivot + ".rx", 90)
cmds.setDrivenKeyframe([insidePivot + ".rx", outsidePivot + ".rx"], cd = toeControl + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(toeControl + ".rx", 90)
cmds.setAttr(insidePivot + ".rx", -90)
cmds.setAttr(outsidePivot + ".rx", 0)
cmds.setDrivenKeyframe([insidePivot + ".rx", outsidePivot + ".rx"], cd = toeControl + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(toeControl + ".rx", 0)
cmds.setAttr(insidePivot + ".rx", 0)
cmds.setAttr(outsidePivot + ".rx", 0)
#parent the IK nodes into the foot rig setup
cmds.parent(footIK, ballPivot)
cmds.parent(ballIKNodes[0], ballPivot)
cmds.parent(toeIKNodes[0], toeWiggleControl)
cmds.pointConstraint(footCtrl, targetLoc, mo = True)
cmds.parent([toeTipPivot + "_grp", heelControl + "_grp", toeControl + "_grp"], masterBallPivot)
cmds.parent(masterBallPivot + "_grp", footCtrl)
#add the heel pivot and ball pivot attrs to the foot control
cmds.select(heelControl)
cmds.addAttr(longName= ( "heelPivot" ), defaultValue=0, keyable = True)
cmds.addAttr(longName= ( "ballPivot" ), defaultValue=0, keyable = True)
#setup heel and ball pivot
if side == "r":
heelPivotMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = heelPivot + "_MultNode")
cmds.connectAttr(heelControl + ".heelPivot", heelPivotMultNode + ".input1X")
cmds.setAttr(heelPivotMultNode + ".input2X", -1)
cmds.connectAttr(heelPivotMultNode + ".outputX", heelPivot + ".rx")
else:
cmds.connectAttr(heelControl + ".heelPivot", heelPivot + ".rx")
cmds.connectAttr(heelControl + ".ballPivot", masterBallPivot + ".ry")
#clean up the hierarchy
ctrlGrp = cmds.group(name = "leg_ctrl_grp_" + side, empty = True)
cmds.parent([ikThighJoint, targetGrp, aimGrp, noflipVectorGrp], ctrlGrp)
legGroup = cmds.group(name = "leg_group_" + side, empty = True)
constraint = cmds.pointConstraint("driver_pelvis", legGroup)[0]
cmds.delete(constraint)
cmds.parent([footCtrlSpaceSwitcherFollow, beginJoint, ctrlGrp], legGroup)
cmds.orientConstraint("body_anim_grp", ctrlGrp, mo = True)
cmds.pointConstraint("body_anim", ctrlGrp, mo = True)
#constrain aimGrp
cmds.pointConstraint("body_anim", aimGrp, mo = True)
cmds.orientConstraint("offset_anim", aimGrp, mo = True)
#cmds.parentConstraint("driver_pelvis", beginJoint, mo = True)
ikGrp = cmds.group(name = "ik_leg_grp_" + side, empty = True)
cmds.parent(ikGrp, legGroup)
cmds.parent([kneeCtrlGrp, footCtrlSpaceSwitcherFollow], ikGrp)
#color the controls
if side == "l":
color = 6
else:
color = 13
for control in [footCtrl]:
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#connect ik twist attr to ik leg twist
cmds.select(footCtrl)
cmds.addAttr(longName=("knee_twist"), at = 'double', keyable = True)
if side == "r":
cmds.connectAttr(footCtrl + ".knee_twist", footIK + ".twist")
else:
twistMultNode = cmds.shadingNode("multiplyDivide", name = "ik_leg_" + side + "_twistMultNode", asUtility = True)
cmds.connectAttr(footCtrl + ".knee_twist", twistMultNode + ".input1X")
cmds.setAttr(twistMultNode + ".input2X", -1)
cmds.connectAttr(twistMultNode + ".outputX", footIK + ".twist")
#add stretchy IK to legs
cmds.select(footCtrl)
cmds.addAttr(longName=("stretch"), at = 'double',min = 0, max = 1, dv = 0, keyable = True)
cmds.addAttr(longName=("squash"), at = 'double',min = 0, max = 1, dv = 0, keyable = True)
cmds.addAttr(longName=("toeCtrlVis"), at = 'bool', dv = 0, keyable = True)
stretchMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "ikLeg_stretchToggleMultNode_" + side)
#need to get the total length of the leg chain
totalDist = abs(cmds.getAttr(ikCalfJoint + ".tx" ) + cmds.getAttr(ikFootJoint + ".tx"))
#create a distanceBetween node
distBetween = cmds.shadingNode("distanceBetween", asUtility = True, name = side + "_ik_leg_distBetween")
#get world positions of upper arm and ik
baseGrp = cmds.group(empty = True, name = "ik_leg_base_grp_" + side)
endGrp = cmds.group(empty = True, name = "ik_leg_end_grp_" + side)
cmds.pointConstraint(ikThighJoint, baseGrp)
cmds.pointConstraint(footCtrl, endGrp)
#hook in group translates into distanceBetween node inputs
cmds.connectAttr(baseGrp + ".translate", distBetween + ".point1")
cmds.connectAttr(endGrp + ".translate", distBetween + ".point2")
#create a condition node that will compare original length to current length
#if second term is greater than, or equal to the first term, the chain needs to stretch
ikLegCondition = cmds.shadingNode("condition", asUtility = True, name = side + "_ik_leg_stretch_condition")
cmds.setAttr(ikLegCondition + ".operation", 3)
cmds.connectAttr(distBetween + ".distance", ikLegCondition + ".secondTerm")
cmds.setAttr(ikLegCondition + ".firstTerm", totalDist)
#hook up the condition node's return colors
cmds.setAttr(ikLegCondition + ".colorIfTrueR", totalDist)
cmds.connectAttr(distBetween + ".distance", ikLegCondition + ".colorIfFalseR")
#create the mult/divide node(set to divide) that will take the original creation length as a static value in input2x, and the connected length into 1x.
legDistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "leg_dist_multNode_" + side)
cmds.setAttr(legDistMultNode + ".operation", 2) #divide
cmds.connectAttr(ikLegCondition + ".outColorR", legDistMultNode + ".input1X")
#add attr to foot control for stretch bias
cmds.addAttr(footCtrl, ln = "stretchBias", minValue = 0.0, maxValue = 1.0, defaultValue = 0.0, keyable = True)
#add divide node so that instead of driving 0-1, we're actually only driving 0 - 0.2
divNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "stretchBias_Div_" + side)
cmds.connectAttr(footCtrl + ".stretchBias", divNode + ".input1X")
cmds.setAttr(divNode + ".operation", 2)
cmds.setAttr(divNode + ".input2X", 5)
#create the add node and connect the stretchBias into it, adding 1
addNode = cmds.shadingNode("plusMinusAverage", asUtility = True, name = "stretchBias_Add_" + side)
cmds.connectAttr(divNode + ".outputX", addNode + ".input1D[0]")
cmds.setAttr(addNode + ".input1D[1]", 1.0)
#connect output of addNode to new mult node input1x
stretchBiasMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "stretchBias_multNode_" + side)
cmds.connectAttr(addNode + ".output1D", stretchBiasMultNode + ".input1X")
#set input2x to totalDist
cmds.setAttr(stretchBiasMultNode + ".input2X", totalDist)
#connect output to input2x on legDistMultNode
cmds.connectAttr(stretchBiasMultNode + ".outputX", legDistMultNode + ".input2X")
#create a stretch toggle mult node that multiplies the stretch factor by the bool of the stretch attr. (0 or 1), this way our condition reads
#if this result is greater than the original length(impossible if stretch bool is off, since result will be 0), than take this result and plug it
#into the scale of our IK arm joints
stretchToggleCondition = cmds.shadingNode("condition", asUtility = True, name = "leg_stretch_toggle_condition_" + side)
cmds.setAttr(stretchToggleCondition + ".operation", 0)
cmds.connectAttr(footCtrl + ".stretch", stretchToggleCondition + ".firstTerm")
cmds.setAttr(stretchToggleCondition + ".secondTerm", 1)
cmds.connectAttr(legDistMultNode + ".outputX", stretchToggleCondition + ".colorIfTrueR")
cmds.setAttr(stretchToggleCondition + ".colorIfFalseR", 1)
#set up the squash nodes
squashMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = side + "_ik_leg_squash_mult")
cmds.setAttr(squashMultNode + ".operation", 2)
cmds.setAttr(squashMultNode + ".input1X", totalDist)
cmds.connectAttr(ikLegCondition + ".outColorR", squashMultNode + ".input2X")
#create a stretch toggle mult node that multiplies the stretch factor by the bool of the stretch attr. (0 or 1), this way our condition reads
#if this result is greater than the original length(impossible if stretch bool is off, since result will be 0), than take this result and plug it
#into the scale of our IK arm joints
squashToggleCondition = cmds.shadingNode("condition", asUtility = True, name = "leg_squash_toggle_condition_" + side)
cmds.setAttr(squashToggleCondition + ".operation", 0)
cmds.connectAttr(footCtrl + ".squash", squashToggleCondition + ".firstTerm")
cmds.setAttr(squashToggleCondition + ".secondTerm", 1)
cmds.connectAttr(squashMultNode + ".outputX", squashToggleCondition + ".colorIfTrueR")
cmds.setAttr(squashToggleCondition + ".colorIfFalseR", 1)
#connect to arm scale
cmds.connectAttr(stretchToggleCondition + ".outColorR", ikThighJoint + ".sx")
cmds.connectAttr(stretchToggleCondition + ".outColorR", ikCalfJoint + ".sx")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikCalfJoint + ".sy")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikCalfJoint + ".sz")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikThighJoint + ".sy")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikThighJoint + ".sz")
#add base and end groups to arm grp
cmds.parent([baseGrp, endGrp], ctrlGrp)
#lock attrs on control that shouldn't be animated
for control in [toeControl, heelControl, toeWiggleControl]:
cmds.setAttr(control + ".tx", lock = True, keyable = False)
cmds.setAttr(control + ".ty", lock = True, keyable = False)
cmds.setAttr(control + ".tz", lock = True, keyable = False)
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#lock attrs on foot control that should not be animated
cmds.setAttr(footCtrl + ".sx", lock = True, keyable = False)
cmds.setAttr(footCtrl + ".sy", lock = True, keyable = False)
cmds.setAttr(footCtrl + ".sz", lock = True, keyable = False)
cmds.setAttr(footCtrl + ".v", lock = True, keyable = False)
#lock attrs on knee control that should not be animated
cmds.connectAttr(footCtrl + ".knee_twist", kneeCtrl + ".rx")
cmds.setAttr(kneeCtrl + ".rx", lock = False, keyable = False)
cmds.setAttr(kneeCtrl + ".ry", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".rz", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".tx", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".ty", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".tz", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".sx", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".sy", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".sz", lock = True, keyable = False)
cmds.setAttr(kneeCtrl + ".v", lock = True, keyable = False)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildFingers(self):
#find out which finger joints need to be rigged
for side in ["l", "r"]:
#create a list to hold all ctrl groups that are created
ctrlGroups = []
ikGrps = []
joints = []
fkOrients = []
metaJoints = []
ikJoints = []
children = cmds.listRelatives("driver_hand_" + side, children = True, type = 'joint')
allChildren = cmds.listRelatives("driver_hand_" + side, allDescendents = True, type = 'joint')
#find out how many finger joints we have for each finger
thumbMeta = [False, None]
indexMeta = [False, None]
middleMeta = [False, None]
ringMeta = [False, None]
pinkyMeta = [False, None]
numThumbJoints = [0, "thumb"]
numIndexJoints = [0, "index"]
numMiddleJoints = [0, "middle"]
numRingJoints = [0, "ring"]
numPinkyJoints = [0, "pinky"]
if allChildren:
for finger in allChildren:
#find if metatarsals exist
if finger.find("meta") != -1:
if finger.partition("driver_")[2].find("index") == 0:
indexMeta = [True, "index"]
if finger.partition("driver_")[2].find("middle") == 0:
middleMeta = [True, "middle"]
if finger.partition("driver_")[2].find("ring") == 0:
ringMeta = [True, "ring"]
if finger.partition("driver_")[2].find("pinky") == 0:
pinkyMeta = [True, "pinky"]
#get num fingers -meta
if finger.partition("driver_")[2].find("thumb") == 0:
numThumbJoints[0] += 1
if finger.partition("driver_")[2].find("index") == 0:
numIndexJoints[0] += 1
if finger.partition("driver_")[2].find("middle") == 0:
numMiddleJoints[0] += 1
if finger.partition("driver_")[2].find("ring") == 0:
numRingJoints[0] += 1
if finger.partition("driver_")[2].find("pinky") == 0:
numPinkyJoints[0] += 1
#subtract metacarpals (only if they exist!)
if indexMeta[0] == True:
numIndexJoints[0] -= 1
if middleMeta[0] == True:
numMiddleJoints[0] -= 1
if ringMeta[0] == True:
numRingJoints[0] -= 1
if pinkyMeta[0] == True:
numPinkyJoints[0] -= 1
#duplicate the driver joints to be used as the rig joints
if children:
for child in children:
for mode in ["fk", "ik"]:
dupeChildNodes = cmds.duplicate(child, name = "temp")
#parent root joint of each finger to world if not already child of world
parent = cmds.listRelatives(dupeChildNodes[0], parent = True)[0]
if parent != None:
cmds.parent(dupeChildNodes[0], world = True)
#rename duped joints
for node in dupeChildNodes:
if node == "temp":
niceName = child.partition("driver_")[2]
joint = cmds.rename(node, "rig_" + mode + "_" + niceName)
if mode == "ik":
ikJoints.append(joint)
else:
joints.append(joint)
else:
niceName = node.partition("driver_")[2]
cmds.rename("rig_*|" + node, "rig_" + mode + "_" + niceName)
#if the metacarpal fingers exist, create a control for them
for meta in [indexMeta, middleMeta, ringMeta, pinkyMeta]:
if meta[0] == True:
#create the control object for the metacarpal
ctrlName = meta[1]
ctrlName = ctrlName + "_metacarpal_ctrl_" + side
control = self.createControl("square", 1, ctrlName)
constraint = cmds.parentConstraint("rig_fk_" + meta[1] + "_metacarpal_" + side, control)[0]
cmds.delete(constraint)
cmds.setAttr(control + ".sx", 0)
cmds.setAttr(control + ".sy", 15)
cmds.setAttr(control + ".sz", 15)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#create the group node and parent ctrl to it
ctrlGrp = cmds.group(empty = True, name = ctrlName + "_grp")
constraint = cmds.parentConstraint("rig_fk_" + meta[1] + "_metacarpal_" + side, ctrlGrp)[0]
metaJoints.append(ctrlGrp)
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#parent constrain the rig joint to the control
cmds.parentConstraint(control, "rig_fk_" + meta[1] + "_metacarpal_" + side, mo = True)
cmds.parentConstraint(control, "rig_ik_" + meta[1] + "_metacarpal_" + side, mo = True)
#lock attrs on control that shouldn't be animated
cmds.setAttr(control + ".tx", lock = True, keyable = False)
cmds.setAttr(control + ".ty", lock = True, keyable = False)
cmds.setAttr(control + ".tz", lock = True, keyable = False)
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#color the controls
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#Create the FK orient joints
#first create a group for the IK handles to go into. Then setup the constraints on this group and set driven keys
ikHandlesGrp = cmds.group(empty = True, name = "fkOrient_ikHandles_" + side + "_grp")
constraint = cmds.parentConstraint("ik_wrist_" + side + "_anim", "fk_wrist_" + side + "_anim", ikHandlesGrp, mo = True)[0]
cmds.setAttr("Rig_Settings" + "." + side + "ArmMode", 0)
cmds.setAttr(constraint + ".ik_wrist_" + side + "_anim" + "W0", 0)
cmds.setAttr(constraint + ".fk_wrist_" + side + "_anim" + "W1", 1)
cmds.setDrivenKeyframe([constraint + ".ik_wrist_" + side + "_anim" + "W0", constraint + ".fk_wrist_" + side + "_anim" + "W1"], cd = "Rig_Settings" + "." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings" + "." + side + "ArmMode", 1)
cmds.setAttr(constraint + ".ik_wrist_" + side + "_anim" + "W0", 1)
cmds.setAttr(constraint + ".fk_wrist_" + side + "_anim" + "W1", 0)
cmds.setDrivenKeyframe([constraint + ".ik_wrist_" + side + "_anim" + "W0", constraint + ".fk_wrist_" + side + "_anim" + "W1"], cd = "Rig_Settings" + "." + side + "ArmMode", itt = "linear", ott = "linear")
for fingers in [numIndexJoints, numMiddleJoints, numRingJoints, numPinkyJoints, numThumbJoints]:
if fingers[0] > 0:
#setup metaCtrl name
if fingers[1] == "thumb":
metaCtrl = fingers[1] + "_01_" + side
else:
metaCtrl = fingers[1] + "_metacarpal_ctrl_" + side
#create the base and end joint
baseJoint = cmds.duplicate("rig_fk_" + fingers[1] + "_01_" + side, po = True, name = "rig_fkOrient_" + fingers[1] + "_01_" + side)[0]
endJoint = cmds.duplicate("rig_fk_" + fingers[1] + "_0" + str(fingers[0]) + "_" + side, po = True, name = "rig_fkOrient_" + fingers[1] + "_0" + str(fingers[0]) + "_" + side)[0]
#position the end joint
scaleFactor = self.getScaleFactor()
if side == "l":
cmds.parent(endJoint, "rig_fk_" + fingers[1] + "_0" + str(fingers[0]) + "_" + side)
cmds.setAttr(endJoint + ".tx", 5 * scaleFactor)
else:
cmds.parent(endJoint, "rig_fk_" + fingers[1] + "_0" + str(fingers[0]) + "_" + side)
cmds.setAttr(endJoint + ".tx", -5 * scaleFactor)
#parent the end joint to the base joint
cmds.parent(endJoint, baseJoint)
#create SC ik handles for each chain
ikNodes = cmds.ikHandle(sol = "ikSCsolver", name = baseJoint + "_ikHandle", sj = baseJoint, ee = endJoint)[0]
cmds.parent(ikNodes, ikHandlesGrp)
cmds.setAttr(ikNodes + ".v", 0)
#parent our orient joint to the metacarpal if it exists
if cmds.objExists(metaCtrl):
if fingers[1] == "thumb":
fkOrients.append(baseJoint)
else:
cmds.parent(baseJoint, metaCtrl)
else:
fkOrients.append(baseJoint)
#Create FK controls for the fingers
fkControls = []
for fingers in [numIndexJoints, numMiddleJoints, numRingJoints, numPinkyJoints, numThumbJoints]:
for i in range(int(fingers[0])):
#create an FK control per finger
ctrlName = fingers[1] + "_finger_fk_ctrl_" + str(i + 1) + "_" + side
control = self.createControl("circle", 3, ctrlName)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
metaCtrl = fingers[1] + "_metacarpal_ctrl_" + side
if cmds.objExists(metaCtrl) == False:
if (i + 1) == 1:
ctrlGroups.append(ctrlGrp)
#add the created control to the controls list
fkControls.append(control)
#position control
constraint = cmds.parentConstraint("rig_fk_" + fingers[1] + "_0" + str(i+1) + "_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_fk_" + fingers[1] + "_0" + str(i+1) + "_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
#duplicate the ctrl group to create the driven group
drivenGrp = cmds.duplicate(ctrlGrp, parentOnly = True, name = control + "_driven_grp")[0]
ctrlGroups.append(drivenGrp)
cmds.parent(drivenGrp, ctrlGrp)
#parent control to grp
cmds.parent(control, drivenGrp)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".ry", -90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#constrain finger joint to control
cmds.parentConstraint(control, "rig_fk_" + fingers[1] + "_0" + str(i+1) + "_" + side, mo = True)
#if we aren't the root of the finger chain, then parent our ctrlGrp to the previous fk control
if i != 0:
cmds.parent(ctrlGrp, ctrlParent)
else:
#if the control grp is the root of the finger chain, need to parent the ctrl grp to the metaCtrl
if cmds.objExists(metaCtrl):
cmds.parent(ctrlGrp, metaCtrl)
#setup set driven keys for the orientation options
cmds.select(control)
cmds.addAttr(longName= ( "sticky" ), defaultValue=0, minValue=0, maxValue=1, keyable = True)
#setup the constraint between the fk finger orient joint and the ctrlGrp
constraint = cmds.parentConstraint("rig_fkOrient_" + fingers[1] + "_01_" + side, ctrlGrp, mo = True)[0]
#set driven keyframes on constraint
cmds.setAttr(control + ".sticky", 1)
cmds.setAttr(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", 1)
cmds.setDrivenKeyframe(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", cd = control + ".sticky", itt = "linear", ott = "linear")
cmds.setAttr(control + ".sticky", 0)
cmds.setAttr(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", 0)
cmds.setDrivenKeyframe(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", cd = control + ".sticky", itt = "linear", ott = "linear")
if fingers[1] == "thumb":
cmds.setAttr(control + ".sticky", 1)
else:
cmds.setAttr(control + ".sticky", 0)
ctrlGroups.append(ctrlGrp)
#if the meta carpal does not exist, simply parent the root group under the base joint
else:
ctrlGroups.append(ctrlGrp)
constraint = cmds.parentConstraint("rig_fkOrient_" + fingers[1] + "_01_" + side, ctrlGrp, mo = True)[0]
#setup set driven keys for the orientation options
cmds.select(control)
cmds.addAttr(longName= ( "sticky" ), defaultValue=0, minValue=0, maxValue=1, keyable = True)
#set driven keyframes on constraint
cmds.setAttr(control + ".sticky", 1)
cmds.setAttr(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", 1)
cmds.setDrivenKeyframe(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", cd = control + ".sticky", itt = "linear", ott = "linear")
cmds.setAttr(control + ".sticky", 0)
cmds.setAttr(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", 0)
cmds.setDrivenKeyframe(constraint + "." + "rig_fkOrient_" + fingers[1] + "_01_" + side + "W0", cd = control + ".sticky", itt = "linear", ott = "linear")
#set the control parent for the next ctrl in the chain to the current control
ctrlParent = control
#lock attrs on control that shouldn't be animated
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#color the controls
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#setup the hand roll feature
#create our 4 locators(pivots) and position
pinkyPiv = cmds.spaceLocator(name = "hand_" + side + "_pinky_pivot")[0]
thumbPiv = cmds.spaceLocator(name = "hand_" + side + "_thumb_pivot")[0]
midPiv = cmds.spaceLocator(name = "hand_" + side + "_mid_pivot")[0]
tipPiv = cmds.spaceLocator(name = "hand_" + side + "_tip_pivot")[0]
for piv in [pinkyPiv, thumbPiv, midPiv, tipPiv]:
cmds.setAttr(piv + ".v", 0)
constraint = cmds.parentConstraint(side + "_hand_pinky_pivot", pinkyPiv)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(side + "_hand_thumb_pivot", thumbPiv)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(side + "_hand_mid_pivot", midPiv)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(side + "_hand_tip_pivot", tipPiv)[0]
cmds.delete(constraint)
#create the control groups for the pivots so our values are zeroed
for each in [pinkyPiv, thumbPiv, midPiv, tipPiv]:
group = cmds.group(empty = True, name = each + "_grp")
constraint = cmds.parentConstraint(each, group)[0]
cmds.delete(constraint)
cmds.parent(each, group)
#setup hierarchy
cmds.parent(thumbPiv + "_grp", pinkyPiv)
cmds.parent(tipPiv + "_grp", thumbPiv)
cmds.parent(midPiv + "_grp", tipPiv)
#parent the arm IK handles under the midPiv locator
cmds.parent(["arm_ikHandle_" + side, "invis_arm_ikHandle_" + side], midPiv)
cmds.parent(pinkyPiv + "_grp", "ik_wrist_" + side + "_anim")
#add attrs to the IK hand control (side, roll, tip pivot)
cmds.select("ik_wrist_" + side + "_anim")
cmds.addAttr(longName= ( "side" ), defaultValue=0, keyable = True)
cmds.addAttr(longName= ( "mid_bend" ), defaultValue=0, keyable = True)
cmds.addAttr(longName= ( "mid_swivel" ), defaultValue=0, keyable = True)
cmds.addAttr(longName= ( "tip_pivot" ), defaultValue=0, keyable = True)
cmds.addAttr(longName= ( "tip_swivel" ), defaultValue=0, keyable = True)
#hook up attrs to pivot locators
cmds.connectAttr("ik_wrist_" + side + "_anim.mid_bend", midPiv + ".rz")
cmds.connectAttr("ik_wrist_" + side + "_anim.tip_pivot", tipPiv + ".rz")
cmds.connectAttr("ik_wrist_" + side + "_anim.mid_swivel", midPiv + ".ry")
cmds.connectAttr("ik_wrist_" + side + "_anim.tip_swivel", tipPiv + ".ry")
#set driven keys for the side to side attr
if side == "l":
thumbVal = 180
pinkyVal = -180
else:
thumbVal = 180
pinkyVal = -180
cmds.setAttr("ik_wrist_" + side + "_anim.side", 0)
cmds.setAttr(pinkyPiv + ".rx", 0)
cmds.setAttr(thumbPiv + ".rx", 0)
cmds.setDrivenKeyframe([pinkyPiv + ".rx", thumbPiv + ".rx"], cd = "ik_wrist_" + side + "_anim.side", itt = "linear", ott = "linear")
cmds.setAttr("ik_wrist_" + side + "_anim.side", 180)
cmds.setAttr(pinkyPiv + ".rx", pinkyVal)
cmds.setAttr(thumbPiv + ".rx", 0)
cmds.setDrivenKeyframe([pinkyPiv + ".rx", thumbPiv + ".rx"], cd = "ik_wrist_" + side + "_anim.side", itt = "linear", ott = "linear")
cmds.setAttr("ik_wrist_" + side + "_anim.side", -180)
cmds.setAttr(pinkyPiv + ".rx", 0)
cmds.setAttr(thumbPiv + ".rx", thumbVal)
cmds.setDrivenKeyframe([pinkyPiv + ".rx", thumbPiv + ".rx"], cd = "ik_wrist_" + side + "_anim.side", itt = "linear", ott = "linear")
cmds.setAttr("ik_wrist_" + side + "_anim.side", 0)
#If there are enough finger joints on each finger, create IK rig
ikCtrls = []
poleVectorLocs = []
modeGrps = []
for fingers in [numIndexJoints, numMiddleJoints, numRingJoints, numPinkyJoints, numThumbJoints]:
if fingers[0] == 3:
#set preferred angles on joints so IK will create properly
cmds.setAttr("rig_ik_" + fingers[1] + "_01_" + side + ".preferredAngleZ", 45)
cmds.setAttr("rig_ik_" + fingers[1] + "_02_" + side + ".preferredAngleZ", 45)
cmds.setAttr("rig_ik_" + fingers[1] + "_03_" + side + ".preferredAngleZ", 45)
#create a tip joint
tipJoint = cmds.duplicate("rig_ik_" + fingers[1] + "_03_" + side, po = True, name = "rig_ik_" + fingers[1] + "_tip_" + side)[0]
cmds.parent(tipJoint, "rig_ik_" + fingers[1] + "_03_" + side)
#position tip joint
if side == "l":
cmds.setAttr(tipJoint + ".tx", 5 * scaleFactor)
else:
cmds.setAttr(tipJoint + ".tx", -5 * scaleFactor)
#create the IK handle
ikNodes = cmds.ikHandle(sol = "ikRPsolver", name = fingers[1] + "_" + side + "_ikHandle", sj = "rig_ik_" + fingers[1] + "_01_" + side, ee = "rig_ik_" + fingers[1] + "_03_" + side)[0]
ikTipNodes = cmds.ikHandle(sol = "ikSCsolver", name = fingers[1] + "_" + side + "_end_ikHandle", sj = "rig_ik_" + fingers[1] + "_03_" + side, ee = tipJoint)[0]
cmds.setAttr(ikNodes + ".v", 0)
cmds.parent(ikTipNodes, ikNodes)
#create a pole vector locator and position it
poleVector = cmds.spaceLocator(name = fingers[1] + "_" + side + "_poleVector")[0]
constraint = cmds.parentConstraint("rig_ik_" + fingers[1] + "_02_" + side, poleVector)[0]
cmds.delete(constraint)
#color the control
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(poleVector + ".overrideEnabled", 1)
cmds.setAttr(poleVector + ".overrideColor", color)
#create a pole vector group
pvGrp = cmds.group(empty = True, name = poleVector + "_grp")
constraint = cmds.parentConstraint(poleVector, pvGrp)[0]
cmds.delete(constraint)
#parent to the joint, and move out away from finger
cmds.parent(poleVector, "rig_ik_" + fingers[1] + "_02_" + side)
if side == "l":
cmds.setAttr(poleVector + ".ty", -20 * scaleFactor)
else:
cmds.setAttr(poleVector + ".ty", 20 * scaleFactor)
cmds.makeIdentity(poleVector, t =1, r =1, s = 1, apply = True)
cmds.parent(poleVector, pvGrp, absolute = True)
cmds.makeIdentity(poleVector, t =1, r =1, s = 1, apply = True)
#lock pole vector attrs
for attr in [".sx", ".sy", ".sz", ".v"]:
if attr == ".v":
cmds.setAttr(poleVector + attr, keyable = False)
else:
cmds.setAttr(poleVector + attr, lock = True, keyable = False)
#create the IK finger controls
ctrlName = fingers[1] + "_" + side + "_ik_anim"
control = self.createControl("circle", 3, ctrlName)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
ikCtrls.append(control)
#position control
constraint = cmds.parentConstraint(tipJoint, control)[0]
grpConstraint = cmds.parentConstraint(tipJoint, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
#parent control to grp
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".ry", -90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.parent(ikNodes, control)
#setup the pole vector constraint and add the locator to the poleVectorLocs list
cmds.poleVectorConstraint(poleVector, ikNodes)
poleVectorLocs.append(pvGrp)
#add attr to show pole vector control
cmds.select(control)
cmds.addAttr(longName= ( "poleVectorVis" ), defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.connectAttr(control + ".poleVectorVis", poleVector + ".v")
#create a tip locator with finger mode attrs
fingerModeCtrl = cmds.spaceLocator(name = fingers[1] + "_finger_" + side + "_mode_anim")[0]
fingerModeCtrlGrp = cmds.group(empty = True, name = fingers[1] + "_finger_" + side + "_mode_grp")
modeGrps.append(fingerModeCtrlGrp)
cmds.setAttr(fingerModeCtrl + ".v", 0)
constraint = cmds.parentConstraint(tipJoint, fingerModeCtrl)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(tipJoint, fingerModeCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(fingerModeCtrl, fingerModeCtrlGrp)
#lock attrs
for attr in [".tx", ".ty", ".tz", ".rx", ".ry", ".rz", ".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(fingerModeCtrl + attr, lock = True, keyable = False)
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
#scale up the fingerModeCtrl
shape = cmds.listRelatives(fingerModeCtrl, shapes = True)[0]
cmds.setAttr(shape + ".localScaleX", 3 * scaleFactor)
cmds.setAttr(shape + ".localScaleY", 3 * scaleFactor)
cmds.setAttr(shape + ".localScaleZ", 3 * scaleFactor)
#constrain the fingerModeCtrlGrp to the driver base knuckle
if cmds.objExists("driver_" + fingers[1] + "_03_" + side):
cmds.parentConstraint("driver_" + fingers[1] + "_03_" + side, fingerModeCtrlGrp, mo = True)
else:
if cmds.objExists("driver_" + fingers[1] + "_02_" + side):
cmds.parentConstraint("driver_" + fingers[1] + "_02_" + side, fingerModeCtrlGrp, mo = True)
else:
if cmds.objExists("driver_" + fingers[1] + "_01_" + side):
cmds.parentConstraint("driver_" + fingers[1] + "_01_" + side, fingerModeCtrlGrp, mo = True)
#color the control
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(fingerModeCtrl + ".overrideEnabled", 1)
cmds.setAttr(fingerModeCtrl + ".overrideColor", color)
#add attr for finger mode(fk/ik) on both IK and FK control
cmds.select(fingerModeCtrl)
cmds.addAttr(longName= "FK_IK", defaultValue = 0, minValue = 0, maxValue = 1, keyable = True)
#take all of the pole vector groups and add them to a master pv group
masterPvGrp = cmds.group(empty = True, name = "fingers_" + side + "_poleVectors_grp")
for pv in poleVectorLocs:
cmds.parent(pv, masterPvGrp, absolute = True)
#create a global IK control if there are any IK fingers
if ikCtrls:
ctrlName = side + "_global_ik_anim"
control = self.createControl("square", 20, ctrlName)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
#position control
constraint = cmds.pointConstraint(midPiv, control)[0]
grpConstraint = cmds.pointConstraint(midPiv, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
#parent control to grp
cmds.parent(control, ctrlGrp)
#cmds.setAttr(control + ".rx", -90)
#freeze rots
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
#translate down in y 13
cmds.setAttr(control + ".tz", -13)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.parent(control, world = True)
constraint = cmds.pointConstraint(control, ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#create a space switcher grp
spaceSwitcherFollow = cmds.duplicate(ctrlGrp, po = True, name = ctrlName + "_space_switcher_follow")[0]
spaceSwitcher = cmds.duplicate(ctrlGrp, po = True, name = ctrlName + "_space_switcher")[0]
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(ctrlGrp, spaceSwitcher)
cmds.parent(spaceSwitcherFollow, "ik_wrist_" + side + "_anim")
#parent ik control grps to this global control
for ctrl in ikCtrls:
parent = cmds.listRelatives(ctrl, parent = True)[0]
cmds.parent(parent, control)
#parent constrain the master pv group to the global control
cmds.parentConstraint(control, masterPvGrp, mo = True)
#lock attrs
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
#clean up hand rig hierarchy
jointsGrp = cmds.group(empty = True, name = "hand_fk_joints_grp_" + side)
handDrivenGrp = cmds.group(empty = True, name = "hand_driven_grp_" + side)
handDrivenGrpMaster = cmds.group(empty = True, name = "hand_driven_grp_master_" + side)
fkCtrlGrp = cmds.group(empty = True, name = "fk_finger_controls_" + side + "_grp")
constraint = cmds.parentConstraint("ik_wrist_" + side + "_anim", handDrivenGrpMaster)
cmds.delete(constraint)
#create fk hand match node
fkHandMatchNode = cmds.duplicate(handDrivenGrpMaster, po = True, name = "hand_match_loc_" + side)[0]
cmds.parent(fkHandMatchNode, handDrivenGrpMaster)
#find aim axis of arm chain to determine offset value
vector1 = cmds.xform("driver_lowerarm_" + side, q = True, ws = True, t = True)
vector2 = cmds.xform("driver_hand_" + side, q = True, ws = True, t = True)
aimAxis = self.normalizeSubVector(vector1, vector2)
axis = None
offset = 0
for item in [ ["X", ".rx"], ["-X", ".rx"], ["Y", ".ry"], ["-Y", ".ry"], ["Z", ".rz"], ["-Z", ".rz"]]:
if aimAxis == item[0]:
axis = item[1]
if item[0].find("-") == 0:
offset = 90
else:
offset = -90
cmds.setAttr(fkHandMatchNode + axis, offset)
cmds.parent(handDrivenGrp, handDrivenGrpMaster)
for joint in joints:
cmds.parent(joint, jointsGrp)
for control in ctrlGroups:
parent = cmds.listRelatives(control, parent = True)
if parent == None:
cmds.parent(control, fkCtrlGrp)
for control in metaJoints:
cmds.parent(control, handDrivenGrp)
for control in fkOrients:
cmds.parent(control, handDrivenGrp)
for joint in ikJoints:
cmds.parent(joint, handDrivenGrp)
#constrain the master grp to the fk and ik hand joints
fingerSysGrp = cmds.group(empty = True, name = "finger_sys_grp_" + side)
cmds.parent(fkCtrlGrp, handDrivenGrp)
cmds.parent([jointsGrp, ikHandlesGrp, masterPvGrp, handDrivenGrpMaster], fingerSysGrp)
if len(modeGrps) > 0:
cmds.parent(modeGrps, fingerSysGrp)
constraint = cmds.parentConstraint(["fk_wrist_" + side + "_anim", "ik_hand_" + side], handDrivenGrpMaster, mo = True)[0]
cmds.setAttr("Rig_Settings" + "." + side + "ArmMode", 0)
cmds.setAttr(constraint + ".fk_wrist_" + side + "_animW0", 1)
cmds.setAttr(constraint + ".ik_hand_" + side + "W1", 0)
cmds.setDrivenKeyframe([constraint + ".fk_wrist_" + side + "_animW0", constraint + ".ik_hand_" + side + "W1"], cd = "Rig_Settings" + "." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings" + "." + side + "ArmMode", 1)
cmds.setAttr(constraint + ".fk_wrist_" + side + "_animW0", 0)
cmds.setAttr(constraint + ".ik_hand_" + side + "W1", 1)
cmds.setDrivenKeyframe([constraint + ".fk_wrist_" + side + "_animW0", constraint + ".ik_hand_" + side + "W1"], cd = "Rig_Settings" + "." + side + "ArmMode", itt = "linear", ott = "linear")
#Constrain the driver joints to the fk and ik joints
for fingers in [numIndexJoints, numMiddleJoints, numRingJoints, numPinkyJoints, numThumbJoints]:
for i in range(int(fingers[0])):
driverJoint = "driver_" + fingers[1] + "_0" + str(i + 1) + "_" + side
fkJoint = "rig_fk_" + fingers[1] + "_0" + str(i + 1) + "_" + side
ikJoint = "rig_ik_" + fingers[1] + "_0" + str(i + 1) + "_" + side
#set driven keys on constraint
if cmds.objExists(fingers[1] + "_" + side + "_ik_anim"):
constraint = cmds.parentConstraint([fkJoint, ikJoint], driverJoint)[0]
ikCtrl = fingers[1] + "_finger_" + side + "_mode_anim"
#set driven keyframes on constraint
cmds.setAttr(ikCtrl + "." + "FK_IK", 0)
cmds.setAttr(constraint + "." + fkJoint + "W0", 1)
cmds.setAttr(constraint + "." + ikJoint + "W1", 0)
cmds.setDrivenKeyframe([constraint + "." + fkJoint + "W0", constraint + "." + ikJoint + "W1"], cd = ikCtrl + "." + "FK_IK", itt = "linear", ott = "linear")
cmds.setAttr(ikCtrl + "." + "FK_IK", 1)
cmds.setAttr(constraint + "." + fkJoint + "W0", 0)
cmds.setAttr(constraint + "." + ikJoint + "W1", 1)
cmds.setDrivenKeyframe([constraint + "." + fkJoint + "W0", constraint + "." + ikJoint + "W1"], cd = ikCtrl + "." + "FK_IK", itt = "linear", ott = "linear")
cmds.setAttr(ikCtrl + "." + "FK_IK", 0)
#setup driven keys for fk/ik control visibility
ikCtrl = fingers[1] + "_finger_" + side + "_mode_anim"
cmds.setAttr(ikCtrl + "." + "FK_IK", 0)
cmds.setAttr(fingers[1] + "_finger_fk_ctrl_1_" + side + "_grp.v" , 1)
cmds.setAttr(fingers[1] + "_" + side + "_ik_anim_grp.v", 0)
cmds.setDrivenKeyframe([fingers[1] + "_finger_fk_ctrl_1_" + side + "_grp.v", fingers[1] + "_" + side + "_ik_anim_grp.v"], cd = ikCtrl + "." + "FK_IK", itt = "linear", ott = "linear")
cmds.setAttr(ikCtrl + "." + "FK_IK", 1)
cmds.setAttr(fingers[1] + "_finger_fk_ctrl_1_" + side + "_grp.v" , 0)
cmds.setAttr(fingers[1] + "_" + side + "_ik_anim_grp.v", 1)
cmds.setDrivenKeyframe([fingers[1] + "_finger_fk_ctrl_1_" + side + "_grp.v", fingers[1] + "_" + side + "_ik_anim_grp.v"], cd = ikCtrl + "." + "FK_IK", itt = "linear", ott = "linear")
cmds.setAttr(ikCtrl + "." + "FK_IK", 0)
else:
constraint = cmds.parentConstraint([fkJoint], driverJoint)[0]
#constrain the driver metacarpals(if they exist) to the ik and fk ones
for metacarpal in [thumbMeta, indexMeta, middleMeta, ringMeta, pinkyMeta]:
if metacarpal[0] == True:
driverJoint = "driver_" + metacarpal[1] + "_metacarpal_" + side
fkJoint = "rig_fk_" + metacarpal[1] + "_metacarpal_" + side
ikJoint = "rig_ik_" + metacarpal[1] + "_metacarpal_" + side
if cmds.objExists(metacarpal[1] + "_" + side + "_ik_anim"):
constraint = cmds.parentConstraint([fkJoint, ikJoint], driverJoint)[0]
ikCtrl = metacarpal[1] + "_finger_" + side + "_mode_anim"
constraint = cmds.parentConstraint([fkJoint, ikJoint], driverJoint)[0]
#set driven keyframes on constraint
cmds.setAttr(ikCtrl + "." + "FK_IK", 0)
cmds.setAttr(constraint + "." + fkJoint + "W0", 1)
cmds.setAttr(constraint + "." + ikJoint + "W1", 0)
cmds.setDrivenKeyframe([constraint + "." + fkJoint + "W0", constraint + "." + ikJoint + "W1"], cd = ikCtrl + "." + "FK_IK", itt = "linear", ott = "linear")
cmds.setAttr(ikCtrl + "." + "FK_IK", 1)
cmds.setAttr(constraint + "." + fkJoint + "W0", 0)
cmds.setAttr(constraint + "." + ikJoint + "W1", 1)
cmds.setDrivenKeyframe([constraint + "." + fkJoint + "W0", constraint + "." + ikJoint + "W1"], cd = ikCtrl + "." + "FK_IK", itt = "linear", ott = "linear")
cmds.setAttr(ikCtrl + "." + "FK_IK", 0)
else:
constraint = cmds.parentConstraint([fkJoint], driverJoint)[0]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildToes(self):
#find out which toe joints need to be rigged
for side in ["l", "r"]:
#create a list to hold all ctrl groups that are created
ctrlGroups = []
ikGrps = []
joints = []
if cmds.objExists("driver_ball_" + side):
children = cmds.listRelatives("driver_ball_" + side, children = True, type = 'joint')
allToes = cmds.listRelatives("driver_ball_" + side, allDescendents = True, type = 'joint')
#find out how many toe joints we have for each toe
bigToeMeta = [False, None]
indexMeta = [False, None]
middleMeta = [False, None]
ringMeta = [False, None]
pinkyMeta = [False, None]
numBigToes = 0
numIndexToes = [0, "index"]
numMiddleToes = [0, "middle"]
numRingToes = [0, "ring"]
numPinkyToes = [0, "pinky"]
if allToes:
for toe in allToes:
#find if metatarsals exist
if toe.find("meta") != -1:
if toe.partition("driver_")[2].find("bigtoe") == 0:
bigToeMeta = [True, "bigtoe"]
if toe.partition("driver_")[2].find("index") == 0:
indexMeta = [True, "index"]
if toe.partition("driver_")[2].find("middle") == 0:
middleMeta = [True, "middle"]
if toe.partition("driver_")[2].find("ring") == 0:
ringMeta = [True, "ring"]
if toe.partition("driver_")[2].find("pinky") == 0:
pinkyMeta = [True, "pinky"]
#get num toes -meta
if toe.partition("driver_")[2].find("bigtoe") == 0:
numBigToes += 1
if toe.partition("driver_")[2].find("index") == 0:
numIndexToes[0] += 1
if toe.partition("driver_")[2].find("middle") == 0:
numMiddleToes[0] += 1
if toe.partition("driver_")[2].find("ring") == 0:
numRingToes[0] += 1
if toe.partition("driver_")[2].find("pinky") == 0:
numPinkyToes[0] += 1
#subtract metatarsals (only if they exist!)
if bigToeMeta[0] == True:
numBigToes -= 1
if indexMeta[0] == True:
numIndexToes[0] -= 1
if middleMeta[0] == True:
numMiddleToes[0] -= 1
if ringMeta[0] == True:
numRingToes[0] -= 1
if pinkyMeta[0] == True:
numPinkyToes[0] -= 1
#duplicate the driver joints to be used as the rig joints
if children:
for child in children:
dupeChildNodes = cmds.duplicate(child, name = "temp")
#parent root joint of each toe to world if not already child of world
parent = cmds.listRelatives(dupeChildNodes[0], parent = True)[0]
if parent != None:
cmds.parent(dupeChildNodes[0], world = True)
#rename duped joints
for node in dupeChildNodes:
if node == "temp":
niceName = child.partition("driver_")[2]
joint = cmds.rename(node, "rig_" + niceName)
joints.append(joint)
else:
niceName = node.partition("driver_")[2]
cmds.rename("rig_*|" + node, "rig_" + niceName)
#if the metacarpal toes exist, create a control for them
for meta in [bigToeMeta, indexMeta, middleMeta, ringMeta, pinkyMeta]:
if meta[0] == True:
#create the control object for the metacarpal
ctrlName = meta[1]
ctrlName = ctrlName + "_metatarsal_ctrl_" + side
control = self.createControl("square", 1, ctrlName)
constraint = cmds.parentConstraint("rig_" + meta[1] + "_metatarsal_" + side, control)[0]
cmds.delete(constraint)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".rz", -90)
cmds.setAttr(control + ".sz", 15)
#create the group node and parent ctrl to it
ctrlGrp = cmds.group(empty = True, name = ctrlName + "_grp")
ctrlGroups.append(ctrlGrp)
constraint = cmds.parentConstraint("rig_" + meta[1] + "_metatarsal_" + side, ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(control + ".sz", 0)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#parent the rig joint to the control
cmds.parentConstraint(control, "rig_" + meta[1] + "_metatarsal_" + side, mo = True)
#lock attrs on control that shouldn't be animated
cmds.setAttr(control + ".tx", lock = True, keyable = False)
cmds.setAttr(control + ".ty", lock = True, keyable = False)
cmds.setAttr(control + ".tz", lock = True, keyable = False)
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#color the controls
if side == "l":
color = 5
else:
color = 12
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#if the number of toes(aside from metacarpals) is 1 or 2, just create fk controls for each toe and setup hierarchy
toeControls = []
for toes in [numIndexToes, numMiddleToes, numRingToes, numPinkyToes]:
if toes[0] < 3:
for i in range(int(toes[0])):
#create an FK control per toe
ctrlName = toes[1] + "_toe_fk_ctrl_" + str(i + 1) + "_" + side
control = self.createControl("circle", 3, ctrlName)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
metaCtrl = toes[1] + "_metatarsal_ctrl_" + side
if cmds.objExists(metaCtrl) == False:
if (i + 1) == 1:
ctrlGroups.append(ctrlGrp)
toeControls.append(control)
#position control
if i == 0:
constraint = cmds.parentConstraint("rig_" + toes[1] + "_proximal_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_" + toes[1] + "_proximal_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.parentConstraint(control, "rig_" + toes[1] + "_proximal_phalange_" + side, mo = True)
if i == 1:
constraint = cmds.parentConstraint("rig_" + toes[1] + "_middle_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_" + toes[1] + "_middle_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.parentConstraint(control, "rig_" + toes[1] + "_middle_phalange_" + side, mo = True)
if i == 2:
constraint = cmds.parentConstraint("rig_" + toes[1] + "_distal_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_" + toes[1] + "_distal_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.parentConstraint(control, "rig_" + toes[1] + "_distal_phalange_" + side, mo = True)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".rz", -90)
#duplicate the ctrl group to create the driven group
drivenGrp = cmds.duplicate(ctrlGrp, parentOnly = True, name = control + "_driven_grp")[0]
ctrlGroups.append(drivenGrp)
cmds.parent(drivenGrp, ctrlGrp)
#parent control to grp
cmds.parent(control, drivenGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#if we aren't the root of the toe chain, then parent our ctrlGrp to the previous fk control
if i != 0:
cmds.parent(ctrlGrp, ctrlParent)
else:
if cmds.objExists(toes[1] + "_metatarsal_ctrl_" + side):
cmds.parent(ctrlGrp, toes[1] + "_metatarsal_ctrl_" + side)
ctrlParent = control
#lock attrs on control that shouldn't be animated
cmds.setAttr(control + ".tx", lock = True, keyable = False)
cmds.setAttr(control + ".ty", lock = True, keyable = False)
cmds.setAttr(control + ".tz", lock = True, keyable = False)
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#if the number of toes(aside from metacarpals) is 3, setup a singular rp IK chain, and a SC IK chain for toe 3 and a newly created toe tip joint
else:
#take the end joint and duplicate it
tipJoint = cmds.duplicate("rig_" + toes[1] + "_distal_phalange_" + side, parentOnly = True, name = "rig_" + toes[1] + "_tip_" + side)[0]
cmds.parent(tipJoint, "rig_" + toes[1] + "_distal_phalange_" + side)
#move tip joint out a bit
if side == "r":
cmds.setAttr(tipJoint + ".tx", -5)
else:
cmds.setAttr(tipJoint + ".tx", 5)
#create RP IK handle from base knuckle to distal
toeRpIkNodes = cmds.ikHandle(sol = "ikRPsolver", name = toes[1] + "_RP_ikHandle_" + side, sj = "rig_" + toes[1] + "_proximal_phalange_" + side, ee = "rig_" + toes[1] + "_distal_phalange_" + side)
toeScIkNodes = cmds.ikHandle(sol = "ikSCsolver", name = toes[1] + "_SC_ikHandle_" + side, sj = "rig_" + toes[1] + "_distal_phalange_" + side, ee = tipJoint)
cmds.setAttr(toeRpIkNodes[0] + ".v", 0)
cmds.setAttr(toeScIkNodes[0] + ".v", 0)
#parent SC IK to RP IK
cmds.parent(toeScIkNodes[0], toeRpIkNodes[0])
#create an IK control
control = self.createControl("circle", 3, toes[1] + "_ik_ctrl_" + side)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
ikGrps.append(ctrlGrp)
toeControls.append(control)
#position control
constraint = cmds.parentConstraint("rig_" + toes[1] + "_distal_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_" + toes[1] + "_distal_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
#create dummy group so IK controls on both sides behave the same (dummy group will have 180 offset if right side)
dummyGrp = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_dummy")[0]
spaceSwitcherFollow = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_space_switcher_follow")[0]
spaceSwitcher = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_space_switcher")[0]
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(dummyGrp, spaceSwitcher)
cmds.parent(spaceSwitcherFollow, ctrlGrp)
#parent ctrl to group
if side == "r":
cmds.setAttr(dummyGrp + ".ry", 180)
cmds.parent(control, dummyGrp)
cmds.setAttr(control + ".ry", -90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.parent(toeRpIkNodes[0], control)
#lock attrs on control that should not be animated
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
#need to do the bigToe separately since it will only have 3 toes max anyway, and bigToesNum == 2 will mean IK setup, and anything less than 2 == FK setup
if numBigToes < 2:
for i in range(int(numBigToes)):
#create an FK control per toe
ctrlName = "bigtoe_toe_fk_ctrl_" + str(i + 1) + "_" + side
control = self.createControl("circle", 8, ctrlName)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
toeControls.append(control)
metaCtrl = "bigtoe_metatarsal_ctrl_" + side
if cmds.objExists(metaCtrl) == False:
if (i + 1) == 1:
ctrlGroups.append(ctrlGrp)
#position control
if i == 0:
constraint = cmds.parentConstraint("rig_bigtoe_proximal_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_bigtoe_proximal_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.parentConstraint(control, "rig_bigtoe_proximal_phalange_" + side, mo = True)
if i == 1:
constraint = cmds.parentConstraint("rig_bigtoe_distal_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_bigtoe_distal_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
cmds.parentConstraint(control, "rig_bigtoe_distal_phalange_" + side, mo = True)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".rz", -90)
#duplicate the ctrl group to create the driven group
drivenGrp = cmds.duplicate(ctrlGrp, parentOnly = True, name = control + "_driven_grp")[0]
ctrlGroups.append(drivenGrp)
cmds.parent(drivenGrp, ctrlGrp)
#parent control to grp
cmds.parent(control, drivenGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#if we aren't the root of the toe chain, then parent our ctrlGrp to the previous fk control
if i != 0:
cmds.parent(ctrlGrp, ctrlParent)
else:
if cmds.objExists("bigtoe_metatarsal_ctrl_" + side):
cmds.parent(ctrlGrp, "bigtoe_metatarsal_ctrl_" + side)
ctrlParent = control
#lock attrs on control that shouldn't be animated
cmds.setAttr(control + ".tx", lock = True, keyable = False)
cmds.setAttr(control + ".ty", lock = True, keyable = False)
cmds.setAttr(control + ".tz", lock = True, keyable = False)
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
else:
#take the end joint and duplicate it
tipJoint = cmds.duplicate("rig_bigtoe_distal_phalange_" + side, parentOnly = True, name = "rig_bigtoe_tip_" + side)[0]
cmds.parent(tipJoint, "rig_bigtoe_distal_phalange_" + side)
#since the toe has 1 less knuckle, we need another tip
tipJointEnd = cmds.duplicate(tipJoint, parentOnly = True, name = "rig_bigtoe_tip_end_" + side)[0]
cmds.parent(tipJointEnd, tipJoint)
#move tip joint out a bit
if side == "r":
cmds.setAttr(tipJoint + ".tx", -5)
cmds.setAttr(tipJointEnd + ".tx", -5)
else:
cmds.setAttr(tipJoint + ".tx", 5)
cmds.setAttr(tipJointEnd + ".tx", 5)
#set preferred angles on 1rst and 2nd knuckle
cmds.setAttr("rig_bigtoe_proximal_phalange_" + side + ".preferredAngleZ", 45)
cmds.setAttr("rig_bigtoe_distal_phalange_" + side + ".preferredAngleZ", -45)
#create RP IK handle from base knuckle to distal
toeRpIkNodes = cmds.ikHandle(sol = "ikRPsolver", name = "bigtoe_RP_ikHandle_" + side, sj = "rig_bigtoe_proximal_phalange_" + side, ee = tipJoint)
toeScIkNodes = cmds.ikHandle(sol = "ikSCsolver", name = "bigtoe_SC_ikHandle_" + side, sj = "rig_bigtoe_distal_phalange_" + side, ee = tipJointEnd)
cmds.setAttr(toeRpIkNodes[0] + ".v", 0)
cmds.setAttr(toeScIkNodes[0] + ".v", 0)
#parent SC IK to RP IK
cmds.parent(toeScIkNodes[0], toeRpIkNodes[0])
#create an IK control
control = self.createControl("circle", 6, "bigtoe_ik_ctrl_" + side)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
ikGrps.append(ctrlGrp)
toeControls.append(control)
#position control
constraint = cmds.parentConstraint("rig_bigtoe_distal_phalange_" + side, control)[0]
grpConstraint = cmds.parentConstraint("rig_bigtoe_distal_phalange_" + side, ctrlGrp)[0]
cmds.delete([constraint, grpConstraint])
#create dummy group so IK controls on both sides behave the same (dummy group will have 180 offset if right side)
dummyGrp = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_dummy")[0]
spaceSwitcherFollow = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_space_switcher_follow")[0]
spaceSwitcher = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_space_switcher")[0]
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(dummyGrp, spaceSwitcher)
cmds.parent(spaceSwitcherFollow, ctrlGrp)
#parent ctrl to group
if side == "r":
cmds.setAttr(dummyGrp + ".ry", 180)
cmds.parent(control, dummyGrp)
cmds.setAttr(control + ".ry", -90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.parent(toeRpIkNodes[0], control)
#lock attrs on control that should not be animated
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
#setup global control for toes
#if toes < 3, rotation based(spread, curl) (grp node above FK control)
fkControls = []
ikControls = []
for control in toeControls:
if control.find("fk") != -1:
fkControls.append(control)
if control.find("ik") != -1:
ikControls.append(control)
#IF AlL TOES ARE IK TOES
if len(fkControls) == 0:
#create a control at the tip of the toes that will globally move the IK controls
if joints:
control = self.createControl("square", 1, "ik_global_ctrl_" + side)
constraint = cmds.parentConstraint("ikHandle_toe_" + side, control)[0]
cmds.delete(constraint)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".rz", -90)
cmds.setAttr(control + ".sz", 5)
#add a spread attr to the global control
cmds.select(control)
cmds.addAttr(longName='spread', defaultValue=0, minValue=0, maxValue=10, keyable = True)
#create the group node and parent ctrl to it
ctrlGrp = cmds.group(empty = True, name = "ik_global_ctrl_" + side + "_grp")
ctrlGroups.append(ctrlGrp)
constraint = cmds.parentConstraint("ikHandle_toe_" + side, ctrlGrp)[0]
cmds.delete(constraint)
#create a space switcher node
spaceSwitcherFollow = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_space_switcher_follow")[0]
spaceSwitcher = cmds.duplicate(ctrlGrp, parentOnly = True, name = ctrlGrp + "_space_switcher")[0]
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(spaceSwitcherFollow, ctrlGrp)
cmds.parent(control, spaceSwitcher)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(control + ".rx", 90)
cmds.setAttr(control + ".scale", 2.5, 2.5, 2.5, type = 'double3')
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#set the pivot to be at the base of the toes
pivPos = cmds.xform("jointmover_knuckle_base_" + side, q = True, ws = True, t = True)
cmds.xform(control, ws = True, piv = (pivPos[0], pivPos[1], pivPos[2]))
cmds.xform(ctrlGrp, ws = True, piv = (pivPos[0], pivPos[1], pivPos[2]))
cmds.xform(spaceSwitcher, ws = True, piv = (pivPos[0], pivPos[1], pivPos[2]))
#lock attrs on control that are not needed to be animated
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#parent the IK groups to the global grp and also set driven keys for toe spread
for grp in ikGrps:
#create a driven group
group = cmds.group(empty = True, name = grp + "_driven")
if grp.find("index") != -1:
constraint = cmds.parentConstraint("rig_index_proximal_phalange_" + side, group)[0]
cmds.delete(constraint)
cmds.parent(group, "index_ik_ctrl_" + side + "_grp_space_switcher")
cmds.parent("index_ik_ctrl_" + side + "_grp_dummy", group)
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", -9)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if grp.find("middle") != -1:
constraint = cmds.parentConstraint("rig_middle_proximal_phalange_" + side, group)[0]
cmds.delete(constraint)
cmds.parent(group, "middle_ik_ctrl_" + side + "_grp_space_switcher")
cmds.parent("middle_ik_ctrl_" + side + "_grp_dummy", group)
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", 9.5)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if grp.find("ring") != -1:
constraint = cmds.parentConstraint("rig_ring_proximal_phalange_" + side, group)[0]
cmds.delete(constraint)
cmds.parent(group, "ring_ik_ctrl_" + side + "_grp_space_switcher")
cmds.parent("ring_ik_ctrl_" + side + "_grp_dummy", group)
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", 17)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if grp.find("pinky") != -1:
constraint = cmds.parentConstraint("rig_pinky_proximal_phalange_" + side, group)[0]
cmds.delete(constraint)
cmds.parent(group, "pinky_ik_ctrl_" + side + "_grp_space_switcher")
cmds.parent("pinky_ik_ctrl_" + side + "_grp_dummy", group)
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", 32)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if grp.find("bigtoe") != -1:
constraint = cmds.parentConstraint("rig_bigtoe_proximal_phalange_" + side, group)[0]
cmds.delete(constraint)
cmds.parent(group, "bigtoe_ik_ctrl_" + side + "_grp_space_switcher")
cmds.parent("bigtoe_ik_ctrl_" + side + "_grp_dummy", group)
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", -15)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.parent(grp, control)
#color the control
if side == "l":
color = 5
else:
color = 12
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#IF ALL TOES ARE FK TOES
if len(ikControls) == 0:
if joints:
#create a control at the tip of the toes that will give the user some handy global controls, like curl, spread, etc.
control = self.createControl("square", 1, "fk_global_ctrl_" + side)
constraint = cmds.parentConstraint("ikHandle_toe_" + side, control)[0]
cmds.delete(constraint)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
cmds.setAttr(control + ".rz", -90)
cmds.setAttr(control + ".sz", 5)
#create the group node and parent ctrl to it
ctrlGrp = cmds.group(empty = True, name = "fk_global_ctrl_" + side + "_grp")
ctrlGroups.append(ctrlGrp)
constraint = cmds.parentConstraint("ikHandle_toe_" + side, ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(control + ".rx", 90)
cmds.setAttr(control + ".scale", 2.5, 2.5, 2.5, type = 'double3')
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#lock attrs on control that are not needed to be animated
cmds.setAttr(control + ".tx", lock = True, keyable = False)
cmds.setAttr(control + ".ty", lock = True, keyable = False)
cmds.setAttr(control + ".tz", lock = True, keyable = False)
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#find all driven fk grps
drivenGroups = []
for group in ctrlGroups:
if group.find("driven") != -1:
if group.find("fk") != -1:
drivenGroups.append(group)
#add a spread attr to the global control
cmds.select(control)
cmds.addAttr(longName='spread', defaultValue=0, minValue=0, maxValue=10, keyable = True)
#setup driven keys for the fk group nodes
for group in drivenGroups:
#Curl
cmds.setAttr(control + ".rz", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rz", -180)
cmds.setAttr(group + ".rz", -90)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rz", 90)
cmds.setAttr(group + ".rz", 45)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rz", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rz", 0)
cmds.setAttr(group + ".rz", 0)
#Toe Lean
#only the base knuckle
if group.partition("ctrl_")[2].find("1") == 0:
cmds.setAttr(control + ".ry", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".ry", itt = "linear", ott = "linear")
cmds.setAttr(control + ".ry", 45)
cmds.setAttr(group + ".ry", 45)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".ry", itt = "linear", ott = "linear")
cmds.setAttr(control + ".ry", -45)
cmds.setAttr(group + ".ry", -45)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".ry", itt = "linear", ott = "linear")
cmds.setAttr(control + ".ry", 0)
cmds.setAttr(group + ".ry", 0)
#Toe Tilt
if group.find("pinky") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", 65)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", -65)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("2") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", -60)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", 60)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("ring") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", 45)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", -45)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("2") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", -30)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", 30)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("middle") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", 50)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", -50)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("2") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", -40)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", 40)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("index") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", 35)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", -35)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("2") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", -25)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", 25)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
if group.find("bigtoe") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 60)
cmds.setAttr(group + ".rz", 5)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", -60)
cmds.setAttr(group + ".rz", -5)
cmds.setDrivenKeyframe(group + ".rz", cd = control + ".rx", itt = "linear", ott = "linear")
cmds.setAttr(control + ".rx", 0)
cmds.setAttr(group + ".rz", 0)
#toe spread
if group.find("bigtoe") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", -15)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if group.find("index") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", -9)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if group.find("middle") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", 9.5)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if group.find("ring") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", 17)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if group.find("pinky") != -1:
if group.find("1") != -1:
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 10)
cmds.setAttr(group + ".ry", 32)
cmds.setDrivenKeyframe(group + ".ry", cd = control + ".spread", itt = "linear", ott = "linear")
cmds.setAttr(control + ".spread", 0)
cmds.setAttr(group + ".ry", 0)
if len(ikControls) and len(fkControls) > 0:
for group in ikGrps:
ctrlGroups.append(group)
#need to hook into foot rig, both fk and ik. To do this, we'll group up the toe controls for each side, and parent under the driver ball
if joints:
masterGrp = cmds.group(empty = True, name = "toe_rig_" + side + "_grp")
jointsGrp = cmds.group(empty = True, name = "toe_rig_joints_" + side + "_grp")
cmds.parent(joints, jointsGrp)
cmds.parent(jointsGrp, masterGrp)
for group in ctrlGroups:
if group.find("driven") == -1:
cmds.parent(group, masterGrp)
cmds.parentConstraint("driver_ball_" + side, masterGrp, mo = True)
#parent toe groups to leg sys grp
cmds.parent(masterGrp, "leg_sys_grp")
#Need to constrain driver joints to rig joints
for toe in allToes:
rigToe = toe.partition("driver_")[2]
rigToe = "rig_" + rigToe
cmds.parentConstraint(rigToe, toe)
#color the controls
for control in toeControls:
if side == "l":
color = 5
else:
color = 12
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#lastly, hook up toe control visibility to foot control attribute
cmds.connectAttr("ik_foot_anim_" + side + ".toeCtrlVis", masterGrp + ".v")
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def finishLegs(self):
ball = False
legMasterGrp = cmds.group(empty = True, name = "leg_sys_grp")
for side in ["l", "r"]:
#organize joints
legJointGrp = cmds.group(empty = True, name = "leg_joints_grp_" + side)
constraint = cmds.parentConstraint("driver_thigh_" + side, legJointGrp)[0]
cmds.delete(constraint)
cmds.parent(["fk_leg_thigh_" + side, "ik_leg_thigh_" + side, "fk_thigh_" + side + "_orient_grp"], legJointGrp)
cmds.parent(legJointGrp, "leg_group_" + side)
#create invisible legs that will drive the hips
filePath = self.mayaToolsDir + "/General/ART/invis_legs.mb"
cmds.select("leg_group_" + side, replace = True)
cmds.file(filePath, es = True, type = "mayaBinary", force = True)
invisLegNodes = cmds.file(filePath, i = True, returnNewNodes = True, renameAll = True)
#clean up import
for node in invisLegNodes:
if node.find("body_anim_space") != -1:
if cmds.objExists(node):
cmds.delete(node)
#constrain the no flip begin joint to the driver pelvis
cmds.parentConstraint("driver_pelvis", "noflip_begin_joint_" + side, mo = True)
cmds.parentConstraint("hip_anim", "invis_legs_leg_group_" + side, mo = True)
#connect real knee vector to invis knee vector
cmds.connectAttr("noflip_pv_loc_" + side + ".translate", ("invis_legs_noflip_pv_loc_" + side + ".translate"))
cmds.delete("invis_legs_ik_knee_anim_grp_" + side)
if cmds.objExists("invis_legs_ik_leg_" + side + "_twistMultNode"):
cmds.delete("invis_legs_ik_leg_" + side + "_twistMultNode")
if side == "r":
cmds.disconnectAttr("invis_legs_ik_foot_anim_" + side + ".knee_twist", "invis_legs_foot_ikHandle_" + side + ".twist")
cmds.connectAttr("foot_ikHandle_" + side + ".twist", "invis_legs_foot_ikHandle_" + side + ".twist")
#make sure leg orients are good
tempConstraint = cmds.orientConstraint("fk_thigh_" + side + "_orient_grp", "invis_legs_fk_thigh_" + side + "_orient_grp")[0]
cmds.delete(tempConstraint)
#point constraint invis target loc to real foot control so invis IK goes with real foot. delete invis foot
cmds.parentConstraint("ik_foot_anim_" + side, ("invis_legs_ik_foot_anim_" + side))
#drive invis fk thigh with real
cmds.connectAttr("fk_thigh_" + side + "_anim.rotate", "invis_legs_fk_thigh_" + side + "_anim.rotate")
cmds.connectAttr("fk_calf_" + side + "_anim.rotate", "invis_legs_fk_calf_" + side + "_anim.rotate")
#hide invisible legs
cmds.setAttr("invis_legs_leg_group_" + side + ".v", 0)
parent = cmds.listRelatives("invis_legs_leg_group_" + side, parent = True)
cmds.parent("invis_legs_leg_group_" + side, "leg_group_" + side)
if parent:
cmds.delete(parent)
#create result joints
thighJoint = cmds.duplicate("driver_thigh_" + side, name = "result_leg_thigh_" + side, parentOnly = True)[0]
calfJoint = cmds.duplicate("driver_calf_" + side, name = "result_leg_calf_" + side, parentOnly = True)[0]
footJoint = cmds.duplicate("driver_foot_" + side, name = "result_leg_foot_" + side, parentOnly = True)[0]
if cmds.objExists("driver_ball_" + side):
ball = True
ballJoint = cmds.duplicate("driver_ball_" + side, name = "result_leg_ball_" + side, parentOnly = True)[0]
for joint in [thighJoint, calfJoint, footJoint]:
cmds.parent(joint, world = True)
if ball:
cmds.parent(ballJoint, world = True)
cmds.parent(footJoint, calfJoint)
cmds.parent(calfJoint, thighJoint)
if ball:
cmds.parent(ballJoint, footJoint)
cmds.makeIdentity(thighJoint, t = 0, r = 1, s = 0, apply = True)
#create IK fix joints so that all the orients of the leg systems match up
ikFixThighJoint = cmds.duplicate("driver_thigh_" + side, name = "ikFix_leg_thigh_" + side, parentOnly = True)[0]
ikFixCalfJoint = cmds.duplicate("driver_calf_" + side, name = "ikFix_leg_calf_" + side, parentOnly = True)[0]
ikFixFootJoint = cmds.duplicate("driver_foot_" + side, name = "ikFix_leg_foot_" + side, parentOnly = True)[0]
if cmds.objExists("driver_ball_" + side):
ball = True
ikFixBallJoint = cmds.duplicate("driver_ball_" + side, name = "ikFix_leg_ball_" + side, parentOnly = True)[0]
for joint in [ikFixThighJoint, ikFixCalfJoint, ikFixFootJoint]:
cmds.parent(joint, world = True)
if ball:
cmds.parent(ikFixBallJoint, world = True)
cmds.parent(ikFixFootJoint, ikFixCalfJoint)
cmds.parent(ikFixCalfJoint, ikFixThighJoint)
if ball:
cmds.parent(ikFixBallJoint, ikFixFootJoint)
cmds.makeIdentity(ikFixThighJoint, t = 0, r = 1, s = 0, apply = True)
cmds.parentConstraint("ik_leg_thigh_" + side, ikFixThighJoint, mo = True)
cmds.parentConstraint("ik_leg_calf_" + side, ikFixCalfJoint, mo = True)
cmds.parentConstraint("ik_leg_foot_" + side, ikFixFootJoint, mo = True)
if ball:
cmds.parentConstraint("ik_leg_ball_" + side, ikFixBallJoint, mo = True)
#constrain result joints to fk and ik joints
thighConstraint = cmds.parentConstraint(["fk_leg_thigh_" + side, ikFixThighJoint], thighJoint, mo = True)[0]
calfConstraint = cmds.parentConstraint(["fk_leg_calf_" + side, ikFixCalfJoint], calfJoint, mo = True)[0]
footConstraint = cmds.parentConstraint(["fk_leg_foot_" + side, ikFixFootJoint], footJoint, mo = True)[0]
if ball:
ballConstraint = cmds.parentConstraint(["fk_leg_ball_" + side, ikFixBallJoint], ballJoint, mo = True)[0]
#add switch attr
cmds.select("Rig_Settings")
cmds.addAttr(longName=(side + "LegMode"), at = 'enum', en = "fk:ik:", keyable = True)
#connect up attr to constraints
constraints =[thighConstraint, calfConstraint, footConstraint]
if ball:
constraints.append(ballConstraint)
reverseNode = cmds.shadingNode("reverse", asUtility = True, name = "legSwitcher_reverse_node_" + side)
cmds.connectAttr("Rig_Settings" + "." + side + "LegMode", reverseNode + ".inputX")
for constraint in constraints:
targets = cmds.parentConstraint(constraint, q = True, weightAliasList = True)
cmds.connectAttr("Rig_Settings" + "." + side + "LegMode", constraint + "." + targets[1])
cmds.connectAttr(reverseNode + ".outputX", constraint + "." + targets[0])
#connect up visibility of controls to leg mode
cmds.connectAttr("Rig_Settings" + "." + side + "LegMode", "ik_leg_grp_" + side + ".v")
cmds.connectAttr(reverseNode + ".outputX", "fk_thigh_" + side + "_anim_grp.v")
#set default to IK
cmds.setAttr("Rig_Settings" + "." + side + "LegMode", 1)
#constrain driver legs to result legs
cmds.parentConstraint(thighJoint, "driver_thigh_" + side, mo = True)
cmds.parentConstraint(calfJoint, "driver_calf_" + side, mo = True)
cmds.parentConstraint(footJoint, "driver_foot_" + side, mo = True)
if ball:
cmds.parentConstraint(ballJoint, "driver_ball_" + side, mo = True)
#create blend nodes for the scale
scaleBlendColors_UpLeg = cmds.shadingNode("blendColors", asUtility = True, name = side + "_up_leg_scale_blend")
cmds.connectAttr("ik_leg_thigh_" + side + ".scale", scaleBlendColors_UpLeg + ".color1")
cmds.connectAttr("fk_thigh_" + side + "_anim.scale", scaleBlendColors_UpLeg + ".color2")
cmds.connectAttr(scaleBlendColors_UpLeg + ".output", "driver_thigh_" + side + ".scale")
scaleBlendColors_LoLeg = cmds.shadingNode("blendColors", asUtility = True, name = side + "_lo_leg_scale_blend")
cmds.connectAttr("ik_leg_calf_" + side + ".scale", scaleBlendColors_LoLeg + ".color1")
cmds.connectAttr("fk_calf_" + side + "_anim.scale", scaleBlendColors_LoLeg + ".color2")
cmds.connectAttr(scaleBlendColors_LoLeg + ".output", "driver_calf_" + side + ".scale")
scaleBlendColors_Foot = cmds.shadingNode("blendColors", asUtility = True, name = side + "_foot_scale_blend")
cmds.connectAttr("ik_leg_foot_" + side + ".scale", scaleBlendColors_Foot + ".color1")
cmds.connectAttr("fk_foot_" + side + "_anim.scale", scaleBlendColors_Foot + ".color2")
cmds.connectAttr(scaleBlendColors_Foot + ".output", "driver_foot_" + side + ".scale")
#set limits
cmds.select("driver_thigh_" + side)
cmds.transformLimits(sy = (.05, 2.0), sz = (.05, 2.0), esy = [False, True], esz = [False, True])
cmds.select("driver_calf_" + side)
cmds.transformLimits(sy = (.05, 2.0), sz = (.05, 2.0), esy = [False, True], esz = [False, True])
#clean up legs hiearchy
cmds.parent([thighJoint, ikFixThighJoint], legJointGrp)
cmds.setAttr("leg_ctrl_grp_" + side + ".v", 0)
#hide stuff
cmds.setAttr(ikFixThighJoint + ".v", 0)
cmds.setAttr("fk_leg_thigh_" + side + ".v", 0)
#CRA CODE CHANGES
#Setup Twist Joints if the user selected them
if side == "l":
if cmds.getAttr("Skeleton_Settings.leftUpperLegTwist") > 0:
self.buildThighTwist("l")
#uplegik.upperIKTwist(6, "_l", "", "", "thigh", "calf", "leg_sys_grp")
if cmds.getAttr("Skeleton_Settings.leftLowerLegTwist") > 0:
self.buildCalfTwist("l")
if side == "r":
if cmds.getAttr("Skeleton_Settings.rightUpperLegTwist") > 0:
self.buildThighTwist("r")
#uplegik.upperIKTwist(6, "_r", "", "", "thigh", "calf", "leg_sys_grp")
if cmds.getAttr("Skeleton_Settings.rightLowerLegTwist") > 0:
self.buildCalfTwist("r")
#CRA CODE CHANGES END
#clean up the leg hierarchy. group all leg systems under 1 group
cmds.parent(["leg_group_l", "leg_group_r"], legMasterGrp)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildCalfTwist(self, side):
if side == "l":
color = 5
else:
color = 12
#create our roll group
rollGrp = cmds.group(empty = True, name = "calf_" + side + "_roll_grp")
cmds.parentConstraint("driver_calf_" + side, rollGrp)
#create our twist joint and twist mod joint
cmds.select(clear = True)
twistJoint = cmds.joint(name = "calf_" + side + "_twist_joint")
cmds.select(clear = True)
constraint = cmds.parentConstraint("driver_calf_twist_01_" + side, twistJoint)[0]
cmds.delete(constraint)
cmds.parent(twistJoint, rollGrp)
cmds.makeIdentity(twistJoint, t = 0, r = 1, s = 0, apply = True)
#twist mod joint
twistMod = cmds.duplicate(twistJoint, po = True, name = "calf_" + side + "_twist_mod")[0]
cmds.parent(twistMod, twistJoint)
#create the manual twist control
twistCtrl = self.createControl("circle", 15, "calf_" + side + "_twist_anim")
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(twistMod, twistCtrl)[0]
cmds.delete(constraint)
twistCtrlGrp = cmds.group(empty = True, name = "calf_" + side + "_twist_anim_grp")
constraint = cmds.parentConstraint(twistMod, twistCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, twistCtrlGrp)
cmds.parent(twistCtrlGrp, twistMod)
cmds.makeIdentity(twistCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
for attr in [".sx", ".sy", ".sz"]:
cmds.setAttr(twistCtrl + attr, lock = True, keyable = False)
cmds.setAttr(twistCtrl + ".v", keyable = False)
#add attr on clavicle anim for manual twist control visibility
cmds.select("hip_anim")
cmds.addAttr(longName=(side + "CalfTwistCtrlVis"), at = 'bool', dv = 0, keyable = True)
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistCtrl + ".v")
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistMod + ".v")
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistJoint + ".v")
cmds.setAttr(twistMod + ".radius", .01)
cmds.setAttr(twistJoint + ".radius", .01)
#setup a simple relationship of foot rotateX value into mult node. input2X is driven by an attr on rig settings for twist amt(default is .5). Output into twist joint
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "calf_twist_" + side + "_mult_node")
#add attr to rig settings
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "CalfTwistAmount" ), defaultValue=.5, minValue=0, maxValue=1, keyable = True)
#connect output of driver hand into input1x
cmds.connectAttr("driver_foot_" + side + ".rx", twistMultNode + ".input1X")
#connect attr into input2x
cmds.connectAttr("Rig_Settings." + side + "CalfTwistAmount", twistMultNode + ".input2X")
#connect output into driver calf twist
cmds.connectAttr(twistMultNode + ".outputX", twistJoint + ".rx")
#constrain driver joint to twist joint
cmds.parentConstraint(twistCtrl, "driver_calf_twist_01_" + side, mo = True)
#if there is more than 1 roll bone, set those up now:
if side == "l":
sideName = "left"
else:
sideName = "right"
data = cmds.getAttr("SkeletonSettings_Cache." + sideName + "LegOptions_numCalfTwistBones")
numRolls = ast.literal_eval(data)[0]
if numRolls > 1:
for i in range(int(numRolls)):
if i == 1:
cmds.setAttr("Rig_Settings." + side + "CalfTwistAmount", .75)
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "CalfTwist2Amount" ), defaultValue=.5, minValue=0, maxValue=1, keyable = True)
#create the manual twist control setup
twistMod = cmds.duplicate("driver_calf_twist_0" + str(i + 1) + "_" + side , po = True, name = "calf_" + side + "_twist2_mod")[0]
cmds.parent(twistMod, rollGrp)
#create the manual twist control
twistCtrl = self.createControl("circle", 15, "calf_" + side + "_twist2_anim")
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(twistMod, twistCtrl)[0]
cmds.delete(constraint)
twistCtrlGrp = cmds.group(empty = True, name = "calf_" + side + "_twist2_anim_grp")
constraint = cmds.parentConstraint(twistMod, twistCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, twistCtrlGrp)
cmds.parent(twistCtrlGrp, twistMod)
cmds.makeIdentity(twistCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistCtrl + ".v")
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistMod + ".v")
for attr in [".sx", ".sy", ".sz"]:
cmds.setAttr(twistCtrl + attr, lock = True, keyable = False)
cmds.setAttr(twistCtrl + ".v", keyable = False)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
#drive the twist joint
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "calf_twist_2_" + side + "_mult_node")
cmds.connectAttr("driver_calf_twist_01_" + side + ".rx", twistMultNode + ".input1X")
cmds.connectAttr("Rig_Settings." + side + "CalfTwist2Amount", twistMultNode + ".input2X")
cmds.connectAttr(twistMultNode + ".outputX", twistCtrlGrp + ".rx")
cmds.parentConstraint(twistCtrl, "driver_calf_twist_0" + str(i + 1) + "_" + side, mo = True)
if i == 2:
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "CalfTwist3Amount" ), defaultValue=.25, minValue=0, maxValue=1, keyable = True)
#create the manual twist control setup
twistMod = cmds.duplicate("driver_calf_twist_0" + str(i + 1) + "_" + side , po = True, name = "calf_" + side + "_twist3_mod")[0]
cmds.parent(twistMod, rollGrp)
#create the manual twist control
twistCtrl = self.createControl("circle", 15, "calf_" + side + "_twist3_anim")
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(twistMod, twistCtrl)[0]
cmds.delete(constraint)
twistCtrlGrp = cmds.group(empty = True, name = "calf_" + side + "_twist3_anim_grp")
constraint = cmds.parentConstraint(twistMod, twistCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, twistCtrlGrp)
cmds.parent(twistCtrlGrp, twistMod)
cmds.makeIdentity(twistCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistCtrl + ".v")
cmds.connectAttr("hip_anim." + side + "CalfTwistCtrlVis", twistMod + ".v")
for attr in [".sx", ".sy", ".sz"]:
cmds.setAttr(twistCtrl + attr, lock = True, keyable = False)
cmds.setAttr(twistCtrl + ".v", keyable = False)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
#drive the twist joint
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "calf_twist_3_" + side + "_mult_node")
cmds.connectAttr("driver_calf_twist_01_" + side + ".rx", twistMultNode + ".input1X")
cmds.connectAttr("Rig_Settings." + side + "CalfTwist3Amount", twistMultNode + ".input2X")
cmds.connectAttr(twistMultNode + ".outputX", twistCtrlGrp + ".rx")
cmds.parentConstraint(twistCtrl, "driver_calf_twist_0" + str(i + 1) + "_" + side, mo = True)
#clean up hierarchy
cmds.parent(rollGrp, "leg_group_" + side)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildForearmTwist(self, side):
if side == "l":
color = 5
else:
color = 12
#create our roll group
rollGrp = cmds.group(empty = True, name = "lowerarm_" + side + "_roll_grp")
cmds.parentConstraint("driver_lowerarm_" + side, rollGrp)
#create our twist joint and twist mod joint
cmds.select(clear = True)
twistJoint = cmds.joint(name = "lowerarm_" + side + "_twist_joint")
cmds.select(clear = True)
constraint = cmds.parentConstraint("driver_lowerarm_twist_01_" + side, twistJoint)[0]
cmds.delete(constraint)
cmds.parent(twistJoint, rollGrp)
#twist mod joint
twistMod = cmds.duplicate(twistJoint, po = True, name = "lowerarm_" + side + "_twist_mod")[0]
cmds.parent(twistMod, twistJoint)
#create the manual twist control
twistCtrl = self.createControl("circle", 15, "lowerarm_" + side + "_twist_anim")
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(twistMod, twistCtrl)[0]
cmds.delete(constraint)
twistCtrlGrp = cmds.group(empty = True, name = "lowerarm_" + side + "_twist_anim_grp")
constraint = cmds.parentConstraint(twistMod, twistCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, twistCtrlGrp)
cmds.parent(twistCtrlGrp, twistMod)
cmds.makeIdentity(twistCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
for attr in [".sx", ".sy", ".sz"]:
cmds.setAttr(twistCtrl + attr, lock = True, keyable = False)
cmds.setAttr(twistCtrl + ".v", keyable = False)
#add attr on clavicle anim for manual twist control visibility
cmds.select("clavicle_" + side + "_anim")
cmds.addAttr(longName=("twistCtrlVisLower"), at = 'bool', dv = 0, keyable = True)
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistCtrl + ".v")
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistMod + ".v")
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistJoint + ".v")
cmds.setAttr(twistMod + ".radius", .01)
cmds.setAttr(twistJoint + ".radius", .01)
#setup a simple relationship of foot rotateX value into mult node. input2X is driven by an attr on rig settings for twist amt(default is .5). Output into twist joint
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "forearm_twist_" + side + "_mult_node")
#add attr to rig settings
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "ForearmTwistAmount" ), defaultValue=.5, minValue=0, maxValue=1, keyable = True)
#connect output of driver hand into input1x
cmds.connectAttr("driver_hand_" + side + ".rx", twistMultNode + ".input1X")
#connect attr into input2x
cmds.connectAttr("Rig_Settings." + side + "ForearmTwistAmount", twistMultNode + ".input2X")
#connect output into driver calf twist
cmds.connectAttr(twistMultNode + ".outputX", twistJoint + ".rx")
#constrain driver joint to twist joint
cmds.parentConstraint(twistCtrl, "driver_lowerarm_twist_01_" + side, mo = True)
#if there is more than 1 roll bone, set those up now:
if side == "l":
sideName = "left"
else:
sideName = "right"
data = cmds.getAttr("SkeletonSettings_Cache." + sideName + "ArmOptions_numLowArmTwistBones")
numRolls = ast.literal_eval(data)[0]
if numRolls > 1:
for i in range(int(numRolls)):
if i == 1:
cmds.setAttr("Rig_Settings." + side + "ForearmTwistAmount", .75)
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "ForearmTwist2Amount" ), defaultValue=.5, minValue=0, maxValue=1, keyable = True)
#create the manual twist control setup
twistMod = cmds.duplicate("driver_lowerarm_twist_0" + str(i + 1) + "_" + side , po = True, name = "lowerarm_" + side + "_twist2_mod")[0]
cmds.parent(twistMod, rollGrp)
#create the manual twist control
twistCtrl = self.createControl("circle", 15, "lowerarm_" + side + "_twist2_anim")
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(twistMod, twistCtrl)[0]
cmds.delete(constraint)
twistCtrlGrp = cmds.group(empty = True, name = "lowerarm_" + side + "_twist2_anim_grp")
constraint = cmds.parentConstraint(twistMod, twistCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, twistCtrlGrp)
cmds.parent(twistCtrlGrp, twistMod)
cmds.makeIdentity(twistCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistCtrl + ".v")
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistMod + ".v")
for attr in [".sx", ".sy", ".sz"]:
cmds.setAttr(twistCtrl + attr, lock = True, keyable = False)
cmds.setAttr(twistCtrl + ".v", keyable = False)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
#drive the twist joint
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "forearm_twist_2_" + side + "_mult_node")
cmds.connectAttr("driver_lowerarm_twist_01_" + side + ".rx", twistMultNode + ".input1X")
cmds.connectAttr("Rig_Settings." + side + "ForearmTwist2Amount", twistMultNode + ".input2X")
cmds.connectAttr(twistMultNode + ".outputX", twistCtrlGrp + ".rx")
cmds.parentConstraint(twistCtrl, "driver_lowerarm_twist_0" + str(i + 1) + "_" + side, mo = True)
if i == 2:
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "ForearmTwist3Amount" ), defaultValue=.25, minValue=0, maxValue=1, keyable = True)
#create the manual twist control setup
twistMod = cmds.duplicate("driver_lowerarm_twist_0" + str(i + 1) + "_" + side , po = True, name = "lowerarm_" + side + "_twist3_mod")[0]
cmds.parent(twistMod, rollGrp)
#create the manual twist control
twistCtrl = self.createControl("circle", 15, "lowerarm_" + side + "_twist3_anim")
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(twistMod, twistCtrl)[0]
cmds.delete(constraint)
twistCtrlGrp = cmds.group(empty = True, name = "lowerarm_" + side + "_twist3_anim_grp")
constraint = cmds.parentConstraint(twistMod, twistCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, twistCtrlGrp)
cmds.parent(twistCtrlGrp, twistMod)
cmds.makeIdentity(twistCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistCtrl + ".v")
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVisLower", twistMod + ".v")
for attr in [".sx", ".sy", ".sz"]:
cmds.setAttr(twistCtrl + attr, lock = True, keyable = False)
cmds.setAttr(twistCtrl + ".v", keyable = False)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
#drive the twist joint
twistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "forearm_twist_3_" + side + "_mult_node")
cmds.connectAttr("driver_lowerarm_twist_01_" + side + ".rx", twistMultNode + ".input1X")
cmds.connectAttr("Rig_Settings." + side + "ForearmTwist3Amount", twistMultNode + ".input2X")
cmds.connectAttr(twistMultNode + ".outputX", twistCtrlGrp + ".rx")
cmds.parentConstraint(twistCtrl, "driver_lowerarm_twist_0" + str(i + 1) + "_" + side, mo = True)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildArmRoll(self, side):
if side == "l":
color = 5
sideName = "left"
else:
color = 12
sideName = "right"
#get number of roll bones
data = cmds.getAttr("SkeletonSettings_Cache." + sideName + "ArmOptions_numUpArmTwistBones")
numRolls = ast.literal_eval(data)[0]
#create a nurbs plane for our ribbon
ribbon = cmds.nurbsPlane(ax = [0,0,1], lr = numRolls, width = 10, d = 3, u = 1, v = numRolls, ch = True, name = "upperarm_twist_ribbon_" + side)[0]
#rebuild the ribbon with 1 U span
ribbon = cmds.rebuildSurface(ribbon, su = 1, du = 1, sv = numRolls, dv = 1, ch = 1)[0]
cmds.setAttr(ribbon + ".rz", -90)
cmds.makeIdentity(ribbon, apply = True, t = 1, r = 1, s = 1)
#create 2 temporary skin joints
moveVal = 0
for i in range(numRolls - 1):
moveVal += 10
cmds.select(clear = True)
topSkinJoint = cmds.joint(name = "top_skinJoint_temp")
cmds.move(moveVal, 0, 0, r = True, os = True, wd = True)
cmds.select(clear = True)
cmds.select(clear = True)
bottomSkinJoint = cmds.joint(name = "bottom_skinJoint_temp")
cmds.move(moveVal * -1, 0, 0, r = True, os = True, wd = True)
cmds.select(clear = True)
#skin ribbon
cmds.select([ribbon, topSkinJoint, bottomSkinJoint])
skin = cmds.skinCluster(tsb = True, mi = 2, omi = True, dr = 5, sm = 0)
#position the joints, thus moving the ribbon
constraint = cmds.parentConstraint("driver_upperarm_" + side, topSkinJoint)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint("driver_lowerarm_" + side, bottomSkinJoint)[0]
cmds.delete(constraint)
#delete ribbon history and skin joints
cmds.delete(ribbon, ch = True)
cmds.delete([bottomSkinJoint, topSkinJoint])
#create hair system on ribbon
cmds.select(ribbon)
mel.eval("createHair 1 3 10 0 0 0 0 5 0 2 1 1;")
#figure out which follicles created represent which areas on the ribbon
hairs = cmds.ls(type = "hairSystem")
if len(hairs) > 0:
hairSys = hairs[0]
parent = cmds.listRelatives(hairs[0], parent = True)[0]
hairSys = cmds.rename(parent, "upperarm_twist_" + side + "_hairSys")
follicles = cmds.listConnections(hairSys + "Shape", type = "follicle")
follicles = set(follicles)
hairFollicles = follicles
#delete outputCurves
cmds.delete(parent + "OutputCurves")
#create a joint per follicle
for follicle in hairFollicles:
cmds.select(clear = True)
joint = cmds.joint(name = follicle + "_joint")
cmds.select(clear = True)
constraint = cmds.parentConstraint(follicle, joint)[0]
cmds.delete(constraint)
cmds.parent(joint, follicle)
cmds.makeIdentity(joint, apply = True, t = 0, r = 1, s = 0)
#create the skin joints (final)
skinJoints = []
for i in range(numRolls + 1):
cmds.select(clear = True)
skinJoint = cmds.joint(name = "skin_upperarm_twist_joint_" + side + str(i))
cmds.select(clear = True)
skinJoints.append(skinJoint)
for i in range(numRolls):
constraint = cmds.parentConstraint("driver_upperarm_twist_0" + str(i + 1) + "_" + side, "skin_upperarm_twist_joint_" + side + str(i))[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint("driver_lowerarm_" + side, skinJoint)[0]
cmds.delete(constraint)
#create our manual control curves
x = 1
groups = []
for joint in skinJoints:
if joint != skinJoints[-1]:
if joint == skinJoints[0]:
name = "upperarm_" + side + "_twist_anim_grp"
else:
name = "upperarm_" + side + "_twist" + str(x) + "_anim_grp"
group = cmds.group(empty = True, name = name)
groups.append(group)
constraint = cmds.parentConstraint(joint, group)[0]
cmds.delete(constraint)
x = x + 1
for i in range(int(len(groups))):
name = groups[i].partition("_grp")[0]
twistCtrl = self.createControl("circle", 20, name)
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(groups[i], twistCtrl)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, groups[i])
cmds.parent(skinJoints[i], twistCtrl)
cmds.makeIdentity(skinJoints[i], apply = True, t = 0, r = 1, s = 0)
#clean up control
cmds.setAttr(twistCtrl + ".v", keyable = False)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
#organize groups
masterGrp = cmds.group(empty = True, name = "upperarm_twist_master_grp_" + side)
constraint = cmds.parentConstraint("rig_clavicle_" + side, masterGrp)[0]
cmds.delete(constraint)
rollGrp = cmds.duplicate(masterGrp, name = "upperarm_twist_roll_grp_" + side)[0]
constraint = cmds.parentConstraint("driver_upperarm_" + side, rollGrp)[0]
cmds.delete(constraint)
cmds.parent(rollGrp, masterGrp)
#set rotate order on roll grp (xzy)
cmds.setAttr(rollGrp + ".rotateOrder", 3)
for group in groups:
cmds.parent(group, rollGrp)
#skin ribbon to skin joints
cmds.select(ribbon)
for joint in skinJoints:
cmds.select(joint, add = True)
skin = cmds.skinCluster(tsb = True, mi = 2, omi = True, dr = 5, sm = 0)
#orient roll grp to both fk/ik arm joints and set driven keys between them
upArmConstOrient = cmds.orientConstraint(["fk_upperarm_" + side, "ik_upperarm_" + side], rollGrp, mo = True, skip = "x")[0]
cmds.setAttr("Rig_Settings." + side + "ArmMode", 0)
cmds.setAttr(upArmConstOrient + "." + "fk_upperarm_" + side + "W0", 1)
cmds.setAttr(upArmConstOrient + "." + "ik_upperarm_" + side + "W1", 0)
cmds.setDrivenKeyframe([upArmConstOrient + "." + "fk_upperarm_" + side + "W0", upArmConstOrient + "." + "ik_upperarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "ArmMode", 1)
cmds.setAttr(upArmConstOrient + "." + "fk_upperarm_" + side + "W0", 0)
cmds.setAttr(upArmConstOrient + "." + "ik_upperarm_" + side + "W1", 1)
cmds.setDrivenKeyframe([upArmConstOrient + "." + "fk_upperarm_" + side + "W0", upArmConstOrient + "." + "ik_upperarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "ArmMode", 0)
#parent end skin joint to masterGrp and orientConstrain twist to driver upper arm
cmds.parent(skinJoints[-1], rollGrp)
cmds.orientConstraint("driver_upperarm_" + side, skinJoints[-1], skip = ["y", "z"])
#parentConstraint master roll grp to driver clavicle
cmds.parentConstraint("driver_clavicle_" + side, masterGrp, mo = True)
#hook up driver joints
hairFollicles = sorted(hairFollicles)
hairFollicles = hairFollicles[::-1]
num = 1
for i in range(len(hairFollicles)):
if cmds.objExists("driver_upperarm_twist_0" + str(num) + "_" + side):
cmds.orientConstraint(skinJoints[i], "driver_upperarm_twist_0" + str(num) + "_" + side)
cmds.pointConstraint(skinJoints[i], "driver_upperarm_twist_0" + str(num) + "_" + side, mo = True)
cmds.scaleConstraint(skinJoints[i], "driver_upperarm_twist_0" + str(num) + "_" + side)
num = num + 1
#add attr on clavicle anim for manual twist control visibility
cmds.select("clavicle_" + side + "_anim")
cmds.addAttr(longName=("twistCtrlVis"), at = 'bool', dv = 0, keyable = True)
cmds.connectAttr("clavicle_" + side + "_anim.twistCtrlVis", rollGrp + ".v")
#hook up multiply nodes so that twistAmount values from rig settings affect the ribbon twist
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "UpperarmTwistAmount" ), defaultValue= .9, minValue= 0 , maxValue= 1, keyable = True)
#take twist ammount attr, multiply by -1, and feed into upperarm twist joint 1
multNodeA = cmds.shadingNode("multiplyDivide", asUtility = True, name = "upperarm_twist_" + side + "_multNodeA")
cmds.connectAttr("Rig_Settings." + side + "UpperarmTwistAmount", multNodeA+ ".input1X")
cmds.setAttr(multNodeA + ".input2X", -1)
multNodeB = cmds.shadingNode("multiplyDivide", asUtility = True, name = "upperarm_twist_" + side + "_multNodeB")
cmds.connectAttr(rollGrp + ".rx", multNodeB+ ".input1X")
cmds.connectAttr(multNodeA + ".outputX", multNodeB + ".input2X")
cmds.connectAttr(multNodeB + ".outputX", groups[0] + ".rx")
#any twist joints over the initial, setup simply mult nodes for carry down values
if numRolls > 1:
for i in range(int(numRolls)):
if i == 1:
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "UpperarmTwist2Amount" ), defaultValue=.5, minValue=0, maxValue=1, keyable = True)
#hook up multiply nodes so that twistAmount values from rig settings affect the ribbon twist
multNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "upperarm_twist2_" + side + "_multNode")
blendNode = cmds.shadingNode("blendColors", asUtility = True, name = "upperarm_twist2_" + side + "_multNode")
#hook up blendnode to take in fk and ik upperarm rx values
cmds.connectAttr( "ik_upperarm_" + side + ".rx", blendNode + ".color1R")
cmds.connectAttr( "fk_upperarm_" + side + ".rx", blendNode + ".color2R")
#take output of that and plug into multNode. multiply by the twist ammount attribute value
cmds.connectAttr(blendNode + ".outputR", multNode + ".input1X")
cmds.connectAttr("Rig_Settings." + side + "UpperarmTwist2Amount" , multNode + ".input2X")
cmds.connectAttr(multNode + ".outputX", groups[i] + ".rx")
#connect blendNode.blender to rig settings arm mode
cmds.connectAttr("Rig_Settings." + side + "ArmMode", blendNode + ".blender")
if i == 2:
cmds.select("Rig_Settings")
cmds.addAttr(longName= ( side + "UpperarmTwist3Amount" ), defaultValue=.5, minValue=0, maxValue=1, keyable = True)
#hook up multiply nodes so that twistAmount values from rig settings affect the ribbon twist
multNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "upperarm_twist3_" + side + "_multNode")
blendNode = cmds.shadingNode("blendColors", asUtility = True, name = "upperarm_twist3_" + side + "_multNode")
#hook up blendnode to take in fk and ik upperarm rx values
cmds.connectAttr( "ik_upperarm_" + side + ".rx", blendNode + ".color1R")
cmds.connectAttr( "fk_upperarm_" + side + ".rx", blendNode + ".color2R")
#take output of that and plug into multNode. multiply by the twist ammount attribute value
cmds.connectAttr(blendNode + ".outputR", multNode + ".input1X")
cmds.connectAttr("Rig_Settings." + side + "UpperarmTwist3Amount" , multNode + ".input2X")
cmds.connectAttr(multNode + ".outputX", groups[i] + ".rx")
#connect blendNode.blender to rig settings arm mode
cmds.connectAttr("Rig_Settings." + side + "ArmMode", blendNode + ".blender")
#Group up and parent into rig
twistGrp = cmds.group(empty = True, name = "upperarm_twist_grp_" + side)
cmds.parent([ribbon, hairSys, masterGrp], twistGrp)
#find follicles grp
for follicle in hairFollicles:
folliclesGrp = cmds.listRelatives(follicle, parent = True)
cmds.parent(folliclesGrp[0], twistGrp)
if cmds.objExists("nucleus1"):
cmds.parent("nucleus1", twistGrp)
#turn inherits transforms off
cmds.setAttr(folliclesGrp[0] + ".inheritsTransform", 0)
cmds.setAttr(ribbon + ".inheritsTransform", 0)
#hide nodes
for node in [folliclesGrp[0], ribbon, hairSys, skinJoints[0]]:
cmds.setAttr(node + ".v", 0)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildThighTwist(self, side):
if side == "l":
color = 5
sideName = "left"
else:
color = 12
sideName = "right"
#get the number of roll bones
data = cmds.getAttr("SkeletonSettings_Cache." + sideName + "LegOptions_numThighTwistBones")
numRolls = ast.literal_eval(data)[0]
#create our manual control curves and groups
groups = []
for i in range(numRolls):
if i == 0:
grpName = side + "_thigh_twist_01_driven_grp"
else:
grpName = side + "_thigh_twist_0" + str(i + 1) + "_driven_grp"
group = cmds.group(empty = True, name = grpName)
groups.append(group)
constraint = cmds.parentConstraint("driver_thigh_twist_0" + str(i+1) + "_" + side, group)[0]
cmds.delete(constraint)
for i in range(int(len(groups))):
grpName = groups[i].partition("_grp")[0]
grpName = grpName.replace("driven", "anim")
twistCtrl = utils.createControl("circle", 30, grpName)
cmds.setAttr(twistCtrl + ".ry", -90)
cmds.makeIdentity(twistCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(groups[i], twistCtrl)[0]
cmds.delete(constraint)
cmds.parent(twistCtrl, groups[i])
#clean up control
cmds.setAttr(twistCtrl + ".v", keyable = False)
cmds.setAttr(twistCtrl + ".overrideEnabled", 1)
cmds.setAttr(twistCtrl + ".overrideColor", color)
#constrain driver joint to twist joint
cmds.parentConstraint(twistCtrl, "driver_thigh_twist_0" + str(i+1) + "_" + side, mo = True)
#create ik twist bone chain
ikTwistUpper = cmds.createNode("joint", name = "thigh_twist_" + side + "_ik")
ikTwistLower = cmds.createNode("joint", name = "thigh_twist_" + side + "end_ik")
cmds.parent(ikTwistLower, ikTwistUpper)
#parent twist ik joints under result leg
cmds.parent(ikTwistUpper, "leg_joints_grp_" + side)
constraint = cmds.parentConstraint("result_leg_thigh_" + side, ikTwistUpper)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint("result_leg_calf_" + side, ikTwistLower)[0]
cmds.delete(constraint)
#add rp ik to those joints
twistIK = cmds.ikHandle(sol = "ikRPsolver", name = "thigh_twist_" + side + "_IK", sj = ikTwistUpper, ee = ikTwistLower)[0]
cmds.parent(twistIK, "result_leg_thigh_" + side)
ikWorldPos = cmds.xform(twistIK, q = True, ws = True, t = True)[0]
if ikWorldPos < 0:
cmds.setAttr(twistIK + ".twist", 180)
#create ik pole vector
twistVector = cmds.spaceLocator(name = "thight_twist_" + side + "_PoleVector")[0]
constraint = cmds.parentConstraint("result_leg_thigh_" + side, twistVector)[0]
cmds.delete(constraint)
cmds.parent(twistVector, "result_leg_thigh_" + side)
#create pole vector constraint
cmds.poleVectorConstraint(twistVector, twistIK)
#create roll locator (locator that actually will drive the roll amount)
rollLoc = cmds.spaceLocator(name = "thigh_twist_" + side + "_Tracker")[0]
constraint = cmds.parentConstraint("result_leg_thigh_" + side, rollLoc)[0]
cmds.delete(constraint)
cmds.parent(rollLoc, "leg_joints_grp_" + side)
cmds.makeIdentity(rollLoc, t = 0, r = 1, s = 0, apply = True)
cmds.orientConstraint("result_leg_thigh_" + side, rollLoc, skip = ["y", "z"])
#Group up and parent into rig
twistGrp = cmds.group(empty = True, name = "thigh_twist_grp_" + side)
#add twist grp to arm_sys_grp
cmds.parent(twistGrp, "leg_group_" + side)
for group in groups:
grpName = group.replace("driven", "anim")
animGrp = cmds.group(empty = True, name = grpName)
constraint = cmds.parentConstraint(group, animGrp)[0]
cmds.delete(constraint)
cmds.parent(group, animGrp)
cmds.parent(animGrp, twistGrp)
#constrain animGrp to driver upper arm
cmds.parentConstraint("result_leg_thigh_" + side, animGrp, mo = True)
#hook up multiply divide nodes
#first one takes rollLoc rotateX and multiplies it by -1 to get the counter
counterMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "thigh_twist_" + side + "_counterNode")
cmds.connectAttr(rollLoc + ".rotateX", counterMultNode + ".input1X")
cmds.setAttr(counterMultNode + ".input2X", -1)
#second one takes the output of the counterMultNode and multiplies it with the twist amount
for i in range(numRolls):
attrName = side + "ThighTwist" + str(i + 1) + "Amount"
grpName = side + "_thigh_twist_0" + str(i + 1) + "_driven_grp"
if i == 0:
cmds.addAttr("Rig_Settings", ln = side + "ThighTwistAmount", dv = 1, keyable = True)
attrName = side + "ThighTwistAmount"
grpName = side + "_thigh_twist_01_driven_grp"
else:
if i == 1:
dv = 0.6
if i == 2:
dv = 0.3
cmds.addAttr("Rig_Settings", ln = side + "ThighTwist" + str(i + 1) + "Amount", dv = dv, keyable = True)
#multNode creation
rollMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = side + "_thigh_rollNode")
cmds.connectAttr(counterMultNode + ".outputX", rollMultNode + ".input1X")
cmds.connectAttr("Rig_Settings." + attrName, rollMultNode + ".input2X")
#connect output of roll node to driven group
cmds.connectAttr(rollMultNode + ".outputX", grpName + ".rotateX")
#add attr on rig settings node for manual twist control visibility
cmds.select("Rig_Settings")
cmds.addAttr(longName=(side + "legTwistCtrlVis"), at = 'bool', dv = 0, keyable = True)
cmds.connectAttr("Rig_Settings." + side + "legTwistCtrlVis", twistGrp + ".v")
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildAutoHips(self):
hipWorld = cmds.group(empty = True, name = "auto_hip_world")
yzRot = cmds.group(empty = True, name = "auto_hip_yz_rot_solver")
xRot = cmds.group(empty = True, name = "auto_hip_x_rot_solver")
legSys = cmds.group(empty = True, name = "auto_hip_legs_system")
switchNode = cmds.spaceLocator(name = "auto_hip_on_off")[0]
hipRedirect = cmds.spaceLocator(name = "hip_ctrl_redirect")[0]
#hide locators
for node in [switchNode, hipRedirect]:
shape = cmds.listRelatives(node, children = True)[0]
try:
cmds.setAttr(shape + ".v", 0)
cmds.setAttr(shape + ".v", lock = True)
except:
pass
for node in [hipWorld, yzRot, xRot, legSys, switchNode, hipRedirect]:
constraint = cmds.parentConstraint("driver_pelvis", node)[0]
cmds.delete(constraint)
#setup hierarchy
cmds.parent("hip_anim", hipWorld)
cmds.parent([yzRot, xRot, legSys], "hip_anim")
cmds.parent(switchNode, yzRot)
cmds.parent(hipRedirect, switchNode)
#create the fk knee space locators
pelvisPos = cmds.xform("driver_pelvis", q = True, t = True, ws = True)
height = pelvisPos[2]
leftKneeLoc = cmds.spaceLocator(name = "auto_hips_knee_loc_l")[0]
rightKneeLoc = cmds.spaceLocator(name = "auto_hips_knee_loc_r")[0]
constraint = cmds.pointConstraint("ik_leg_calf_l", leftKneeLoc)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint("ik_leg_calf_r", rightKneeLoc)[0]
cmds.delete(constraint)
cmds.makeIdentity([leftKneeLoc, rightKneeLoc], t = 1, r = 1, s = 1, apply = True)
leftKneeLocConstraint = cmds.pointConstraint(["invis_legs_ik_leg_calf_l", "invis_legs_fk_calf_l_anim"], leftKneeLoc)[0]
rightKneeLocConstraint = cmds.pointConstraint(["invis_legs_ik_leg_calf_r","invis_legs_fk_calf_r_anim"], rightKneeLoc)[0]
leftTargets = cmds.pointConstraint(leftKneeLocConstraint, q = True, weightAliasList = True)
rightTargets = cmds.pointConstraint(rightKneeLocConstraint, q = True, weightAliasList = True)
cmds.setAttr(leftKneeLocConstraint + "." + leftTargets[1], 0)
cmds.setAttr(rightKneeLocConstraint + "." + rightTargets[1], 0)
#create the thigh locators for solving x (twist)
leftThighLoc = cmds.spaceLocator(name = "auto_hips_x_rot_solv_l")[0]
rightThighLoc = cmds.spaceLocator(name = "auto_hips_x_rot_solv_r")[0]
constraint = cmds.pointConstraint("driver_thigh_l", leftThighLoc)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint("driver_thigh_r", rightThighLoc)[0]
cmds.delete(constraint)
cmds.setAttr(leftThighLoc + ".tz", height)
cmds.setAttr(rightThighLoc + ".tz", height)
#create the x rotation solver joint chain
cmds.select(clear = True)
xRotJointStart = cmds.joint(name = "auto_hips_x_rot_solv_joint_start")
cmds.select(clear = True)
constraint = cmds.pointConstraint(leftThighLoc, xRotJointStart)[0]
cmds.delete(constraint)
constraint = cmds.orientConstraint("driver_pelvis", xRotJointStart)[0]
cmds.delete(constraint)
xRotJointEnd = cmds.duplicate(xRotJointStart, name = "auto_hips_x_rot_solv_joint_end")[0]
cmds.parent(xRotJointEnd, xRotJointStart)
cmds.xform(xRotJointEnd, ws = True, t = (pelvisPos[0], pelvisPos[1], pelvisPos[2]))
cmds.makeIdentity(xRotJointStart, r = 1, apply = True)
cmds.pointConstraint(leftThighLoc, xRotJointStart)
xRotIKNodes = cmds.ikHandle(sol = "ikSCsolver", name = "auto_hips_x_rot_solver_ik", sj = xRotJointStart, ee = xRotJointEnd)
cmds.pointConstraint(rightThighLoc, xRotIKNodes[0])
#hookup x rot solver
upAxis = self.getUpAxis("hip_anim")
cmds.connectAttr(xRotJointStart + ".rotate" + upAxis, legSys + ".rotate" + upAxis)
#hookup motion of thigh locators
rotXikHipL = cmds.spaceLocator(name = "auto_hips_ik_x_rot_solv_loc_l")[0]
rotXikHipR = cmds.spaceLocator(name = "auto_hips_ik_x_rot_solv_loc_r")[0]
constraint = cmds.pointConstraint("noflip_pv_loc_l", rotXikHipL)[0]
cmds.delete(constraint)
constraint = cmds.pointConstraint("noflip_pv_loc_r", rotXikHipR)[0]
cmds.delete(constraint)
cmds.pointConstraint(leftKneeLoc, leftThighLoc, mo = True, skip = ["x", "z"])
cmds.pointConstraint(rightKneeLoc, rightThighLoc, mo = True, skip = ["x", "z"])
#create the multiply node for our x rot solver node to halve the results
xRotMult = cmds.shadingNode("multiplyDivide", name = "auto_hips_x_rot_mult_node", asUtility = True)
cmds.connectAttr(legSys + ".rotate" + upAxis, xRotMult + ".input1X")
cmds.setAttr(xRotMult + ".input2X", .5)
cmds.connectAttr(xRotMult + ".outputX", xRot + ".rotate" + upAxis)
#create the joints for the yz rotations
cmds.select(clear = True)
yzRotStartJoint = cmds.joint(name = "auto_hips_yz_rot_solv_joint_start")
constraint = cmds.parentConstraint("driver_pelvis", yzRotStartJoint)[0]
cmds.delete(constraint)
yzRotEndJoint = cmds.duplicate(yzRotStartJoint, name = "auto_hips_yz_rot_solv_joint_end")[0]
cmds.parent(yzRotEndJoint, yzRotStartJoint)
cmds.setAttr(yzRotEndJoint + ".tx", (height/2)* -1)
cmds.makeIdentity(yzRotStartJoint, r = 1, apply = True)
yzRotikNodes = cmds.ikHandle(sol = "ikRPsolver", name = "auto_hips_yz_rot_solv_ik", sj = yzRotStartJoint, ee = yzRotEndJoint)
yzRotTargetLoc = cmds.spaceLocator(name = "auto_hips_yz_target_loc")[0]
constraint = cmds.pointConstraint([leftKneeLoc, rightKneeLoc], yzRotTargetLoc)[0]
cmds.delete(constraint)
cmds.makeIdentity(yzRotTargetLoc, t = 1, apply = True)
cmds.parent(yzRotikNodes[0], yzRotTargetLoc)
#setup motion for yz solver
cmds.pointConstraint([leftKneeLoc, rightKneeLoc], yzRotTargetLoc)
yzSolvConst = cmds.orientConstraint(yzRotStartJoint, yzRot)[0]
#setup distance tools for reducing popping when foot gets close to pelvis
cmds.select(clear = True)
yzRotFlipCtrlNodesL = cmds.duplicate("noflip_begin_joint_l", name = "auto_hips_dist_ctrl_begin_joint_l", rc = True)
yzRotFlipCtrlBeginL = yzRotFlipCtrlNodesL[0]
yzRotFlipCtrlEndL = cmds.rename(yzRotFlipCtrlNodesL[1], "auto_hips_dist_ctrl_end_joint_l")
#now for the right side
cmds.select(clear = True)
yzRotFlipCtrlNodesR = cmds.duplicate("noflip_begin_joint_r", name = "auto_hips_dist_ctrl_begin_joint_r", rc = True)
yzRotFlipCtrlBeginR = yzRotFlipCtrlNodesR[0]
yzRotFlipCtrlEndR = cmds.rename(yzRotFlipCtrlNodesR[1], "auto_hips_dist_ctrl_end_joint_r")
#setup the distance mover joint
distMoverL = cmds.duplicate(yzRotFlipCtrlEndL, name = "distance_mover_joint_l")[0]
distMoverR = cmds.duplicate(yzRotFlipCtrlEndR, name = "distance_mover_joint_r")[0]
cmds.pointConstraint("ik_foot_anim_l", distMoverL, mo = True)
cmds.pointConstraint("ik_foot_anim_r", distMoverR, mo = True)
#setup system for fixing flipping when foot gets too close to pelvis
originalLen = cmds.getAttr(yzRotFlipCtrlEndL + ".tz")
conditionNodeL = cmds.shadingNode("condition", asUtility = True, name = "autoHips_flipFix_condition_l")
conditionNodeR = cmds.shadingNode("condition", asUtility = True, name = "autoHips_flipFix_condition_r")
cmds.setAttr(conditionNodeL + ".secondTerm", originalLen)
cmds.setAttr(conditionNodeR + ".secondTerm", originalLen)
cmds.connectAttr(distMoverL + ".tz", conditionNodeL + ".firstTerm")
cmds.connectAttr(distMoverR + ".tz", conditionNodeR + ".firstTerm")
scaleFactor = self.getScaleFactor()
cmds.setAttr(conditionNodeL + ".operation", 2)
cmds.setAttr(conditionNodeR + ".operation", 2)
cmds.setAttr(conditionNodeL + ".colorIfFalseR", 0)
cmds.setAttr(conditionNodeR + ".colorIfFalseR", 0)
cmds.setAttr(conditionNodeL + ".colorIfTrueR", -60 * scaleFactor)
cmds.setAttr(conditionNodeR + ".colorIfTrueR", -60 * scaleFactor)
cmds.connectAttr(conditionNodeL + ".outColorR", "noflip_aim_soft_grp_l.tz")
cmds.connectAttr(conditionNodeR + ".outColorR", "noflip_aim_soft_grp_r.tz")
#hookup the hips to use the x and yz rot solver data
cmds.connectAttr(xRot + ".rotate" + upAxis, yzSolvConst + ".offset" + upAxis)
cmds.connectAttr("hip_anim.rotate", hipRedirect + ".rotate")
#orient constrain the on/off node to the world control and the yz rot solver
onOffConstraint = cmds.orientConstraint([hipWorld, yzSolvConst], switchNode)[0]
#add auto on/off attr to hip control. hookup connections to constraint
cmds.select("hip_anim")
cmds.addAttr(longName='autoHips', defaultValue=0, minValue=0, maxValue=1, keyable = True)
orientTargets = cmds.orientConstraint(onOffConstraint, q = True, weightAliasList = True)
cmds.connectAttr("hip_anim.autoHips", onOffConstraint + "." + orientTargets[1])
reverseNode = cmds.shadingNode("reverse", asUtility = True, name = "autoHips_reverse_node_onOff")
cmds.connectAttr("hip_anim.autoHips", reverseNode + ".inputX")
cmds.connectAttr(reverseNode + ".outputX", onOffConstraint + "." + orientTargets[0])
#plug the body anim's rotates into the onOffConstraint's offsets
bodyMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "autoHips_body_rotation_fix")
cmds.connectAttr("body_anim.rotateX", bodyMultNode + ".input1X")
cmds.connectAttr("body_anim.rotateY", bodyMultNode + ".input1Y")
cmds.connectAttr("body_anim.rotateZ", bodyMultNode + ".input1Z")
cmds.connectAttr("hip_anim.autoHips", bodyMultNode + ".input2X")
cmds.connectAttr("hip_anim.autoHips", bodyMultNode + ".input2Y")
cmds.connectAttr("hip_anim.autoHips", bodyMultNode + ".input2Z")
#cmds.connectAttr(bodyMultNode + ".outputX", onOffConstraint + ".offsetX")
#cmds.connectAttr(bodyMultNode + ".outputY", onOffConstraint + ".offsetY")
#cmds.connectAttr(bodyMultNode + ".outputZ", onOffConstraint + ".offsetZ")
#update invisible leg IK joints
cmds.setToolTo('moveSuperContext')
cmds.select("invis_legs_ik_leg_thigh_l", hi = True)
cmds.setToolTo('RotateSuperContext')
cmds.select(clear = True)
#constrain driver joint to control
cmds.parentConstraint(hipRedirect, "driver_pelvis", mo = True)
#parent hip world to body anim
cmds.parent(hipWorld, "body_anim")
#clean up hierarchy
autoHipsMasterGrp = cmds.group(empty = True, name = "autoHips_sys_grp")
cmds.parent([leftKneeLoc, rightKneeLoc, leftThighLoc, rightThighLoc, xRotJointStart, rotXikHipL, rotXikHipR, yzRotStartJoint,xRotIKNodes[0], yzRotTargetLoc], autoHipsMasterGrp)
#cosntrain ik leg bones(thighs) to the hip ctrl redirect
cmds.parentConstraint(hipRedirect, "leg_joints_grp_l", mo = True)
cmds.parentConstraint(hipRedirect, "leg_joints_grp_r", mo = True)
#parent the bottom of the spline ik spine bone to the hip redirect
if cmds.objExists("spine_splineIK_bottom_joint"):
cmds.parent("spine_splineIK_bottom_joint", hipRedirect)
#hide stuff
cmds.setAttr("autoHips_sys_grp.v", 0)
#hook up autohips to leg mode
reverseNodeL = "legSwitcher_reverse_node_l"
reverseNodeR = "legSwitcher_reverse_node_r"
targets = cmds.pointConstraint(leftKneeLocConstraint, q = True, weightAliasList = True)
cmds.connectAttr("Rig_Settings" + ".lLegMode", leftKneeLocConstraint + "." + targets[0])
cmds.connectAttr(reverseNodeL + ".outputX", leftKneeLocConstraint + "." + targets[1])
targets = cmds.pointConstraint(rightKneeLocConstraint, q = True, weightAliasList = True)
cmds.connectAttr("Rig_Settings" + ".rLegMode", rightKneeLocConstraint + "." + targets[0])
cmds.connectAttr(reverseNodeR + ".outputX", rightKneeLocConstraint + "." + targets[1])
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def autoSpine(self):
numSpineBones = cmds.getAttr("Skeleton_Settings.numSpineBones")
if numSpineBones > 2:
#drive the mid IK spine control based on what the upper spine control is doing
#drives the ik spine controls based on auto hip attr and hip motion
yzRotSolver = "auto_hip_yz_rot_solver"
midDriver = "mid_ik_anim_driver_grp"
midDriverTop = "mid_ik_anim_translate_driver_grp"
#add auto on/off attr to hip control. hookup connections to constraint
cmds.select("chest_ik_anim")
cmds.addAttr(longName='autoSpine', defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.addAttr(longName='rotationInfluence', defaultValue=.25, minValue=0, maxValue=1, keyable = True)
topCtrlMultRY = cmds.shadingNode("multiplyDivide", asUtility = True, name = "autoSpine_top_driver_mult_ry")
topCtrlMultRZ = cmds.shadingNode("multiplyDivide", asUtility = True, name = "autoSpine_top_driver_mult_rz")
topCtrlMultSwitchRY = cmds.shadingNode("multiplyDivide", asUtility = True, name = "autoSpine_top_mult_switch_ry")
topCtrlMultSwitchRZ = cmds.shadingNode("multiplyDivide", asUtility = True, name = "autoSpine_top_mult_switch_rz")
#create a node that will track all world space translations and rotations on the chest IK anim
chestMasterTrackNode = cmds.spaceLocator(name = "chest_ik_track_parent")[0]
constraint = cmds.parentConstraint("chest_ik_anim", chestMasterTrackNode)[0]
cmds.delete(constraint)
chestTrackNode = cmds.spaceLocator(name = "chest_ik_tracker")[0]
constraint = cmds.parentConstraint("chest_ik_anim", chestTrackNode)[0]
cmds.delete(constraint)
cmds.parent(chestTrackNode, chestMasterTrackNode)
cmds.parentConstraint("chest_ik_anim", chestTrackNode)
cmds.parent(chestMasterTrackNode, "body_anim")
#hide locator
cmds.setAttr(chestMasterTrackNode + ".v", 0)
#Rotate Y
cmds.connectAttr(chestTrackNode + ".ry", topCtrlMultRY + ".input1X")
cmds.connectAttr("chest_ik_anim.rotationInfluence", topCtrlMultRY + ".input2X")
cmds.connectAttr(topCtrlMultRY + ".outputX", topCtrlMultSwitchRY + ".input1X")
cmds.connectAttr("chest_ik_anim.autoSpine", topCtrlMultSwitchRY + ".input2X")
cmds.connectAttr(topCtrlMultSwitchRY + ".outputX", midDriver + ".tz")
#Rotate Z
multInverse = cmds.shadingNode("multiplyDivide", asUtility = True, name = "autoSpine_mult_rz_inverse")
cmds.connectAttr("chest_ik_anim.rotationInfluence", multInverse + ".input1X")
cmds.setAttr(multInverse + ".input2X", -1)
cmds.connectAttr(chestTrackNode + ".rz", topCtrlMultRZ + ".input1X")
cmds.connectAttr(multInverse + ".outputX", topCtrlMultRZ + ".input2X")
cmds.connectAttr(topCtrlMultRZ + ".outputX", topCtrlMultSwitchRZ + ".input1X")
cmds.connectAttr("chest_ik_anim.autoSpine", topCtrlMultSwitchRZ + ".input2X")
cmds.connectAttr(topCtrlMultSwitchRZ + ".outputX", midDriver + ".ty")
#Translate X
#Chest Control Translate X + Hip Control Translate X / 2 * autpSpine
autoSpineTXNode = cmds.shadingNode("plusMinusAverage", asUtility = True, name = midDriverTop + "_TX_Avg")
cmds.setAttr(autoSpineTXNode + ".operation", 3)
autoSpineTX_MultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = midDriverTop + "_TX_Mult")
cmds.connectAttr("chest_ik_anim.translateX", autoSpineTXNode + ".input1D[0]")
cmds.connectAttr("hip_anim.translateX", autoSpineTXNode + ".input1D[1]")
cmds.connectAttr(autoSpineTXNode + ".output1D", autoSpineTX_MultNode + ".input1X")
cmds.connectAttr("chest_ik_anim.autoSpine", autoSpineTX_MultNode + ".input2X")
cmds.connectAttr(autoSpineTX_MultNode + ".outputX", midDriverTop + ".translateX")
#Translate Y
autoSpineTYNode = cmds.shadingNode("plusMinusAverage", asUtility = True, name = midDriverTop + "_TY_Avg")
cmds.setAttr(autoSpineTYNode + ".operation", 3)
autoSpineTY_MultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = midDriverTop + "_TY_Mult")
cmds.connectAttr(chestTrackNode + ".translateY", autoSpineTYNode + ".input1D[0]")
cmds.connectAttr("hip_anim.translateY", autoSpineTYNode + ".input1D[1]")
cmds.connectAttr(autoSpineTYNode + ".output1D", autoSpineTY_MultNode + ".input1X")
cmds.connectAttr("chest_ik_anim.autoSpine", autoSpineTY_MultNode + ".input2X")
cmds.connectAttr(autoSpineTY_MultNode + ".outputX", midDriverTop + ".translateY")
#Translate Z
autoSpineTZNode = cmds.shadingNode("plusMinusAverage", asUtility = True, name = midDriverTop + "_TZ_Avg")
cmds.setAttr(autoSpineTZNode + ".operation", 3)
autoSpineTZ_MultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = midDriverTop + "_TZ_Mult")
cmds.connectAttr(chestTrackNode + ".translateZ", autoSpineTZNode + ".input1D[0]")
cmds.connectAttr("hip_anim.translateZ", autoSpineTZNode + ".input1D[1]")
cmds.connectAttr(autoSpineTZNode + ".output1D", autoSpineTZ_MultNode + ".input1X")
cmds.connectAttr("chest_ik_anim.autoSpine", autoSpineTZ_MultNode + ".input2X")
cmds.connectAttr(autoSpineTZ_MultNode + ".outputX", midDriverTop + ".translateZ")
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def hookupSpine(self, ikControls, fkControls):
#constrain the driver joints to the FK and IK controls
i = 0
upAxis = "X"
for joint in ikControls:
driverJoint = joint.partition("splineIK_")[2]
driverJoint = "driver_" + driverJoint
if joint == ikControls[0]:
upAxis = self.getUpAxis(driverJoint)
if upAxis == "X":
axisB = "Y"
axisC = "Z"
if upAxis == "Y":
axisB = "X"
axisC = "Z"
if upAxis == "Z":
axisB = "X"
axisC = "Y"
twistJoint = "twist_" + joint
cmds.parentConstraint([twistJoint, fkControls[i]], driverJoint, mo = True)
cmds.scaleConstraint([twistJoint, fkControls[i]], driverJoint, mo = True)
scaleDriverJoint = driverJoint
if joint != ikControls[len(ikControls) - 1] and joint != ikControls[0]:
twistJoint = "twist_" + joint
cmds.parentConstraint([twistJoint, fkControls[i]], driverJoint, mo = True)
#create blendColors nodes for scale
blenderNodeScale = cmds.shadingNode("blendColors", asUtility = True, name = driverJoint + "_blenderNodeScale")
cmds.connectAttr(twistJoint + ".scale" + axisB, blenderNodeScale + ".color1R")
cmds.connectAttr(fkControls[i] + ".scale" + axisB, blenderNodeScale + ".color2R")
cmds.connectAttr(twistJoint + ".scale" + axisC, blenderNodeScale + ".color1G")
cmds.connectAttr(fkControls[i] + ".scale" + axisC, blenderNodeScale + ".color2G")
cmds.connectAttr(blenderNodeScale + ".outputR", driverJoint + ".scale" + axisB)
cmds.connectAttr(blenderNodeScale + ".outputG", driverJoint + ".scale" + axisC)
if joint == ikControls[len(ikControls) - 1]:
topJoint = "spine_splineIK_top_joint"
twistJoint = "twist_" + joint
cmds.orientConstraint([topJoint, fkControls[i]], driverJoint, mo = True)
cmds.pointConstraint([twistJoint, fkControls[i]], driverJoint, mo = True)
i = i + 1
#add attributes to the Rig_Settings node
cmds.select("Rig_Settings")
cmds.addAttr(longName='spine_ik', defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.addAttr(longName='spine_fk', defaultValue=0, minValue=0, maxValue=1, keyable = True)
#hookup Rig_Settings attrs to the parentConstraint weights
#find connection targets
for ctrl in ikControls:
driverJoint = ctrl.partition("splineIK_")[2]
driverJoint = "driver_" + driverJoint
constraint = driverJoint + "_parentConstraint1"
#hook up blendColors scale node
try:
blenderNodeScale = driverJoint + "_blenderNodeScale"
cmds.connectAttr("Rig_Settings" + ".spine_ik", blenderNodeScale + ".blender")
except:
pass
if cmds.objExists(constraint):
targets = cmds.parentConstraint(constraint, q = True, weightAliasList = True)
for target in targets:
if target.find("IK") != -1:
cmds.connectAttr("Rig_Settings" + ".spine_ik", constraint + "." + target)
else:
cmds.connectAttr("Rig_Settings" + ".spine_fk", constraint + "." + target)
else:
pointConstraint = driverJoint + "_pointConstraint1"
orientConstraint = driverJoint + "_orientConstraint1"
pointTargets = cmds.pointConstraint(pointConstraint, q = True, weightAliasList = True)
orientTargets = cmds.orientConstraint(orientConstraint, q = True, weightAliasList = True)
for target in pointTargets:
if target.find("IK") != -1:
cmds.connectAttr("Rig_Settings" + ".spine_ik", pointConstraint + "." + target)
else:
cmds.connectAttr("Rig_Settings" + ".spine_fk", pointConstraint + "." + target)
for target in orientTargets:
if target.find("IK") != -1:
cmds.connectAttr("Rig_Settings" + ".spine_ik", orientConstraint + "." + target)
else:
cmds.connectAttr("Rig_Settings" + ".spine_fk", orientConstraint + "." + target)
#hook up spine control vis to the rig settings
cmds.connectAttr("Rig_Settings" + ".spine_fk", "spine_01_anim_grp.v")
cmds.connectAttr("Rig_Settings" + ".spine_ik", "mid_ik_anim_grp.v")
cmds.connectAttr("Rig_Settings" + ".spine_ik", "chest_ik_anim_grp.v")
#set spine rig to be IK by default
cmds.setAttr("Rig_Settings" + ".spine_ik", 1)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildFKArms(self):
#duplicate our driver joints to create our FK arm skeleton
for side in ["l", "r"]:
#if the side has an arm, create the fk joints
if cmds.objExists("driver_upperarm_" + side):
autoClavJointStart = cmds.duplicate("driver_clavicle_" + side, po = True, name = "auto_clavicle_" + side)[0]
clavJoint = cmds.duplicate("driver_clavicle_" + side, po = True, name = "rig_clavicle_" + side)[0]
fkArmJoint = cmds.duplicate("driver_upperarm_" + side, po = True, name = "fk_upperarm_" + side)[0]
fkElbowJoint = cmds.duplicate("driver_lowerarm_" + side, po = True, name = "fk_lowerarm_" + side)[0]
fkWristJoint = cmds.duplicate("driver_hand_" + side, po = True, name = "fk_hand_" + side)[0]
#parent the fk upperarm to the world
parent = cmds.listRelatives(clavJoint, parent = True)
if parent != None:
cmds.parent(clavJoint, world = True)
#recreate the fk arm hierarchy
cmds.parent(fkArmJoint, clavJoint)
cmds.parent(fkElbowJoint, fkArmJoint)
cmds.parent(fkWristJoint, fkElbowJoint)
cmds.makeIdentity(fkArmJoint, t = 0, r = 1, s = 0, apply = True)
#set rotation order on fk arm joint
cmds.setAttr(fkArmJoint + ".rotateOrder", 3)
#create the shoulder hierarchy
parent = cmds.listRelatives(autoClavJointStart, parent = True)
if parent != None:
cmds.parent(autoClavJointStart, world = True)
autoClavEndJoint = cmds.duplicate(fkArmJoint, parentOnly = True, name = "auto_clavicle_end_" + side)[0]
pos = cmds.xform(autoClavEndJoint, q = True, ws = True, t = True)
zPos = cmds.xform(autoClavJointStart, q = True, ws = True, t = True)[2]
cmds.xform(autoClavEndJoint, ws = True, t = [pos[0], pos[1], zPos])
cmds.parent(autoClavEndJoint, autoClavJointStart)
#create the IK for the clavicle
ikNodes = cmds.ikHandle(sj = autoClavJointStart, ee = autoClavEndJoint, sol = "ikSCsolver", name = "auto_clav_to_elbow_ikHandle_" + side)[0]
#position the IK handle at the elbow joint
constraint = cmds.pointConstraint(fkElbowJoint, ikNodes)[0]
cmds.delete(constraint)
#create our autoClav world grp
autoClavWorld = cmds.group(empty = True, name = "auto_clav_world_grp_" + side)
constraint = cmds.pointConstraint(autoClavEndJoint, autoClavWorld)[0]
cmds.delete(constraint)
cmds.makeIdentity(autoClavWorld, t = 1, r = 1, s = 1, apply = True)
#duplicate the FK arm to create our invisible arm
invisUpArm = cmds.duplicate(fkArmJoint, po = True, name = "invis_upperarm_" + side)[0]
invisLowArm = cmds.duplicate(fkElbowJoint, po = True, name = "invis_lowerarm_" + side)[0]
invisHand = cmds.duplicate(fkWristJoint, po = True, name = "invis_hand_" + side)[0]
cmds.parent(invisHand, invisLowArm)
cmds.parent(invisLowArm, invisUpArm)
cmds.parent(invisUpArm, autoClavWorld)
#create our upperarm orient locator
invisArmOrient = cmds.spaceLocator(name = "invis_arm_orient_loc_" + side)[0]
invisArmOrientGrp = cmds.group(empty = True, name = "invis_arm_orient_loc_grp_" + side)
constraint = cmds.parentConstraint(fkArmJoint, invisArmOrient)[0]
cmds.delete(constraint)
constraint = cmds.parentConstraint(fkArmJoint, invisArmOrientGrp)[0]
cmds.delete(constraint)
cmds.parent(invisArmOrient, invisArmOrientGrp)
#create the invis arm fk control (to derive autoClav info)
invisFkArmCtrl = self.createControl("circle", 20, "invis_fk_arm_" + side + "_anim")
cmds.setAttr(invisFkArmCtrl + ".ry", -90)
cmds.makeIdentity(invisFkArmCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(fkArmJoint, invisFkArmCtrl)[0]
cmds.delete(constraint)
invisFkArmCtrlGrp = cmds.group(empty = True, name = "invis_fk_arm_" + side + "_grp")
constraint = cmds.parentConstraint(fkArmJoint, invisFkArmCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(invisFkArmCtrl, invisFkArmCtrlGrp)
#position the arm FK control so that it is about halfway down the arm length
dist = (cmds.getAttr(fkElbowJoint + ".tx")) / 2
cmds.setAttr(invisFkArmCtrl + ".translateX", dist)
#set the pivot of the arm control back to the arm joint
piv = cmds.xform(fkArmJoint, q = True, ws = True, rotatePivot = True)
cmds.xform(invisFkArmCtrl, ws = True, piv = [piv[0], piv[1], piv[2]])
#freeze transforms on the control
cmds.makeIdentity(invisFkArmCtrl, t = 1, r = 1, s = 1, apply = True)
#parent the orient arm grp to the fk ctrl
cmds.parent(invisArmOrientGrp, invisFkArmCtrl)
#duplicate the invis arm fk control setup for the real fk control(upper arm)
dupeNodes = cmds.duplicate(invisFkArmCtrlGrp, rc = True)
for node in dupeNodes:
name = node.partition("invis_")[2]
if name.find("1") != -1:
name = name.partition("1")[0]
cmds.rename(node, name)
#orient constrain the invis fk up arm to the invis up arm orient loc. Also do this for the real arm
cmds.orientConstraint(invisArmOrient, invisUpArm)
cmds.orientConstraint("arm_orient_loc_" + side, fkArmJoint)
#connect invis arm ctrl rotates to be driven by real arm control rotates
cmds.connectAttr("fk_arm_" + side + "_anim.rotate", invisFkArmCtrl + ".rotate")
#the following section of code will essentially give us a vector from the clav joint to the elbow. This will help to drive the rotations of the auto clav
#create our locators to determine elbow's position in space (will drive the ik handle on the auto clav)
autoTransLoc = cmds.spaceLocator(name = "elbow_auto_trans_loc_" + side)[0]
constraint = cmds.pointConstraint(fkElbowJoint, autoTransLoc)[0]
cmds.delete(constraint)
#duplicate the locator to create a parent loc
autoTransLocParent = cmds.duplicate(autoTransLoc, po = True, name = "elbow_auto_trans_loc_parent_" + side)[0]
cmds.pointConstraint(autoTransLoc, ikNodes)
cmds.parent(autoTransLoc, autoTransLocParent)
cmds.parent(autoTransLocParent, autoClavWorld)
cmds.makeIdentity(autoTransLocParent, t = 1, r = 1, s = 1, apply = True)
#constrain the parent trans loc(elbow) to the invis elbow joint
cmds.pointConstraint(invisLowArm, autoTransLocParent, mo = True)
#create our locator that will handle switching between auto clav and manual clav. position at end joint (autoClavEndJoint)
autoClavSwitchLoc = cmds.spaceLocator(name = "auto_clav_switch_loc_" + side)[0]
constraint = cmds.pointConstraint(autoClavEndJoint, autoClavSwitchLoc)[0]
cmds.delete(constraint)
cmds.parent(autoClavSwitchLoc, autoClavWorld)
cmds.makeIdentity(autoClavSwitchLoc, t = 1, r = 1, s = 1, apply = True)
cmds.parent(autoClavJointStart, autoClavWorld)
#setup constraint for switching between auto/manual
autoClavSwitchConstraint = cmds.pointConstraint([autoClavEndJoint, autoClavWorld], autoClavSwitchLoc, mo = True)[0]
cmds.setAttr(autoClavSwitchConstraint + "." + autoClavWorld + "W1", 0)
#create our IK for the auto clav to move
autoClavIK = cmds.ikHandle(sj = clavJoint, ee = fkArmJoint, sol = "ikSCsolver", name = "auto_clav_ikHandle_" + side)[0]
autoClavIKGrp = cmds.group(empty = True, name = "auto_clav_ikHandle_grp_" + side)
constraint = cmds.pointConstraint(autoClavIK, autoClavIKGrp)[0]
cmds.delete(constraint)
autoClavIKGrpMaster = cmds.duplicate(po = True, name = "auto_clav_ikHandle_grp_master_" + side)[0]
cmds.parent(autoClavIKGrpMaster, autoClavSwitchLoc)
cmds.parent(autoClavIKGrp, autoClavIKGrpMaster)
cmds.parent(autoClavIK, autoClavIKGrp)
#cmds.makeIdentity(autoClavIKGrp, t = 1, r = 1, s = 1, apply = True)
#create the shoulder control
shoulderCtrl = self.createControl("pin", 1.5, "clavicle_" + side + "_anim")
cmds.setAttr(shoulderCtrl + ".ry", 90)
cmds.setAttr(shoulderCtrl + ".rx", 90)
constraint = cmds.pointConstraint(fkArmJoint, shoulderCtrl)[0]
cmds.delete(constraint)
shoulderCtrlGrp = cmds.group(empty = True, name = "clavicle_" + side + "_anim_grp")
constraint = cmds.pointConstraint(fkArmJoint, shoulderCtrl)[0]
cmds.delete(constraint)
cmds.parent(shoulderCtrl, shoulderCtrlGrp)
cmds.parent(shoulderCtrlGrp, autoClavWorld)
cmds.makeIdentity(shoulderCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.setAttr(shoulderCtrl + ".sx", .65)
cmds.setAttr(shoulderCtrl + ".sy", 1.2)
cmds.setAttr(shoulderCtrl + ".sz", 1.2)
cmds.makeIdentity(shoulderCtrl, t = 1, r = 1, s = 1, apply = True)
#connect shoulder ctrl translate to the autoClavIKGrp translate
cmds.connectAttr(shoulderCtrl + ".translate", autoClavIKGrp + ".translate")
cmds.connectAttr(autoClavSwitchLoc + ".translate", shoulderCtrl + ".rotatePivotTranslate")
#set limits on shoulder control
cmds.select(shoulderCtrl)
if side == "l":
cmds.transformLimits(tx = (-1,0), etx = (False, True))
else:
cmds.transformLimits(tx = (0,1), etx = (True, False))
#create FK elbow control
fkElbowCtrl = self.createControl("circle", 18, "fk_elbow_" + side + "_anim")
cmds.setAttr(fkElbowCtrl + ".ry", -90)
cmds.makeIdentity(fkElbowCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(fkElbowJoint, fkElbowCtrl)[0]
cmds.delete(constraint)
fkElbowCtrlGrp = cmds.group(empty = True, name = "fk_elbow_" + side + "_anim_grp")
constraint = cmds.parentConstraint(fkElbowJoint, fkElbowCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(fkElbowCtrl, fkElbowCtrlGrp)
cmds.makeIdentity(fkElbowCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.parent(fkElbowCtrlGrp, "fk_arm_" + side + "_anim")
#constrain elbow joint to ctrl
cmds.parentConstraint(fkElbowCtrl, fkElbowJoint)
#create FK wrist control
fkWristCtrl = self.createControl("circle", 15, "fk_wrist_" + side + "_anim")
cmds.setAttr(fkWristCtrl + ".ry", -90)
cmds.makeIdentity(fkWristCtrl, r = 1, apply =True)
constraint = cmds.parentConstraint(fkWristJoint, fkWristCtrl)[0]
cmds.delete(constraint)
fkWristCtrlGrp = cmds.group(empty = True, name = "fk_wrist_" + side + "_anim_grp")
constraint = cmds.parentConstraint(fkWristJoint, fkWristCtrlGrp)[0]
cmds.delete(constraint)
cmds.parent(fkWristCtrl, fkWristCtrlGrp)
cmds.makeIdentity(fkWristCtrl, t = 1, r = 1, s = 1, apply = True)
cmds.parent(fkWristCtrlGrp, fkElbowCtrl)
#constrain wrist joint to ctrl
cmds.parentConstraint(fkWristCtrl, fkWristJoint)
#point constrain the fk arm grp to the fk upper arm joint
cmds.pointConstraint(fkArmJoint, "fk_arm_" + side + "_grp")
#clean up FK rig in scene
cmds.parent(invisFkArmCtrlGrp, autoClavWorld)
#find children under autoClavWorld
children = cmds.listRelatives(autoClavWorld, children = True)
dntGrp = cmds.group(empty = True, name = "auto_clav_sys_grp_" + side)
cmds.parent(dntGrp, autoClavWorld)
for child in children:
cmds.parent(child, dntGrp)
cmds.parent(shoulderCtrlGrp, autoClavWorld)
#group up the groups!
jointsGrp = cmds.group(empty = True, name = "joints_" + side + "_grp")
cmds.parent(clavJoint, jointsGrp)
masterGrp = cmds.group(empty = True, name = "arm_rig_master_grp_" + side)
constraint = cmds.pointConstraint(fkArmJoint, masterGrp)[0]
cmds.delete(constraint)
cmds.parent([ikNodes, jointsGrp, autoClavWorld], masterGrp)
cmds.setAttr(dntGrp + ".v", 0)
cmds.setAttr(ikNodes + ".v", 0)
#add fk orientation options(normal, body, world)
fkOrient = cmds.spaceLocator(name = "fk_orient_master_loc_" + side)[0]
shape = cmds.listRelatives(fkOrient, shapes = True)[0]
cmds.setAttr(shape + ".v", 0)
constraint = cmds.parentConstraint(autoClavWorld, fkOrient)[0]
cmds.delete(constraint)
fkNormalOrient = cmds.duplicate(fkOrient, po = True, name = "fk_orient_normal_loc_" + side)[0]
fkBodyOrient = cmds.duplicate(fkOrient, po = True, name = "fk_orient_body_loc_" + side)[0]
fkWorldOrient = cmds.duplicate(fkOrient, po = True, name = "fk_orient_world_loc_" + side)[0]
fkOrientConstraint = cmds.orientConstraint([fkNormalOrient, fkBodyOrient, fkWorldOrient], fkOrient)[0]
cmds.parent(fkBodyOrient, "body_anim")
cmds.parent(fkNormalOrient, shoulderCtrl)
cmds.parent(fkOrient, masterGrp)
#parent FK arm ctrl grp to shoulder ctrl
cmds.parent("fk_arm_" + side + "_grp", fkOrient)
#put mode into default fk operation
cmds.setAttr(fkOrientConstraint + "." + fkBodyOrient + "W1", 0)
cmds.setAttr(fkOrientConstraint + "." + fkWorldOrient + "W2", 0)
#get the number of spine bones and constrain the master grp to the last spine joint
numSpineBones = self.getSpineJoints()
cmds.parentConstraint("driver_spine_0" + str(len(numSpineBones)), masterGrp, mo = True)
#setup autoShoulder attr
cmds.select(shoulderCtrl)
cmds.addAttr(longName='autoShoulders', defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.setAttr(shoulderCtrl + ".autoShoulders", 0)
cmds.setAttr(autoClavSwitchConstraint + "." + autoClavEndJoint + "W0", 0)
cmds.setAttr(autoClavSwitchConstraint + "." + autoClavWorld + "W1", 1)
cmds.setDrivenKeyframe([autoClavSwitchConstraint + "." + autoClavEndJoint + "W0", autoClavSwitchConstraint + "." + autoClavWorld + "W1"], cd = shoulderCtrl + ".autoShoulders", itt = "linear", ott = "linear")
cmds.setAttr(shoulderCtrl + ".autoShoulders", 1)
cmds.setAttr(autoClavSwitchConstraint + "." + autoClavEndJoint + "W0", 1)
cmds.setAttr(autoClavSwitchConstraint + "." + autoClavWorld + "W1", 0)
cmds.setDrivenKeyframe([autoClavSwitchConstraint + "." + autoClavEndJoint + "W0", autoClavSwitchConstraint + "." + autoClavWorld + "W1"], cd = shoulderCtrl + ".autoShoulders", itt = "linear", ott = "linear")
cmds.setAttr(shoulderCtrl + ".autoShoulders", 0)
#setup FK arm orient attr
cmds.select("Rig_Settings")
cmds.addAttr(longName= side + "FkArmOrient", at = 'enum', en = "fk:body:world:", keyable = True)
cmds.setAttr("Rig_Settings." + side + "FkArmOrient", 0)
cmds.setAttr(fkOrientConstraint + "." + fkNormalOrient + "W0", 1)
cmds.setAttr(fkOrientConstraint + "." + fkBodyOrient + "W1", 0)
cmds.setAttr(fkOrientConstraint + "." + fkWorldOrient + "W2", 0)
cmds.setDrivenKeyframe([fkOrientConstraint + "." + fkNormalOrient + "W0", fkOrientConstraint + "." + fkBodyOrient + "W1", fkOrientConstraint + "." + fkWorldOrient + "W2"], cd = "Rig_Settings." + side + "FkArmOrient", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "FkArmOrient", 1)
cmds.setAttr(fkOrientConstraint + "." + fkNormalOrient + "W0", 0)
cmds.setAttr(fkOrientConstraint + "." + fkBodyOrient + "W1", 1)
cmds.setAttr(fkOrientConstraint + "." + fkWorldOrient + "W2", 0)
cmds.setDrivenKeyframe([fkOrientConstraint + "." + fkNormalOrient + "W0", fkOrientConstraint + "." + fkBodyOrient + "W1", fkOrientConstraint + "." + fkWorldOrient + "W2"], cd = "Rig_Settings." + side + "FkArmOrient", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "FkArmOrient", 2)
cmds.setAttr(fkOrientConstraint + "." + fkNormalOrient + "W0", 0)
cmds.setAttr(fkOrientConstraint + "." + fkBodyOrient + "W1", 0)
cmds.setAttr(fkOrientConstraint + "." + fkWorldOrient + "W2", 1)
cmds.setDrivenKeyframe([fkOrientConstraint + "." + fkNormalOrient + "W0", fkOrientConstraint + "." + fkBodyOrient + "W1", fkOrientConstraint + "." + fkWorldOrient + "W2"], cd = "Rig_Settings." + side + "FkArmOrient", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "FkArmOrient", 0)
#setup limits on auto clavicle
cmds.setAttr(shoulderCtrl + ".autoShoulders", 1)
#cmds.setAttr("fk_arm_" + side + "_anim.ry", -60)
#grrr. need to force update since maya is not getting the info correctly
cmds.select("fk_arm_" + side + "_anim")
cmds.setToolTo( 'moveSuperContext' )
cmds.refresh(force = True)
cmds.select(clear = True)
#limitInfo = cmds.xform(autoClavSwitchLoc, q = True, t = True)
#cmds.setAttr("fk_arm_" + side + "_anim.ry", 0)
cmds.setAttr(shoulderCtrl + ".autoShoulders", 0)
cmds.select("fk_arm_" + side + "_anim")
cmds.setToolTo( 'moveSuperContext' )
cmds.refresh(force = True)
cmds.select(clear = True)
#lock attrs that should not be animated and colorize controls
for control in [shoulderCtrl, "fk_arm_" + side + "_anim", fkElbowCtrl, fkWristCtrl]:
if control == shoulderCtrl:
for attr in [".rx", ".ry", ".rz", ".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
else:
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
#parent fkWorldOrient to master anim
cmds.parent(fkWorldOrient, "master_anim")
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildIkArms(self):
#duplicate the fk arm joints and create our ik arm chain
for side in ["l", "r"]:
if cmds.objExists("fk_upperarm_" + side):
ikUpArmJoint = cmds.duplicate("fk_upperarm_" + side, po = True, name = "ik_upperarm_" + side)[0]
ikLowArmJoint = cmds.duplicate("fk_lowerarm_" + side, po = True, name = "ik_lowerarm_" + side)[0]
ikWristJoint = cmds.duplicate("fk_hand_" + side, po = True, name = "ik_hand_" + side)[0]
ikWristEndJoint = cmds.duplicate("fk_hand_" + side, po = True, name = "ik_hand_end_" + side)[0]
cmds.parent([ikWristEndJoint], ikWristJoint)
cmds.parent(ikWristJoint, ikLowArmJoint)
cmds.parent(ikLowArmJoint, ikUpArmJoint)
#create fk matching joints
fkMatchUpArm = cmds.duplicate(ikUpArmJoint, po = True, name = "ik_upperarm_fk_matcher_" + side)[0]
fkMatchLowArm = cmds.duplicate(ikLowArmJoint, po = True, name = "ik_lowerarm_fk_matcher_" + side)[0]
fkMatchWrist = cmds.duplicate(ikWristJoint, po = True, name = "ik_wrist_fk_matcher_" + side)[0]
cmds.parent(fkMatchWrist, fkMatchLowArm)
cmds.parent(fkMatchLowArm, fkMatchUpArm)
cmds.parentConstraint(ikUpArmJoint, fkMatchUpArm, mo = True)
cmds.parentConstraint(ikLowArmJoint, fkMatchLowArm, mo = True)
cmds.parentConstraint(ikWristJoint, fkMatchWrist, mo = True)
#move wrist end joint out a bit
scaleFactor = self.getScaleFactor()
if side == "l":
cmds.setAttr(ikWristEndJoint + ".tx", 15 * scaleFactor)
else:
cmds.setAttr(ikWristEndJoint + ".tx", -15 * scaleFactor)
cmds.makeIdentity(ikUpArmJoint, t = 0, r = 1, s = 0, apply = True)
#set rotate order on ikUpArm
cmds.setAttr(ikUpArmJoint + ".rotateOrder", 3)
#set preferred angle on arm
cmds.setAttr(ikLowArmJoint + ".preferredAngleZ", -90)
#create ik control
ikCtrl = self.createControl("circle", 15, "ik_wrist_" + side + "_anim")
cmds.setAttr(ikCtrl + ".ry", -90)
cmds.makeIdentity(ikCtrl, r = 1, apply =True)
constraint = cmds.pointConstraint(ikWristJoint, ikCtrl)[0]
cmds.delete(constraint)
ikCtrlGrp = cmds.group(empty = True, name = "ik_wrist_" + side + "_anim_grp")
constraint = cmds.pointConstraint(ikWristJoint, ikCtrlGrp)[0]
cmds.delete(constraint)
ikCtrlSpaceSwitchFollow = cmds.duplicate(ikCtrlGrp, po = True, n = "ik_wrist_" + side + "_anim_space_switcher_follow")[0]
ikCtrlSpaceSwitch = cmds.duplicate(ikCtrlGrp, po = True, n = "ik_wrist_" + side + "_anim_space_switcher")[0]
cmds.parent(ikCtrlSpaceSwitch, ikCtrlSpaceSwitchFollow)
cmds.parent(ikCtrlGrp, ikCtrlSpaceSwitch)
cmds.parent(ikCtrl, ikCtrlGrp)
cmds.makeIdentity(ikCtrlGrp, t = 1, r = 1, s = 1, apply = True)
#create RP IK on arm and SC ik from wrist to wrist end
rpIkHandle = cmds.ikHandle(name = "arm_ikHandle_" + side, solver = "ikRPsolver", sj = ikUpArmJoint, ee = ikWristJoint)[0]
scIkHandle = cmds.ikHandle(name = "hand_ikHandle_" + side, solver = "ikSCsolver", sj = ikWristJoint, ee = ikWristEndJoint)[0]
cmds.parent(scIkHandle, rpIkHandle)
cmds.setAttr(rpIkHandle + ".v", 0)
cmds.setAttr(scIkHandle + ".v", 0)
#parent IK to ik control
cmds.parent(rpIkHandle, ikCtrl)
#create a pole vector control
ikPvCtrl = self.createControl("sphere", 6, "ik_elbow_" + side + "_anim")
constraint = cmds.pointConstraint(ikLowArmJoint, ikPvCtrl)[0]
cmds.delete(constraint)
cmds.makeIdentity(ikPvCtrl, t = 1, r = 1, s = 1, apply = True)
#move out a bit
cmds.setAttr(ikPvCtrl + ".ty", (30 * scaleFactor))
cmds.makeIdentity(ikPvCtrl, t = 1, r = 1, s = 1, apply = True)
#create group for control
ikPvCtrlGrp = cmds.group(empty = True, name = "ik_elbow_" + side + "_anim_grp")
constraint = cmds.parentConstraint(ikPvCtrl, ikPvCtrlGrp)[0]
cmds.delete(constraint)
ikPvSpaceSwitchFollow = cmds.duplicate(ikPvCtrlGrp, po = True, name = "ik_elbow_" + side + "_anim_space_switcher_follow")[0]
ikPvSpaceSwitch = cmds.duplicate(ikPvCtrlGrp, po = True, name = "ik_elbow_" + side + "_anim_space_switcher")[0]
cmds.parent(ikPvSpaceSwitch, ikPvSpaceSwitchFollow)
cmds.parent(ikPvCtrlGrp, ikPvSpaceSwitch)
cmds.parent(ikPvCtrl, ikPvCtrlGrp)
cmds.parent(ikPvSpaceSwitchFollow, "offset_anim")
cmds.makeIdentity(ikPvCtrl, t = 1, r = 1, s = 1, apply = True)
#setup pole vector constraint
cmds.poleVectorConstraint(ikPvCtrl, rpIkHandle)
#create IK for invisible arm
invisRpIkHandle = cmds.ikHandle(name = "invis_arm_ikHandle_" + side, solver = "ikRPsolver", sj = "invis_upperarm_" + side, ee = "invis_hand_" + side)[0]
cmds.parent(invisRpIkHandle, ikCtrl)
cmds.poleVectorConstraint(ikPvCtrl, invisRpIkHandle)
cmds.setAttr(invisRpIkHandle + ".v", 0)
#constrain driver joints to both fk and ik chains
cmds.parentConstraint("rig_clavicle_" + side, "driver_clavicle_" + side, mo = True)
upArmConstPoint = cmds.pointConstraint(["fk_arm_" + side + "_anim", "ik_upperarm_" + side], "driver_upperarm_" + side)[0]
upArmConstOrient = cmds.orientConstraint(["fk_upperarm_" + side, "ik_upperarm_" + side], "driver_upperarm_" + side)[0]
lowArmConst = cmds.parentConstraint(["fk_lowerarm_" + side, "ik_lowerarm_" + side], "driver_lowerarm_" + side)[0]
handConst = cmds.parentConstraint(["fk_hand_" + side, "ik_hand_" + side], "driver_hand_" + side, mo = True)[0]
#create blend nodes for the scale
scaleBlendColors_UpArm = cmds.shadingNode("blendColors", asUtility = True, name = side + "_up_arm_scale_blend")
cmds.connectAttr(ikUpArmJoint + ".scale", scaleBlendColors_UpArm + ".color1")
cmds.connectAttr("fk_arm_" + side + "_anim.scale", scaleBlendColors_UpArm + ".color2")
cmds.connectAttr(scaleBlendColors_UpArm + ".output", "driver_upperarm_" + side + ".scale")
scaleBlendColors_LoArm = cmds.shadingNode("blendColors", asUtility = True, name = side + "_lo_arm_scale_blend")
cmds.connectAttr(ikLowArmJoint + ".scale", scaleBlendColors_LoArm + ".color1")
cmds.connectAttr("fk_elbow_" + side + "_anim.scale", scaleBlendColors_LoArm + ".color2")
cmds.connectAttr(scaleBlendColors_LoArm + ".output", "driver_lowerarm_" + side + ".scale")
scaleBlendColors_Wrist = cmds.shadingNode("blendColors", asUtility = True, name = side + "_wrist_scale_blend")
cmds.connectAttr(ikWristJoint + ".scale", scaleBlendColors_Wrist + ".color1")
cmds.connectAttr("fk_wrist_" + side + "_anim.scale", scaleBlendColors_Wrist + ".color2")
cmds.connectAttr(scaleBlendColors_Wrist + ".output", "driver_hand_" + side + ".scale")
#set limits
cmds.select("driver_upperarm_" + side)
cmds.transformLimits(sy = (.05, 1.25), sz = (.05, 1.25), esy = [False, True], esz = [False, True])
cmds.select("driver_lowerarm_" + side)
cmds.transformLimits(sy = (.05, 1.25), sz = (.05, 1.25), esy = [False, True], esz = [False, True])
#create the IK/FK switch
cmds.select("Rig_Settings")
cmds.addAttr(longName= side + "ArmMode", at = 'enum', en = "fk:ik:", keyable = True)
cmds.setAttr("Rig_Settings." + side + "ArmMode", 0)
cmds.setAttr(upArmConstPoint + "." + "fk_arm_" + side + "_anim" + "W0", 1)
cmds.setAttr(upArmConstPoint + "." + "ik_upperarm_" + side + "W1", 0)
cmds.setAttr(upArmConstOrient + "." + "fk_upperarm_" + side + "W0", 1)
cmds.setAttr(upArmConstOrient + "." + "ik_upperarm_" + side + "W1", 0)
cmds.setAttr(scaleBlendColors_UpArm + "." + "blender", 0)
cmds.setAttr(lowArmConst + "." + "fk_lowerarm_" + side + "W0", 1)
cmds.setAttr(lowArmConst + "." + "ik_lowerarm_" + side + "W1", 0)
cmds.setAttr(scaleBlendColors_LoArm + "." + "blender", 0)
cmds.setAttr(handConst + "." + "fk_hand_" + side + "W0", 1)
cmds.setAttr(handConst + "." + "ik_hand_" + side + "W1", 0)
cmds.setAttr(scaleBlendColors_Wrist + "." + "blender", 0)
cmds.setAttr(invisRpIkHandle + ".ikBlend", 0)
cmds.setAttr("fk_arm_" + side + "_grp.v", 1)
cmds.setAttr("ik_wrist_" + side + "_anim_space_switcher.v", 0)
cmds.setAttr("ik_elbow_" + side + "_anim_space_switcher.v", 0)
cmds.setDrivenKeyframe([scaleBlendColors_UpArm + "." + "blender", scaleBlendColors_LoArm + "." + "blender", scaleBlendColors_Wrist + "." + "blender", upArmConstPoint + "." + "fk_arm_" + side + "_anim" + "W0", upArmConstPoint + "." + "ik_upperarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([upArmConstOrient + "." + "fk_upperarm_" + side + "W0", upArmConstOrient + "." + "ik_upperarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([lowArmConst + "." + "fk_lowerarm_" + side + "W0", lowArmConst + "." + "ik_lowerarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([handConst + "." + "fk_hand_" + side + "W0", handConst + "." + "ik_hand_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([invisRpIkHandle + ".ikBlend", "fk_arm_" + side + "_grp.v"], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe(["ik_wrist_" + side + "_anim_space_switcher.v", "ik_elbow_" + side + "_anim_space_switcher.v"], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "ArmMode", 1)
cmds.setAttr(upArmConstPoint + "." + "fk_arm_" + side + "_anim" "W0", 0)
cmds.setAttr(upArmConstPoint + "." + "ik_upperarm_" + side + "W1", 1)
cmds.setAttr(upArmConstOrient + "." + "fk_upperarm_" + side + "W0", 0)
cmds.setAttr(upArmConstOrient + "." + "ik_upperarm_" + side + "W1", 1)
cmds.setAttr(scaleBlendColors_UpArm + "." + "blender", 1)
cmds.setAttr(lowArmConst + "." + "fk_lowerarm_" + side + "W0", 0)
cmds.setAttr(lowArmConst + "." + "ik_lowerarm_" + side + "W1", 1)
cmds.setAttr(scaleBlendColors_LoArm + "." + "blender", 1)
cmds.setAttr(handConst + "." + "fk_hand_" + side + "W0", 0)
cmds.setAttr(handConst + "." + "ik_hand_" + side + "W1", 1)
cmds.setAttr(scaleBlendColors_Wrist + "." + "blender", 1)
cmds.setAttr(invisRpIkHandle + ".ikBlend", 1)
cmds.setAttr("fk_arm_" + side + "_grp.v", 0)
cmds.setAttr("ik_wrist_" + side + "_anim_space_switcher.v", 1)
cmds.setAttr("ik_elbow_" + side + "_anim_space_switcher.v", 1)
cmds.setDrivenKeyframe([scaleBlendColors_UpArm + "." + "blender", scaleBlendColors_LoArm + "." + "blender", scaleBlendColors_Wrist + "." + "blender", upArmConstPoint + "." + "fk_arm_" + side + "_anim" + "W0", upArmConstPoint + "." + "ik_upperarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([upArmConstOrient + "." + "fk_upperarm_" + side + "W0", upArmConstOrient + "." + "ik_upperarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([lowArmConst + "." + "fk_lowerarm_" + side + "W0", lowArmConst + "." + "ik_lowerarm_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([handConst + "." + "fk_hand_" + side + "W0", handConst + "." + "ik_hand_" + side + "W1", ], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe([invisRpIkHandle + ".ikBlend", "fk_arm_" + side + "_grp.v"], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setDrivenKeyframe(["ik_wrist_" + side + "_anim_space_switcher.v", "ik_elbow_" + side + "_anim_space_switcher.v"], cd = "Rig_Settings." + side + "ArmMode", itt = "linear", ott = "linear")
cmds.setAttr("Rig_Settings." + side + "ArmMode", 0)
#setup stretch on IK
cmds.select(ikCtrl)
cmds.addAttr(longName=("stretch"), at = 'double',min = 0, max = 1, dv = 0, keyable = True)
cmds.addAttr(longName=("squash"), at = 'double',min = 0, max = 1, dv = 0, keyable = True)
stretchMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "ikHand_stretchToggleMultNode_" + side)
#need to get the total length of the arm chain
totalDist = abs(cmds.getAttr(ikLowArmJoint + ".tx" ) + cmds.getAttr(ikWristJoint + ".tx"))
#create a distanceBetween node
distBetween = cmds.shadingNode("distanceBetween", asUtility = True, name = side + "_ik_arm_distBetween")
#get world positions of upper arm and ik
baseGrp = cmds.group(empty = True, name = "ik_arm_base_grp_" + side)
endGrp = cmds.group(empty = True, name = "ik_arm_end_grp_" + side)
cmds.pointConstraint(ikUpArmJoint, baseGrp)
cmds.pointConstraint(ikCtrl, endGrp)
#hook in group translates into distanceBetween node inputs
cmds.connectAttr(baseGrp + ".translate", distBetween + ".point1")
cmds.connectAttr(endGrp + ".translate", distBetween + ".point2")
#create a condition node that will compare original length to current length
#if second term is greater than, or equal to the first term, the chain needs to stretch
ikArmCondition = cmds.shadingNode("condition", asUtility = True, name = side + "_ik_arm_stretch_condition")
cmds.setAttr(ikArmCondition + ".operation", 3)
cmds.connectAttr(distBetween + ".distance", ikArmCondition + ".secondTerm")
cmds.setAttr(ikArmCondition + ".firstTerm", totalDist)
#hook up the condition node's return colors
cmds.setAttr(ikArmCondition + ".colorIfTrueR", totalDist)
cmds.connectAttr(distBetween + ".distance", ikArmCondition + ".colorIfFalseR")
#create the mult/divide node(set to divide) that will take the original creation length as a static value in input2x, and the connected length into 1x.
armDistMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = "arm_dist_multNode_" + side)
cmds.setAttr(armDistMultNode + ".operation", 2) #divide
cmds.setAttr(armDistMultNode + ".input2X", totalDist)
cmds.connectAttr(ikArmCondition + ".outColorR", armDistMultNode + ".input1X")
#create a stretch toggle mult node that multiplies the stretch factor by the bool of the stretch attr. (0 or 1), this way our condition reads
#if this result is greater than the original length(impossible if stretch bool is off, since result will be 0), than take this result and plug it
#into the scale of our IK arm joints
stretchToggleCondition = cmds.shadingNode("condition", asUtility = True, name = "arm_stretch_toggle_condition_" + side)
cmds.setAttr(stretchToggleCondition + ".operation", 0)
cmds.connectAttr(ikCtrl + ".stretch", stretchToggleCondition + ".firstTerm")
cmds.setAttr(stretchToggleCondition + ".secondTerm", 1)
cmds.connectAttr(armDistMultNode + ".outputX", stretchToggleCondition + ".colorIfTrueR")
cmds.setAttr(stretchToggleCondition + ".colorIfFalseR", 1)
#set up the squash nodes
squashMultNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = side + "_ik_arm_squash_mult")
cmds.setAttr(squashMultNode + ".operation", 2)
cmds.setAttr(squashMultNode + ".input1X", totalDist)
cmds.connectAttr(ikArmCondition + ".outColorR", squashMultNode + ".input2X")
#create a stretch toggle mult node that multiplies the stretch factor by the bool of the stretch attr. (0 or 1), this way our condition reads
#if this result is greater than the original length(impossible if stretch bool is off, since result will be 0), than take this result and plug it
#into the scale of our IK arm joints
squashToggleCondition = cmds.shadingNode("condition", asUtility = True, name = "arm_squash_toggle_condition_" + side)
cmds.setAttr(squashToggleCondition + ".operation", 0)
cmds.connectAttr(ikCtrl + ".squash", squashToggleCondition + ".firstTerm")
cmds.setAttr(squashToggleCondition + ".secondTerm", 1)
cmds.connectAttr(squashMultNode + ".outputX", squashToggleCondition + ".colorIfTrueR")
cmds.setAttr(squashToggleCondition + ".colorIfFalseR", 1)
#connect to arm scale
cmds.connectAttr(stretchToggleCondition + ".outColorR", ikUpArmJoint + ".sx")
cmds.connectAttr(stretchToggleCondition + ".outColorR", ikLowArmJoint + ".sx")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikLowArmJoint + ".sy")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikLowArmJoint + ".sz")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikUpArmJoint + ".sy")
cmds.connectAttr(squashToggleCondition + ".outColorR", ikUpArmJoint + ".sz")
#add base and end groups to arm grp
cmds.parent([baseGrp, endGrp], "arm_rig_master_grp_" + side)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
#setup roll bones if obj Exists
if cmds.objExists("driver_upperarm_twist_01_" + side):
self.buildArmRoll(side)
if cmds.objExists("driver_lowerarm_twist_01_" + side):
self.buildForearmTwist(side)
#colorize controls, cleanup attrs, and cleanup hierarchy
for attr in [".sx", ".sy", ".sz", ".v"]:
cmds.setAttr(ikCtrl + attr, lock = True, keyable = False)
for attr in [".sx", ".sy", ".sz", ".rx", ".ry", ".rz", ".v"]:
cmds.setAttr(ikPvCtrl + attr, lock = True, keyable = False)
for control in [ikCtrl, ikPvCtrl]:
if side == "l":
color = 6
else:
color = 13
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", color)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def buildNeckAndHead(self):
numNeckBones = cmds.getAttr("Skeleton_Settings.numNeckBones")
if numNeckBones == 1:
#create the FK control for the neck
neckControl = self.createControl("circle", 25, "neck_01_fk_anim")
constraint = cmds.parentConstraint("driver_neck_01", neckControl)[0]
cmds.delete(constraint)
neckControlGrp = cmds.group(empty = True, name = "neck_01_fk_anim_grp")
constraint = cmds.parentConstraint("driver_neck_01", neckControlGrp)[0]
cmds.delete(constraint)
cmds.parent(neckControl, neckControlGrp)
cmds.setAttr(neckControl + ".ry", -90)
cmds.makeIdentity(neckControl, t = 1, r = 1, s = 1, apply = True)
#create the FK control for the head
headControl = self.createControl("circle", 30, "head_fk_anim")
constraint = cmds.parentConstraint("driver_head", headControl)[0]
cmds.delete(constraint)
headControlGrp = cmds.group(empty = True, name = "head_fk_anim_grp")
constraint = cmds.parentConstraint("driver_head", headControlGrp)[0]
cmds.delete(constraint)
cmds.parent(headControl, headControlGrp)
cmds.setAttr(headControl + ".ry", 90)
cmds.setAttr(headControl + ".rz", -35)
cmds.makeIdentity(headControl, t = 1, r = 1, s = 1, apply = True)
#setup head orientation
orientNodes = self.setupHeadOrientation(neckControl, headControl)
neckOrientNodes = self.setupNeckOrientation(neckControl)
#hook into spine
cmds.parent(headControlGrp, orientNodes[0])
cmds.parent(orientNodes[0], neckControl)
numSpineBones = self.getSpineJoints()
cmds.parent(neckOrientNodes[0], neckControlGrp)
cmds.parent(neckControl, neckOrientNodes[0])
cmds.parentConstraint("driver_spine_0" + str(len(numSpineBones)), neckControlGrp, mo = True)
#constrain driver joints to controls
cmds.parentConstraint(neckControl, "driver_neck_01", mo = True)
cmds.parentConstraint(headControl, "driver_head", mo = True)
cmds.connectAttr(neckControl + ".scale", "driver_neck_01.scale")
cmds.connectAttr(headControl + ".scale", "driver_head.scale")
#lock attrs, color controls, and clean up hierarchy
for control in [neckControl, headControl]:
for attr in [".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
cmds.setAttr(neckControl + ".overrideEnabled", 1)
cmds.setAttr(neckControl + ".overrideColor", 18)
cmds.setAttr(headControl + ".overrideEnabled", 1)
cmds.setAttr(headControl + ".overrideColor", 17)
masterGrp = cmds.group(empty = True, name = "head_sys_grp")
cmds.parent(orientNodes[4], masterGrp)
cmds.parent(neckOrientNodes[3], masterGrp)
#cmds.parent(neckOrientNodes[0], masterGrp)
else:
neckControlMid = ""
if numNeckBones == 2:
#create the FK controls for the neck
neckControl = self.createControl("circle", 25, "neck_01_fk_anim")
constraint = cmds.parentConstraint("driver_neck_01", neckControl)[0]
cmds.delete(constraint)
neckControlGrp = cmds.group(empty = True, name = "neck_01_fk_anim_grp")
constraint = cmds.parentConstraint("driver_neck_01", neckControlGrp)[0]
cmds.delete(constraint)
cmds.parent(neckControl, neckControlGrp)
cmds.setAttr(neckControl + ".ry", -90)
cmds.makeIdentity(neckControl, t = 1, r = 1, s = 1, apply = True)
neckControlEnd = self.createControl("circle", 25, "neck_02_fk_anim")
constraint = cmds.parentConstraint("driver_neck_02", neckControlEnd)[0]
cmds.delete(constraint)
neckControlEndGrp = cmds.group(empty = True, name = "neck_02_fk_anim_grp")
constraint = cmds.parentConstraint("driver_neck_02", neckControlEndGrp)[0]
cmds.delete(constraint)
cmds.parent(neckControlEnd, neckControlEndGrp)
cmds.setAttr(neckControlEnd + ".ry", -90)
cmds.makeIdentity(neckControlEnd, t = 1, r = 1, s = 1, apply = True)
#setup neck hiearchy
cmds.parent(neckControlEndGrp, neckControl)
if numNeckBones == 3:
#create the FK controls for the neck
neckControl = self.createControl("circle", 25, "neck_01_fk_anim")
constraint = cmds.parentConstraint("driver_neck_01", neckControl)[0]
cmds.delete(constraint)
neckControlGrp = cmds.group(empty = True, name = "neck_01_fk_anim_grp")
constraint = cmds.parentConstraint("driver_neck_01", neckControlGrp)[0]
cmds.delete(constraint)
cmds.parent(neckControl, neckControlGrp)
cmds.setAttr(neckControl + ".ry", -90)
cmds.makeIdentity(neckControl, t = 1, r = 1, s = 1, apply = True)
neckControlMid = self.createControl("circle", 25, "neck_02_fk_anim")
constraint = cmds.parentConstraint("driver_neck_02", neckControlMid)[0]
cmds.delete(constraint)
neckControlMidGrp = cmds.group(empty = True, name = "neck_02_fk_anim_grp")
constraint = cmds.parentConstraint("driver_neck_02", neckControlMidGrp)[0]
cmds.delete(constraint)
cmds.parent(neckControlMid, neckControlMidGrp)
cmds.setAttr(neckControlMid + ".ry", -90)
cmds.makeIdentity(neckControlMid, t = 1, r = 1, s = 1, apply = True)
neckControlEnd = self.createControl("circle", 25, "neck_03_fk_anim")
constraint = cmds.parentConstraint("driver_neck_03", neckControlEnd)[0]
cmds.delete(constraint)
neckControlEndGrp = cmds.group(empty = True, name = "neck_03_fk_anim_grp")
constraint = cmds.parentConstraint("driver_neck_03", neckControlEndGrp)[0]
cmds.delete(constraint)
cmds.parent(neckControlEnd, neckControlEndGrp)
cmds.setAttr(neckControlEnd + ".ry", -90)
cmds.makeIdentity(neckControlEnd, t = 1, r = 1, s = 1, apply = True)
#setup neck hiearchy
cmds.parent(neckControlEndGrp, neckControlMid)
cmds.parent(neckControlMidGrp, neckControl)
#create the FK control for the head
headControl = self.createControl("circle", 30, "head_fk_anim")
constraint = cmds.parentConstraint("driver_head", headControl)[0]
cmds.delete(constraint)
headControlGrp = cmds.group(empty = True, name = "head_fk_anim_grp")
constraint = cmds.parentConstraint("driver_head", headControlGrp)[0]
cmds.delete(constraint)
cmds.parent(headControl, headControlGrp)
cmds.setAttr(headControl + ".ry", 90)
cmds.setAttr(headControl + ".rz", -35)
cmds.makeIdentity(headControl, t = 1, r = 1, s = 1, apply = True)
#setup head orientation
orientNodes = self.setupHeadOrientation(neckControlEnd, headControl)
neckOrientNodes = self.setupNeckOrientation(neckControl)
#hook into spine
cmds.parent(headControlGrp, orientNodes[0])
cmds.parent(orientNodes[0], neckControlEnd)
numSpineBones = self.getSpineJoints()
cmds.parent(neckOrientNodes[0], neckControlGrp)
cmds.parent(neckControl, neckOrientNodes[0])
cmds.parentConstraint("driver_spine_0" + str(len(numSpineBones)), neckControlGrp, mo = True)
#constrain driver joints to controls
if numNeckBones == 2:
cmds.parentConstraint(neckControl, "driver_neck_01", mo = True)
cmds.parentConstraint(neckControlEnd, "driver_neck_02", mo = True)
cmds.connectAttr(neckControl + ".scale", "driver_neck_01.scale")
cmds.connectAttr(neckControlEnd + ".scale", "driver_neck_02.scale")
if numNeckBones == 3:
cmds.parentConstraint(neckControl, "driver_neck_01", mo = True)
cmds.parentConstraint(neckControlMid, "driver_neck_02", mo = True)
cmds.parentConstraint(neckControlEnd, "driver_neck_03", mo = True)
cmds.connectAttr(neckControl + ".scale", "driver_neck_01.scale")
cmds.connectAttr(neckControlMid + ".scale", "driver_neck_02.scale")
cmds.connectAttr(neckControlEnd + ".scale", "driver_neck_03.scale")
cmds.parentConstraint(headControl, "driver_head", mo = True)
cmds.connectAttr(headControl + ".scale", "driver_head.scale")
#lock attrs, color controls, and clean up hierarchy
for control in [neckControl, neckControlEnd, neckControlMid, headControl]:
if cmds.objExists(control):
for attr in [".v"]:
cmds.setAttr(control + attr, lock = True, keyable = False)
cmds.setAttr(control + ".overrideEnabled", 1)
for control in [neckControl, neckControlEnd, neckControlMid]:
if cmds.objExists(control):
cmds.setAttr(control + ".overrideColor", 18)
cmds.setAttr(headControl + ".overrideEnabled", 1)
cmds.setAttr(headControl + ".overrideColor", 17)
masterGrp = cmds.group(empty = True, name = "head_sys_grp")
cmds.parent(orientNodes[4], masterGrp)
cmds.parent(neckOrientNodes[3], masterGrp)
#cmds.parent(neckOrientNodes[0], masterGrp)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def setupHeadOrientation(self, neckControl, headControl):
#create head orient controls (neck, shoulder, body, world)
orientMaster = cmds.group(empty = True, name = "head_fk_orient_master")
constraint = cmds.parentConstraint("driver_head", orientMaster)[0]
cmds.delete(constraint)
orientNeck = cmds.duplicate(orientMaster, po = True, name = "head_fk_orient_neck")[0]
orientShoulder = cmds.duplicate(orientMaster, po = True, name = "head_fk_orient_shoulder")[0]
orientBody = cmds.duplicate(orientMaster, po = True, name = "head_fk_orient_body")[0]
orientWorld = cmds.duplicate(orientMaster, po = True, name = "head_fk_orient_world")[0]
fkHeadOrientConstraint = cmds.orientConstraint([orientNeck, orientShoulder, orientBody, orientWorld], orientMaster)[0]
numSpineBones = self.getSpineJoints()
cmds.parent(orientNeck, neckControl)
cmds.parent(orientShoulder, "driver_spine_0" + str(len(numSpineBones)))
cmds.parent(orientBody, "body_anim")
#add the fk orient attr to the head control
cmds.select(headControl)
cmds.addAttr(longName= "fkOrientation", at = 'enum', en = "neck:shoulder:body:world:", keyable = True)
#setup sdks for controlling constraint weight
cmds.setAttr(headControl + ".fkOrientation", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientNeck + "W0", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W1", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W2", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W3", 0)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientNeck + "W0", fkHeadOrientConstraint + "." + orientShoulder + "W1", fkHeadOrientConstraint + "." + orientBody + "W2", fkHeadOrientConstraint + "." + orientWorld + "W3"], cd = headControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(headControl + ".fkOrientation", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientNeck + "W0", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W1", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W2", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W3", 0)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientNeck + "W0", fkHeadOrientConstraint + "." + orientShoulder + "W1", fkHeadOrientConstraint + "." + orientBody + "W2", fkHeadOrientConstraint + "." + orientWorld + "W3"], cd = headControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(headControl + ".fkOrientation", 2)
cmds.setAttr(fkHeadOrientConstraint + "." + orientNeck + "W0", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W1", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W2", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W3", 0)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientNeck + "W0", fkHeadOrientConstraint + "." + orientShoulder + "W1", fkHeadOrientConstraint + "." + orientBody + "W2", fkHeadOrientConstraint + "." + orientWorld + "W3"], cd = headControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(headControl + ".fkOrientation", 3)
cmds.setAttr(fkHeadOrientConstraint + "." + orientNeck + "W0", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W1", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W2", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W3", 1)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientNeck + "W0", fkHeadOrientConstraint + "." + orientShoulder + "W1", fkHeadOrientConstraint + "." + orientBody + "W2", fkHeadOrientConstraint + "." + orientWorld + "W3"], cd = headControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(headControl + ".fkOrientation", 0)
return [orientMaster, orientNeck, orientShoulder, orientBody, orientWorld]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def setupNeckOrientation(self, neckControl):
#create head orient controls (neck, shoulder, body, world)
orientMaster = cmds.group(empty = True, name = "neck_fk_orient_master")
constraint = cmds.parentConstraint("driver_neck_01", orientMaster)[0]
cmds.delete(constraint)
orientShoulder = cmds.duplicate(orientMaster, po = True, name = "neck_fk_orient_shoulder")[0]
orientBody = cmds.duplicate(orientMaster, po = True, name = "neck_fk_orient_body")[0]
orientWorld = cmds.duplicate(orientMaster, po = True, name = "neck_fk_orient_world")[0]
fkHeadOrientConstraint = cmds.orientConstraint([orientShoulder, orientBody, orientWorld], orientMaster)[0]
numSpineBones = self.getSpineJoints()
cmds.parent(orientShoulder, "driver_spine_0" + str(len(numSpineBones)))
cmds.parent(orientBody, "body_anim")
#add the fk orient attr to the head control
cmds.select(neckControl)
cmds.addAttr(longName= "fkOrientation", at = 'enum', en = "shoulder:body:world:", keyable = True)
#setup sdks for controlling constraint weight
cmds.setAttr(neckControl + ".fkOrientation", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W0", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W1", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W2", 0)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientShoulder + "W0", fkHeadOrientConstraint + "." + orientBody + "W1", fkHeadOrientConstraint + "." + orientWorld + "W2"], cd = neckControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(neckControl + ".fkOrientation", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W0", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W1", 1)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W2", 0)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientShoulder + "W0", fkHeadOrientConstraint + "." + orientBody + "W1", fkHeadOrientConstraint + "." + orientWorld + "W2"], cd = neckControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(neckControl + ".fkOrientation", 2)
cmds.setAttr(fkHeadOrientConstraint + "." + orientShoulder + "W0", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientBody + "W1", 0)
cmds.setAttr(fkHeadOrientConstraint + "." + orientWorld + "W2", 1)
cmds.setDrivenKeyframe([fkHeadOrientConstraint + "." + orientShoulder + "W0", fkHeadOrientConstraint + "." + orientBody + "W1", fkHeadOrientConstraint + "." + orientWorld + "W2"], cd = neckControl + ".fkOrientation", itt = "linear", ott = "linear")
cmds.setAttr(neckControl + ".fkOrientation", 0)
return [orientMaster, orientShoulder, orientBody, orientWorld]
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def rigLeafJoints(self):
#find attrs on the skeleton settings node
createdControls = []
attrs = cmds.listAttr("Skeleton_Settings")
for attr in attrs:
if attr.find("extraJoint") == 0:
attribute = cmds.getAttr("Skeleton_Settings." + attr, asString = True)
jointType = attribute.partition("/")[2].partition("/")[0]
name = attribute.rpartition("/")[2]
parent = attribute.partition("/")[0]
if parent.find("(") != -1:
parent = parent.partition(" (")[0]
if jointType == "leaf":
attrs = name.partition("(")[2].partition(")")[0]
name = name.partition(" (")[0]
#create the control
control = cmds.curve(name = (name + "_anim"), d = 1, p = [(0, 0, 1), (0, 0.5, 0.866025), (0, 0.866025, 0.5), (0, 1, 0), (0, 0.866025, -0.5), (0, 0.5, -0.866025), (0, 0, -1), (0, -0.5, -0.866025), (0, -0.866025, -0.5), (0, -1, 0), (0, -0.866025, 0.5), (0, -0.5, 0.866025), (0, 0, 1), (0.707107, 0, 0.707107), (1, 0, 0), (0.707107, 0, -0.707107), (0, 0, -1), (-0.707107, 0, -0.707107), (-1, 0, 0), (-0.866025, 0.5, 0), (-0.5, 0.866025, 0), (0, 1, 0), (0.5, 0.866025, 0), (0.866025, 0.5, 0), (1, 0, 0), (0.866025, -0.5, 0), (0.5, -0.866025, 0), (0, -1, 0), (-0.5, -0.866025, 0), (-0.866025, -0.5, 0), (-1, 0, 0), (-0.707107, 0, 0.707107), (0, 0, 1)])
#scale up
cmds.setAttr(control + ".sx", 9)
cmds.setAttr(control + ".sy", 9)
cmds.setAttr(control + ".sz", 9)
#freeze transforms
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#position control
constraint = cmds.parentConstraint("driver_" + name, control)[0]
cmds.delete(constraint)
#create the control group
ctrlGrp = cmds.group(empty = True, name = (name + "_anim_grp"))
constraint = cmds.parentConstraint("driver_" + name, ctrlGrp)[0]
cmds.delete(constraint)
#create space switcher group
spaceSwitcherFollow = cmds.duplicate(ctrlGrp, po = True, name = (name + "_anim_space_switcher_follow"))[0]
spaceSwitcher = cmds.duplicate(ctrlGrp, po = True, name = (name + "_anim_space_switcher"))[0]
#create the top parent group
topParent = cmds.duplicate(ctrlGrp, po = True, name = (name + "_parent_grp"))[0]
#parent control to group
cmds.parent(spaceSwitcher, spaceSwitcherFollow)
cmds.parent(spaceSwitcherFollow, topParent)
cmds.parent(ctrlGrp, spaceSwitcher)
cmds.parent(control, ctrlGrp)
#constrain driver joint to control
cmds.parentConstraint(control, "driver_" + name)
cmds.connectAttr(control + ".scale", "driver_" + name + ".scale")
#lock attrs depending on type of control
lockAttrs = []
if attrs == "TR":
lockAttrs = [".v"]
if attrs == "T":
lockAttrs = [".v", ".rx", ".ry", ".rz"]
if attrs == "R":
lockAttrs = [".v", ".tx", ".ty", ".tz"]
for attr in lockAttrs:
cmds.setAttr(control + attr, lock = True, keyable = False)
#parent constrain the topParent to the parent of the control
cmds.parentConstraint("driver_" + parent, topParent, mo = True)
#color the control
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
#add the topParent to the createdControls list
createdControls.append(topParent)
return createdControls
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def rigJiggleJoints(self):
#find attrs on the skeleton settings node
createdControls = []
attrs = cmds.listAttr("Skeleton_Settings")
for attr in attrs:
if attr.find("extraJoint") == 0:
attribute = cmds.getAttr("Skeleton_Settings." + attr, asString = True)
jointType = attribute.partition("/")[2].partition("/")[0]
name = attribute.rpartition("/")[2]
parent = attribute.partition("/")[0]
if jointType == "jiggle":
#duplicate the driver joint
jiggleStart = cmds.duplicate("driver_" + name, po = True, name = "rig_" + name + "_start")[0]
cmds.parent(jiggleStart, world = True)
jiggleEnd = cmds.duplicate(jiggleStart, po = True, name = "rig_" + name + "_end")[0]
cmds.parent(jiggleEnd, jiggleStart)
#move jiggleEnd down a bit in up axis
scaleFactor = self.getScaleFactor()
jointPos = cmds.xform(jiggleStart, q = True, ws = True, t = True)
cmds.xform(jiggleEnd, ws = True, t = (jointPos[0], jointPos[1], (jointPos[2] - (25 * scaleFactor))))
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create curve on joint chain
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
joints = [jiggleStart, jiggleEnd]
positions = []
#get the world space positions of each joint, and create a curve using those positions
for i in range(int(len(joints))):
pos = cmds.xform(joints[i], q = True, ws = True, t = True)
positions.append(pos)
createCurveCommand = "curve -d 1"
for pos in positions:
xPos = pos[0]
yPos = pos[1]
zPos = pos[2]
createCurveCommand += " -p " + str(xPos) + " " + str(yPos) + " " + str(zPos)
for i in range(int(len(positions))):
createCurveCommand += " -k " + str(i)
curve = mel.eval(createCurveCommand)
curve = cmds.rename(curve, name + "_dynCurve")
cmds.setAttr(curve + ".v", 0)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create hair system
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
cmds.select(curve)
#find all hair systems in scene
hairSystems = cmds.ls(type = "hairSystem")
hairSys = ""
#create the hair system and make the stiffness uniform
madeHairCurve = True
if hairSys == "":
hairSys = cmds.createNode("hairSystem")
cmds.removeMultiInstance(hairSys + ".stiffnessScale[1]", b = True)
cmds.setAttr(hairSys + ".clumpWidth", 0.0)
cmds.connectAttr("time1.outTime", hairSys + ".currentTime")
hairSysParent = cmds.listRelatives(hairSys, parent = True)
hairSysParent = cmds.rename(hairSysParent, name + "_hairSystem")
cmds.setAttr(hairSysParent + ".v", 0)
hairSys = name + "_hairSystemShape"
#create the hair follicle
hair = cmds.createNode("follicle")
cmds.setAttr(hair + ".parameterU", 0)
cmds.setAttr(hair + ".parameterV", 0)
hairTransforms = cmds.listRelatives(hair, p = True)
hairDag = hairTransforms[0]
hairDag = cmds.rename(hairDag, name + "_follicle")
hair = name + "_follicleShape"
cmds.setAttr(hairDag + ".v", 0)
cmds.setAttr(hair + ".startDirection", 1)
#get the curve CVs and set follicle degree to 1 if CVs are less than 3
curveCVs = cmds.getAttr(curve + ".cp", size = True)
if curveCVs < 3:
cmds.setAttr(hair + ".degree", 1)
#parent the curve to the follicle and connect the curve's worldspace[0] to the follicle startPos
cmds.parent(curve, hairDag, relative = True)
cmds.connectAttr(curve + ".worldSpace[0]", hair + ".startPosition")
#connect the hair follicle to the hair system
cmds.connectAttr(hair + ".outHair", hairSys + ".inputHair[0]")
#create a new curve and connect the follicle's outCurve attr to the new curve
cmds.connectAttr(hairSys + ".outputHair[0]", hair + ".currentPosition")
crv = cmds.createNode("nurbsCurve")
crvParent = cmds.listRelatives(crv, parent = True)[0]
crvParent = cmds.rename(crvParent, name + "_track_rt_curve")
crv = name + "_track_rt_curveShape"
cmds.setAttr(crvParent + ".v", 0)
cmds.connectAttr(hair + ".outCurve", crv + ".create")
#set the hair follicle attrs
if len(hairDag) > 0:
cmds.setAttr(hairDag + ".pointLock", 3)
cmds.setAttr(hairDag + ".restPose", 1)
cmds.select(hairSys)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create Spline Handle for the selected chain and the duplicated curve. the original is driven by hair
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
ikNodes = cmds.ikHandle(sol = "ikSplineSolver", ccv = False, pcv = False, snc = True, sj = jiggleStart, ee = jiggleEnd, c = crv)[0]
cmds.setAttr(ikNodes + ".v", 0)
ikNodes = cmds.rename(ikNodes, name + "_dynChain_ikHandle")
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create a duplicate joint chain for manual animation
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
dupeChain = cmds.duplicate(jiggleStart, rr = True, rc = True)
dupeStartJoint = dupeChain[0]
dupeJoints = cmds.listRelatives(dupeStartJoint, ad = True)
joints = cmds.listRelatives(jiggleStart, ad = True)
#rename duped joints and connect real joints to duped joints
for i in range(int(len(joints))):
if cmds.objectType(dupeJoints[i], isType = 'joint'):
cmds.rename(dupeJoints[i], "ANIM_" + joints[i])
cmds.connectAttr("ANIM_" + joints[i] + ".r", joints[i] + ".r", force = True)
else:
cmds.delete(dupeJoints[i])
#connect up start joint to ANIM start joint
cmds.connectAttr(dupeStartJoint + ".t", jiggleStart + ".t")
cmds.connectAttr(dupeStartJoint + ".r", jiggleStart + ".r")
cmds.connectAttr(dupeStartJoint + ".s", jiggleStart + ".s")
dupeStartJoint = cmds.rename(dupeStartJoint, "ANIM_" + jiggleStart)
#cmds.parent(dupeStartJoint, world = True)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create skinCluster between duplicate curve and animation joint chain(dupe chain)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
cmds.select(dupeStartJoint, hi = True)
dupeSkel = cmds.ls(sl = True, type = "joint")
cmds.select(curve)
cmds.select(dupeSkel, add = True)
skinCluster = cmds.skinCluster(tsb = True, mi = 3, dr = 4)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create the control that has all of our dynamic attrs
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
control = self.createControl("square", 15, name + "_anim")
constraint = cmds.parentConstraint(jiggleStart, control)[0]
cmds.delete(constraint)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
constraint = cmds.parentConstraint(jiggleStart, ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.parentConstraint(control, dupeStartJoint)
#lock attrs
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#add attrs
cmds.select(control)
cmds.addAttr(ln = "___DYNAMICS___", at = "double", keyable = True)
cmds.setAttr(control + ".___DYNAMICS___", lock = True)
cmds.addAttr(ln = "chainAttach", at = "enum", en = "No Attach:Base:Tip:Both End:", dv = 1, keyable = True)
cmds.addAttr(ln = "chainStartEnvelope", at = "double", min = 0, max = 1, dv = 1, keyable = True)
cmds.addAttr(ln = "chainStartFrame", at = "double", dv = 1, keyable = True)
cmds.addAttr(ln = "___BEHAVIOR___", at = "double", keyable = True)
cmds.setAttr(control + ".___BEHAVIOR___", lock = True)
cmds.addAttr(ln = "chainStiffness", at = "double", min = 0, dv = .1, keyable = True)
cmds.addAttr(ln = "chainDamping", at = "double", min = 0, dv = 0.2, keyable = True)
cmds.addAttr(ln = "chainGravity", at = "double", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "chainIteration", at = "long", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "___COLLISIONS___", at = "double", keyable = True)
cmds.setAttr(control + ".___COLLISIONS___", lock = True)
cmds.addAttr(ln = "chainCollide", at = "bool", dv = 0, keyable = True)
cmds.addAttr(ln = "chainWidthBase", at = "double", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "chainWidthExtremity", at = "double", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "chainCollideGround", at = "bool", dv = 0, keyable = True)
cmds.addAttr(ln = "chainCollideGroundHeight", at = "double", dv = 0, keyable = True)
#connect attrs
cmds.connectAttr(control + ".chainStartEnvelope", ikNodes + ".ikBlend")
cmds.connectAttr(control + ".chainAttach", hair + ".pointLock")
cmds.connectAttr(control + ".chainStartFrame", hairSys + ".startFrame")
cmds.connectAttr(control + ".chainStiffness", hairSys + ".stiffness")
cmds.connectAttr(control + ".chainDamping", hairSys + ".damp")
cmds.connectAttr(control + ".chainGravity", hairSys + ".gravity")
cmds.connectAttr(control + ".chainIteration", hairSys + ".iterations")
cmds.connectAttr(control + ".chainCollide", hairSys + ".collide")
cmds.connectAttr(control + ".chainWidthBase", hairSys + ".clumpWidth")
cmds.connectAttr(control + ".chainWidthExtremity", hairSys + ".clumpWidthScale[1].clumpWidthScale_FloatValue")
cmds.connectAttr(control + ".chainCollideGround", hairSys + ".collideGround")
cmds.connectAttr(control + ".chainCollideGroundHeight", hairSys + ".groundHeight")
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Create the expression for real time
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
track_RealTime = cmds.spaceLocator(name = name + "_track_rt_loc")[0]
cmds.pointConstraint(dupeSkel[len(dupeSkel) -1], track_RealTime)
connections = cmds.listConnections(hairSys + ".currentTime", p = True, c = True)
cmds.disconnectAttr(connections[1], connections[0])
expressionString = "if(frame!= " + hairSys + ".startFrame)\n\t" + hairSys + ".currentTime = " + hairSys + ".currentTime + 1 + " + track_RealTime + ".tx - " + track_RealTime + ".tx + " + track_RealTime + ".ty - " + track_RealTime + ".ty + " + track_RealTime + ".tz - " + track_RealTime + ".tz + " + control + ".chainWidthBase - "+ control + ".chainWidthBase + "+ control + ".chainWidthExtremity - "+ control + ".chainWidthExtremity + " + control + ".chainGravity - "+ control + ".chainGravity;\n" +"else\n\t" + hairSys + ".currentTime = " + hairSys + ".startFrame;"
cmds.expression(name = "EXP_" + hairSys + "_TRACK_RealTime", string = expressionString)
cmds.setAttr(track_RealTime + ".v", 0)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Set Defaults
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
cmds.setAttr(hairSys + ".drawCollideWidth", 1)
cmds.setAttr(hairSys + ".widthDrawSkip", 0)
cmds.setAttr(hair + ".degree", 1)
cmds.parentConstraint("driver_" + parent, ctrlGrp, mo = True)
if cmds.objExists("dynHairChain") == False:
cmds.group(empty = True, name = "dynHairChain")
if cmds.objExists(jiggleStart + "_HairControls") == False:
group = cmds.group([ikNodes, hairSys, hair, track_RealTime, ctrlGrp, crvParent], name = jiggleStart + "_HairControls")
else:
cmds.parent([ikNodes, hairSys, hair, ctrlGrp,crvParent ], jiggleStart + "_HairControls")
cmds.parent(group, "dynHairChain")
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Cleanup
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
jointsGrp = cmds.group(empty = True, name = name + "_jiggle_jointsGrp")
createdControls.append(jointsGrp)
cmds.parent([jiggleStart, dupeStartJoint], jointsGrp)
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
#constrain driver joints
cmds.parentConstraint(jiggleStart, "driver_" + name, mo = True)
#return top level group
return createdControls
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def rigCustomJointChains(self):
#find attrs on the skeleton settings node
createdControls = []
rootControl = ""
attrs = cmds.listAttr("Skeleton_Settings")
for attr in attrs:
if attr.find("extraJoint") == 0:
attribute = cmds.getAttr("Skeleton_Settings." + attr, asString = True)
jointType = attribute.partition("/")[2].partition("/")[0]
name = attribute.rpartition("/")[2]
parent = attribute.partition("/")[0]
if jointType == "chain":
numJointsInChain = name.partition("(")[2].partition(")")[0]
name = name.partition(" (")[0]
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#FK RIG
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
fkJoints = []
frameCacheNodes = []
fkRootGrp = ""
for i in range(int(numJointsInChain)):
jointNum = i + 1
if jointNum == 1:
firstControl = "fk_" + name + "_0" + str(jointNum) + "_anim"
#create and position the joint
if cmds.objExists("rig_fk_" + name + "_0" + str(jointNum)):
cmds.delete("rig_fk_" + name + "_0" + str(jointNum))
cmds.select(clear = True)
joint = cmds.joint(name = "rig_fk_" + name + "_0" + str(jointNum))
cmds.select(clear = True)
fkJoints.append(joint)
constraint = cmds.parentConstraint("driver_" + name + "_0" + str(jointNum), joint)[0]
cmds.delete(constraint)
#create the control and position
control = self.createControl("circle", 15, "fk_" + name + "_0" + str(jointNum) + "_anim")
cmds.setAttr(control + ".rx", 90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
constraint = cmds.parentConstraint(joint, control)[0]
cmds.delete(constraint)
cmds.makeIdentity(control, t = 0, r = 1, s = 0, apply = True)
#cmds.setAttr(control + ".rz", -90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#create the control grp and parent the control to the group
ctrlGrp = cmds.group(empty = True, name = "fk_" + name + "_0" + str(jointNum) + "_grp")
if i == 0:
fkRootGrp = ctrlGrp
constraint = cmds.parentConstraint(joint, ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#duplicate the ctrl grp for the lag mode
lagGrp = cmds.duplicate(ctrlGrp, po = True, name = "fk_" + name + "_0" + str(jointNum) + "_lag_grp")[0]
cmds.parent(lagGrp, ctrlGrp)
cmds.parent(control, lagGrp)
#color the control
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
if jointNum != 1:
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
else:
#aliasAttr one of the scale axis and connect the other two to that one
cmds.aliasAttr("global_scale", control + ".scaleZ")
cmds.connectAttr(control + ".scaleZ", control + ".scaleX")
cmds.connectAttr(control + ".scaleZ", control + ".scaleY")
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#parent the joint to the control
cmds.parent(joint, control)
#TEMP!
cmds.parentConstraint(joint, "driver_" + name + "_0" + str(jointNum))
#add attr to root joint of chain for turning on "lag" mode
if i == 0:
rootControl = ctrlGrp
cmds.select(control)
cmds.addAttr(longName='lagMode', defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.addAttr(longName='lagValue', defaultValue= 3, minValue= 0, maxValue=100, keyable = False)
#setup lag mode node chain
frameCacheX = cmds.createNode("frameCache")
frameCacheX = cmds.rename(frameCacheX, name + "_frameCacheX")
frameCacheY = cmds.createNode("frameCache")
frameCacheY = cmds.rename(frameCacheY, name + "_frameCacheY")
frameCacheZ = cmds.createNode("frameCache")
frameCacheZ = cmds.rename(frameCacheZ, name + "_frameCacheZ")
frameCacheNodes.append(frameCacheX)
frameCacheNodes.append(frameCacheY)
frameCacheNodes.append(frameCacheZ)
#create a switcher node
switchNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = name + "_switcherNode")
frameCacheNodes.append(switchNode)
cmds.connectAttr(control + ".rotateX", switchNode + ".input1X")
cmds.connectAttr(control + ".lagMode", switchNode + ".input2X")
cmds.connectAttr(control + ".rotateY", switchNode + ".input1Y")
cmds.connectAttr(control + ".lagMode", switchNode + ".input2Y")
cmds.connectAttr(control + ".rotateZ", switchNode + ".input1Z")
cmds.connectAttr(control + ".lagMode", switchNode + ".input2Z")
cmds.connectAttr(switchNode + ".outputX", frameCacheX + ".stream")
cmds.connectAttr(switchNode + ".outputY", frameCacheY + ".stream")
cmds.connectAttr(switchNode + ".outputZ", frameCacheZ + ".stream")
mainControl = control
#setup FK hierarchy
lagValue = cmds.getAttr(mainControl + ".lagValue")
if i != 0:
cmds.parent(ctrlGrp, lastControl)
#connect framecache results to lag Grps
mode = "past"
cmds.connectAttr(frameCacheX + "." + mode + "[" + str(int(abs(lagValue)) * (i + 1)) + "]", lagGrp + ".rotateX")
cmds.connectAttr(frameCacheY + "." + mode + "[" + str(int(abs(lagValue)) * (i + 1)) + "]", lagGrp + ".rotateY")
cmds.connectAttr(frameCacheZ + "." + mode + "[" + str(int(abs(lagValue)) * (i + 1)) + "]", lagGrp + ".rotateZ")
lastControl = control
#add nodes to container
lagContainer = cmds.container(name = (name + "_lag_container"))
for node in frameCacheNodes:
cmds.container(lagContainer, edit = True, addNode = node, includeNetwork = True, ihb = True)
#constrain root of fk chain to driver's parent joint
parent = cmds.listRelatives("driver_" + name + "_01", parent = True)[0]
cmds.parentConstraint(parent, rootControl, mo = True)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#IK RIG
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
ikJoints = []
clusterControls = []
for i in range(int(numJointsInChain)):
jointNum = i + 1
#create and position the joint
if cmds.objExists("rig_ik_" + name + "_0" + str(jointNum)):
cmds.delete("rig_ik_" + name + "_0" + str(jointNum))
cmds.select(clear = True)
joint = cmds.joint(name = "rig_ik_" + name + "_0" + str(jointNum))
cmds.select(clear = True)
ikJoints.append(joint)
constraint = cmds.parentConstraint("driver_" + name + "_0" + str(jointNum), joint)[0]
cmds.delete(constraint)
#recreate the joint heirarchy
if i != 0:
cmds.parent(joint, lastJoint)
lastJoint = joint
startJoint = ikJoints[0]
endJoint = ikJoints[(len(ikJoints) - 1)]
cmds.makeIdentity(startJoint, r = 1, t = 0, s = 0, apply = True)
#create the spline IK
ikNodes = cmds.ikHandle(sj = startJoint, ee = endJoint, sol = "ikSplineSolver", createCurve = True, simplifyCurve = False, parentCurve = False, name = str(ikJoints[0]) + "_splineIK")
ikHandle = ikNodes[0]
ikCurve = ikNodes[2]
ikCurve = cmds.rename(ikCurve, name + "_splineIK_curve")
cmds.setAttr(ikCurve + ".inheritsTransform", 0)
cmds.setAttr(ikHandle + ".v", 0)
cmds.setAttr(ikCurve + ".v", 0)
#create the three joints to skin the curve to
if int(numJointsInChain) <= 6:
#3 joints for the curve
skinJoints = 3
if int(numJointsInChain) >= 7:
#add 1 joint to the curve every odd number
oddJoints = []
for i in range(7, int(numJointsInChain)):
if i % 2 != 0:
oddJoints.append(i)
#now we have a list of the total number of odd joints in our numJointsInChain. Take the length of the list + 3 to get the joints to create for our curve
skinJoints = 3 + len(oddJoints)
#create the joints to skin to the curve
curveJoints = []
if skinJoints == 3:
botJoint = cmds.duplicate(startJoint, name = name + "_splineIK_skin_joint_1", parentOnly = True)[0]
topJoint = cmds.duplicate(endJoint, name = name + "_splineIK_skin_joint_2", parentOnly = True)[0]
midJoint = cmds.duplicate(topJoint, name = name + "_splineIK_skin_joint_3", parentOnly = True)[0]
cmds.parent([botJoint, topJoint,midJoint], world = True)
constraint = cmds.pointConstraint([botJoint, topJoint], midJoint)[0]
cmds.delete(constraint)
curveJoints.append(botJoint)
curveJoints.append(topJoint)
curveJoints.append(midJoint)
else:
for i in range(skinJoints):
if i == 0:
joint = cmds.duplicate(ikJoints[i], name = name + "_splineIK_skin_joint_" + str(i), parentOnly = True)[0]
curveJoints.append(joint)
else:
joint = cmds.duplicate(ikJoints[i + i], name = name + "_splineIK_skin_joint_" + str(i), parentOnly = True)[0]
curveJoints.append(joint)
#parent all of the joints to the world
for joint in curveJoints:
try:
cmds.parent(joint, world = True)
except:
print joint
pass
#skin the joints to the curve
cmds.select(curveJoints)
cmds.skinCluster( curveJoints, ikCurve, toSelectedBones = True )
#find number of CVs on created curve
numSpans = cmds.getAttr(ikCurve + ".spans")
degree = cmds.getAttr(ikCurve + ".degree")
numCVs = numSpans + degree
#for each cv, create a cluster, then create the control
clusters = []
for cv in range(int(numCVs)):
cmds.select(ikCurve + ".cv[" + str(cv) + "]" )
cluster = cmds.cluster(name = name + "_cluster_" + str(cv))
clusters.append(cluster)
#cleanup clusters list
cmds.delete(clusters[1])
cmds.delete(clusters[(len(clusters) - 2)])
clusters.pop(1)
clusters.pop(len(clusters) - 2)
clusterNodes = []
ikAnimGrps = []
#create the controls for each cluster
for i in range(int(len(clusters))):
cluster = cmds.rename(clusters[i][1], name + "_cluster_" + str(i))
clusterNodes.append(cluster)
cmds.setAttr(cluster + ".v", 0)
control = cmds.spaceLocator(name = name + "_cv_" + str(i) + "_anim")[0]
constraint = cmds.parentConstraint(ikJoints[i], control)[0]
cmds.delete(constraint)
clusterControls.append(control)
#scale up the locator
scaleFactor = self.getScaleFactor()
shape = cmds.listRelatives(control, shapes = True)[0]
cmds.setAttr(shape + ".localScaleX", 15 * scaleFactor)
cmds.setAttr(shape + ".localScaleY", 15 * scaleFactor)
cmds.setAttr(shape + ".localScaleZ", 15 * scaleFactor)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
ikAnimGrps.append(ctrlGrp)
constraint = cmds.pointConstraint(ikJoints[i], ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#point constrain the ctrlGrp to the corresponding joint
cmds.pointConstraint(ikJoints[i], ctrlGrp)
#connect the clusters translate to the control's so the cluster will move when the control does
cmds.connectAttr(control + ".translate", cluster + ".translate")
#color controls
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
#hookup stretch to joint scale
cmds.select(ikCurve)
curveInfoNode = cmds.arclen(cmds.ls(sl = True), ch = True )
originalLength = cmds.getAttr(curveInfoNode + ".arcLength")
#create the multiply/divide node that will get the scale factor
divideNode = cmds.shadingNode("multiplyDivide", asUtility = True, name = name + "_divideNode")
cmds.setAttr(divideNode + ".operation", 2)
cmds.setAttr(divideNode + ".input2X", originalLength)
#create the blendcolors node
blenderNode = cmds.shadingNode("blendColors", asUtility = True, name = name + "_blenderNode")
cmds.setAttr(blenderNode + ".color2R", 1)
#connect attrs
cmds.connectAttr(curveInfoNode + ".arcLength", divideNode + ".input1X")
for joint in ikJoints:
cmds.connectAttr(divideNode + ".outputX", joint + ".scaleX")
cmds.connectAttr(divideNode + ".outputX", joint + ".scaleY")
cmds.connectAttr(divideNode + ".outputX", joint + ".scaleZ")
#create the control curves for the ik curve joints
i = 1
ikControls = []
for joint in curveJoints:
if joint != curveJoints[0]:
control = self.createControl("circle", 25, name + "_ik_" + str(i) + "_anim")
cmds.setAttr(control + ".rx", 90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
ikControls.append(control)
#position
constraint = cmds.parentConstraint(joint, control)[0]
cmds.delete(constraint)
#create grp
controlGrp = cmds.group(empty = True, name = control + "_grp")
constraint = cmds.parentConstraint(joint, controlGrp)[0]
cmds.delete(constraint)
#setup hierarchy
cmds.parent(control, controlGrp)
cmds.parent(joint, control)
#color controls
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
#lock attrs
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
else:
#find parent of base joint and constrain base joint to the parent
parent = cmds.listRelatives("driver_" + name + "_01", parent = True)[0]
#create a control for the base
control = self.createControl("circle", 30, name + "_ik_base_anim")
cmds.setAttr(control + ".rx", 90)
cmds.makeIdentity(control, t = 1, r = 1, s = 1, apply = True)
#position
constraint = cmds.parentConstraint(joint, control)[0]
cmds.delete(constraint)
#create grp
controlGrp = cmds.group(empty = True, name = control + "_grp")
constraint = cmds.parentConstraint(joint, controlGrp)[0]
cmds.delete(constraint)
#setup hierarchy
cmds.parent(control, controlGrp)
cmds.parent(joint, control)
#color controls
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 17)
#lock attrs
cmds.aliasAttr("global_scale", control + ".scaleZ")
cmds.connectAttr(control + ".scaleZ", control + ".scaleX")
cmds.connectAttr(control + ".scaleZ", control + ".scaleY")
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#hook the base control grp to the chain's parent
cmds.parentConstraint(parent, controlGrp, mo = True)
i = i + 1
#parent the other IK grp controls under the base
for control in ikControls:
grp = control + "_grp"
cmds.parent(grp, name + "_ik_base_anim")
#tip control only:
#add attr to show clusters on tip control
tipControl = ikControls[len(ikControls) - 1]
cmds.select(tipControl)
cmds.addAttr(longName=("clusterControlVis"), at = 'bool', dv = 0, keyable = True)
for control in clusterControls:
cmds.connectAttr(tipControl + ".clusterControlVis", control + ".v")
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
cmds.setAttr(control + ".rx", lock = True, keyable = False)
cmds.setAttr(control + ".ry", lock = True, keyable = False)
cmds.setAttr(control + ".rz", lock = True, keyable = False)
#set color for tip
cmds.setAttr(tipControl + ".overrideColor", 17)
#lock tip attrs
cmds.setAttr(tipControl + ".sx", lock = True, keyable = False)
cmds.setAttr(tipControl + ".sy", lock = True, keyable = False)
cmds.setAttr(tipControl + ".sz", lock = True, keyable = False)
cmds.setAttr(tipControl + ".v", lock = True, keyable = False)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#Dynamics RIG
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
dynamicJoints = []
for i in range(int(numJointsInChain)):
jointNum = i + 1
#create and position the joint
if cmds.objExists("rig_dyn_" + name + "_0" + str(jointNum)):
cmds.delete("rig_dyn_" + name + "_0" + str(jointNum))
cmds.select(clear = True)
joint = cmds.joint(name = "rig_dyn_" + name + "_0" + str(jointNum))
if joint.find("|") == 0:
joint = joint.partition("|")[2]
cmds.select(clear = True)
dynamicJoints.append(joint)
constraint = cmds.parentConstraint("driver_" + name + "_0" + str(jointNum), joint)[0]
cmds.delete(constraint)
#recreate the joint heirarchy
if i != 0:
cmds.parent(joint, lastJoint)
lastJoint = joint
#freeze rotations on joints
cmds.makeIdentity(dynamicJoints[0], t = False, r = True, scale = False, apply = True)
#Create curve on joint chain
positions = []
#get the world space positions of each joint, and create a curve using those positions
for i in range(int(len(dynamicJoints))):
pos = cmds.xform(dynamicJoints[i], q = True, ws = True, t = True)
positions.append(pos)
createCurveCommand = "curve -d 1"
for pos in positions:
xPos = pos[0]
yPos = pos[1]
zPos = pos[2]
createCurveCommand += " -p " + str(xPos) + " " + str(yPos) + " " + str(zPos)
for i in range(int(len(positions))):
createCurveCommand += " -k " + str(i)
curve = mel.eval(createCurveCommand)
curve = cmds.rename(curve, name + "_dynCurve")
cmds.setAttr(curve + ".v", 0)
#Create hair system
cmds.select(curve)
#find all hair systems in scene
hairSystems = cmds.ls(type = "hairSystem")
hairSys = ""
#create the hair system and make the stiffness uniform
madeHairCurve = True
if hairSys == "":
hairSys = cmds.createNode("hairSystem")
cmds.removeMultiInstance(hairSys + ".stiffnessScale[1]", b = True)
cmds.setAttr(hairSys + ".clumpWidth", 0.0)
cmds.connectAttr("time1.outTime", hairSys + ".currentTime")
hairSysParent = cmds.listRelatives(hairSys, parent = True)
hairSysParent = cmds.rename(hairSysParent, name + "_hairSystem")
cmds.setAttr(hairSysParent + ".v", 0)
hairSys = name + "_hairSystemShape"
#create the hair follicle
hair = cmds.createNode("follicle")
cmds.setAttr(hair + ".parameterU", 0)
cmds.setAttr(hair + ".parameterV", 0)
hairTransforms = cmds.listRelatives(hair, p = True)
hairDag = hairTransforms[0]
hairDag = cmds.rename(hairDag, name + "_follicle")
hair = name + "_follicleShape"
cmds.setAttr(hairDag + ".v", 0)
cmds.setAttr(hair + ".startDirection", 1)
#get the curve CVs and set follicle degree to 1 if CVs are less than 3
curveCVs = cmds.getAttr(curve + ".cp", size = True)
if curveCVs < 3:
cmds.setAttr(hair + ".degree", 1)
#parent the curve to the follicle and connect the curve's worldspace[0] to the follicle startPos
cmds.parent(curve, hairDag, relative = True)
cmds.connectAttr(curve + ".worldSpace[0]", hair + ".startPosition")
#connect the hair follicle to the hair system
cmds.connectAttr(hair + ".outHair", hairSys + ".inputHair[0]")
#create a new curve and connect the follicle's outCurve attr to the new curve
cmds.connectAttr(hairSys + ".outputHair[0]", hair + ".currentPosition")
crv = cmds.createNode("nurbsCurve")
crvParent = cmds.listRelatives(crv, parent = True)[0]
crvParent = cmds.rename(crvParent, name + "_track_rt_curve")
crv = name + "_track_rt_curveShape"
cmds.setAttr(crvParent + ".v", 0)
cmds.connectAttr(hair + ".outCurve", crv + ".create")
#set the hair follicle attrs
if len(hairDag) > 0:
cmds.setAttr(hairDag + ".pointLock", 3)
cmds.setAttr(hairDag + ".restPose", 1)
cmds.select(hairSys)
#Create Spline Handle for the selected chain and the duplicated curve. the original is driven by hair
ikNodes = cmds.ikHandle(sol = "ikSplineSolver", ccv = False, pcv = False, snc = True, rootTwistMode = False, sj = dynamicJoints[0], ee = dynamicJoints[len(dynamicJoints) - 1], c = crv)[0]
cmds.setAttr(ikNodes + ".v", 0)
ikNodes = cmds.rename(ikNodes, name + "_dynChain_ikHandle")
#Create a duplicate joint chain for manual animation
dupeChain = cmds.duplicate(dynamicJoints[0], rr = True, rc = True)
dupeStartJoint = dupeChain[0]
dupeJoints = cmds.listRelatives(dupeStartJoint, ad = True)
joints = cmds.listRelatives(dynamicJoints[0], ad = True)
#rename duped joints and connect real joints to duped joints
for i in range(int(len(joints))):
if cmds.objectType(dupeJoints[i], isType = 'joint'):
cmds.rename(dupeJoints[i], "ANIM_" + joints[i])
cmds.connectAttr("ANIM_" + joints[i] + ".r", joints[i] + ".r", force = True)
else:
cmds.delete(dupeJoints[i])
#connect up start joint to ANIM start joint
cmds.connectAttr(dupeStartJoint + ".t", dynamicJoints[0] + ".t")
cmds.connectAttr(dupeStartJoint + ".r", dynamicJoints[0] + ".r")
cmds.connectAttr(dupeStartJoint + ".s", dynamicJoints[0] + ".s")
dupeStartJoint = cmds.rename(dupeStartJoint, "ANIM_" + dynamicJoints[0])
#cmds.parent(dupeStartJoint, world = True)
#Create skinCluster between duplicate curve and animation joint chain(dupe chain)
cmds.select(dupeStartJoint, hi = True)
dupeSkel = cmds.ls(sl = True, type = "joint")
cmds.select(curve)
cmds.select(dupeSkel, add = True)
skinCluster = cmds.skinCluster(tsb = True, mi = 3, dr = 4)
#Create the control that has all of our dynamic attrs
control = self.createControl("square", 30, name + "_dyn_anim")
constraint = cmds.parentConstraint(dynamicJoints[0], control)[0]
cmds.delete(constraint)
cmds.makeIdentity(control, r = 1, t = 0, s = 0, apply = True)
cmds.setAttr(control + ".rx", 90)
ctrlGrp = cmds.group(empty = True, name = control + "_grp")
constraint = cmds.parentConstraint(dynamicJoints[0], ctrlGrp)[0]
cmds.delete(constraint)
cmds.parent(control, ctrlGrp)
cmds.makeIdentity(control, r = 1, t = 1, s = 1, apply = True)
cmds.parentConstraint(control, dupeStartJoint)
#lock attrs
cmds.setAttr(control + ".sx", lock = True, keyable = False)
cmds.setAttr(control + ".sy", lock = True, keyable = False)
cmds.setAttr(control + ".sz", lock = True, keyable = False)
cmds.setAttr(control + ".v", lock = True, keyable = False)
#add attrs
cmds.select(control)
cmds.addAttr(ln = "___DYNAMICS___", at = "double", keyable = True)
cmds.setAttr(control + ".___DYNAMICS___", lock = True)
cmds.addAttr(ln = "chainAttach", at = "enum", en = "No Attach:Base:Tip:Both End:", dv = 1, keyable = True)
cmds.addAttr(ln = "chainStartEnvelope", at = "double", min = 0, max = 1, dv = 1, keyable = True)
cmds.addAttr(ln = "chainStartFrame", at = "double", dv = 1, keyable = True)
cmds.addAttr(ln = "___BEHAVIOR___", at = "double", keyable = True)
cmds.setAttr(control + ".___BEHAVIOR___", lock = True)
cmds.addAttr(ln = "chainStiffness", at = "double", min = 0, dv = .1, keyable = True)
cmds.addAttr(ln = "chainDamping", at = "double", min = 0, dv = 0.2, keyable = True)
cmds.addAttr(ln = "chainGravity", at = "double", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "chainIteration", at = "long", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "___COLLISIONS___", at = "double", keyable = True)
cmds.setAttr(control + ".___COLLISIONS___", lock = True)
cmds.addAttr(ln = "chainCollide", at = "bool", dv = 0, keyable = True)
cmds.addAttr(ln = "chainWidthBase", at = "double", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "chainWidthExtremity", at = "double", min = 0, dv = 1, keyable = True)
cmds.addAttr(ln = "chainCollideGround", at = "bool", dv = 0, keyable = True)
cmds.addAttr(ln = "chainCollideGroundHeight", at = "double", dv = 0, keyable = True)
#connect attrs
cmds.connectAttr(control + ".chainStartEnvelope", ikNodes + ".ikBlend")
cmds.connectAttr(control + ".chainAttach", hair + ".pointLock")
cmds.connectAttr(control + ".chainStartFrame", hairSys + ".startFrame")
cmds.connectAttr(control + ".chainStiffness", hairSys + ".stiffness")
cmds.connectAttr(control + ".chainDamping", hairSys + ".damp")
cmds.connectAttr(control + ".chainGravity", hairSys + ".gravity")
cmds.connectAttr(control + ".chainIteration", hairSys + ".iterations")
cmds.connectAttr(control + ".chainCollide", hairSys + ".collide")
cmds.connectAttr(control + ".chainWidthBase", hairSys + ".clumpWidth")
cmds.connectAttr(control + ".chainWidthExtremity", hairSys + ".clumpWidthScale[1].clumpWidthScale_FloatValue")
cmds.connectAttr(control + ".chainCollideGround", hairSys + ".collideGround")
cmds.connectAttr(control + ".chainCollideGroundHeight", hairSys + ".groundHeight")
#Create the expression for real time
track_RealTime = cmds.spaceLocator(name = name + "_track_rt_loc")[0]
cmds.pointConstraint(dupeSkel[len(dupeSkel) -1], track_RealTime)
connections = cmds.listConnections(hairSys + ".currentTime", p = True, c = True)
cmds.disconnectAttr(connections[1], connections[0])
expressionString = "if(frame!= " + hairSys + ".startFrame)\n\t" + hairSys + ".currentTime = " + hairSys + ".currentTime + 1 + " + track_RealTime + ".tx - " + track_RealTime + ".tx + " + track_RealTime + ".ty - " + track_RealTime + ".ty + " + track_RealTime + ".tz - " + track_RealTime + ".tz + " + control + ".chainWidthBase - "+ control + ".chainWidthBase + "+ control + ".chainWidthExtremity - "+ control + ".chainWidthExtremity + " + control + ".chainGravity - "+ control + ".chainGravity;\n" +"else\n\t" + hairSys + ".currentTime = " + hairSys + ".startFrame;"
cmds.expression(name = "EXP_" + hairSys + "_TRACK_RealTime", string = expressionString)
cmds.setAttr(track_RealTime + ".v", 0)
#Set Defaults
cmds.setAttr(hairSys + ".drawCollideWidth", 1)
cmds.setAttr(hairSys + ".widthDrawSkip", 0)
cmds.setAttr(hair + ".degree", 1)
cmds.parentConstraint(parent, ctrlGrp, mo = True)
if cmds.objExists("dynHairChain") == False:
cmds.group(empty = True, name = "dynHairChain")
if cmds.objExists(dynamicJoints[0] + "_HairControls") == False:
group = cmds.group([ikNodes, hairSys, hair, track_RealTime, ctrlGrp, crvParent], name = dynamicJoints[0] + "_HairControls")
else:
cmds.parent([ikNodes, hairSys, hair, ctrlGrp,crvParent ], dynamicJoints[0] + "_HairControls")
cmds.parent(group, "dynHairChain")
#Cleanup
jointsGrp = cmds.group(empty = True, name = name + "_jointGrp")
cmds.parent([dynamicJoints[0], dupeStartJoint], jointsGrp)
cmds.setAttr(control + ".overrideEnabled", 1)
cmds.setAttr(control + ".overrideColor", 18)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#CLEAN UP SCENE
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
ikGrp = cmds.group(empty = True, name = name + "_ik_ctrl_grp")
clustersGrp = cmds.group(empty = True, name = name + "_ik_clusters_grp")
dynGrp = cmds.group(empty = True, name = name + "_dyn_ctrl_grp")
masterGrp = cmds.group(empty = True, name = name + "_master_ctrl_grp")
createdControls.append(masterGrp)
#need to parent control groups in here
cmds.parent([ikHandle, ikJoints[0], ikCurve, name + "_ik_base_anim_grp"], ikGrp)
for cluster in clusterNodes:
cmds.parent(cluster, clustersGrp)
for grp in ikAnimGrps:
cmds.parent(grp, ikGrp)
cmds.parent(clustersGrp, "master_anim")
cmds.setAttr(clustersGrp + ".inheritsTransform", 0)
cmds.parent(name + "_jointGrp", dynGrp)
cmds.parent([ikGrp, dynGrp, fkRootGrp], masterGrp)
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
#HOOKUP RIGS TO RIG SETTINGS
#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#
cmds.select("Rig_Settings")
cmds.addAttr(longName= (name + "_fk"), defaultValue=1, minValue=0, maxValue=1, keyable = True)
cmds.addAttr(longName= (name + "_ik"), defaultValue=0, minValue=0, maxValue=1, keyable = True)
cmds.addAttr(longName= (name + "_dynamic"), defaultValue=0, minValue=0, maxValue=1, keyable = True)
for i in range(int(len(dynamicJoints))):
driverJoint = dynamicJoints[i].replace("rig_dyn_", "driver_")
constraint = cmds.parentConstraint([fkJoints[i], ikJoints[i], dynamicJoints[i]], driverJoint)[0]
cmds.connectAttr("Rig_Settings." + name + "_fk", constraint + "." + fkJoints[i] + "W0")
cmds.connectAttr("Rig_Settings." + name + "_ik", constraint + "." + ikJoints[i] + "W1")
cmds.connectAttr("Rig_Settings." + name + "_dynamic", constraint + "." + dynamicJoints[i] + "W2")
#create blend Color nodes for scale
scaleBlendColors = cmds.shadingNode("blendColors", asUtility = True, name = name + "_scale_blend")
cmds.connectAttr(firstControl + ".scale", scaleBlendColors + ".color1")
cmds.connectAttr(name + "_ik_base_anim" + ".scale", scaleBlendColors + ".color2")
cmds.connectAttr(scaleBlendColors + ".output", driverJoint + ".scale")
cmds.connectAttr("Rig_Settings." + name + "_fk", scaleBlendColors + ".blender")
#setup visibility connections
cmds.connectAttr("Rig_Settings." + name + "_fk", fkRootGrp + ".v")
cmds.connectAttr("Rig_Settings." + name + "_ik", ikGrp + ".v")
cmds.connectAttr("Rig_Settings." + name + "_dynamic", name + "_dyn_anim_grp.v")
return createdControls
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def createDriverSkeleton(self):
dupe = cmds.duplicate("root", rc = True)[0]
cmds.select("root", hi = True)
joints = cmds.ls(sl = True)
cmds.select(dupe, hi = True)
dupeJoints = cmds.ls(sl = True)
driverJoints = []
for i in range(int(len(dupeJoints))):
if cmds.objExists(dupeJoints[i]):
driverJoint = cmds.rename(dupeJoints[i], "driver_" + joints[i])
driverJoints.append(driverJoint)
#create a direct connection between the driver and the export joints
exceptionJoints = ["upperarm_l", "upperarm_r"]
for joint in driverJoints:
exportJoint = joint.partition("_")[2]
if exportJoint not in exceptionJoints:
cmds.connectAttr(joint + ".translate", exportJoint + ".translate")
cmds.connectAttr(joint + ".rotate", exportJoint + ".rotate")
cmds.connectAttr(joint + ".scale", exportJoint + ".scale")
else:
cmds.connectAttr(joint + ".translate", exportJoint + ".translate")
cmds.connectAttr(joint + ".scale", exportJoint + ".scale")
cmds.orientConstraint(joint, exportJoint)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def getSpineJoints(self):
numSpineBones = int(cmds.getAttr("Skeleton_Settings.numSpineBones"))
spineJoints = []
for i in range(int(numSpineBones)):
if i < 10:
spineJoint = "spine_0" + str(i + 1)
else:
spineJoint = "spine_" + (i + 1)
spineJoints.append(spineJoint)
return spineJoints
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def createControl(self, controlType, size, name):
scale = self.getScaleFactor()
if controlType == "circle":
control = cmds.circle(c = (0,0,0), sw = 360, r = size * scale, d = 3, name = name)[0]
if controlType == "circleSpecial":
control = cmds.circle(c = (0,0,0), sw = 360, r = 1, d = 3, name = name)[0]
side = name.rpartition("_")[2]
if side == "l":
cmds.xform(control, piv = (0, -1, 0))
else:
cmds.xform(control, piv = (0, 1, 0))
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
if controlType == "square":
control = cmds.circle(c = (0,0,0), s = 4, sw = 360, r = size * scale, d = 1, name = name)[0]
cmds.setAttr(control + ".rz", 45)
if controlType == "foot":
control = cmds.curve(name = name, d = 3, p = [(0, 40, 0), (-3.42, 39, 0), (-10.2, 37, 0), (-13, 22, 0), (-15.7, 13.2, 0), (-20, -14, 0), (-18.1, -25.6, 0), (-15, -44.8, 0), (1.1, -41.2, 0), (4.8, -41.7, 0), (15.5, -31.9, 0), (16.9, -22.7, 0), (18.6, -15.2, 0), (16.5, -.5, 0), (11.2, 29.2, 0), (10.7, 39.7, 0), (3.6, 39.9, 0), (0, 40, 0)])
footLoc = cmds.spaceLocator(name = (name + "_end_loc"))[0]
cmds.parent(footLoc, control)
cmds.setAttr(footLoc + ".ty", -40)
cmds.setAttr(footLoc + ".v", 0)
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
if controlType == "arrow":
control = cmds.curve(name = name, d = 1, p = [(0, -45, 0), (5, -45, 0), (5, -62, 0), (10, -62, 0), (0, -72, 0), (-10, -62, 0), (-5, -62, 0), (-5, -45, 0), (0, -45, 0)])
cmds.xform(control, cp = True)
cmds.setAttr(control + ".ty", 58.5)
cmds.makeIdentity(control, t = 1, apply = True)
cmds.xform(control, piv = (0, 13.5, 0))
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
if controlType == "arrowOnBall":
control = cmds.curve(name = name, d = 1, p = [(0.80718, 0.830576, 8.022739), (0.80718, 4.219206, 7.146586 ), (0.80718, 6.317059, 5.70073), (2.830981, 6.317059, 5.70073), (0, 8.422749, 2.94335), (-2.830981, 6.317059, 5.70073), (-0.80718, 6.317059, 5.70073), (-0.80718, 4.219352, 7.146486), (-0.80718, 0.830576, 8.022739), (-4.187851, 0.830576, 7.158003), (-6.310271, 0.830576, 5.705409), (-6.317059, 2.830981, 5.7007), (-8.422749, 0, 2.94335), (-6.317059, -2.830981, 5.70073), (-6.317059, -0.830576, 5.70073), (-4.225134, -0.830576, 7.142501), (-0.827872, -0.830576, 8.017446), (-0.80718, -4.176512, 7.160965), (-0.80718, -6.317059, 5.70073), (-2.830981, -6.317059, 5.70073), (0, -8.422749, 2.94335), (2.830981, -6.317059, 5.70073), (0.80718, -6.317059, 5.70073), (0.80718, -4.21137, 7.151987), (0.80718, -0.830576, 8.022739), (4.183345, -0.830576, 7.159155), (6.317059, -0.830576, 5.70073), (6.317059, -2.830981, 5.70073), (8.422749, 0, 2.94335), (6.317059, 2.830981, 5.70073), (6.317059, 0.830576, 5.70073), (4.263245, 0.830576, 7.116234), (0.80718, 0.830576, 8.022739)])
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
if controlType == "semiCircle":
control = cmds.curve(name = name, d = 3, p = [(0,0,0), (7, 0, 0), (8, 0, 0), (5, 4, 0), (0, 5, 0), (-5, 4, 0), (-8, 0, 0), (-7, 0, 0), (0,0,0)])
cmds.xform(control, ws = True, t = (0, 5, 0))
cmds.xform(control, ws = True, piv = (0,0,0))
cmds.makeIdentity(control, t = 1, apply = True)
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
if controlType == "pin":
control = cmds.curve(name = name, d = 1, p = [(12,0,0), (0, 0, 0), (-12, -12, 0), (-12, 12, 0), (0, 0, 0)])
cmds.xform(control, ws = True, piv = [12,0,0])
cmds.setAttr(control + ".scaleY", .5)
cmds.makeIdentity(control, t = 1, apply = True)
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
if controlType == "sphere":
points = [(0, 0, 1), (0, 0.5, 0.866), (0, 0.866025, 0.5), (0, 1, 0), (0, 0.866025, -0.5), (0, 0.5, -0.866025), (0, 0, -1), (0, -0.5, -0.866025), (0, -0.866025, -0.5), (0, -1, 0), (0, -0.866025, 0.5), (0, -0.5, 0.866025), (0, 0, 1), (0.707107, 0, 0.707107), (1, 0, 0), (0.707107, 0, -0.707107), (0, 0, -1), (-0.707107, 0, -0.707107), (-1, 0, 0), (-0.866025, 0.5, 0), (-0.5, 0.866025, 0), (0, 1, 0), (0.5, 0.866025, 0), (0.866025, 0.5, 0), (1, 0, 0), (0.866025, -0.5, 0), (0.5, -0.866025, 0), (0, -1, 0), (-0.5, -0.866025, 0), (-0.866025, -0.5, 0), (-1, 0, 0), (-0.707107, 0, 0.707107), (0, 0, 1)]
control = cmds.curve(name = name, d = 1, p = points)
cmds.setAttr(control + ".scaleX", size * scale)
cmds.setAttr(control + ".scaleY", size * scale)
cmds.setAttr(control + ".scaleZ", size * scale)
return control
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def getScaleFactor(self):
headLoc = cmds.spaceLocator(name = "headLoc")[0]
cmds.parentConstraint("head", headLoc)
height = cmds.getAttr(headLoc + ".tz")
defaultHeight = 400
scaleFactor = height/defaultHeight
cmds.delete(headLoc)
return scaleFactor
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def getUpAxis(self, obj):
cmds.xform(obj, ws = True, relative = True, t = [0, 0, 10])
translate = cmds.getAttr(obj + ".translate")[0]
newTuple = (abs(translate[0]), abs(translate[1]), abs(translate[2]))
cmds.xform(obj, ws = True, relative = True, t = [0, 0, -10])
highestVal = max(newTuple)
axis = newTuple.index(highestVal)
upAxis = None
if axis == 0:
upAxis = "X"
if axis == 1:
upAxis = "Y"
if axis == 2:
upAxis = "Z"
return upAxis
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
def normalizeSubVector(self, vector1, vector2):
import math
returnVec = []
for i in range(len(vector1)):
returnVec.append(vector1[i] - vector2[i])
#get length of vector
length = math.sqrt( (returnVec[0] * returnVec[0]) + (returnVec[1] * returnVec[1]) + (returnVec[2] * returnVec[2]) )
#normalize the vector
normalizedVector = []
for i in range(len(returnVec)):
normalizedVector.append(returnVec[i]/length)
absVector = []
for i in range(len(normalizedVector)):
absVector.append(abs(normalizedVector[i]))
aimAxis = max(absVector)
aimAxisIndex = absVector.index(aimAxis)
if aimAxisIndex == 0:
if normalizedVector[0] < 0:
axis = "X"
if normalizedVector[0] > 0:
axis = "-X"
if aimAxisIndex == 1:
if normalizedVector[1] < 0:
axis = "Y"
if normalizedVector[1] > 0:
axis = "-Y"
if aimAxisIndex == 2:
if normalizedVector[2] < 0:
axis = "Z"
if normalizedVector[2] > 0:
axis = "-Z"
return axis