Animation

From owdev
Jump to: navigation, search
 struct header {
   uint32 counter1;			// this value is 288 or 160, may be the version, but the structures are the same
   float duration;			// Time in Seconds. duration * fps = Total # of frames.
   float fps;				// Frames per second for the animation. Usually 30.0
   uint16 bone_count;			// number of bones used
   uint16 flag;                        // usually zero, in the new files = 1
   uint64 unk2;				// zero
   uint64 f08FKey;			// ref 08F file 
   uint64 padding;			// 0xFFFF...
   uint64 offset_bone_list;		// Offset to start of bone list, each entry is a int32, size is bone_count
   uint64 offset_information_table;	// Offset to start of the Information Table, size = is ((int) fps * duration) + 1
   uint64 end1;			// size of file - 12? data end? version 288 has still 8 bytes after this?
   uint64 end2;			// size of file - 12? data end?
   uint64 zero;			// 0
 }

Information Table

 struct information_table_entry {
   uint16 scale_count;
   uint16 position_count;
   uint16 rotation_count;
   uint16 flags;
   int32 scale_indices_offset;		// index of bone, if "n_count" < 255 then read byte, else read ushort; where n = "scale"
   int32 position_indices_offset;	// "" where n = "position"
   int32 rotation_indices_offset;	// "" where n = "rotation"
   int32 scale_data_offset;		// each is 3 uint16, see Unpacking Scale
   int32 position_data_offset;		// each is 3 float32s
   int32 rotation_data_offset;		// each is 3 uint16, see Unpacking Rotation
 }

offsets inside the information table are calculated as: offset * 4 + this_entry_offset

Unpacking Scale

Divide each short by 1024.0

Unpacking Rotation

// assuming a = first ushort, b = second ushort, c = third ushort

axis1 = a >> 15
axis2 = b >> 15
axis = axis1 << 1 | axis2

a = a & 0x7FFF
b = b & 0x7FFF

x = 1.41421 * (a - 0x4000) / 0x8000
y = 1.41421 * (b - 0x4000) / 0x8000
z = 1.41421 * (c - 0x8000) / 0x10000
w = pow(1.0 - x * x - y * y - z * z, 0.5)

if(axis == 3) {
  q = [x, y, z, w]
} else if(axis == 2) {
  q = [x, y, w, z]
} else if(axis == 1) {
  q = [x, w, y, z]
} else {
  q = [w, x, y, z]
}

// NOTE: in 3D Studio Max, the axis are somewhat different.