Inverse Kinematics – FABRIK

Patrick Yelkenci

Introduction

I first came across procedural animations on youtube while watching game development videos, one of the main inspirations i had to do this was from Codeer (Codeer, 2020). I had always been a bit interested in animations but also had no idea how to make animations. Seeing how animations could be made by code as well this really piqued my interest since i did not have to learn (a new program to make) animations. So i wondered, How to implement procedural animations myself.

What are procedural animations

Most animations and especially in most games are a form of “static” animations. This means that every movement or every animation that a character in the game does, has been predefined by an animator. This also means that for every possible way of moving a predefined animation has to be made.


Procedural animations are the opposite of these “static” animations. Procedural animations are animations where there is no predefined animation and the animation will be automatically generated during run time. For this the character has to have bones and joints on which the rotation and transformation can be applied. Almost all procedural animations use a form of Forward Kinematics(FK) and Inverse Kinematics(IK). Forward- and inverse kinematics are based on a physics study to move robotic arms.

Structure of character

To be able to apply Forward and Inverse kinematics, the object you want to be moving has to have “Bones”, “Joints” and an “end effector”. These bones, joints and the end effector are all attached to each other in a chained matter, meaning there is a parent-child structure.

Joints

The joints are the parts which can be rotated, the joints are found at the attachment of the limb to the body, this is called the root (joint). But also before and after every bone, with the exception being the end effector. The root is the joint that “glues” or attaches the limb to the actual body. In the picture below the joints are indicated as A.

Bones

The bones are the lengths that are in between the joints. These signify the length of the limb. These always start and end with a joint, except for the last bone in the structure which ends with an end effector. The length of the bones do not change. In the picture below the bones are indicated as B.

End effector

