Skip to content

Section 4 ‐ Rotation Keyframes

Buu342 edited this page Nov 17, 2023 · 4 revisions

The first 4 bytes of this section actually contain two 2-byte values. I haven't quite figured out their use yet, so I will ignore them for the time being.

After that, you have a 4-byte float value which I'll call the "magic float value".

Offsets to the rotation data

After the first 8 bytes of this section, you have the first 4-byte offset value. This offset value will point to the start of the first rotation data. Every subsequent 4 bytes contain the offset value for the next set of rotation data.

Using the following formula:

((((int)(magicfloat*ANIMLENGTH)) >> 3)*4) + 8

You can calculate the offset (from the start of this section) to the last offset value. There is one more 4-byte value after this, which gives you the size of this entire section (not including the zero byte padding).

To find out the size of each rotation data section, you simply subtract an offset value by its next largest.

The rotation data itself

Quaternions are stored in three groups of 16-bit values. The first two quaternion components can be obtained by masking out all bits except the first bit (so apply an 0x7FFFF mask), multiplying by 4.315969e-05, and then subtracting by 0.7071068. The third component is obtained the same way, except you don't need to mask it before multiplying. The fourth component of the quaternion is obtained using the following formula:

sqrt(((1.0 - fVar1 * fVar1) - fVar2 * fVar2) - fVar3 * fVar3);

The order of the components can be obtained by getting the first bit (apply a 0x8000 mask) of the first and second packed quaternion value, and then using the following formula:

if ((FirstWord & 0x8000) == 0)
{
    if ((SecondWord & 0x8000) != 0)
        return Quaternion(fVar1, fVar2, fVar4, fVar3);
}
else if ((SecondWord & 0x8000) != 0)
    return Quaternion(fVar1, fVar2, fVar3, fVar4);

if ((FirstWord & 0x8000) != 0)
    return Quaternion(fVar1, fVar4, fVar2, fVar3);
return Quaternion(fVar4, fVar1, fVar2, fVar3)

where Quaternion is defined as Quaternion(x, y, z, w).

Quaternions are stored contiguously, somehow... Still figuring it out.

Clone this wiki locally