I'm writing a model viewer for a 20-year-old game. The file format has already been reverse-engineered (by other people much smarter than me), the problem now is playing back the animations. I can correctly display the mesh and skeleton in the bind-pose, but an animated skeleton looks like a jumbled mess of sticks.
1. Skeleton format.
The bind-pose skeleton is stored as an array of bones, each bone is stored as an orientation quaternion (float[4]) and position vector (float[3]) in model space (i.e. not relative to the parent bone), parent bone index (int32) and a name string. Strangely, the bones are not sorted in depth-first order, starting from the root, i.e. the root bone is not necessarily the first one in the array of bones and can be the 2nd, 4th, 10th, etc. - their order seems arbitrary.
2. Skeletal animation format.
Animations are simply stored as arrays of key-frames (bone tracks?) for each bone.
A rotation key-frame is stored as a timestamp (uint32, in milliseconds) and four 16-bit unsigned integers (a quaternion?), a position key-frame - a timestamp and a position vector (3 floats).
I assume that rotation frames store quaternions, but when I build quaternions (by multiplying each number by (1.0f/65535.0f)), some of the resulting quaternions can be unnormalized (e.g. their length can be 0.249954, 0.842029, 1.029763, …), so I normalize them afterwards.
Each bone track always has the first and the last frame (at the beginning and the end of animation)
3. Questions.
So, after loading the mesh, I build a bone tree and build an array of bones sorted in depth-first order (so that I can concatenate parent → child transforms by walking the array). I assumed that keyframes store position and orientation in the bone local space (relative to the parent bone), but this clearly must be wrong, because the animated/interpolated frame skeleton looks like this:
0) What is most probably wrong? Where should I look into?
1) What would be the most obvious and straightforward way to animate using the above data? Can anyone give me ideas of how the original game could do it or point me in the right direction? How was skeletal animation usually done back in the olden days?