The papers I’ve found on FABRIK aren’t very clear on how constraints should be implemented. Sometimes they’re even cryptic. Nevertheless, I think I’ve been making some progress.
My first attempt at implementing constraints failed. I first thought you could apply constraints to the entire tree every iteration, but as you can see, the algorithm no longer converges. (Here, I’m trying to force one of those joints to always be straight no matter what, but it seems he’d rather remain gay).
I’m now working on my second attempt where constraints are applied per node as the tree is being iterated. The math is cumbersome as it involves computing joint rotations and transforming to and from local space.
It looks like this could work. I think I have to apply constraints during forwards iteration as well as during backwards iteration (right now it’s only during backwards iteration). Calculating local joint angles is going to be a lot harder in forward iteration, I’m not yet sure how to tackle this.
The nature of the FABRIK algorithm makes constraint support inherently inefficient, because FABRIK has no need for joint angles and works entirely in global space. Joint constraints require joint angles in local space. There is an unfortunate performance penalty, which is fairly evident by just looking at the code.