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.

The ANIM format is used in conjunction with CINF + CSKR rigging to animate CMDL meshes.

There are two versions of the ANIM format in Metroid Prime 3 (indicated by the file's first u32 value):

Version Description
0x0 Quaternion Array Format
0x1 Bitstream 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.

Bitstream Format

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).

Key Values

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.

Layout

Data Type Element Count Identifier Notes
Header1 1 header
float header.key_count key_times Array of time positions in seconds
u8 1 channel_flag_count
u8 channel_flag_count channel_flags Field of 3-bits for enabling channel attributes
  • 0x1: Rotation
  • 0x2: Translation
  • 0x4: Scale
s16 header.init_block_size / 2 init_block Initial values for each channel-attribute animated by this ANIM (bone-major)
u32 1 channel_q_count
u32 1 unknown0
u32 1 unknown1
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
u8 unknown_bool_count unknown_bools

Header1

Offset Length Data Type Identifier Notes
0x0 2 u16 unknown0
0x2 1 u8 unknown1
0x3 4 u32 unknown2
0x7 3 u8[3] unknown3
0xA 4 float translation_multiplier Translation vectors are multiplied by this value before being applied
0xE 4 u32 unknown4
0x12 4 u32 unknown5
0x16 4 float unknown6
0x1A 4 float unknown7
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
0x28 1 u8 unknown8
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)
0x39 4 u32 unknown9
0x3D 4 u32 bone_count Count of bone channels in this ANIM