June 15, 2023

Procedural Animation

Just a bunch of "spiders"

Over my years at Cal Poly, I took a variety of graphics classes but one of my favorites was computer animation. This class was taught in C++ and OpenGl. I learned animation file structures, quaternions, splines, Bezier curves, animation blending, skinning, and inverse kinematics. For the final project I decided I wanted to teach myself procedural animation. This is the process of automatically generating animation in real-time to allow for a more diverse series of actions than could otherwise be created using predefined animations. In my case, I thought it would be straight forward to start with spiders.

Implementation

My goal was to have a body that you could simply move it's position and the legs would automatically animate. To achieve this I had to start with the basis of most procedural animation, which is inverse kinematics. Inverse kinematics or IK is the process of determining the appropriate joint angles to achieve a desired position in a robotic or animated system. This basically allows you to simulate joint movement in real-time.

F.A.B.R.I.K.

There are many inverse kinematic algorithms, but I chose to use the Forward And Backward Reaching Inverse Kinematics (FABRIK) algorithm.

It works like this: First, you define the starting positions of the limb and the target position you want it to reach. Then, you divide the arm into segments, just like our human arm has bones and joints. Each segment has a certain length and can rotate at its joint. The algorithm starts at the last segment, like the hand. It then pretends that the hand is already at the target position and works backwards to move each joint corresponding to the segment lengths. Once that's done it checks if the distance from the start of the arm to the new start position is the same. If not, it then moves the new start position to the original start position (just like how it moved the hand to the target) and works forward through the arm. Then it checks if the hand is at the target. If not, it repeats until the positions line up.

Once it's done you have new positions for a limb that is touching any target position. With this in mind, I can use this algorithm on the limbs of the spiders to have them realistically move to any position.

The Spider Class

This shows that the legs are really just a vector of points. The black boxes are the points and the colored lines show each separate leg.

I made a spider class in C++ that consisted of a spiders position, legs, and target points. The legs are just an array of points that I would send into my implementation of the fabrik algorithm. This would snap the legs to the target points. Now I needed to have it create fluid animation.

Animation

In order to procedurally animate the spider's legs I had to think about how legs actually walk. If you try to move you body without moving your legs, you're going to fall on your face. With this enlightening fact in mind, I decided that if the body of the spider moves and the target positions get too far form the leg, then I should interpolate the legs to the target position (using fabrik).

There is still one last issue. Normally, when an animal takes a step it lifts it's leg slightly and then drops it on the target position. With the current explanation, the spiders legs would just slide across the ground. To fix this, whenever the leg decides it needs to take a step, I first make a fake target that is half way to the real one but also above the ground. Then once the leg is there, I lerp to the actual target position.

Finally, once you combine all of those steps you get spiders than can walk around by themselves. I implemented a simple AI that just randomly moves and rotates the position of the spider's body and the effect was complete.

Retrospective

Learning the basics of procedural animation was a blast and watching these little AI spiders crawl around is so amazing. There is so much more to learn, like procedural facial animation, more physics based animations, or even bigger simulations. I can't wait to explore more!