ANIM (File Format)

From Retro Modding Wiki
Revision as of 23:01, 25 March 2015 by imported>Jackoalan (→‎Key Values)
Jump to navigation Jump to search

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 long 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's only used in a Ridley intro animation and the rotating pirate data artifact hologram above the Impact Crater.

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
char 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
long 1 bone_channel_count Count of bone channels present in the bone_translation_map and quaternion_key_array below
char 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
long 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 |
|------------|------------|-----|------------|
long 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

long 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 float key_interval Time in seconds between keys of each bone channel (reciprocal of frame-rate)
0x8 4 long bone_entry_count Count of bone-channels in animation
0xC 4 long key_count Count of keys for each bone channel (keys are set for every frame of the 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^2 + Y^2 + Z^2)), 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
long 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.
long 1 bone_channel_count Count of animated bone channels (matches header‑>bone_channel_count)
long 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
long <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 long scratch_size Amount of memory that the animation system needs to allocate to process animation
0x4 4 long evnt_ref ID for this ANIM's EVNT resource, or 0xffffffff if no events triggered
0x8 4 long 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 long unknown1 Always 0x3
0x18 4 long unknown2 Always 0x0
0x1C 4 long 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 long bone_channel_count Count of bone channels present in ANIM
0x28 4 long unknown3 Always 0x1
0x2C 4 long key_bitmap_length Number of bits in key_bitmap

Bone Channel Descriptor

Offset Length Data Type Identifier Notes
0x0 4 long bone_id Bone ID in the associated CINF for this bone channel
0x4 2 short key_count Number of keys in the bitstream for this bone channel (same value for all channels in animation)
0x6 2 short initial_rx Initial X value of bone's rotation vector
0x8 1 char q_rx Number of bits allocated to bone's rx in bitstream
0x9 2 short initial_ry Initial Y value of bone's rotation vector
0xB 1 char q_ry Number of bits allocated to bone's ry in bitstream
0xC 2 short initial_rz Initial Z value of bone's rotation vector
0xE 1 char q_rz Number of bits allocated to bone's rz in bitstream
0xF 2 short 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 short initial_tx Initial X value of bone's translation vector
0x13 1 char q_tx Number of bits allocated to bone's tx in bitstream
0x14 2 short initial_ty Initial Y value of bone's translation vector
0x16 1 char q_ty Number of bits allocated to bone's ty in bitstream
0x17 2 short initial_tz Initial Z value of bone's translation vector
0x19 1 char q_tz Number of bits allocated to bone's tz in bitstream