How skeletons are stored in Outcast (this is generalization)
=============================================================
Each joint is defined like this:
integer index (always starting with 1, leaving 0 for whole object root)
string name
vector position
matrix rotation
Example (all human like characters have this sort of skeleton)
==============================================================
(position, rotation) omitted
1, BIPED
2, LF_HIP
3, LF_KNEE
4, LF_ANKLE
5, LF_TOES
2, RT_HIP
3, RT_KNEE
4, RT_ANKLE
5, RT_TOES
2, BACK
3, NECK
4, HEAD
5, LF_EYEBROW
5, RT_EYEBROW
4, JAW
3, LF_SHOULDER
4, LF_ELBOW
5, LF_WRIST
6, LF_FINGERS
6, LF_THUMB
3, RT_SHOULDER
4, RT_ELBOW
5, RT_WRIST
6, RT_FINGERS
6, RT_THUMB
The whole object root is implicit and its index is 0.
It looks like this taking hierarchy into account
implicit root 0
BIPED 1
LF_HIP 2
LF_KNEE 3
LF_ANKLE 4
LF_TOES 5
RT_HIP 2
RT_KNEE 3
RT_ANKLE 4
RT_TOES 5
BACK 2
NECK 3
HEAD 4
LF_EYEBROW 5
RT_EYEBROW 5
JAW 4
LF_SHOULDER 3
LF_ELBOW 4
LF_WRIST 5
LF_FINGERS 6
LF_THUMB 6
RT_SHOULDER 3
RT_ELBOW 4
RT_WRIST 5
RT_FINGERS 6
RT_THUMB 6
Traversal and reconstruction
============================
Matrices are 4x4 homogenous
matrix rotations[max(index)] # temporary storage, stack in reality
vector positions[len(skeleton)] # joint positions after reconstruction
rotations[0] = identity_matrix
i = 0
for joint in skeleton:
parent_index = joint.index - 1
parent_rotation = rotations[parent_index]
## rotation is around joint, not origin
rotation = translation(-joint.position) * joint.rotation * translation(joint.position)
rotations[joint.index] = parent_rotation * rotation # rotations are accumulated
## store the coordinates of joint in array
positions[i] = joint.position * parent_rotation
i = i + 1
Animations
==========
Each frame(?) is defined as array of following structures:
integer index
short OX
short OY
short OZ
OX,OY,OZ rotation angles (fixed point)
Most indices start with 0, some with 2, one with 1.
Examples
=========
First skeleton idinces, then anim's
x_tentacle [16] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14]
tentacle_grab [ 8] [0, 1, 2, 3, 4, 5, 6, 6]
tentacle_spit [16] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 13]
tentacle_stop1 [18] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 13, 14]
x_shark [ 7] [1, 2, 3, 4, 5, 2, 2]
shark_attack [ 7] [1, 2, 3, 4, 5, 2, 2] this is the only anim with first index = 1
shark_swim [ 5] [0, 1, 2, 3, 4]
x_aquarex [30] [1, 2, 3, 4, 5, 6, 7, 8, 8, 8, 4, 5, 6, 7, 4, 5, 6, 7, 3, 4, 5, 6, 3, 4, 5, 6, 3, 4, 5, 6]
gorgor_slow_walk [30] [0, 1, 2, 3, 4, 5, 6, 7, 7, 7, 3, 4, 5, 6, 3, 4, 5, 6, 2, 3, 4, 5, 2, 3, 4, 5, 2, 3, 4, 5]