Saturday, October 23, 2010

Spline IK - Looking back one year...

This evening, I finally settled down and tracked down a Spline IK bug report dating back to January (!) this year. During that time, I've kindof gotten "busy" with other projects and stuff in general, not to mention starting to get a bit tired of bugfixing around the middle of the year (which really made it hard to try and track down any bugs, let alone this one, which I'd already tried a few times to crack and failed to fix at the time).

"The Bug" eventually succumbed to one of my favourite debugging techniques, and one which almost everyone who has debugged something before will try: strategic data dumps (also known as printing the values). I know that some people advocate that clever use of debuggers is better practice than modifying the code with prints everywhere. However, IMO going through putting in prints in strategic places and only printing out data you think is going to be of interest is actually a slightly superior technique, as the process of adding these means that you revise the code figuring out where checks for errors should go and also only selecting the information that is potentially going to be enlightening, means that you're putting yourself in the "right headspace". I also find that doing this saves recompiling debug symbols for entire projects and/or is sometimes the only weapon against certain bugs in code that ends up being a pain to step through without setting breakpoints too sparse or too dense.

Anyhow, fixing this bug reminded me that it's been a year since I introduced this feature to Blender. So, I thought I'd share the story of Spline IK's development...


IIRC, riggers had been lobbying for Spline IK for years. In particular I remember that during BBB, Nathan wanted it for Rinky's tail, although in the end, a pure bone-based solution (using IK/FK chains animated by hand) seems to have been used.

Fast forward to October 2009. The Durian project was finally gearing up into production to make the 3rd Open Movie Project at the Blender Institute in Amsterdam. Prior to the start of production, a feature wishlist was posted (though IIRC, this remaining items on this list were abandoned by December or so, when the harsh realities of the situation began to become clear). And of course, Spline IK was one of the items on this list ;)

Having already attacked the rest of the rigging wishlist items (implemented rotation orders stuff, and decided that fixing the constraints rotation thing was going to be too hard in the meantime), one the final weekend of October 2009, I decided to attack "the Spline IK issue".

At 11am (I am not a morning person!) on the Saturday morning, I started work. IIRC, an hour later, I'd sorted out the basic padding stuff for the constraint, and was starting to figure out how to actually get this constraint working.

By the time I had to leave for lunch, I had figured out the basic idea behind how to get this working: basically keep track of 'n' points on the curve, and figure out how to attach the joints of ~ n-1 bones to these points. In effect, this was just a massive automation of the closest manual equivalent of this operation, which would be making some empties follow a curve, and then adding IK-constraints to each of the bones that would follow these empties.

Actually getting this working in practice turned out to be a bit more difficult. After squeezing in some more dev time late on Saturday night, I finally managed to get the very first prototype running, but found that the bones were doing some very weird things (staying in place, but rotating+scaling IIRC).

On Sunday afternoon, I finally got a bit more time to start getting this working. There were several different approaches trialled that afternoon, with varying success. Sometimes the bones rotated, sometimes they didn't. Sometimes they scaled off weirdly, sometimes they didn't.

The details are getting a bit hazy now, but finally at some point on Sunday evening, I came to a point when I needed to research some math to get a final piece of the puzzle working. Hallelujah to the "Gram-Schmidt" procedure for finding a set of orthogonal (or basis) vectors, given a single "known" axis (the head->tail of the bone). Plugging this in, it all suddenly worked! It was just before midnight on Sunday :)

And the rest is history:

...or so I thought at the time. I spent the next 2 weeks bugfixing it, and perhaps a further week later improving it in response to feedback from Nathan as he began using it for his rigs. In the end, the Gram-Schmidt stuff was replaced in favour for the approach used for the "Damped Track" constraint, which fixed some of the problems with different segments having drastically different orientations, which was ok for bone chains, but not for deformed geometry (would you like a dragon's tail that self-intersects and twists like a chain of sausages? :P)

But what I didn't quite expect, was to still be fixing it a year later (hehe)...


  1. Maya's spline IK has been out for at least 5 years now, Blender2.5's spline has already exceeded it in terms of reliability.

  2. Great, keep this behind the scenes stories omming :D still no way to pass curve twist to bone roll? :p

  3. correct me if I'm wrong (I have this working on a test file) but since spline IK in blender doesn't affect twist you are free to implement it yourself.
    I have two tests, one using drivers which uses axis angle type math and gets the twist from the control bones (not the spline, that's too hard for me) and the other using constraints (So I'm guessing it evaluates after the spline IK). Both seem to work, but my eyes currently believe the driver one looks nicer.
    Joshua can probably say better whether I'm right about post/pre evaluation.
    Of course, having twist at least optionally in the constraint would be easier than implementing it in the rig.