ANIM (Metroid Prime 3)
This article is for the ANIM format used in Metroid Prime 3. See ANIM (File Format) for the other revisions of this format.
There are two versions of the ANIM format in Metroid Prime 3 (indicated by the file's first u32 value):
|0x0||Quaternion Array Format|
Quaternion Array Format
Main article: ANIM (Metroid Prime)
This format is identical to Metroid Prime 2's Version 0 except for an unknown u16 value inserted at the beginning.
The Bitstream Format (0x1) version of ANIM is a significant departure from Version 0x2 used in MP1/2. It's still based on a bitstream with delta encoding and quantization, but the quaternion encoding is simpler to decode and the key-layout is slightly different.
There is no longer a frame interval value for defining a consistent frame-rate; each keyed-frame's time position is explicitly defined as a floating-point value in seconds.
Additionally, CINF bone-IDs are no longer explicitly defined; the indexing position of the bone channel serves as the bone-ID (beginning at 0 for the root bone).
Each keyed-frame begins with 1-bit in the stream; its purpose is unknown.
Each channel attribute is initialized iteratively using the init_block values. For every frame of every bone channel, the key value in the bitstream is added with the previous key value (to resolve the delta encoding).
Once resolved, rotation imaginary components and scale components are divided by 0x7FFF, resulting in normalized floats.
Rotation channels consist of 4-components per-bone. The first expresses the quaternion W-sign in the least-significant bit. The remaining 3 express quaternion imaginary (XYZ) values. The W value itself is calculated using normalized-difference:
q = 1.0 / 0x7FFF X = rx * q Y = ry * q Z = rz * q W = sqrt(MAX((1.0 - (X*X + Y*Y + Z*Z)), 0.0)) W = (rw & 0x1) ? -W : W
Translation components are multiplied by translation_multiplier, yielding world units.
|Data Type||Element Count||Identifier||Notes|
|float||header.key_count||key_times||Array of time positions in seconds|
|u8||channel_flag_count||channel_flags||Field of 3-bits for enabling channel attributes
|s16||header.init_block_size / 2||init_block||Initial values for each channel-attribute animated by this ANIM (bone-major)|
|u8||1||channel_q_block||Quantized bit-count for each channel-attribute animated by this ANIM (bone-major)|
|<remainder-of-stream-block>||key_bitstream||Word-packed bitstream laid out as described by the tables above. The bitstream is unpacked least-significant to most-significant bit for each word.
Key values are tightly-packed, quantized integers whose bit-depth is specified by the values in the channel_q_block.
The key integers are signed using Two's complement representation.
|u32||1||unknown_bool_count||Seems to match the bone count|
|0xA||4||float||translation_multiplier||Translation vectors are multiplied by this value before being applied|
|0x1E||4||float||duration||Time in seconds that the animation plays for|
|0x22||2||u16||key_count||Count of keyed-frames in animation (including initializer keys)|
|0x24||4||u32||data_blob_size||Count of bytes after header|
|0x29||4||u32||key_times_size||Count of bytes in key times array|
|0x2D||4||u32||channel_flags_size||Count of bytes in channel flags array|
|0x31||4||u32||init_block_size||Count of bytes in init block|
|0x35||4||u32||stream_block_size||Count of bytes in bitstream block (everything after init_block)|
|0x3D||4||u32||bone_count||Count of bone channels in this ANIM|