PDA

View Full Version : Countering IK-Popping without the use of fine-tuned set driven keys/reactions


Aearon
05-12-2007, 09:00 PM
I sat down this weekend and tried to figure out a formula for countering IK-pop, the effect of an IK joint chain ‘snapping’ into position when approaching full stretch, using a function that would work for any joint chain consisting of two bones, without fine-tuning any set driven keys or reactions, as I’ve seen it in some rigs and used to do it myself.

I just want to share the following solution that i came up with. it works for any chain length as far as i've tested and also with uneven joint lengths.

Basically it counters the exponential speed increase of the middle joint by exponentially stretching the two joints as the chain approaches full stretch.

You can see the effect of this function here, the red line is the trajectory of the middle joint when the IK goal moves away from the start joint at constant speed. The spacing between the keys gives you an idea of it's speed. Without the function applied, the speed of the joint increases exponentially, resulting in the familiar snapping effect. With the function applied the motion is much smoother.

http://www.aearon.de/files/public/smoothik.gif

The code

initLenA = 50.0 -- initial length of the first bone
initLenB = 50.0 -- initial length of the second bone
startDist = 0.965 -- the normalized distance at which the stretch will start
endDist = 1.059 -- the normalized distance at which the stretch will end
mult = 0.0295 -- multiplier for the stretch effect
exp = pi/2 -- exponent for the stretch effect

-- momentary distance between first bone and ik goal
dist = distance ikGoal firstBone

-- divide distance by sum of initial bone lengths (so dist equals 1 when chain is just fully stretched)
dist /= initLenA+initLenB

-- scale dist from [startDist,endDist] to [0,1] so we can apply an exponent to it and use it as a multiplier for the stretch function
blendVal = dist - startDist
blendVal /= (endDist - startDist)
if blendVal < 0.0 then blendVal = 0.0
if blendVal > 1.0 then blendVal = 1.0

-- stretch function
return ((initLenA+initLenB) * mult * blendVal^exp)

The resulting value is added to the initial length of both bones.

Note that this is not an auto-stretch solution, it only stretches the chain as far as it needs to achieve smooth motion. Automatic stretching can be implemented on top of this. The stretching of the chain is practically invisible in motion. the stretching is fairly subtle so it hardly changes the proportions of a character.

eek
05-12-2007, 11:19 PM
Hi Kai,

Awesome work! I was thinking if its even cleaner to use a curve interpolation to slow down the solver when it reaches its limits, with a simple bezier curve function. First by getting your range of the combined lengths of the bones / by the distance like yours:

so start being 0.95 and end being 1.05 - converting this into a range of t[0,1] and passing it into a bezier function of the lengths you want to add. So for example instead of passing it two knots and two tangents you pass it :

p0 = 0.0
p1 = 0.5
p2 = 1.0
p3 = 0.0

So as it goes through this range it interpolates it none linearly add these values to the lengths of the bones - the nice thing with this is you can tailor how you want the solver to resolve itself, slow in/out, fast in/slow out etc etc rather than a pure exponential ramp. you could also pass it a nurb curve genralization - and even pump this into a f-curve for animators to control on a shot by shot basis :)

edit: hehe, come to think of this hell you could even just pass the length of the hypotenuse of the ik solver, so if the final lengths of the bones are say 100, then all you do is have a range of t[95,100] you pass into your curve function, then you can set whenever you want the slowdown to happen.

lifire
05-15-2007, 06:39 PM
Smarties....

Seriously though, super helpful. Thanks guys.

Aearon
06-03-2007, 12:15 PM
hey eek,

yes this is a good idea, for sure with this you could tweak it even better. what i did was measure the angle between bones with an expose transform and look at the curve, then tweak the values of my formula to get the smoothest possible curve. for sure if you used a curve to counteract this it can be customized even better.




i just played a bit with houdini and implemented my function as a VEX operator, so this would be a deployable solution that can be used in rigs throughout a production.

i really like houdini for developing this kind of general idea, plus everyone can download it for free so it's a good base to share R&D concepts

here you have the VEX network, should be understandable whether you have houdini knowledge or not. it would be fairly easy to implement something spline based like eek suggested too, as houdini has a generic spline operator in vex.

http://www.aearon.de/files/public/smoothik_vop_network.gif

the operator takes the distance between chain root and ik goal as an input, and outputs the new lengths for one of the two bones in the chain, this is then exported back to the bones object.

here you have the scene file (http://www.aearon.de/files/public/rigging_antiIKPop.hipnc)

and a video in action (http://www.aearon.de/files/public/smoothik_houdini.avi)

eek
06-03-2007, 03:35 PM
Nice Aaeron,

Curves are pretty much my thing atm - plus fourier transforms - combined these are amazingly powerful. I just read up on CCDIK - where in theory you could write in a dampering into the algorithm.

Neill
06-04-2007, 07:40 AM
Hi Aearon,

I have tryed your algorithm, but result isn't enough smooth :sad:
I link 3dsmax scene with these post and hope someone can help me

in any case thanks Aearon, it's good idea to write better ik system

djlane
06-04-2007, 09:04 AM
Neill, I`ve attached a setup I use to counter the IK snapping issue. The chain on the right is a standard type setup to show the difference, just open the file and press play.

Hope it helps

Cheers
Dan

Neill
06-04-2007, 09:10 AM
Neill, I`ve attached a setup I use to counter the IK snapping issue. Hope it helps

Cheers
Dan


Thank's Dan,

u scene look great! It's not stretch method for ik poping, but works well.

Aearon
06-04-2007, 07:19 PM
very cool technique, i wouldn't have thought of that.

i find it distracting though that you have to move the ctrl away from the chain to get a full stretch. i think it will create strange motion and awkward feeling for the animator if you leave the foot/hand with the chain and the control is actually some way off.

the advantage is that the actual chain remains the same length though.

what do you guys think about this?

djlane
06-05-2007, 09:31 AM
Its a valid point, I kind of got used to it. The root helper has a CA spinner to set at what distance the padding kicks in or it can be dialed out completely. It kind of gives it the feeling the bicep is reisting the arm completely locking out, which I suppose is what happens in real life yor muscle always wants to keep the arm slightly bent.

Dan

Aearon
06-05-2007, 07:10 PM
i think you could implement this technique without having to stretch the controller beyond full chain length, you would just have to compensate for the acceleration much earlier and more spread out, in the middle of the movement.

i'll have to think about this,

thanks for giving me a new direction ;)

djlane
06-05-2007, 08:19 PM
Could you post any results you get, I would be really interested.

Thanks

Dan

Aearon
06-06-2007, 06:23 AM
of course! when i find the time to investigate this i will post something

CGTalk Moderation
06-06-2007, 06:23 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.