Difference between revisions of "ANIM (Metroid Prime)"
(→Quaternion Array Format (Uncompressed)) |
(→Quaternion Array Format (Uncompressed)) |
||
(11 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
− | ''This article is for the ANIM format used in ''Metroid Prime''. See [[ANIM (File Format)]] for the other revisions of this format.'' | + | ''This article is for the ANIM format used in ''Metroid Prime'' and ''Metroid Prime 2: Echoes''. See [[ANIM (File Format)]] for the other revisions of this format.'' |
− | The '''ANIM format''' is used in conjunction with [[CINF (File Format)|CINF]] + [[CSKR (File Format)|CSKR]] | + | The '''ANIM format''' is used in conjunction with [[CINF (File Format)|CINF]] + [[CSKR (File Format)|CSKR]] rigging to animate [[CMDL (Metroid Prime)|CMDL meshes]]. The format is largely the same between the two games, with the main difference being that starting in ''Metroid Prime 2'', support for animating scale was added. |
− | rigging to animate [[CMDL (Metroid Prime)|CMDL meshes]]. | + | |
− | There are two versions of the ANIM format | + | There are two versions of the ANIM format (indicated by the file's first u32 value), one with compressed animations and one with uncompressed ones: |
{| class="wikitable" | {| class="wikitable" | ||
Line 19: | Line 18: | ||
== Quaternion Array Format (Uncompressed) == | == Quaternion Array Format (Uncompressed) == | ||
− | The '''Quaternion Array Format''' (0x0) is a less common animation 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, while in ''Metroid Prime 2'', it only seems to show up in some draft/test animations not used in the final game. |
− | + | ||
− | above the Impact Crater, as well as some unused Samus animations. | + | |
− | + | This format stores uncompressed animations by mapping animation channels to bones, supplying rotations as an array of [[wikipedia:Quaternion|quaternion]] (WXYZ) keys and translations/scales as an array of XYZ keys. Translations may be specified for a subset of bones as an array of XYZ keys. In ''Metroid Prime'', rotation keys are required on every channel, while translations may be specified for a subset of bones. In ''Metroid Prime 2'', all three transform components are opt-in. | |
− | + | ||
=== Layout === | === Layout === | ||
Line 34: | Line 30: | ||
!style="width: 240px;"|Name | !style="width: 240px;"|Name | ||
!Notes | !Notes | ||
+ | !MP1 | ||
+ | !MP2 | ||
|- | |- | ||
|0x4 | |0x4 | ||
− | | | + | |[[Char Anim Time]] |
|1 | |1 | ||
|'''Duration''' | |'''Duration''' | ||
|Time in seconds that the animation plays for | |Time in seconds that the animation plays for | ||
− | | | + | |{{check}} |
− | + | |{{check}} | |
− | + | ||
− | + | ||
− | |{{ | + | |
− | + | ||
|- | |- | ||
|0xC | |0xC | ||
− | | | + | |[[Char Anim Time]] |
|1 | |1 | ||
|'''Key Interval''' | |'''Key Interval''' | ||
|Time in seconds between keys of each bone channel (reciprocal of frame-rate) | |Time in seconds between keys of each bone channel (reciprocal of frame-rate) | ||
− | | | + | |{{check}} |
− | + | |{{check}} | |
− | + | ||
− | + | ||
− | |{{ | + | |
− | + | ||
|- | |- | ||
|0x14 | |0x14 | ||
Line 64: | Line 54: | ||
|'''Key Count''' | |'''Key Count''' | ||
|Count of keys for each bone channel (keys are set for every frame of the animation) | |Count of keys for each bone channel (keys are set for every frame of the animation) | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x18 | |0x18 | ||
Line 70: | Line 62: | ||
|'''Root Bone ID''' | |'''Root Bone ID''' | ||
|ID of the root bone in this ANIM | |ID of the root bone in this ANIM | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x1C | |0x1C | ||
+ | |u32 | ||
+ | |1 | ||
+ | |'''Bone Channel Count''' | ||
+ | |Count of bone channel indices in the next array. Always 100. | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x20 | ||
+ | |u8 | ||
+ | |''Bone Channel Count'' | ||
+ | |'''Bone Channel Index Array''' | ||
+ | |This table maps each bone to a bone channel, with the index-position corresponding to a ''Bone ID'' in the associated [[CINF (File Format)|CINF]], while the value corresponds to a bone channel index. The value is 0xFF if the bone is not animated by this ANIM. | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |{{unknown|}} | ||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Rotation Channel Index Count''' | |'''Rotation Channel Index Count''' | ||
− | |Count of rotation channel indices in the next array. | + | |Count of rotation channel indices in the next array. Matches the number of valid bone channels. |
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | | | + | |{{unknown|}} |
|u8 | |u8 | ||
|''Rotation Channel Index Count'' | |''Rotation Channel Index Count'' | ||
|'''Rotation Channel Index Array''' | |'''Rotation Channel Index Array''' | ||
− | |This table maps each bone to a rotation channel, with the index-position corresponding to | + | |This table maps each bone channel to a rotation channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a rotation channel. The value is 0xFF if the bone is not rotated by this ANIM. '''Note:''' In ''Metroid Prime'', every bone channel always has rotations, so this array is omitted. |
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
Line 87: | Line 101: | ||
|1 | |1 | ||
|'''Translation Channel Index Count''' | |'''Translation Channel Index Count''' | ||
− | |Count of translation channel indices in the next array. Matches the number of valid | + | |Count of translation channel indices in the next array. Matches the number of valid bone channels. |
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
Line 93: | Line 109: | ||
|''Translation Channel Index Count'' | |''Translation Channel Index Count'' | ||
|'''Translation Channel Index Array''' | |'''Translation Channel Index Array''' | ||
− | |This table maps each | + | |This table maps each bonechannel to a translation channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a translation channel. The value is 0xFF if the bone is not translated by this ANIM. |
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
|u32 | |u32 | ||
|1 | |1 | ||
− | |''' | + | |'''Scale Channel Index Count''' |
− | |Count of | + | |Count of scale channel indices in the next array. Matches the number of valid bone channels. |
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
− | | | + | |u8 |
− | |'' | + | |''Scale Channel Index Count'' |
− | |''' | + | |'''Scale Channel Index Array''' |
− | |The | + | |This table maps each bone channel to a scale channel, with the index-position corresponding to an entry in the ''Bone Channel Index Array'' above (disregarding 0xFF entries), while the value corresponds to the index of a scale channel. The value is 0xFF if the bone is not scaled by this ANIM. |
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |{{unknown|}} | ||
+ | |u32 | ||
+ | |1 | ||
+ | |'''Scale Key Count''' | ||
+ | |Count of elements in ''Scale Key Array'' below | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |{{unknown|}} | ||
+ | |float3 | ||
+ | |''Scale Key Count'' | ||
+ | |'''Scale Key Array''' | ||
+ | |The scale keys are interleaved as such (bone-major): | ||
<pre> | <pre> | ||
|------------|------------|-----|------------| | |------------|------------|-----|------------| | ||
Line 114: | Line 150: | ||
|------------|------------|-----|------------| | |------------|------------|-----|------------| | ||
</pre> | </pre> | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |{{unknown|}} | ||
+ | |u32 | ||
+ | |1 | ||
+ | |'''Rotation Key Count''' | ||
+ | |Count of elements in ''Rotation Key Array'' below | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |{{unknown|}} | ||
+ | |float4 | ||
+ | |''Rotation Key Count'' | ||
+ | |'''Rotation Key Array''' | ||
+ | |The rotation keys are interleaved the same way as the scale keys. In ''Metroid Prime 2'', any bone channels that were marked 0xFF in the ''Rotation Channel Index Array'' are skipped. | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
Line 120: | Line 174: | ||
|'''Translation Key Count''' | |'''Translation Key Count''' | ||
|Count of elements in ''Translation Key Array'' below | |Count of elements in ''Translation Key Array'' below | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
Line 125: | Line 181: | ||
|''Translation Key Count'' | |''Translation Key Count'' | ||
|'''Translation Key Array''' | |'''Translation Key Array''' | ||
− | |The translation keys are interleaved the same way as the | + | |The translation keys are interleaved the same way as the scale keys. Any bone channels that were marked 0xFF in the ''Translation Channel Index Array'' are skipped. |
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|{{unknown|}} | |{{unknown|}} | ||
Line 132: | Line 190: | ||
|'''EVNT Ref''' | |'''EVNT Ref''' | ||
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered | |ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered | ||
+ | |{{check}} | ||
+ | |{{nocheck}} | ||
|} | |} | ||
== Rotation Vector Bitstream Format (Compressed) == | == Rotation Vector Bitstream Format (Compressed) == | ||
− | The '''Rotation Vector Bitstream Format''' (0x2) is the most widely used animation format | + | The '''Rotation Vector Bitstream Format''' (0x2) is the most widely used animation format. |
The format uses a compressed [[wikipedia:Bitstream|bitstream]] to store keys that have been | The format uses a compressed [[wikipedia:Bitstream|bitstream]] to store keys that have been | ||
[[wikipedia:Delta encoding|delta encoded]] and [[wikipedia:Quantization (signal processing)|quantized]] | [[wikipedia:Delta encoding|delta encoded]] and [[wikipedia:Quantization (signal processing)|quantized]] | ||
Line 146: | Line 206: | ||
=== Key Values === | === Key Values === | ||
− | When decoding the animation, each bone's | + | When decoding the animation, each bone's attribute 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'' | 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). | with the previous key value (to resolve the delta encoding). | ||
Line 164: | Line 224: | ||
</pre> | </pre> | ||
− | Translation components are multiplied by ''Translation Multiplier'', | + | Translation components are multiplied by ''Translation Multiplier'', and scale components are multiplied by ''Scale Multiplier''. |
=== Layout === | === Layout === | ||
{| class="wikitable" | {| class="wikitable" | ||
− | |||
!Type | !Type | ||
!style="width: 220px;"|Element Count | !style="width: 220px;"|Element Count | ||
!style="width: 240px;"|Name | !style="width: 240px;"|Name | ||
!Notes | !Notes | ||
+ | !MP1 | ||
+ | !MP2 | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Scratch Size''' | |'''Scratch Size''' | ||
|Amount of memory that the animation system needs to allocate to process animation | |Amount of memory that the animation system needs to allocate to process animation | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|[[EVNT (File Format)|EVNT]] | |[[EVNT (File Format)|EVNT]] | ||
|1 | |1 | ||
|'''EVNT Ref''' | |'''EVNT Ref''' | ||
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered | |ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered | ||
+ | |{{check}} | ||
+ | |{{nocheck}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|{{unknown|Unknown 1}} | |{{unknown|Unknown 1}} | ||
|Always 0x1 | |Always 0x1 | ||
+ | |{{check}} | ||
+ | |{{nocheck}} | ||
+ | |- | ||
+ | |u16 | ||
+ | |1 | ||
+ | |{{unknown|Unknown 2}} | ||
+ | | | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|float | |float | ||
|1 | |1 | ||
|'''Duration''' | |'''Duration''' | ||
|Time in seconds that the animation plays for | |Time in seconds that the animation plays for | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|float | |float | ||
|1 | |1 | ||
|'''Interval''' | |'''Interval''' | ||
|Time in seconds between frames (reciprocal of frame-rate, typically 30-fps) | |Time in seconds between frames (reciprocal of frame-rate, typically 30-fps) | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
− | |{{ | + | |'''Root Bone ID''' |
− | | | + | |ID of the root bone in this ANIM |
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
− | |{{ | + | |'''Looping Flag''' |
− | | | + | |When non-zero, engine identifies this ANIM as looping |
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Rotation Divisor''' | |'''Rotation Divisor''' | ||
|Rotation vectors are divided by this value before being applied | |Rotation vectors are divided by this value before being applied | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|float | |float | ||
|1 | |1 | ||
|'''Translation Multiplier''' | |'''Translation Multiplier''' | ||
|Translation vectors are multiplied by this value before being applied | |Translation vectors are multiplied by this value before being applied | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |float | ||
+ | |1 | ||
+ | |'''Scale Multiplier''' | ||
+ | |Scale vectors are multiplied by this value before being applied | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Bone Channel Count''' | |'''Bone Channel Count''' | ||
|Count of bone channels present in ANIM | |Count of bone channels present in ANIM | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
− | |||
|u32 | |u32 | ||
+ | |1 | ||
|{{unknown|Unknown 4}} | |{{unknown|Unknown 4}} | ||
|Always 0x1 | |Always 0x1 | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Key Bitmap Length''' | |'''Key Bitmap Length''' | ||
|Number of bits in ''Key Bitmap'' | |Number of bits in ''Key Bitmap'' | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|round_up(''Key Bitmap Length'' / 32) | |round_up(''Key Bitmap Length'' / 32) | ||
|'''Key Bitmap''' | |'''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. If the bit is unset, the keys must be generated via interpolation. | |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. If the bit is unset, the keys must be generated via interpolation. | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Bone Channel Count''' | |'''Bone Channel Count''' | ||
|Count of animated bone channels (matches the previous bone channel count) | |Count of animated bone channels (matches the previous bone channel count) | ||
+ | |{{check}} | ||
+ | |{{nocheck}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|1 | |1 | ||
|'''Bone Channel Descriptor Count''' | |'''Bone Channel Descriptor Count''' | ||
|Count of bone channel descriptors in ''Bone Channel Descriptor Table''. Matches the ''Bone Channel Counts''. | |Count of bone channel descriptors in ''Bone Channel Descriptor Table''. Matches the ''Bone Channel Counts''. | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|[[#Bone Channel Descriptor|Bone Channel Descriptor]] | |[[#Bone Channel Descriptor|Bone Channel Descriptor]] | ||
|''Bone Channel Descriptor Count'' | |''Bone Channel Descriptor Count'' | ||
|'''Bone Channel Descriptor Table''' | |'''Bone Channel Descriptor Table''' | ||
|Table describing animated bone channels | |Table describing animated bone channels | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | |||
|u32 | |u32 | ||
|<remainder of file> | |<remainder of file> | ||
|'''Key Bitstream''' | |'''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). | |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 '' | + | Key values are tightly-packed, quantized integers whose bit-depth is specified by the ''* Bits'' 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). | Each bone-channel key-set starts with a single bit providing the ''W sign-bit'' (1 for negative, 0 for positive). | ||
Line 290: | Line 380: | ||
|------------|------------|-----|------------| | |------------|------------|-----|------------| | ||
</pre> | </pre> | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|} | |} | ||
Line 299: | Line 391: | ||
!Name | !Name | ||
!Notes | !Notes | ||
+ | !MP1 | ||
+ | !MP2 | ||
|- | |- | ||
|0x0 | |0x0 | ||
Line 304: | Line 398: | ||
|'''Bone ID''' | |'''Bone ID''' | ||
|''Bone ID'' in the associated [[CINF (File Format)|CINF]] for this bone channel | |''Bone ID'' in the associated [[CINF (File Format)|CINF]] for this bone channel | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x4 | |0x4 | ||
Line 309: | Line 405: | ||
|'''Rotation Key Count''' | |'''Rotation Key Count''' | ||
|Number of rotation keys in the bitstream for this bone channel. | |Number of rotation keys in the bitstream for this bone channel. | ||
− | ''' | + | '''In MP2, if this value is 0, the remaining Rotation fields aren't present''' |
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x6 | |0x6 | ||
Line 315: | Line 413: | ||
|'''Initial Rotation X''' | |'''Initial Rotation X''' | ||
|Initial X value of bone's rotation vector | |Initial X value of bone's rotation vector | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x8 | |0x8 | ||
Line 320: | Line 420: | ||
|'''Rotation Bits X''' | |'''Rotation Bits X''' | ||
|Number of bits allocated to bone's rotation delta X in bitstream | |Number of bits allocated to bone's rotation delta X in bitstream | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x9 | |0x9 | ||
Line 325: | Line 427: | ||
|'''Initial Rotation Y''' | |'''Initial Rotation Y''' | ||
|Initial Y value of bone's rotation vector | |Initial Y value of bone's rotation vector | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0xB | |0xB | ||
Line 330: | Line 434: | ||
|'''Rotation Bits Y''' | |'''Rotation Bits Y''' | ||
|Number of bits allocated to bone's rotation delta Y in bitstream | |Number of bits allocated to bone's rotation delta Y in bitstream | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0xC | |0xC | ||
Line 335: | Line 441: | ||
|'''Initial Rotation Z''' | |'''Initial Rotation Z''' | ||
|Initial Z value of bone's rotation vector | |Initial Z value of bone's rotation vector | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0xE | |0xE | ||
Line 340: | Line 448: | ||
|'''Rotation Bits Z''' | |'''Rotation Bits Z''' | ||
|Number of bits allocated to bone's rotation delta Z in bitstream | |Number of bits allocated to bone's rotation delta Z in bitstream | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0xF | |0xF | ||
Line 346: | Line 456: | ||
|If this bone channel has an animated translation, its value will match ''Rotation Key Count''; otherwise the value will be 0. | |If this bone channel has an animated translation, its value will match ''Rotation Key Count''; otherwise the value will be 0. | ||
'''If the value is 0, the remaining Translation fields aren't present''' | '''If the value is 0, the remaining Translation fields aren't present''' | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x11 | |0x11 | ||
Line 351: | Line 463: | ||
|'''Initial Translation X''' | |'''Initial Translation X''' | ||
|Initial X value of bone's translation vector | |Initial X value of bone's translation vector | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x13 | |0x13 | ||
Line 356: | Line 470: | ||
|'''Translation Bits X''' | |'''Translation Bits X''' | ||
|Number of bits allocated to bone's translation delta X in bitstream | |Number of bits allocated to bone's translation delta X in bitstream | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x14 | |0x14 | ||
Line 361: | Line 477: | ||
|'''Initial Translation Y''' | |'''Initial Translation Y''' | ||
|Initial Y value of bone's translation vector | |Initial Y value of bone's translation vector | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x16 | |0x16 | ||
Line 366: | Line 484: | ||
|'''Translation Bits Y''' | |'''Translation Bits Y''' | ||
|Number of bits allocated to bone's translation delta Y in bitstream | |Number of bits allocated to bone's translation delta Y in bitstream | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x17 | |0x17 | ||
|s16 | |s16 | ||
− | |'''Translation | + | |'''Initial Translation Z''' |
|Initial Z value of bone's translation vector | |Initial Z value of bone's translation vector | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
|- | |- | ||
|0x19 | |0x19 | ||
Line 376: | Line 498: | ||
|'''Translation Bits Z''' | |'''Translation Bits Z''' | ||
|Number of bits allocated to bone's translation delta Z in bitstream | |Number of bits allocated to bone's translation delta Z in bitstream | ||
+ | |{{check}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x1A | ||
+ | |u16 | ||
+ | |'''Scale Key Count''' | ||
+ | |If this bone channel has an animated scale, its value will match ''Scale Key Count''; otherwise the value will be 0. | ||
+ | '''If the value is 0, the remaining Scale fields aren't present''' | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x1C | ||
+ | |s16 | ||
+ | |'''Initial Scale X''' | ||
+ | |Initial X value of bone's scale vector | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x1E | ||
+ | |u8 | ||
+ | |'''Scale Bits X''' | ||
+ | |Number of bits allocated to bone's scale delta X in bitstream | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x1F | ||
+ | |s16 | ||
+ | |'''Initial Scale Y''' | ||
+ | |Initial Y value of bone's scale vector | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x21 | ||
+ | |u8 | ||
+ | |'''Scale Bits Y''' | ||
+ | |Number of bits allocated to bone's scale delta Y in bitstream | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x22 | ||
+ | |s16 | ||
+ | |'''Initial Scale Z''' | ||
+ | |Initial Z value of bone's scale vector | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
+ | |- | ||
+ | |0x24 | ||
+ | |u8 | ||
+ | |'''Scale Bits Z''' | ||
+ | |Number of bits allocated to bone's scale delta Z in bitstream | ||
+ | |{{nocheck}} | ||
+ | |{{check}} | ||
|- | |- | ||
− | | | + | |0x25 |
− | |colspan= | + | |colspan=5 {{unknown|End of descriptor}} |
|} | |} | ||
[[Category:File Formats]] | [[Category:File Formats]] | ||
[[Category:Metroid Prime]] | [[Category:Metroid Prime]] | ||
+ | [[Category:Metroid Prime 2: Echoes]] |
Latest revision as of 23:48, 2 March 2017
This article is for the ANIM format used in Metroid Prime and Metroid Prime 2: Echoes. 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. The format is largely the same between the two games, with the main difference being that starting in Metroid Prime 2, support for animating scale was added.
There are two versions of the ANIM format (indicated by the file's first u32 value), one with compressed animations and one with uncompressed ones:
Version | Description |
---|---|
0x0 | Quaternion Array Format (Uncompressed) |
0x2 | Rotation Vector Bitstream Format (Compressed) |
Contents
Quaternion Array Format (Uncompressed)
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, while in Metroid Prime 2, it only seems to show up in some draft/test animations not used in the final game.
This format stores uncompressed animations by mapping animation channels to bones, supplying rotations as an array of quaternion (WXYZ) keys and translations/scales as an array of XYZ keys. Translations may be specified for a subset of bones as an array of XYZ keys. In Metroid Prime, rotation keys are required on every channel, while translations may be specified for a subset of bones. In Metroid Prime 2, all three transform components are opt-in.
Layout
Offset | Type | Element Count | Name | Notes | MP1 | MP2 |
---|---|---|---|---|---|---|
0x4 | Char Anim Time | 1 | Duration | Time in seconds that the animation plays for | ✔ | ✔ |
0xC | Char Anim Time | 1 | Key Interval | Time in seconds between keys of each bone channel (reciprocal of frame-rate) | ✔ | ✔ |
0x14 | u32 | 1 | Key Count | Count of keys for each bone channel (keys are set for every frame of the animation) | ✔ | ✔ |
0x18 | u32 | 1 | Root Bone ID | ID of the root bone in this ANIM | ✔ | ✔ |
0x1C | u32 | 1 | Bone Channel Count | Count of bone channel indices in the next array. Always 100. | ✔ | ✔ |
0x20 | u8 | Bone Channel Count | Bone Channel Index Array | This table maps each bone to a bone channel, with the index-position corresponding to a Bone ID in the associated CINF, while the value corresponds to a bone channel index. The value is 0xFF if the bone is not animated by this ANIM. | ✔ | ✔ |
u32 | 1 | Rotation Channel Index Count | Count of rotation channel indices in the next array. Matches the number of valid bone channels. | ✖ | ✔ | |
u8 | Rotation Channel Index Count | Rotation Channel Index Array | This table maps each bone channel to a rotation channel, with the index-position corresponding to an entry in the Bone Channel Index Array above (disregarding 0xFF entries), while the value corresponds to the index of a rotation channel. The value is 0xFF if the bone is not rotated by this ANIM. Note: In Metroid Prime, every bone channel always has rotations, so this array is omitted. | ✖ | ✔ | |
u32 | 1 | Translation Channel Index Count | Count of translation channel indices in the next array. Matches the number of valid bone channels. | ✔ | ✔ | |
u8 | Translation Channel Index Count | Translation Channel Index Array | This table maps each bonechannel to a translation channel, with the index-position corresponding to an entry in the Bone Channel Index Array above (disregarding 0xFF entries), while the value corresponds to the index of a translation channel. The value is 0xFF if the bone is not translated by this ANIM. | ✔ | ✔ | |
u32 | 1 | Scale Channel Index Count | Count of scale channel indices in the next array. Matches the number of valid bone channels. | ✖ | ✔ | |
u8 | Scale Channel Index Count | Scale Channel Index Array | This table maps each bone channel to a scale channel, with the index-position corresponding to an entry in the Bone Channel Index Array above (disregarding 0xFF entries), while the value corresponds to the index of a scale channel. The value is 0xFF if the bone is not scaled by this ANIM. | ✖ | ✔ | |
u32 | 1 | Scale Key Count | Count of elements in Scale Key Array below | ✖ | ✔ | |
float3 | Scale Key Count | Scale Key Array | The scale 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 | Rotation Key Count | Count of elements in Rotation Key Array below | ✔ | ✔ | |
float4 | Rotation Key Count | Rotation Key Array | The rotation keys are interleaved the same way as the scale keys. In Metroid Prime 2, any bone channels that were marked 0xFF in the Rotation Channel Index Array are skipped. | ✔ | ✔ | |
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 the same way as the scale keys. Any bone channels that were marked 0xFF in the Translation Channel Index Array are skipped. | ✔ | ✔ | |
EVNT | 1 | EVNT Ref | ID for this ANIM's EVNT resource, or 0xFFFFFFFF if no events triggered | ✔ | ✖ |
Rotation Vector Bitstream Format (Compressed)
The Rotation Vector Bitstream Format (0x2) is the most widely used animation format. 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 attribute 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, and scale components are multiplied by Scale Multiplier.
Layout
Type | Element Count | Name | Notes | MP1 | MP2 |
---|---|---|---|---|---|
u32 | 1 | Scratch Size | Amount of memory that the animation system needs to allocate to process animation | ✔ | ✔ |
EVNT | 1 | EVNT Ref | ID for this ANIM's EVNT resource, or 0xFFFFFFFF if no events triggered | ✔ | ✖ |
u32 | 1 | Unknown 1 | Always 0x1 | ✔ | ✖ |
u16 | 1 | Unknown 2 | ✖ | ✔ | |
float | 1 | Duration | Time in seconds that the animation plays for | ✔ | ✔ |
float | 1 | Interval | Time in seconds between frames (reciprocal of frame-rate, typically 30-fps) | ✔ | ✔ |
u32 | 1 | Root Bone ID | ID of the root bone in this ANIM | ✔ | ✔ |
u32 | 1 | Looping Flag | When non-zero, engine identifies this ANIM as looping | ✔ | ✔ |
u32 | 1 | Rotation Divisor | Rotation vectors are divided by this value before being applied | ✔ | ✔ |
float | 1 | Translation Multiplier | Translation vectors are multiplied by this value before being applied | ✔ | ✔ |
float | 1 | Scale Multiplier | Scale vectors are multiplied by this value before being applied | ✖ | ✔ |
u32 | 1 | Bone Channel Count | Count of bone channels present in ANIM | ✔ | ✔ |
u32 | 1 | Unknown 4 | Always 0x1 | ✔ | ✔ |
u32 | 1 | Key Bitmap Length | Number of bits in Key Bitmap | ✔ | ✔ |
u32 | round_up(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. If the bit is unset, the keys must be generated via interpolation. | ✔ | ✔ |
u32 | 1 | Bone Channel Count | Count of animated bone channels (matches the previous bone channel count) | ✔ | ✖ |
u32 | 1 | Bone Channel Descriptor Count | Count of bone channel descriptors in Bone Channel Descriptor Table. Matches the Bone Channel Counts. | ✔ | ✔ |
Bone Channel Descriptor | Bone Channel Descriptor 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 * Bits 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. The keys are interleaved as such (key-major): |------------|------------|-----|------------| | bone0/key0 | bone1/key0 | ... | boneN/key0 | | bone0/key1 | bone1/key1 | ... | boneN/key1 | | .......... | .......... | ... | .......... | | bone0/keyN | bone1/keyN | ... | boneN/keyN | |------------|------------|-----|------------| |
✔ | ✔ |
Bone Channel Descriptor
Offset | Type | Name | Notes | MP1 | MP2 |
---|---|---|---|---|---|
0x0 | u32 | Bone ID | Bone ID in the associated CINF for this bone channel | ✔ | ✔ |
0x4 | u16 | Rotation Key Count | Number of rotation keys in the bitstream for this bone channel.
In MP2, if this value is 0, the remaining Rotation fields aren't present |
✔ | ✔ |
0x6 | s16 | Initial Rotation X | Initial X value of bone's rotation vector | ✔ | ✔ |
0x8 | u8 | Rotation Bits X | Number of bits allocated to bone's rotation delta X in bitstream | ✔ | ✔ |
0x9 | s16 | Initial Rotation Y | Initial Y value of bone's rotation vector | ✔ | ✔ |
0xB | u8 | Rotation Bits Y | Number of bits allocated to bone's rotation delta Y in bitstream | ✔ | ✔ |
0xC | s16 | Initial Rotation Z | Initial Z value of bone's rotation vector | ✔ | ✔ |
0xE | u8 | Rotation Bits Z | Number of bits allocated to bone's rotation delta Z in bitstream | ✔ | ✔ |
0xF | u16 | Translation Key Count | If this bone channel has an animated translation, its value will match Rotation Key Count; otherwise the value will be 0.
If the value is 0, the remaining Translation fields aren't present |
✔ | ✔ |
0x11 | s16 | Initial Translation X | Initial X value of bone's translation vector | ✔ | ✔ |
0x13 | u8 | Translation Bits X | Number of bits allocated to bone's translation delta X in bitstream | ✔ | ✔ |
0x14 | s16 | Initial Translation Y | Initial Y value of bone's translation vector | ✔ | ✔ |
0x16 | u8 | Translation Bits Y | Number of bits allocated to bone's translation delta Y in bitstream | ✔ | ✔ |
0x17 | s16 | Initial Translation Z | Initial Z value of bone's translation vector | ✔ | ✔ |
0x19 | u8 | Translation Bits Z | Number of bits allocated to bone's translation delta Z in bitstream | ✔ | ✔ |
0x1A | u16 | Scale Key Count | If this bone channel has an animated scale, its value will match Scale Key Count; otherwise the value will be 0.
If the value is 0, the remaining Scale fields aren't present |
✖ | ✔ |
0x1C | s16 | Initial Scale X | Initial X value of bone's scale vector | ✖ | ✔ |
0x1E | u8 | Scale Bits X | Number of bits allocated to bone's scale delta X in bitstream | ✖ | ✔ |
0x1F | s16 | Initial Scale Y | Initial Y value of bone's scale vector | ✖ | ✔ |
0x21 | u8 | Scale Bits Y | Number of bits allocated to bone's scale delta Y in bitstream | ✖ | ✔ |
0x22 | s16 | Initial Scale Z | Initial Z value of bone's scale vector | ✖ | ✔ |
0x24 | u8 | Scale Bits Z | Number of bits allocated to bone's scale delta Z in bitstream | ✖ | ✔ |
0x25 | End of descriptor |