ANIM (Metroid Prime)

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

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.

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 = &pi; / 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.