Animating a Skeleton, part 1
Ahem, so my first entry on what's essentially going to be my long and tedious work towards a small custom game engine.
The first few entries are just going to be me, playing catchup on what I've done so far.
The first thing I've decided to try to do, is animate a human character. For this purpose I created my own custom human skeleton. I used the measurements from DaVinci's Vitruvian Man to obtain measurements and positioning of each bone. In case you don't know it, the Vitruvian Man is this drawing, of a supposedly ideal man:
The initial skeleton design was done in Google's free program, sketchup, where I traced over the general bone structure in that drawing:
After a somewhat painful manual entry of the positions, lengths, and orientations, I had the base for creating a set of bones. However, a set of bones isn't enough for proper skeleton animation.
Each bone could have 1 parent (potentially NULL) and many children. The next step is figuring out how to represent the rotations. I wanted to be able to access a bone's position and end position without recursive calls. I also wanted rotations to be relative, and to have the ability to move a point "with" the bone. The last requirement was because I know that I would have to animate a model based on that skeleton.
To solve all this, I wrote a class, called Axes. Axes contained 3 vectors, which started off as the XYZ world space vectors. I also wrote several functions for rotation around the Axes in the class, all of which eventually came down to 1 function: rotation of a point around an arbitrary axis.
The rotation of a point around an arbitrary axis, in brief, is done like so:
1. Translate your axis to pass through the origin. In my case, I always assumed my axis was at the origin, though it was actually at the bone's Starting position. To properly rotate then, all you have to do is perform a move of -sp, where sp is a vector representing the bone's starting position.
2. Align your axis with one of the three world axes (X- Y- or Z-) This essentially means undoing the rotation applied to that axis.
3. Perform your desired rotation, now around the world axis with which you aligned.
4. Undo step 2. (apply the rotation of the bone)
5. Undo step 1. (apply the translation to the bone's position)
That was it. After each bone was rotated then, all I had to do is update it's child bones with their new position (the current bone's end position) and their delta-rotation matrix (however much the bone was rotated)
The final result was this:
The actual work too a little less than 2 weeks - 4 days or so to write all the necessary code, and about another week to get rid of all the bugs.
All the graphics are drawn with OpenGL, and I didn't quite start from scratch, I had a somewhat ready framework from a previous project.
The next step was to animate the skeleton.