ANIM (Metroid Prime): Difference between revisions

Jump to navigation Jump to search
Reformatting page for consistency with the rest of the wiki + adding some info, renaming some parameters, etc
imported>Jackoalan
No edit summary
>Aruki
(Reformatting page for consistency with the rest of the wiki + adding some info, renaming some parameters, etc)
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''. See [[ANIM (File Format)]] for the other revisions of this format.''


The '''ANIM format''' is used in conjunction with [[CINF (Metroid Prime)|CINF]] + [[CSKR (Metroid Prime)|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]].
rigging to animate [[CMDL (Metroid Prime)|CMDL meshes]].


There are two versions of the ANIM format in ''Metroid Prime'' (indicated by the file's first u32 value):
There are two versions of the ANIM format in ''Metroid Prime'' (indicated by the file's first u32 value), one with compressed animations and one with uncompressed ones:


{| class="wikitable"
{| class="wikitable"
Line 11: Line 11:
|-
|-
|0x0
|0x0
|[[#Quaternion Array Format|Quaternion Array Format]]
|[[#Quaternion Array Format (Uncompressed)|Quaternion Array Format (Uncompressed)]]
|-
|-
|0x2
|0x2
|[[#Rotation Vector Bitstream Format|Rotation Vector Bitstream Format]]
|[[#Rotation Vector Bitstream Format (Compressed)|Rotation Vector Bitstream Format (Compressed)]]
|}
|}


== Quaternion Array Format ==
== Quaternion Array Format (Uncompressed) ==


The '''Quaternion Array Format''' (0x0) is a less common animation format in ''Metroid Prime''.
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
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.
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 [[wikipedia:Quaternion|quaternion]] (WXYZ) keys.
The format stores uncompressed animations by mapping animation channels to bones and supplying rotations as an array of [[wikipedia:Quaternion|quaternion]] (WXYZ) keys.
Optionally, translations may be specified for a subset of bones as an array of float3 keys.  
Optionally, translations may be specified for a subset of bones as an array of float3 keys.  


Line 29: Line 29:


{| class="wikitable"
{| class="wikitable"
!Data Type
!Offset
!Element Count
!Type
!Identifier
!style="width: 215px;"|Element Count
!style="width: 240px;"|Name
!Notes
!Notes
|-
|-
|[[#Header0|Header0]]
|0x4
|float
|1
|'''Duration'''
|Time in seconds that the animation plays for
|-
|0x8
|u32
|1
|1
|header
|{{unknown|Unknown 1}}
|
|
|-
|-
|0xC
|float
|1
|'''Key Interval'''
|Time in seconds between keys of each bone channel (reciprocal of frame-rate)
|-
|0x10
|u32
|1
|{{unknown|Unknown 2}}
|
|-
|0x14
|u32
|1
|'''Key Count'''
|Count of keys for each bone channel (keys are set for every frame of the animation)
|-
|0x18
|u32
|1
|{{unknown|Unknown 3}}
|
|-
|0x1C
|u32
|1
|'''Rotation Channel Index Count'''
|Count of rotation channel indices in the next array. Always 100.
|-
|0x20
|u8
|u8
|header.bone_entry_count
|''Rotation Channel Index Count''
|bone_entry_map
|'''Rotation Channel Index Array'''
|The index-positions of this table correspond to the ''Bone IDs'' in the associated [[CINF (Metroid Prime)|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
|This table maps each bone to a rotation channel, with the index-position corresponding to a ''Bone ID'' in the associated [[CINF (File Format)|CINF]], while the index corresponds to the index of a rotation channel. The value is 0xFF if the bone is not animated by this ANIM.
|-
|-
|{{unknown|}}
|u32
|u32
|1
|1
|bone_channel_count
|'''Translation Channel Index Count'''
|Count of bone channels present in the ''bone_translation_map'' and ''quaternion_key_array'' below
|Count of translation channel indices in the next array. Matches the number of valid rotation channels.
|-
|-
|{{unknown|}}
|u8
|u8
|bone_channel_count
|''Translation Channel Index Count''
|bone_translation_map
|'''Translation Channel Index Array'''
|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
|This table maps each rotation channel to a translation channel, with the index-position corresponding to an entry in the ''Rotation 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.
|-
|-
|{{unknown|}}
|u32
|u32
|1
|1
|quaternion_key_count
|'''Quaternion Key Count'''
|Count of elements in ''quaternion_key_array'' below
|Count of elements in ''Quaternion Key Array'' below
|-
|-
|{{unknown|}}
|float4
|float4
|quaternion_key_count
|''Quaternion Key Count''
|quaternion_key_array
|'''Quaternion Key Array'''
|The quaternion keys are interleaved as such (bone-major):
|The quaternion keys are interleaved as such (bone-major):
<pre>
<pre>
Line 72: Line 115:
</pre>
</pre>
|-
|-
|{{unknown|}}
|u32
|u32
|1
|1
|translation_key_count
|'''Translation Key Count'''
|Count of elements in ''translation_key_array'' below
|Count of elements in ''Translation Key Array'' below
|-
|-
|{{unknown|}}
|float3
|float3
|translation_key_count
|''Translation Key Count''
|translation_key_array
|'''Translation Key Array'''
|The translation keys are interleaved as such (bone-major):
|The translation keys are interleaved the same way as the rotation keys. Any bone channels that were marked 0xFF in the ''Translation Channel Index Array'' are skipped.
<pre>
|------------|------------|-----|------------|
| bone0/key0 | bone0/key1 | ... | bone0/keyN |
| bone1/key0 | bone1/key1 | ... | bone1/keyN |
| .......... | .......... | ... | .......... |
| boneN/key0 | boneN/key1 | ... | boneN/keyN |
|------------|------------|-----|------------|
</pre>
Any bone channels that were marked 0xff in the ''bone_translation_map'' are skipped by this array
|-
|-
|u32
|{{unknown|}}
|[[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
|}
|}


=== Header0 ===
== Rotation Vector Bitstream Format (Compressed) ==
 
{| class="wikitable"
!Offset
!Length
!Data Type
!Identifier
!Notes
|-
|0x0
|4
|float
|duration
|Time in seconds that the animation plays for
|-
|0x4
|4
|u32
|{{unknown|unknown1}}
|
|-
|0x8
|4
|float
|key_interval
|Time in seconds between keys of each bone channel (reciprocal of frame-rate)
|-
|0xC
|4
|u32
|{{unknown|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
|{{unknown|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 '''Rotation Vector Bitstream Format''' (0x2) is the most widely used animation format in ''Metroid Prime''.
Line 161: Line 146:


=== Key Values ===
=== Key Values ===
When decoding the animation, each bone's rotation (and possibly translation) values are initialized to the ''initial_*''
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''
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).  


Once resolved, rotation components are divided by ''rotation_divisor'', resulting in an axis-angle
Once resolved, rotation components are divided by ''Rotation Divisor'', resulting in an axis-angle
[[wikipedia:Axis–angle_representation#Rotation_vector|rotation vector]]. This rotation vector is converted
[[wikipedia:Axis–angle_representation#Rotation_vector|rotation vector]]. This rotation vector is converted
to quaternion imaginary components with the W component derived via normalized-difference and a ''sign-bit''
to quaternion imaginary components with the W component derived via normalized-difference and a ''sign-bit''
Line 179: Line 164:
</pre>
</pre>


Translation components are multiplied by ''translation_multiplier'', yielding world units.
Translation components are multiplied by ''Translation Multiplier'', yielding world units.


=== Layout ===
=== Layout ===


{| class="wikitable"
{| class="wikitable"
!Data Type
!Offset
!Element Count
!Type
!Identifier
!style="width: 220px;"|Element Count
!style="width: 240px;"|Name
!Notes
!Notes
|-
|-
|[[#Header2|Header2]]
|0x4
|u32
|1
|1
|header
|'''Scratch Size'''
|
|Amount of memory that the animation system needs to allocate to process animation
|-
|-
|u32
|0x8
|round_up(header.key_bitmap_length / 32)
|[[EVNT (File Format)|EVNT]]
|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
|1
|bone_channel_count
|'''EVNT Ref'''
|Count of animated bone channels (matches header.bone_channel_count)
|ID for this ANIM's [[EVNT (File Format)|EVNT]] resource, or 0xFFFFFFFF if no events triggered
|-
|-
|0xC
|u32
|u32
|1
|1
|bone_channel_count
|{{unknown|Unknown 1}}
|Duplicate channel count for some reason
|-
|[[#Bone Channel Descriptor|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 [[wikipedia:Two's complement|Two's complement]] representation.
|}
 
=== Header2 ===
 
{| class="wikitable"
!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 (File Format)|EVNT]] resource, or 0xffffffff if no events triggered
|-
|0x8
|4
|u32
|{{unknown|unknown0}}
|Always 0x1
|Always 0x1
|-
|-
|0xC
|0x10
|4
|float
|float
|duration
|1
|'''Duration'''
|Time in seconds that the animation plays for
|Time in seconds that the animation plays for
|-
|-
|0x10
|0x14
|4
|float
|float
|interval
|1
|'''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)
|-
|-
|0x14
|0x18
|4
|u32
|u32
|{{unknown|unknown1}}
|1
|{{unknown|Unknown 2}}
|Always 0x3
|Always 0x3
|-
|-
|0x18
|0x1C
|4
|u32
|u32
|{{unknown|unknown2}}
|1
|{{unknown|Unknown 3}}
|Always 0x0
|Always 0x0
|-
|-
|0x1C
|0x20
|4
|u32
|u32
|rotation_divisor
|1
|'''Rotation Divisor'''
|Rotation vectors are divided by this value before being applied
|Rotation vectors are divided by this value before being applied
|-
|-
|0x20
|0x20
|4
|float
|float
|translation_multiplier
|1
|'''Translation Multiplier'''
|Translation vectors are multiplied by this value before being applied
|Translation vectors are multiplied by this value before being applied
|-
|-
|0x24
|0x24
|4
|u32
|u32
|bone_channel_count
|1
|'''Bone Channel Count'''
|Count of bone channels present in ANIM
|Count of bone channels present in ANIM
|-
|-
Line 296: Line 238:
|4
|4
|u32
|u32
|{{unknown|unknown3}}
|{{unknown|Unknown 4}}
|Always 0x1
|Always 0x1
|-
|-
|0x2C
|0x2C
|4
|u32
|u32
|key_bitmap_length
|1
|Number of bits in ''key_bitmap''
|'''Key Bitmap Length'''
|Number of bits in ''Key Bitmap''
|-
|0x30
|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.
|-
|{{unknown|}}
|u32
|1
|'''Bone Channel Count'''
|Count of animated bone channels (matches the previous bone channel count)
|-
|{{unknown|}}
|u32
|1
|'''Bone Channel Descriptor Count'''
|Count of bone channel descriptors in ''Bone Channel Descriptor Table''
|-
|{{unknown|}}
|[[#Bone Channel Descriptor|Bone Channel Descriptor]]
|''Bone Channel Descriptor Count''
|'''Bone Channel Descriptor Table'''
|Table describing animated bone channels
|-
|{{unknown|}}
|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 [[wikipedia:Two's complement|Two's complement]] representation.
 
The keys are interleaved as such (key-major):
<pre>
|------------|------------|-----|------------|
| bone0/key0 | bone1/key0 | ... | boneN/key0 |
| bone0/key1 | bone1/key1 | ... | boneN/key1 |
| .......... | .......... | ... | .......... |
| bone0/keyN | bone1/keyN | ... | boneN/keyN |
|------------|------------|-----|------------|
</pre>
|}
|}


Line 310: Line 296:
{| class="wikitable"
{| class="wikitable"
!Offset
!Offset
!Length
!Type
!Data Type
!Name
!Identifier
!Notes
!Notes
|-
|-
|0x0
|0x0
|4
|u32
|u32
|bone_id
|'''Bone ID'''
|''Bone ID'' in the associated [[CINF (Metroid Prime)|CINF]] for this bone channel
|''Bone ID'' in the associated [[CINF (File Format)|CINF]] for this bone channel
|-
|-
|0x4
|0x4
|2
|u16
|u16
|key_count
|'''Rotation Key Count'''
|Number of keys in the bitstream for this bone channel (same value for all channels in animation)
|Number of rotation keys in the bitstream for this bone channel.
'''If this value is 0, the remaining Rotation fields aren't present'''
|-
|-
|0x6
|0x6
|2
|s16
|s16
|initial_rx
|'''Initial Rotation X'''
|Initial X value of bone's rotation vector
|Initial X value of bone's rotation vector
|-
|-
|0x8
|0x8
|1
|u8
|u8
|q_rx
|'''Rotation Bits X'''
|Number of bits allocated to bone's ''rx'' in bitstream
|Number of bits allocated to bone's rotation delta X in bitstream
|-
|-
|0x9
|0x9
|2
|s16
|s16
|initial_ry
|'''Initial Rotation Y'''
|Initial Y value of bone's rotation vector
|Initial Y value of bone's rotation vector
|-
|-
|0xB
|0xB
|1
|u8
|u8
|q_ry
|'''Rotation Bits Y'''
|Number of bits allocated to bone's ''ry'' in bitstream
|Number of bits allocated to bone's rotation delta Y in bitstream
|-
|-
|0xC
|0xC
|2
|s16
|s16
|initial_rz
|'''Initial Rotation Z'''
|Initial Z value of bone's rotation vector
|Initial Z value of bone's rotation vector
|-
|-
|0xE
|0xE
|1
|u8
|u8
|q_rz
|'''Rotation Bits Z'''
|Number of bits allocated to bone's ''rz'' in bitstream
|Number of bits allocated to bone's rotation delta Z in bitstream
|-
|-
|0xF
|0xF
|2
|u16
|u16
|translation_key_count
|'''Translation Key Count'''
|If this bone channel has an animated translation, its value will match ''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, this descriptor ends here'''
'''If the value is 0, the remaining Translation fields aren't present'''
|-
|-
|0x11
|0x11
|2
|s16
|s16
|initial_tx
|'''Initial Translation X'''
|Initial X value of bone's translation vector
|Initial X value of bone's translation vector
|-
|-
|0x13
|0x13
|1
|u8
|u8
|q_tx
|'''Translation Bits X'''
|Number of bits allocated to bone's ''tx'' in bitstream
|Number of bits allocated to bone's translation delta X in bitstream
|-
|-
|0x14
|0x14
|2
|s16
|s16
|initial_ty
|'''Initial Translation Y'''
|Initial Y value of bone's translation vector
|Initial Y value of bone's translation vector
|-
|-
|0x16
|0x16
|1
|u8
|u8
|q_ty
|'''Translation Bits Y'''
|Number of bits allocated to bone's ''ty'' in bitstream
|Number of bits allocated to bone's translation delta Y in bitstream
|-
|-
|0x17
|0x17
|2
|s16
|s16
|initial_tz
|'''Translation Delta Z'''
|Initial Z value of bone's translation vector
|Initial Z value of bone's translation vector
|-
|-
|0x19
|0x19
|1
|u8
|u8
|q_tz
|'''Translation Bits Z'''
|Number of bits allocated to bone's ''tz'' in bitstream
|Number of bits allocated to bone's translation delta Z in bitstream
|}
|}


[[Category:File Formats]]
[[Category:File Formats]]
[[Category:Metroid Prime]]
[[Category:Metroid Prime]]
Anonymous user

Navigation menu