The end effector is the part that is at the end of the chain of joints and bones, this is the part of the limb that has to reach your target. For example in a human arm, the end effector would be the hand, since this is the part that has to reach its goal (of grabbing something for example.

You can basically compare the structure to a human, humans also have joints (elbows, knees ankles, wrist etc.) which are attached to bones. We also have end effectors, basically any time we move somewhere we want an end effector to go towards a goal. The end effector is indicated as C.

Forward Kinematics

Now knowing what bones, joints and the end effector are we can get into forward kinematics. Forward kinematics in one sentence is calculating where the end effector is and what rotation and/or orientation the end effector has. This is done by going forward in the bone and joint chain. So the rotation that each following joint has, is the sum of all the rotations that have occurred in previous joints.

Inverse Kinematics

Given a desired position of the end effector, inverse kinematics is a calculation on how the joints should be configured, the positions and rotations of these joints. When these positions and rotations are calculated the object can be moved towards these rotations and positions to reach the end effector.

In inverse kinematics you would also need constraints of how the joints can move to get a natural way of moving. The way of solving inverse kinematics is an algorithm so of course Inverse kinematics can be solved in numerous different ways. A few of these solutions would be Forward And Backward Reaching Inverse Kinematics (FABRIK), there are goniometric solutions using heavy goniometrie math, and physics based solutions among many others.

Math/physics based

At first i found an article by Alan Zucconi(Zucconi, 2022), this article aims to solve Inverse Kinematics by geometry, maths and gradient descent. This way of solving Inverse Kinematics was really math heavy and after struggling to make it work for a bit too long i deemed that this was not the way to go for me. After reading a bit more i found out that while this is an useful way, it is also a bit more performance heavy than other methods. So i switched over to FABRIK, since FABRIK is faster and in general a bit easier to use. Besides this since FABRIK is also less performance heavy it would be a better solution for creatures with way more legs for example. Or even if it were to be used in a game where every animation is procedurally generated.

FABRIK

FABRIK is an iterative solver, meaning it goes through iterations to solve the inverse kinematics problem. It sets the end effector’s position to the target (b), draws a vector to the previous point and sets the previous point along this vector. This is based on the distance of the bones.

It then adjusts all the positions like this including the root (c)(d).

After this it moves forward from the root and sets this back to the original position and adjusts everything in the same way accordingly(e and f).

this marks one whole iterations. I get more in depth on this later on in the article.

Aristidou en Lasenby (2011) FABRIK: A fast, iterative solver for the Inverse Kinematics problem

To get started with FABRIK, I need a few things. I of course need a target for the arm to reach. I need to know how many joints the arm has, the starting position and rotation of these joints, and the distance in between these joints (the bone lengths). With all of these things I can later calculate the length of the complete arm which I also need.

Set up

To get started i made a simple arm in Unity and added a few gizmos to this. The red balls are the joint positions, the green line indicates the bones.

Simple arm structure
Initializing start values

At first i had the script attached to the end effector and tried to move from that way on, i eventually encountered a problem. This problem happened the instant i tried to apply any rotations to the arm. Because i could not really wrap my head around going from end effector to root i could not find the problem, i later switched from root to end effector (the picture above).

end effector -> root problem

So after initializing all the starting values mentioned above, I could start on the actual FABRIK algorithm. One of the easier parts of FABRIK is that there is a special exception, this is when the target is not in reach of the full length of the arm. In this case we could just extend the full arm towards the target.

FABRIK Exception

We can check if this is the case by calculating the distance from the root to the target. If this is farther away then the length of the full arm, we can go to this exception case. So what to do when this is the case? I take the vector pointing from the root towards the target and set the bones towards it at their maximum lengths.

In this picture i calculate the new positions but haven’t set them to the actual objects.

Which gave me this result:

As you can see, the arm does not yet rotate towards the target, but it does at least point at the target. So the next step is to get the arm to rotate towards the target as well. It should position itself along the green line, which is a gizmo to show how the bones should be positioned.

I use the calculated positions from before and apply them to the actual joints. After this i can get the target rotation for each joint, by getting the vector in between each joint, and use the starting directions i saved when initializing all variables. I used unity’s Quaternion librabry to make this possible to get the rotation from the starting direction towards the new vector and apply this to the joints as well.

which in turn give me a new result of the arm actually pointing towards the target. This works in a 3D environment so it could also turn around as well.

Now we can move on and look into the actual cases where the arm can reach its target, this will be the actual Forward and Backward part of the Forward And Backward Reaching Inverse Kinematics.

Backward

First we are going to look into the backward part of FABRIK. It literally does what it says, it positions the joints in a backwards way, meaning we start at the end effector and move towards the root. The idea of the backwards part of FABRIK puts the position of the end effector on the same position as the target. Once this is done I calculate another direction vector from the new position of the end effector to the joint before this. Then i put the joint on this direction vector the bone’s distance away from the end effector. Then loop through all joints and do the same including the root.

But looping through all joints including the root, means that you’re also changing the root right? right! And that is where the Forward part of FABRIK comes in.

the arm does not stick to its original position with only backward.

Forward

Forward is based on the same thing as Backward, the only thing it moves the other way around. So forward starts from the root and moves towards the end effector. So i start by putting back the root to the original starting position, since this should not move. I then calculate another direction vector between the root and the first following joint, and then move that joint closer to the root again. This is the same as backwards, I move the joint along the direction vector in such a way that it is the original bone length again, and loop all the way forward to the end effector. It’s actually the same as the backwards part just the other way around.

Now the end effector is at least a bit closer to the target, if it is not already on the target. This is now one whole Iteration of the FABRIK algorithm. Now it’s just iterating until the end effector is within a tolerable distance from the target. If it does not reach its target within a set amount of iterations we eliminate the loop to not get stuck in an endless loop. FABRIK however is an algorithm that works really well so i have not seen it not reach its target before it reaches the max iterations, which in my case are 10 iterations.

And now we have an arm that moves towards the target which concludes Inverse Kinematics!

Pole Constraints

In inverse kinematics you would also require certain constraints. This is to ensure that the movements keep going on in a natural way. You can put constraints on the full rotation of certain joints for example, or have simple pole constraints. Which i am using. A pole constraint will only work when the full arm has three(3) joints. A pole constraint is an extra target which is used to keep a certain joint always pointing in a certain direction. Let’s use our knees for example, human knees will always point forward. You can place another target to the direction you want a certain joint to always be pointing. This is how a pole constraint works. For now this should be enough to start testing on having multiple legs.

Implementing more legs

At first i tried to make a raycast from the body to place the targets on the floor. But doing this the easiest way i thought of was having empty gameobjects attached to the body, and raycasting downwards from these points. I tried doing this, but eventually thought that this could be done easier. So i made the targets for the feet attached to the body, and always raycast downwards from these points so they would always be equal to the floor. These targets, since they are attached to the body, would also move when the body moves. This also made it a bit easier for me to know when to move the leg. I could just calculate the distance between the target and the feet of the spider, and if it passes a certain distance i can give the legs the call to move towards the target. This idea of thought was of course a bit too easy. The problem with this is that when moving the body, the position of the legs also moves. This idea was based on Codeer’s 10 steps to procedural animation(Codeer, 2020).

Targets for the legs

So the first thing i did, was make a script on the targets, that always shoots a raycast ray downwards. If it then hits a floor the position of the raycast will be set to the height of the floor, so this would make it so that the targets are always on the floor at least. But as mentioned before, this also moves the targets, since these are still attached to the body.

Afterwards I started working on the actual script that would move the legs, in this script i also lock the targets to their original position, so the legs stay on these targets while the body can move. But this would make it so that i would not have a new target to move the legs to. This however also gave me a weird movement where the spider just drags its body over the floor. I deemed this a problem for later, first I wanted to be able to actually move the targets and get on with the movement.

How to move the legs

So after this i came across a video by Faris Codes(Faris Codes, 2022). In this video they, besides have targets for the legs, also attaches cube targets to the body. The cube targets move along with the body, and then whenever they reach a distance that is far enough from the foot, it moves the foot target to the cube target. So this would make it that the actual inverse kinematic targets also move. This is also along the idea of Codeer’s(Codeer, 2020) steps, but just a little more work. I used the same script as i used on the IK targets, so the cube targets will always be on the floor, however these cube targets move along with the body of the spider.

So first i want to have an array with the targets, or the desired positions to move towards. I save these in the FixedUpdate so that i always have the current positions of the cubes. I could of course just constantly grab the cube targets positions itself, but with the array i prepared the script to be a bit more adaptable.

Moving the legs

Now that i have moving targets i can get started on figuring out how to independently move the legs, and not have them all move at once. So i start with an int called indexToMove, so that whenever i check a distance in a for loop, i can make this indexToMove, the index of the for loop. Then within a for loop, i am checking the distance of the “previous leg position”(or rather the previous target point of the effector) and the accompanied cube target or desired position in this case. If this passes a certain distance i make the index of the for loop, my indexToMove, so now i know which leg i am targeting.

Directly after i have another loop which sets the target of the legs, to the previous leg position if it is not the leg i am targeting with my indexToMove variable, or in other words i set the all legs to their previous positions if i do not want them to move.

Then to move the targets of the legs to the new positions i lerp them towards their new target positions. I do this slowly within a for loop, which in turn is within a coroutine so that it does not instantaneously sets itself to the position, but “slowly” moves towards the new position. I then use the Sin function and give it a step height so the creature actually lifts its leg and it does not just rotate towards the new position.

It actually moves! It still does not look the best, and while this is a form of procedural animation i wanted to go a little further. Now the steps are almost always the same distance since the cube targets are tied to the creatures body. And the spider is not hugging the floor anymore! This was mainly the problem of having a rigid body for the player controller and having gravity on, so i turned the gravity off.

Velocity based movement

To make the animation even more natural like we could make the movement velocity based. This means that we change the distance the leg moves in the sense that it makes a bigger step. For example if you were running you would put your foot further from your body to make a larger step, instead of putting your foot in the same way you would as if you were walking. It is to prepare for a faster movement and bigger steps.

To do this i need to calculate the velocity vector, which is basically the speed and the direction the creature moves in. So i take the desired position and add an offset calculated based on the velocity the creature has. I then clamp(have the value a minimum of 0, and a maximum of 0.5) and this gives me a target point based on the velocity of the creature.

Afterwards i use a function, which shoots a raycast down and adjusts the target’s y-position to the ground. I do this so that the target of the legs will always be on the ground. I save this in an array so that i can also save the normal just in case i need it.

This gave me the result that when it moves slowly, it makes smaller steps, and when it moves faster the steps get bigger and bigger. As you can see in the video below.

There is however a small problem that occurred since i have added this, which is if the creature moves too fast, it seems more like it is half jumping half flying along the floor.

Moving the body

To move the body according the movement of the legs, i could use the cross product. This is always perpendicular to the two inputs(Léo Chaumartin, 2021), so it will in my case always point upwards.

Léo Chaumartin, 2021 https://www.youtube.com/watch?v=swYBGqXtHEY

Based on this idea, i would have to get the distance from each of the legs that are in a diagonal line from each other. After this i can use Vector3.Cross to get the cross product, which you can in turn also call the normal of these two distances. Then i can adjust the body’s position to this new normal and it moves along when walking. This gave a pretty good result on having a more natural pattern of walking for the creature.

Without body movement
With body movement

It is a very subtle movement but i like it a lot since it increases the feeling of the creature naturally moving.

Fixing the rigidbody problem

So the problem of the spider dragging its body along the floor was caused by having a rigidbody and gravity attached to it. But i needed the gravity if i wanted the spider to be able to move along a slanted surface, because otherwise it would not move down. So how to fix this? turn off the rigidbody’s gravity and find a way around it. I stumbled upon an article to have a gameobject always hover above the ground(Knightly, 2018).

This would solve the problem of having to use gravity, and also solve my problem of the spider not being able to move down on a slanted surface! The solution is shooting a raycast down from the body, and adjusting the body’s y-position with a certain surfaceheight and always setting it this height. After this adjust the rotation of the body by the normal vector of the raycasts hit point so it also actually is parallel to the surface.

So as you can see, the legs are still kind of clipping through the slanted surface. This is probably due to the fact that when the spider plants its foot on the surface, the raycast shoot through the surface and hits the floor underneath. So to solve this i used an actual 3D cube instead of a plane, which is a short fix for the problem but it worked. And if i were to use this in perhaps a game, i would not use planes to build the environment. So i deemed that this was a solid fix. If i wanted to change this i could probably add a little bit of height on the raycasthit to fix this as well. The only issue i have with this solution is that it is very snappy when moving up surfaces.

Result

Conclusion

While implementing your own procedural animation i would first make a clear goal for yourself, do you want to implement it in a game, or just test it out. Have a lot of procedural animations or a few? Based on your decision, research the different ways of solving Inverse Kinematics and pick one that applies to your goals. I did not do this and this cost me a lot of time. You can also try to use the tools already given by for example Unity. Unity has a component or plugin to make procedural animations, see if this works for you. While implementing your own solver and animation could be very useful since you have all control over it, it can also be pretty nerve wracking to make, at least in my experience, and why make it if the existing tool works for you.

Future Reference

If i were to have more time i would have liked to fix the snappy movement when moving up surfaces, polish the animation a bit better, so that it could look more natural. And probably fix “the rigidbody problem” with another solution. Also i would love to implement a creature with way more legs, and maybe even some sort of a spine, like a centipede. In this case the body should also move according to the target. Having the creature being able to climb walls, like a spider. And maybe even expanding it to create a flying creature where the wings’ animation are procedurally generated.

Sources

-, B., [Bor]. (2021, 17 maart). 「Unity」Simple Inverse Kinematics implementation. Logicalbeat. 31AD, van https://logicalbeat.jp/blog/6235/

Aristidou, A., & Lasenby, J. (2011). FABRIK: A fast, iterative solver for the Inverse Kinematics problem. Graphical Models /graphical Models and Image Processing /computer Vision, Graphics, and Image Processing, 73(5), 243–260. https://doi.org/10.1016/j.gmod.2011.05.003

Bermudez, L. (2018, 29 juni). Create your own IK in Unity – Unity3DAnimation – Medium. Medium. https://medium.com/unity3danimation/create-your-own-ik-in-unity3d-989debd86770

Codeer. (2020, 28 maart). Unity procedural animation tutorial (10 steps) [Video]. YouTube. https://www.youtube.com/watch?v=e6Gjhr1IP6w

EgoMoose. (2016a, juni 2). FABRIK (Inverse kinematics) [Video]. YouTube. https://www.youtube.com/watch?v=UNoX65PRehA

EgoMoose. (2016b, juni 2). FABRIK (Inverse kinematics) [Video]. YouTube. https://www.youtube.com/watch?v=UNoX65PRehA

Faris Codes. (2022, 5 april). Procedural animation spider like creatures. (Unity Procedural animation series EP1) [Video]. YouTube. https://www.youtube.com/watch?v=EdjAYrssxDM

Knightly, R. (2018, 2 juni). Ground Hugging Vehicles in Unity 3D – The Floating Point – Medium. Medium. https://medium.com/thefloatingpoint/ground-hugging-vehicles-in-unity-3d-50115f421005

Léo Chaumartin. (2021a, februari 24). Spider PROCEDURAL Animation – Works on any other insect! – Unity3D Animation Rigging Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=swYBGqXtHEY

Léo Chaumartin. (2021b, maart 29). Procedural Animation – This Spider can climb anywhere! Unity3D Tutorial [Video]. YouTube. https://www.youtube.com/watch?v=AhywDyu0EGw

「Unity」Simple Inverse Kinematics implementation. (z.d.). [Video]. 株式会社ロジカルビート. https://logicalbeat.jp/blog/6235/

Zucconi, A. (2022, 5 juni). An Introduction to Procedural Animations. Alan Zucconi. https://www.alanzucconi.com/2017/04/17/procedural-animations/