|

Automated Stretchy IK
Limbs
Before we go about creating our script lets quickly go over the
logistics of how to create stretchy IK limbs.
| 1) create a simple arm |

|
| 2) create an RP IK handle |

|
3. a)create a
controller b)group it to itself c) point snap the group to the
IK handle d) parent the IK handle to the controller (not the
group) e) hide the IK handle |

|
4. a) create a measurement
tool with the first locator at the first joint and the last at the
last joint b) point constrain the first locator to the first
joint c) point constrain the second locator the the third
joint
|

|
5. In the Hypergraph bring
together the following nodes (MMB click and drag) - the
distanceDimention shape node - the 1st and 2nd joints
and
create both a multiply/divide and a conditional node |

|
6. stretch the arm until it
is fully extended and can no longer be stretched.
|

|
7. Return to the hypergraph
and connect the distanceDimention distance value to the firstTerm
value of Condition1. Open the attribute editor for the condition
node

The copy this value from the first term box to the
Second Term box and set
the operation to Greater
Than |

|
|
9. Now connect the distance value to the inputX
of the multiplyDivide node. Open the attribute editor for the
multiplyDivide node.
 Set the operation to
Divide, and copy the
value you seen in Input1 to Input2.
|
 |
|
10. Now connect the outputX of the
multiplyDivide to the colourIfTrueR of the condition.
Once you have these values recorded and the appropriate
connections are made return the controller to its zero position then
remove the point constraint on the locator2 of the distance
measure and parent it to the controller. YOU MUST DO THIS BEFORE THE
NEXT STEP.
|

|
|
11. Finally we connect the outColorR to both the joint1 and
joint2 scaleX.
And there we go, we have a very basic stretch limb setup.
|
 |
So now on to scripting...
Lets assume that the arm already exists with the IK handle and
controller already setup (like this
file)
The first step is to create a measurement tool between the first and
last joints.
in MEL this is
distanceDimension -sp X1 Y1 Z1 -ep X2 Y2
Z2;
First, assuming we have both the beginning and end joints selected (we
can invent later some logic to ensure this) we will identify the
selection.
string $jointSelection[]; $jointSelection = `ls -sl`;
So we
will have to be able to extract the coordinates of the beginning and end
joints.
float $jointTrans1[],
$jointTrans2[]; $jointTrans1 = eval("pointPosition -w
"+$jointSelection[0]+".selectHandle"); $jointTrans2 =
eval("pointPosition -w
"+$jointSelection[1]+".selectHandle");
so now we can create our distance dimention with
distanceDimension -sp $jointTrans1[0] $jointTrans1[1] $jointTrans1[2] -ep $jointTrans2[0] $jointTrans2[1] $jointTrans2[2];
Now we find out the name of the distance measure and then change it to
a name we can recognise
string
$distanceMeasures[]; $distanceMeasures = `ls -sl`; rename
$distanceMeasures[1] "stretchLimit";
Next we identify what each of the controlling locators is called and
then point constrain them to the joints.
string $mLocators[]; $mLocators = `
listConnections stretchLimitShape`; pointConstraint -n pc0
$jointSelection[0] $mLocators[0]; pointConstraint -n pc1
$jointSelection[1] $mLocators[1];
Next we create the
required utility nodes
shadingNode -n limitCondition -asUtility
condition; setAttr limitCondition.operation 2; //Greater
Than
shadingNode -n stretchScale -asUtility
multiplyDivide; setAttr stretchScale.operation 2; //Divide
Operation
Move the controller to a stretched pose
setAttr "Wrist_Controller.translateX"
10;
Then start to set up our connections
float $unitStretch = `getAttr
stretchLimitShape.distance`;
connectAttr -f stretchLimitShape.distance
limitCondition.firstTerm; setAttr "limitCondition.secondTerm"
$unitStretch;
connectAttr -f stretchLimitShape.distance
stretchScale.input1X; setAttr "stretchScale.input2X" $unitStretch;
connectAttr -f stretchScale.outputX
limitCondition.colorIfTrueR;
Now we return our controller to its zero position and delete the point
constraint.
setAttr "Wrist_Controller.translateX"
0; delete pc0; parent $mLocators[0] Wrist_Controller;
And the jewel in the crown is to connect up the out condition (the
relative scale) to the scaleX or each of the top two joints.
eval("connectAttr -f limitCondition.outColorR
"+$jointSelection[0]+".scaleX"); $elbowJoint = `listRelatives - c
$jointSelection[1]`; eval("connectAttr -f limitCondition.outColorR
"+$elbowJoint[0]+".scaleX");
Finally we probably want to hide the measurement nodes
setAttr "stretchLimit.visibility" 0; eval("setAttr "+$mLocators[0]+".visibility 0");
eval("setAttr "+$mLocators[1]+".visibility 0");
And thats about it
Sure there is a lot of error and exception control that is still
needed, but its a good start.
-------------------------------------------------------------------------------------------------------------------- Here
is the whole code without any clever flow control, but it does the trick
--------------------------------------------------------------------------------------------------------------------
string $jointSelection[]; $jointSelection = `ls -sl`; float $jointTrans1[], $jointTrans2[]; $jointTrans1 =
eval("pointPosition -w
"+$jointSelection[0]+".selectHandle"); $jointTrans2 =
eval("pointPosition -w
"+$jointSelection[1]+".selectHandle"); distanceDimension -sp
$jointTrans1[0] $jointTrans1[1]
$jointTrans1[2] -ep $jointTrans2[0]
$jointTrans2[1]
$jointTrans2[2]; string
$distanceMeasures[]; $distanceMeasures = `ls -sl`; rename
$distanceMeasures[1] "stretchLimit"; string $mLocators[]; $mLocators
= ` listConnections stretchLimitShape`; pointConstraint -n pc0
$jointSelection[0] $mLocators[0]; pointConstraint -n pc1
$jointSelection[1] $mLocators[1]; shadingNode -n limitCondition
-asUtility condition; setAttr limitCondition.operation 2; //Greater
Than shadingNode -n stretchScale -asUtility multiplyDivide; setAttr
stretchScale.operation 2; //Divide Operation setAttr
"Wrist_Controller.translateX" 10; float $unitStretch = `getAttr
stretchLimitShape.distance`; connectAttr -f stretchLimitShape.distance
limitCondition.firstTerm; setAttr "limitCondition.secondTerm"
$unitStretch; connectAttr -f stretchLimitShape.distance
stretchScale.input1X; setAttr "stretchScale.input2X" $unitStretch;
connectAttr -f stretchScale.outputX
limitCondition.colorIfTrueR; setAttr "Wrist_Controller.translateX"
0; delete pc0; parent $mLocators[0]
Wrist_Controller; eval("connectAttr -f limitCondition.outColorR
"+$jointSelection[1]+".scaleX"); $elbowJoint = `listRelatives - c
$jointSelection[1]`; eval("connectAttr -f limitCondition.outColorR
"+$elbowJoint[0]+".scaleX"); setAttr "stretchLimit.visibility"
0; eval("setAttr "+$mLocators[0]+".visibility 0");
eval("setAttr "+$mLocators[1]+".visibility 0");
|