Last active
April 17, 2018 21:52
-
-
Save drewgillievfx/a3698b20fe608dc7e0309dafda41a355 to your computer and use it in GitHub Desktop.
Hand Rigging Project – This code automatically rigs a hand in Maya with help from the user
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/******************************************************************************* | |
Drew Gillie Hand Rigging Project. | |
December 2016 | |
This code is working there may be a few bugs in the mirroring portion of this | |
code depending on the version of Maya being used | |
*******************************************************************************/ | |
if ( `window -exists MyWindow` ) { | |
deleteUI MyWindow; // delete window when it exists | |
} | |
string $myWindow = `window -title "Hand Rigging Tool" -widthHeight 300 310` ; | |
string $myForm = `formLayout -numberOfDivisions 10`; | |
string $HandButton = `button -label "1. Hand" -w 280 -h 40 -command "hand()"`; | |
// | |
string $ThumbButton = `button -label "2. Thumb" -w 130 -h 40 -command "thumb()" `; | |
string $PointerButton = `button -label "2. Pointer" -w 130 -h 40 -command "pointer()" `; | |
string $MiddleButton = `button -label "2. Middle" -w 130 -h 40 -command "middle()" `; | |
string $RingButton = `button -label "2. Ring" -w 130 -h 40 -command "ring()" `; | |
string $PinkyButton = `button -label "2. Pinky" -w 130 -h 40 -command "pinky()" `; | |
// | |
string $CreateJointButton = `button -label "4. Create Joint" -w 130 -h 40 -command "jointCreate()" `; | |
// | |
string $MirrorHandButton = `button -label "5. Mirror Hand" -w 130 -h 40 -command "mirrorHand()" `; | |
// | |
string $ControlCreateButton = `button -label "3. Control Create" -w 130 -h 40 -command "controlCreate()" `; | |
// | |
string $UserControlButton = `button -label "3. Use Prev Control" -w 130 -h 40 -command "userControl()" `; | |
formLayout -edit // need to move buttons around at later time {delete comment when done} | |
-attachForm $HandButton "top" 10 | |
-attachForm $HandButton "left" 10 | |
-attachForm $ThumbButton "top" 60 | |
-attachForm $ThumbButton "left" 10 | |
-attachForm $PointerButton "top" 110 | |
-attachForm $PointerButton "left" 10 | |
-attachForm $MiddleButton "top" 160 | |
-attachForm $MiddleButton "left" 10 | |
-attachForm $RingButton "top" 210 | |
-attachForm $RingButton "left" 10 | |
-attachForm $PinkyButton "top" 260 | |
-attachForm $PinkyButton "left" 10 | |
-attachForm $CreateJointButton "top" 160 | |
-attachForm $CreateJointButton "right" 10 | |
-attachForm $MirrorHandButton "top" 210 | |
-attachForm $MirrorHandButton "right" 10 | |
-attachForm $UserControlButton "top" 60 | |
-attachForm $UserControlButton "right" 10 | |
-attachForm $ControlCreateButton "top" 110 | |
-attachForm $ControlCreateButton "right" 10 | |
$myForm; | |
showWindow $myWindow; | |
/******************************************************************************* | |
*******************************************************************************/ | |
/* Basically user will create hand control, then place in scene where the | |
wrist is located on character. | |
Then pressing button for each finger will create finger locators, which the y | |
and z values need to be gathered from the wrist and offset by some amount. */ | |
global proc hand(){ | |
spaceLocator -n "handLoc"; | |
move -r 0 0 0; // hand | |
sets -n locSet handLoc; // creates selection set and adds first locator | |
} | |
global proc controlCreate(){ // creates hand ctrl curve and adds some attrs | |
curve -d 3 -p 0 0 4 | |
-p 1 0 5 | |
-p 2 0 5 | |
-p 5 0 5 | |
-p 10 0 2 | |
-p 10 0 -4 | |
-p 0 0 -4 | |
-p 0 0 -4 | |
-p 0 0 -4 | |
-p 0 0 4 ; | |
$WTX = `getAttr "handLoc.tx"`; | |
$WTY = `getAttr "handLoc.ty"`; | |
$WTZ = `getAttr "handLoc.tz"`; | |
rename "curve1" "L_handCtrl"; | |
move -r ($WTX + 0) ($WTY + 2) ($WTZ + 0); | |
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -pn 1; | |
// attributes | |
addAttr -ln "__________" -at double -dv 0 L_handCtrl; | |
setAttr -e-channelBox true |L_handCtrl.__________; | |
} | |
global proc userControl(){ // creates hand ctrl curve and adds some attrs | |
$WTX = `getAttr "handLoc.tx"`; | |
$WTY = `getAttr "handLoc.ty"`; | |
$WTZ = `getAttr "handLoc.tz"`; | |
$uCtrl = `ls -sl`; | |
rename $uCtrl L_handCtrl; | |
select -r L_handCtrl; | |
move -r ($WTX + 0) ($WTY + 2) ($WTZ + 0); | |
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -pn 1; | |
// attributes | |
addAttr -ln "__________" -at double -dv 0 L_handCtrl; | |
setAttr -e-channelBox true |L_handCtrl.__________; | |
// error message for user if control is not selected | |
//error "You must select your hand control curve." | |
} | |
global proc fingerLC( int $fin ){ // finger locator creator | |
$WTX = `getAttr "handLoc.tx"`; | |
$WTY = `getAttr "handLoc.ty"`; | |
$WTZ = `getAttr "handLoc.tz"`; | |
string $fALoc[] = {"space", "ThumbLoc0", "PointerLoc0", "MiddleLoc0", "RingLoc0", "PinkyLoc0"}; | |
string $fingerArray[] = {"space", "Thumb", "Pointer", "Middle", "Ring", "Pinky"}; | |
for ($var = 1; $var < 4; $var ++){ | |
// This for loop creates all space locators for the selected fingers | |
int $fingerLocator[] = {0,4,6,9,13,16}; | |
int $mX = $WTX + 5 + $var; | |
int $mY = $WTY + 0; | |
int $mZ = $WTZ + 2; | |
spaceLocator -n ($fALoc[$fin] + $var); // Pointer | |
move -r $mX $mY $mZ; | |
int $colorLocator = $fingerLocator[$fin]; | |
setAttr ($fALoc[$fin] + $var + ".overrideEnabled") 1; | |
setAttr ($fALoc[$fin] + $var + ".overrideColor") $colorLocator; | |
sets -add locSet ($fALoc[$fin] + $var); | |
} | |
/* | |
creates a mult node with coressponding finger and names it that fingerMult | |
for example "thummbMult". | |
It then sets the attr to 10 for each input so that each joint can later | |
be connected to it | |
*/ | |
string $LtempName = ("L" + $fingerArray[$fin] + "Mult"); | |
string $RtempName = ("R" + $fingerArray[$fin] + "Mult"); | |
shadingNode -asUtility multiplyDivide -n $LtempName; | |
shadingNode -asUtility multiplyDivide -n $RtempName; | |
setAttr ($LtempName + ".input2X") 10; | |
setAttr ($LtempName + ".input2Y") 10; | |
setAttr ($LtempName + ".input2Z") 10; | |
setAttr ($RtempName + ".input2X") 10; | |
setAttr ($RtempName + ".input2Y") 10; | |
setAttr ($RtempName + ".input2Z") 10; | |
} | |
/* | |
The next five proc are to be called by the buttons to create the joints at each | |
finger if it is selected. | |
*/ | |
global proc thumb(){ | |
$fin = 1; | |
fingerLC($fin); | |
} | |
global proc pointer(){ | |
$fin = 2; | |
fingerLC($fin); | |
} | |
global proc middle(){ | |
$fin = 3; | |
fingerLC($fin); | |
} | |
global proc ring(){ | |
$fin = 4; | |
fingerLC($fin); | |
} | |
global proc pinky(){ | |
$fin = 5; | |
fingerLC($fin); | |
} | |
/* | |
This procedure will get the location of the spaceLocators in the scene | |
(for the hand creation). it will then create a joint at those points in | |
world space. Each joint should be parented properly | |
*/ | |
global proc jointCreate(){ // Joint creation at the locators | |
// get wrist locator position | |
$WTX = `getAttr "handLoc.tx"`; | |
$WTY = `getAttr "handLoc.ty"`; | |
$WTZ = `getAttr "handLoc.tz"`; | |
// declaring some variables | |
string $fALoc[] = {"space", "ThumbLoc0", "PointerLoc0", | |
"MiddleLoc0", "RingLoc0", "PinkyLoc0"}; | |
string $fingerArray[] = {"space", "L_Thumb", "L_Pointer", | |
"L_Middle", "L_Ring", "L_Pinky"}; | |
string $multAttr[] = {"space", // used for mult node referencing | |
"Thumb", "Pointer", "Middle", "Ring", "Pinky"}; | |
float $R = 0.5; // setting the radius size | |
string $addJnt = "Jnt0"; | |
string $XYZ[] = {"0", "X", "Y", "Z"}; | |
// creating the hand joint | |
select -cl; | |
joint -n L_handJnt -p $WTX $WTY $WTZ -rad $R; | |
select -cl; | |
/* | |
This loop will creat joints for each finger locator. | |
First it selects the hand joint so the finger can be properly parented. | |
Then it needs to get the world space translation of the finger locators. | |
Next it checks to see if that fingers locators exist, if so create joints | |
Then it will connect attributes from the hand ctrl to the joint. | |
*/ | |
for ($lar = 1; $lar < 6; $lar ++){ // finger select loop | |
select -r L_handJnt; | |
for ($var = 1; $var < 4; $var ++){ // finger joint loop | |
// getAttr of selected finger locator | |
$txyz = ($fALoc[$lar] + $var); // 'ThumbLoc01' | |
if (`objExists ($txyz) `) { | |
// get finger locater translation points | |
float $tx1 = `getAttr ($txyz + ".tx")`; | |
float $ty1 = `getAttr ($txyz + ".ty")`; | |
float $tz1 = `getAttr ($txyz + ".tz")`; | |
// create joint at the finger locator points | |
joint -n ($fingerArray[$lar] + $addJnt + $var ) -p $tx1 $ty1 $tz1 -rad $R; | |
$attrName = ($multAttr[$lar] + "0" + $var); // 'finger 01' | |
$multName = ("L" + $multAttr[$lar]); // 'finger' | |
if($lar == 1){ // if thumb is selected, connect it on x axis too! | |
// addAttr to hand ctrl | |
addAttr -ln $attrName -keyable true -at double -min -10 -max 10 -dv 0 L_handCtrl; | |
// connect handAttr into mult node | |
connectAttr ("L_handCtrl." + $attrName) ($multName + "Mult.input1" + $XYZ[$var]) ; | |
// connect mult node output into joint | |
connectAttr ($multName + "Mult.output" + $XYZ[$var]) ($fingerArray[$lar] + $addJnt + $var + ".rotateX"); | |
connectAttr ($multName + "Mult.output" + $XYZ[$var]) ($fingerArray[$lar] + $addJnt + $var + ".rotateZ"); | |
} | |
else{ | |
// addAttr to hand ctrl | |
addAttr -ln $attrName -keyable true -at double -min -10 -max 10 -dv 0 L_handCtrl; | |
// connect handAttr into mult node | |
connectAttr ("L_handCtrl." + $attrName) ($multName + "Mult.input1" + $XYZ[$var]) ; | |
// connect mult node output into joint | |
connectAttr ($multName + "Mult.output" + $XYZ[$var]) ($fingerArray[$lar] + $addJnt + $var + ".rotateZ"); | |
} | |
} | |
} | |
select -cl; | |
} | |
} | |
global proc mirrorHand(){ // Mirroring hand joints | |
// 1. select L_handJnt, mirror it and change name | |
select -r L_handJnt; | |
mirrorJoint -mirrorYZ -mirrorBehavior -searchReplace "L" "R"; | |
// 2. select L_handCtrl, group it, duplicate it | |
select -r L_handCtrl ; | |
doGroup 0 1 1; | |
select -r group1 ; | |
// 3. -1X scale group, freeze transformations | |
duplicate -rr; | |
setAttr "group2.scaleX" -1; | |
rename "group2|L_handCtrl" "R_handCtrl"; | |
makeIdentity -apply true -t 1 -r 1 -s 1 -n 0 -pn 1; | |
// 4. reparent controls to the world | |
select -r R_handCtrl ; | |
parent -w; | |
select -r L_handCtrl ; | |
parent -w; | |
delete group1 group2 ; | |
// connecting the attributes to the joints | |
string $fingerArrayR[] = {"space", "R_Thumb", "R_Pointer", "R_Middle", "R_Ring", "R_Pinky"}; | |
string $multAttrR[] = {"space", "Thumb", "Pointer", "Middle", "Ring", "Pinky"}; | |
string $addJnt = "Jnt0"; | |
string $XYZ[] = {"0", "X", "Y", "Z"}; | |
for ($lar = 1; $lar < 6; $lar ++){ // finger select loop | |
select -r R_handJnt; | |
for ($var = 1; $var < 4; $var ++){ // finger joint loop | |
$Rjoint = ("R_handCtrl." + $multAttrR[$var] + "0" + $var); | |
if (`objExists ($Rjoint) `) { | |
$attrNameR = ($multAttrR[$lar] + "0" + $var); // 'finger 01' | |
$multNameR = ("R" + $multAttrR[$lar]); // 'finger' | |
if($lar == 1){ // if thumb is selected, connect it on x axis too! | |
// connect handAttr into mult node | |
connectAttr ("R_handCtrl." + $attrNameR) ($multNameR + "Mult.input1" + $XYZ[$var]) ; | |
// connect mult node output into joint | |
connectAttr ($multNameR + "Mult.output" + $XYZ[$var]) ($fingerArrayR[$lar] + $addJnt + $var + ".rotateX"); | |
connectAttr ($multNameR + "Mult.output" + $XYZ[$var]) ($fingerArrayR[$lar] + $addJnt + $var + ".rotateZ"); | |
} | |
else{ | |
// connect handAttr into mult node | |
connectAttr ("R_handCtrl." + $attrNameR) ($multNameR + "Mult.input1" + $XYZ[$var]) ; | |
// connect mult node output into joint | |
connectAttr ($multNameR + "Mult.output" + $XYZ[$var]) ($fingerArrayR[$lar] + $addJnt + $var + ".rotateZ"); | |
} | |
} | |
} | |
select -cl; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment