ANIM (Metroid Prime)

Revision as of 21:35, 4 October 2015 by imported>Jackoalan

This article is for the ANIM format used in Metroid Prime. 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 (indicated by the file's first u32 value):

Version Description
0x0 Quaternion Array Format
0x2 Rotation Vector Bitstream Format

Quaternion Array Format

The Quaternion Array Format (0x0) is a less common animation format in Metroid Prime. It only appears in a Ridley intro animation and the rotating pirate data artifact hologram above the Impact Crater, as well as some unused Samus animations.

The format maps animation channels to bones and supplies rotations as an array of quaternion (WXYZ) keys. Optionally, translations may be specified for a subset of bones as an array of float3 keys.

Layout

Data Type Element Count Identifier Notes
Header0 1 header
u8 header.bone_entry_count bone_entry_map The index-positions of this table correspond to the Bone IDs in the associated CINF. The value is 0xff if the bone is not animated by this ANIM or an index relating the bone_translation_map and quaternion_key_array below
u32 1 bone_channel_count Count of bone channels present in the bone_translation_map and quaternion_key_array below
u8 bone_channel_count bone_translation_map Each bone channel may be optionally augmented with translation vectors at the bottom of the file. The index-positions of this table correspond to the values in the bone_entry_map above. The value is 0xff if the bone is not translated by this ANIM or an index relating the quaternion_key_array below
u32 1 quaternion_key_count Count of elements in quaternion_key_array below
float4 quaternion_key_count quaternion_key_array The quaternion keys are interleaved as such (bone-major):
|------------|------------|-----|------------|
| bone0/key0 | bone0/key1 | ... | bone0/keyN |
| bone1/key0 | bone1/key1 | ... | bone1/keyN |
| .......... | .......... | ... | .......... |
| boneN/key0 | boneN/key1 | ... | boneN/keyN |
|------------|------------|-----|------------|
u32 1 translation_key_count Count of elements in translation_key_array below
float3 translation_key_count translation_key_array The translation keys are interleaved as such (bone-major):
|------------|------------|-----|------------|
| bone0/key0 | bone0/key1 | ... | bone0/keyN |
| bone1/key0 | bone1/key1 | ... | bone1/keyN |
| .......... | .......... | ... | .......... |
| boneN/key0 | boneN/key1 | ... | boneN/keyN |
|------------|------------|-----|------------|

Any bone channels that were marked 0xff in the bone_translation_map are skipped by this array

u32 1 evnt_ref ID for this ANIM's EVNT resource, or 0xffffffff if no events triggered

Header0

Offset Length Data Type Identifier Notes
0x0 4 float duration Time in seconds that the animation plays for
0x4 4 u32 unknown1
0x8 4 float key_interval Time in seconds between keys of each bone channel (reciprocal of frame-rate)
0xC 4 u32 unknown2
0x10 4 u32 key_count Count of keys for each bone channel (keys are set for every frame of the animation)
0x14 4 u32 unknown3
0x18 4 u32 bone_entry_count Count of bone-channels in animation

Rotation Vector Bitstream Format

The Rotation Vector Bitstream Format (0x2) is the most widely used animation format in Metroid Prime. The format uses a compressed bitstream to store keys that have been delta encoded and quantized to make for a very compact, compressed animation. The data is processed sequentially to reconstruct the uncompressed bone channel data as quaternions.

In addition to the bitstream quantization, the format includes a bitmap specifying which frames of the animation have keys added. Consequently, the runtime generates missing keys via interpolation (reducing animation size further).

Key Values

When decoding the animation, each bone's rotation (and possibly translation) values are initialized to the initial_* values in the bone channel descriptors. 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 components are divided by rotation_divisor, resulting in an axis-angle rotation vector. This rotation vector is converted to quaternion imaginary components with the W component derived via normalized-difference and a sign-bit packed into the bitstream:

q = π / 2.0 / rotation_divisor
X = sin(rx * q)
Y = sin(ry * q)
Z = sin(rz * q)
W = sqrt(MAX((1.0 - (X*X + Y*Y + Z*Z)), 0.0))
W = sign_bit ? -W : W

Translation components are multiplied by translation_multiplier, yielding world units.

Layout

Data Type Element Count Identifier Notes
Header2 1 header
u32 round_up(header.key_bitmap_length / 32) key_bitmap Word-packed bitmap. Each word is read from least-significant to most-significant bit. A set bit indicates the frame at the bit's position has keys for each bone channel.
u32 1 bone_channel_count Count of animated bone channels (matches header.bone_channel_count)
u32 1 bone_channel_count Duplicate channel count for some reason
Bone Channel Descriptor header.bone_channel_count bone_channel_descriptor_table Table describing animated bone channels
u32 <remainder of file> key_bitstream Word-packed bitstream laid out as described by the descriptor table. The bitstream is unpacked just like key_bitmap (least-significant to most-significant).

Key values are tightly-packed, quantized integers whose bit-depth is specified by the q_* values in the descriptor table. Each bone-channel key-set starts with a single bit providing the W sign-bit (1 for negative, 0 for positive).

The key integers are signed using Two's complement representation.

Header2

Offset Length Data Type Identifier Notes
0x0 4 u32 scratch_size Amount of memory that the animation system needs to allocate to process animation
0x4 4 u32 evnt_ref ID for this ANIM's EVNT resource, or 0xffffffff if no events triggered
0x8 4 u32 unknown0 Always 0x1
0xC 4 float duration Time in seconds that the animation plays for
0x10 4 float interval Time in seconds between frames (reciprocal of frame-rate, typically 30-fps)
0x14 4 u32 unknown1 Always 0x3
0x18 4 u32 unknown2 Always 0x0
0x1C 4 u32 rotation_divisor Rotation vectors are divided by this value before being applied
0x20 4 float translation_multiplier Translation vectors are multiplied by this value before being applied
0x24 4 u32 bone_channel_count Count of bone channels present in ANIM
0x28 4 u32 unknown3 Always 0x1
0x2C 4 u32 key_bitmap_length Number of bits in key_bitmap

Bone Channel Descriptor

Offset Length Data Type Identifier Notes
0x0 4 u32 bone_id Bone ID in the associated CINF for this bone channel
0x4 2 u16 key_count Number of keys in the bitstream for this bone channel (same value for all channels in animation)
0x6 2 s16 initial_rx Initial X value of bone's rotation vector
0x8 1 u8 q_rx Number of bits allocated to bone's rx in bitstream
0x9 2 s16 initial_ry Initial Y value of bone's rotation vector
0xB 1 u8 q_ry Number of bits allocated to bone's ry in bitstream
0xC 2 s16 initial_rz Initial Z value of bone's rotation vector
0xE 1 u8 q_rz Number of bits allocated to bone's rz in bitstream
0xF 2 u16 translation_key_count If this bone channel has an animated translation, its value will match key_count, otherwise the value will be 0.

If the value is 0, this descriptor ends here

0x11 2 s16 initial_tx Initial X value of bone's translation vector
0x13 1 u8 q_tx Number of bits allocated to bone's tx in bitstream
0x14 2 s16 initial_ty Initial Y value of bone's translation vector
0x16 1 u8 q_ty Number of bits allocated to bone's ty in bitstream
0x17 2 s16 initial_tz Initial Z value of bone's translation vector
0x19 1 u8 q_tz Number of bits allocated to bone's tz in bitstream