Figured I'd start making some blog posts with tidbits of information to do with anything. Could be some simple stuff, could be some hard stuff :)
Today's mini blog post is on rigging stretchy inverse kinematics in Maya. The example is on a 3-Joint chain but could be applied to different joint setups. To follow this you'll need a base knowledge of working with nodes and rigging in Maya.
First Step: Create your joints, orient them appropriately and create your IK control.
Now the basic theory of stretchy IK. Is a simple if statement. If the distance between the joints is greater or less than this, stretch or don't stretch.
So we need to calculate the distance between all of the joints along with the displacement between the first and last joint. Create three distance nodes along with three locators. Each locator is located at each joint. You can see how I've connected the locators to the distance nodes. Their world space positions are plugged into the relative start and end positions of the distance nodes. I've also constrained the offset groups to their relative joints/controls. Watch out for cyclic errors!
Now that we have calculated our distances we need to do a little math (Oh no!)
The first thing we need to know is our true joint distance. You can either used a plusMinusNode to find out or use your brain or a calculator ;)
So add the distance of the shoulderToElbow and shoulderToWrist together. Mine comes to a value of 9.222. Alright, now that we have that value we need to normalize our distances. To do this we get a multiple divide node. Change the operation to divide and inside Input1.x we plug in our shoulderToWrist distance. In Input2.x we type in our calculated value (In my case 9.222) This is going to give us a value between 0 - 1
Alrighty, now that our distance is normalized we need to find out whether our joints should stretch or not. So we're going to make our if statement. To do that in maya we can use a condition node. Change the operation to Greater Than. Inside the First Term plug in the Output.x from the previous multiply divide node. Inside ColourIfTrue.r plug in the Output.x value from the node as well. Change the second term to 1 and ColourIfFalse.r to 1 as well. What we're asking here is if the normalized distance between our joints is somehow greater than one we are going to stretch the joints. If not we're not going to stretch the joints. (Hence the 1)
Ok, we're nearly there. Now we just need to take the OutColor.r of our condition node and plug that into the Scale.x of our first and second joint (In my case this is the shoulder and elbow) and voila a stretchy IK arm.
Now if you want this to scale with your rig all you need to do is make a small change to that original distance we calculated earlier. Add a multiply divide node with the operation set to multiply. In the Input1.x value plug in your global scale attribute (however you've gone about it) and in the Input2.x put the value from earlier. Then we take the output.x from this node and replace the Input2.x in our normalize node.
That's the basics of it. This is joint scaling based stretchy IK. You can also do translation based stretchy IK but it requires a little more math (I might show this in another blog post!). On top of this stretchy IK, you can take it further, I'd recommend adding in another condition node where you input a value to turn stretchy on or off. Middle joint pinning is also another great addition along with volume perservation