OBD:TRAM: Difference between revisions

From OniGalore
Jump to navigation Jump to search
(important limitation to particles in TRAMs)
m (wording, formatting, added some section links)
 
(22 intermediate revisions by 4 users not shown)
Line 2: Line 2:




[[image:tram_all.gif]]
[[Image:Tram_all.gif]]




Line 10: Line 10:
{{OBDtr| 0x004 | lev_id  |FFFF00| 01 00 00 00 | 0          | level 0 }}
{{OBDtr| 0x004 | lev_id  |FFFF00| 01 00 00 00 | 0          | level 0 }}
{{OBDtr| 0x008 | int32    |FFC8C8| 00 00 00 00 | 0          | runtime only; pointer to animation name }}
{{OBDtr| 0x008 | int32    |FFC8C8| 00 00 00 00 | 0          | runtime only; pointer to animation name }}
{{OBDtr| 0x00C | offset  |FFFFC8| A0 B4 80 00 | 00 80 B4 A0 | at this position starts the [[OBD:TRAM/raw0x0C|y-position part]] (heights) of the pelvis in the raw file }}
{{OBDtr| 0x00C | offset  |FFFFC8| A0 B4 80 00 | 0x0080B4A0  | .raw-address of the [[OBD:TRAM/raw0x0C|height]] track (Y-position of the pelvis above the root) }}
{{OBDtr| 0x010 | offset  |FFFFC8| E0 B5 80 00 | 00 80 B5 E0 | at this position starts the [[OBD:TRAM/raw0x10|x-z-position part]] of the pelvis in the raw file }}
{{OBDtr| 0x010 | offset  |FFFFC8| E0 B5 80 00 | 0x0080B5E0  | .raw-address of the [[OBD:TRAM/raw0x10|horizontal velocities]] of the character root }}
{{OBDtr| 0x014 | offset  |FFFFC8| 60 B8 80 00 | 00 80 B8 60 | at this position starts the [[OBD:TRAM/raw0x14|attack part]] in the raw file }}
{{OBDtr| 0x014 | offset  |FFFFC8| 60 B8 80 00 | 0x0080B860  | .raw-address of the [[OBD:TRAM/raw0x14|attack part]] }}
{{OBDtr| 0x018 | offset  |FFFFC8| 00 00 00 00 | unused      | at this position starts the [[OBD:TRAM/raw0x18|damage part]] in the raw file; only tgt throws use it (tgt <nowiki>=</nowiki> target) }}
{{OBDtr| 0x018 | offset  |FFFFC8| 00 00 00 00 | unused      | .raw-address of the [[OBD:TRAM/raw0x18|damage part]] (used only by "_tgt" animations (throw targets/victims) }}
{{OBDtr| 0x1C | offset  |FFFFC8| A0 B8 80 00 | 00 80 B8 A0 | at this position starts the [[OBD:TRAM/raw0x1C|motion blur part]] in the raw file }}
{{OBDtr| 0x01C | offset  |FFFFC8| A0 B8 80 00 | 0x0080B8A0  | .raw-address of the [[OBD:TRAM/raw0x1C|motion blur part]] }}
{{OBDtr| 0x20 | offset  |FFFFC8| C0 B8 80 00 | 00 80 B8 C0 | at this position starts the [[OBD:TRAM/raw0x20|shortcut part]] in the raw file }}
{{OBDtr| 0x020 | offset  |FFFFC8| C0 B8 80 00 | 0x0080B8C0  | .raw-address of the [[OBD:TRAM/raw0x20|shortcut data]] }}
{{OBDtr| 0x24 | offset  |FFFFC8| 00 00 00 00 | unused      | at this position starts the [[OBD:TRAM/raw0x24|throw part]] in the raw file }}
{{OBDtr| 0x024 | offset  |FFFFC8| 00 00 00 00 | unused      | .raw-address of the [[OBD:TRAM/raw0x24|throw data]] }}
{{OBDtr| 0x28 | offset  |FFFFC8| E0 B8 80 00 | 00 80 B8 E0 | at this position starts the [[OBD:TRAM/raw0x28|footstep part]] in the raw file }}
{{OBDtr| 0x028 | offset  |FFFFC8| E0 B8 80 00 | 0x0080B8E0  | .raw-address of the [[OBD:TRAM/raw0x28|footstep data]] }}
{{OBDtr| 0x2C | offset  |FFFFC8| 00 B9 80 00 | 00 80 B9 00 | at this position starts the [[OBD:TRAM/raw0x2C|particle part]] (trails, dust, etc.) in the raw file }}
{{OBDtr| 0x02C | offset  |FFFFC8| 00 B9 80 00 | 0x0080B900  | .raw-address of the [[OBD:TRAM/raw0x2C|particle data]] (trails, dust, etc.) }}
{{OBDtr| 0x30 | offset  |FFFFC8| 60 B9 80 00 | 00 80 B9 60 | at this position starts the [[OBD:TRAM/raw0x30|position part]] in the raw file }}
{{OBDtr| 0x030 | offset  |FFFFC8| 60 B9 80 00 | 0x0080B960  | .raw-address of the [[OBD:TRAM/raw0x30|position data]] (for basic prediction) }}
{{OBDtr| 0x34 | offset  |FFFFC8| 00 BD 80 00 | 00 80 BD 00 | at this position starts the [[OBD:TRAM/raw0x34|bodyparts animation part]] in the raw file }}
{{OBDtr| 0x034 | offset  |FFFFC8| 00 BD 80 00 | 0x0080BD00  | .raw-address of the [[OBD:TRAM/raw0x34|rotations]] (of all body parts) }}
{{OBDtr| 0x38 | offset  |FFFFC8| 00 00 00 00 | unused      | at this position starts the [[OBD:TRAM/raw0x38|sound part]] in the raw file }}
{{OBDtr| 0x038 | offset  |FFFFC8| 00 00 00 00 | unused      | .raw-address of the [[OBD:TRAM/raw0x38|sound data]] }}
{{OBDtr| 0x3C | bitset32 |C8FFC8| 90 00 08 00 | 144, 0, 8, 0| flags; they're stored in the anim_flags.[[OBD:StNA|StNA]] file; the following bits are possible (values in hex):
{{OBDtr| 0x03C | bitset32 |C8FFC8| 90 00 08 00 | attack, atomic, dontAim| flags; same as listed in [[OBD:StNA|StNA]]anim_flags; the bits are as follows:
:0x'''01''' 00 00 00 - private1 (this bit is not animation related, it is used at runtime to mark that the animation was loaded)
:0x'''01''' 00 00 00 - prepared (used at runtime only; marks that the animation was loaded)
:0x'''02''' 00 00 00 - invulnerable
:0x'''02''' 00 00 00 - invulnerable
:0x'''04''' 00 00 00 - blockHigh
:0x'''04''' 00 00 00 - blockHigh
Line 29: Line 29:
:0x'''10''' 00 00 00 - attack
:0x'''10''' 00 00 00 - attack
:0x'''20''' 00 00 00 - dropWeapon
:0x'''20''' 00 00 00 - dropWeapon
:0x'''40''' 00 00 00 - inAir
:0x'''40''' 00 00 00 - inAir (unused)
:0x'''80''' 00 00 00 - atomic
:0x'''80''' 00 00 00 - atomic
:0x00 '''01''' 00 00 - noTurn
:0x00 '''01''' 00 00 - noTurn
Line 46: Line 46:
:0x00 00 '''20''' 00 - aim360
:0x00 00 '''20''' 00 - aim360
:0x00 00 '''40''' 00 - disableShield
:0x00 00 '''40''' 00 - disableShield
:0x00 00 '''80''' 00 - noAIPickup
:0x00 00 '''80''' 00 - noAIPickup
 
;invulnerable
This animation makes the character impervious to melee damage and throws. He can still take damage from particles and falls.
 
;blockHigh, blockLow
An animation with one of these flags can block attacks coming from the front if they have the high/low attack bit on in [[OBD:TRAM/raw0x14|0x14]].
 
;attack, throwSource, throwTarget, realWorld as proxy flags
These flags were looked at by Importer, Bungie West's authoring tool, which assigned the dontAim flag to an animation if any of them were found. Additionally, Importer used throwSource and throwTarget as indicators that an animation should be flagged as noTurn, but Oni itself also refuses to allow turning when it sees these flags. Within Oni, the attack flag has no effect.
 
;throwSource, throwTarget
Besides serving as proxies, throwSource and throwTarget are used in numerous places in the code to handle throws properly, so they should always be assigned appropriately to throw anims. throwTarget in particular allows your teammates to be hurt by an enemy you throw.
 
;realWorld
This flag only served a purpose when the animation was imported from 3ds Max. Animations without this flag had their extents prepared by Importer. Has no effect within Oni except signifying a lack of attack extents data for visual debugging purposes.
 
;atomic
Has no effect within Oni. When seen by Importer during authoring, however, it set the entire animation to atomic by maxing out the range of the atomic start and end frames (0x174, 0x176).
 
;noTurn
This refers to the user's ability to turn with the controls.
 
;attackForward, attackLeft, attackRight, attackBackward
Have no effect within Oni. Used by Importer to set the movement direction at 0x54.
 
;doAim
Applies aiming screen (PIS/RIF) if character has a weapon.
 
;dontAim
Prevents aiming screen from being applied.
 
;aim360
No effect in Oni. Was used by Importer as a cue to mark the attack's direction (0x54) as 360° (but only Forward, Backward, Left and Right seem to be used in the game data).
 
;disableShield
Used on certain Mutant Muro attacks to temporarily remove his supershield (the anims are listed on [[XML:TRAM]] under its DisableShield documentation).
}}
}}
{{OBDtr| 0x040 | link    |C8FFFF| 00 00 00 00 | unused      | direct animation 0 (link to another TRAM file) }}
{{OBDtr| 0x040 | link    |C8FFFF| 00 00 00 00 | unused      | direct animation 0 (link to another TRAM file) }}
{{OBDtr| 0x044 | link    |C8FFFF| 00 00 00 00 | unused      | direct animation 1 (link to another TRAM file) }}
{{OBDtr| 0x044 | link    |C8FFFF| 00 00 00 00 | unused      | direct animation 1 (link to another TRAM file); see {{SectionLink||Direct links}} }}
{{OBDtr| 0x048 | bitset32 |FFC8FF| 00 00 00 00 | 0          | used parts; legend is for original 19-bone chars; the following bits are possible (values in hex):
{{OBDtr| 0x048 | bitset32 |FFC8FF| 00 00 00 00 | 0          | used body parts; for original 19-bone hierarchy the bit layout is as follows:
:0x'''01''' 00 00 00 - pelvis
:0x000000'''01''' - pelvis
:0x'''02''' 00 00 00 - left thigh
:0x000000'''02''' - left thigh
:0x'''04''' 00 00 00 - left calf
:0x000000'''04''' - left calf
:0x'''08''' 00 00 00 - left foot
:0x000000'''08''' - left foot
:0x'''10''' 00 00 00 - right thigh
:0x000000'''10''' - right thigh
:0x'''20''' 00 00 00 - right calf
:0x000000'''20''' - right calf
:0x'''40''' 00 00 00 - right foot
:0x000000'''40''' - right foot
:0x'''80''' 00 00 00 - mid
:0x000000'''80''' - mid
:0x00 '''01''' 00 00 - chest
:0x0000'''01'''00 - chest
:0x00 '''02''' 00 00 - neck
:0x0000'''02'''00 - neck
:0x00 '''04''' 00 00 - head
:0x0000'''04'''00 - head
:0x00 '''08''' 00 00 - left shoulder
:0x0000'''08'''00 - left shoulder
:0x00 '''10''' 00 00 - left arm
:0x0000'''10'''00 - left arm
:0x00 '''20''' 00 00 - left wrist
:0x0000'''20'''00 - left wrist
:0x00 '''40''' 00 00 - left fist
:0x0000'''40'''00 - left fist
:0x00 '''80''' 00 00 - right shoulder
:0x0000'''80'''00 - right shoulder
:0x00 00 '''01''' 00 - right arm
:0x00'''01'''0000 - right arm
:0x00 00 '''02''' 00 - right wrist
:0x00'''02'''0000 - right wrist
:0x00 00 '''04''' 00 - right fist
:0x00'''04'''0000 - right fist
 
Aiming screen TRAMs use several bones here. Other overlay TRAMs use only "chest". Non-overlay TRAMs use none.
Aiming screen TRAMs "use" several bones here. Other overlay TRAMs use only "chest". Non-overlay TRAMs use none.
}}
}}
{{OBDtr| 0x04C | bitset32 |FFC8FF| 00 00 00 00 | 0          | replaced parts; same legend as above; only overlay TRAMs other than aiming-screen ones "replace" parts. }}
{{OBDtr| 0x04C | bitset32 |FFC8FF| 00 00 00 00 | 0          | replaced parts; same bitset layout as above; only overlay TRAMs other than aiming-screen ones replace parts. }}
{{OBDtr| 0x050 | float    |FFC800| 00 00 00 00 | 0.000000    | final rotation in radians (for anims that make you turn) }}
{{OBDtr| 0x050 | float    |FFC800| 00 00 00 00 | 0.000000    | final rotation in radians (for anims that make you turn) }}
{{OBDtr| 0x054 | int16    |C800C8| 01 00      | 1          | main attack direction; the following directions are possible:
{{OBDtr| 0x054 | int16    |C800C8| 01 00      | 1          | main moving direction; the following directions are possible:
:0 - none
:0 - none
:1 - forward
:1 - forward
Line 81: Line 116:
:3 - left
:3 - left
:4 - right
:4 - right
:5 - 360 (unused? even Devil Spin Kick uses "forward")
}}
}}
{{OBDtr| 0x056 | uint16  |C87C64| 06 00       | 6           | attack sound ("Rising fury!"); the number belongs to the sound slot in the [[OBD:ONCC|ONCC]] file}}
{{OBDtr| 0x056 | uint16  |C87C64| 06 00   | 6 | vocalization type (-1 if unused); references one of the 10 vocalization slots in [[OBD:ONCC|ONCC]]
{{OBDtrBK|Extent info}}
:0 - taunt
:1 - alert
:2 - startle
:3 - checkbody
:4 - pursue
:5 - cower
:6 - superpunch
:7 - superkick
:8 - super3
:9 - super4
In this case the value 6 triggers Konoko's "superpunch" vocalization, "Rising fury!" }}
{{OBDtrBK|Extent info}}<br>See {{SectionLink||Extent info}} for explanation
{{OBDtr| 0x058 | float    |B0C3D4| 8D 87 CF 41 | 25.941187  | max horizontal extent of the attack }}
{{OBDtr| 0x058 | float    |B0C3D4| 8D 87 CF 41 | 25.941187  | max horizontal extent of the attack }}
{{OBDtr| 0x05C | float    |B0C3D4| DE E9 1A 40 | 2.420524    | min Y of the attack }}
{{OBDtr| 0x05C | float    |B0C3D4| DE E9 1A 40 | 2.420524    | min Y of the attack }}
Line 108: Line 155:
{{OBDtr| 0x110 | float    |64AAAA| 5E 93 BF 40 | 5.986739    | extent angle (in radians) }}
{{OBDtr| 0x110 | float    |64AAAA| 5E 93 BF 40 | 5.986739    | extent angle (in radians) }}
{{OBDtrBK|Farthest extent info - information about the farthest reaching extent in the extent part }}
{{OBDtrBK|Farthest extent info - information about the farthest reaching extent in the extent part }}
{{OBDtr| 0x114 | int16    |EBEBEB| 2F 00      | 47          | frame; -1 if the attack part doesn't exist or the attack part exists and it's a tgt animation (tgt <nowiki>=</nowiki> target) }}
{{OBDtr| 0x114 | int16    |EBEBEB| 2F 00      | 47          | frame; -1 if there is no attack part of if the animation is for a throw target/victim ("_tgt") }}
{{OBDtr| 0x116 | int8    |8C8CCC| 01          | 1          | attack index to which the max extent belongs }}
{{OBDtr| 0x116 | int8    |8C8CCC| 01          | 1          | attack index to which the max extent belongs }}
{{OBDtr| 0x117 | int8    |FF00C8| 16          | 22          | attack frame offset from the attack with index 0 }}
{{OBDtr| 0x117 | int8    |FF00C8| 16          | 22          | attack frame offset from the attack with index 0 }}
Line 124: Line 171:
{{OBDtrBK|End extent info}}
{{OBDtrBK|End extent info}}
{{OBDtr2|0x140 | char[16] |FFCD96| konflash1                | impact particle name (reference to 01018-.[[OBD:ONIA|ONIA]], which is called up in the [[OBD:ONCC|ONCC]] file) }}
{{OBDtr2|0x140 | char[16] |FFCD96| konflash1                | impact particle name (reference to 01018-.[[OBD:ONIA|ONIA]], which is called up in the [[OBD:ONCC|ONCC]] file) }}
{{OBDtr| 0x150 | uint16  |C8C864| 00 00      | 0          | hard pause in 1/60 seconds }}
{{OBDtr| 0x150 | uint16  |C8C864| 00 00      | 0          | hard pause in game ticks (1/60 seconds) }}
{{OBDtr| 0x152 | uint16  |C8C864| 12 00      | 18          | soft pause in 1/60 seconds }}
{{OBDtr| 0x152 | uint16  |C8C864| 12 00      | 18          | soft pause in game ticks (1/60 seconds) }}
{{OBDtr| 0x154 | int32    |0096C8| 00 00 00 00 | 0          | number of elements in the sound part }}
{{OBDtr| 0x154 | int32    |0096C8| 00 00 00 00 | 0          | number of elements in the sound part }}
{{OBDtr| 0x158 | int32    |FF80C0| 00 00 00 00 | 0          | runtime only; pointer to the sound for this animation (initialised from [[OBD:BINA/SABD|SABD]])}}
{{OBDtr| 0x158 | int32    |FF80C0| 00 00 00 00 | 0          | runtime only; pointer to the sound for this animation (from [[OBD:BINA/SABD|SABD]])}}
{{OBDtr| 0x15C | int16    |D0C0AF| 00 00      | 0          | runtime only; sound start frame (initialised from SABD) }}
{{OBDtr| 0x15C | int16    |D0C0AF| 00 00      | 0          | runtime only; sound start frame (from SABD) }}
{{OBDtr| 0x15E | int16    |D0C0AF| 3C 00      | 60          | frames per second }}
{{OBDtr| 0x15E | int16    |D0C0AF| 3C 00      | 60          | animation frame rate (always 60?) }}
{{OBDtr| 0x160 | int16    |EEDDFF| 06 00      | 6          | compression size }}
{{OBDtr| 0x160 | int16    |EEDDFF| 06 00      | 6          | compression size }}
{{OBDtr| 0x162 | int16    |EEDDFF| 16 00      | 22          | animation type (from anim_types.[[OBD:StNA|StNA]]) }}
{{OBDtr| 0x162 | int16    |EEDDFF| 16 00      | 22          | animation type (from [[XML:StNA|StNA]]) }}
{{OBDtr| 0x164 | int16    |C5FF8A| 16 00      | 6          | aiming type }}
{{OBDtr| 0x164 | int16    |C5FF8A| 16 00      | 22          | aiming type from StNA }}
{{OBDtr| 0x166 | int16    |C5FF8A| 00 00      | 0          | from state }}
{{OBDtr| 0x166 | int16    |C5FF8A| 00 00      | 0          | from state; see {{SectionLink||From state, to state, animation type, variant, shortcuts}} }}
{{OBDtr| 0x168 | int16    |C0C0C0| 07 00      | 7          | to state }}
{{OBDtr| 0x168 | int16    |C0C0C0| 07 00      | 7          | to state }}
{{OBDtr| 0x16A | int16    |C0C0C0| 13 00      | 19          | number of bodyparts }}
{{OBDtr| 0x16A | int16    |C0C0C0| 13 00      | 19          | number of body parts }}
{{OBDtr| 0x16C | int16    |FF0080| 50 00      | 80          | number of frames }}
{{OBDtr| 0x16C | int16    |FF0080| 50 00      | 80          | number of frames }}
{{OBDtr| 0x16E | int16    |FF0080| 50 00      | 80          | duration in in 1/60 seconds }}
{{OBDtr| 0x16E | int16    |FF0080| 50 00      | 80          | duration in game ticks (1/60 seconds) }}
{{OBDtr| 0x170 | bitset16 |FFFFA6| 00 02      | 0, 2        | varient, the following bits are possible (values in hex):
{{OBDtr| 0x170 | bitset16 |FFFFA6| 00 02      | 0x0200 <nowiki>=</nowiki> COM| variant, the following bits are possible (values in hex):
:0x00 '''01''' - '''SPR'''int animation
:0x'''01'''00 - "sprint" ('''SPR'''int animation)
:0x00 '''02''' - '''COM'''bat animation
:0x'''02'''00 - "fight" ('''COM'''bat animation)
:0x00 '''08''' - '''PIS'''tol animation
:0x'''04'''00 - "shoulder" (not used by the engine; apparently used at one time for weapons like [[:Image:Pre-beta enigma 5.png|rocket launchers]])
:0x00 '''10''' - '''NIN'''ja '''PIS'''tol animation (left-handed)
:0x'''08'''00 - "righty pistol" ('''PIS'''tol animation)
:0x00 '''20''' - '''RIF'''le animation
:0x'''10'''00 - "lefty pistol" ('''NIN'''ja '''PIS'''tol animation)
:0x00 '''40''' - '''NIN'''ja '''RIF'''le animation (left-handed)
:0x'''20'''00 - "righty rifle" ('''RIF'''le animation)
:0x00 '''80''' - '''PAN'''ic or '''SCR'''amble animation
:0x'''40'''00 - "lefty rifle" ('''NIN'''ja '''RIF'''le animation)
:0x'''80'''00 - "panic" ('''PAN'''ic or '''SCR'''amble animation)
}}
}}
{{OBDtr| 0x172 | char[2]  |FFFFA6| AD DE      | dead        | "varient end"; ignored }}
{{OBDtr| 0x172 | char[2]  |FFFFA6| AD DE      | dead        | "varient end"; ignored by the engine }}
{{OBDtr| 0x174 | uint16  |71FFB8| 00 00      | 0          | atomic start }}
{{OBDtr| 0x174 | uint16  |71FFB8| 00 00      | 0          | atomic start }}
{{OBDtr| 0x176 | uint16  |71FFB8| FF FF      | 65535      | atomic end }}
{{OBDtr| 0x176 | uint16  |71FFB8| FF FF      | 65535      | atomic end }}
{{OBDtr| 0x178 | uint16  |0000BF| 00 00      | 0          | end interpolation }}
{{OBDtr| 0x178 | uint16  |0000BF| 00 00      | 0          | end interpolation }}
{{OBDtr| 0x17A | uint16  |0000BF| FF FF      | 65535      | maximal interpolation }}
{{OBDtr| 0x17A | uint16  |0000BF| FF FF      | 65535      | maximum interpolation }}
{{OBDtr| 0x17C | uint16  |804040| FF FF      | 65535      | action frame }}
{{OBDtr| 0x17C | uint16  |804040| FF FF      | 65535      | action frame; e.g. when weapon theft occurs in a disarm anim }}
{{OBDtr| 0x17E | uint16  |804040| 0A 00      | 10          | first level where the animation is available }}
{{OBDtr| 0x17E | uint16  |804040| 0A 00      | 10          | first level where the animation is available }}
{{OBDtr| 0x180 | uint8    |FF22FF| 01          | 1          | first "invulnerable" frame }}
{{OBDtr| 0x180 | uint8    |FF22FF| 01          | 1          | first "invulnerable" frame }}
{{OBDtr| 0x181 | uint8    |FF22FF| 1C          | 28          | last "invulnerable" frame }}
{{OBDtr| 0x181 | uint8    |FF22FF| 1C          | 28          | last "invulnerable" frame }}
{{OBDtr| 0x182 | uint8    |808080| 02          | 2          | number of elements in the attack part }}
{{OBDtr| 0x182 | uint8    |808080| 02          | 2          | number of elements in the attack part above }}
{{OBDtr| 0x183 | uint8    |808080| 00          | 0          | number of elements in the take damage part }}
{{OBDtr| 0x183 | uint8    |808080| 00          | 0          | number of elements in the take damage part above }}
{{OBDtr| 0x184 | uint8    |FFAA82| 01          | 1          | number of elements in the motion blur part }}
{{OBDtr| 0x184 | uint8    |FFAA82| 01          | 1          | number of elements in the motion blur part above }}
{{OBDtr| 0x185 | uint8    |FFAA82| 01          | 1          | number of elements in the shortcut part }}
{{OBDtr| 0x185 | uint8    |FFAA82| 01          | 1          | number of elements in the shortcut part above }}
{{OBDtr| 0x186 | uint8    |00D900| 02          | 2          | number of elements in the footstep part }}
{{OBDtr| 0x186 | uint8    |00D900| 02          | 2          | number of elements in the footstep part above }}
{{OBDtr| 0x187 | uint8    |00D900| 04          | 4          | number of elements in the particle part }}
{{OBDtr| 0x187 | uint8    |00D900| 04          | 4          | number of elements in the particle part above }}
{{OBDtr| 0x188 | char[24] |CACAFF| AD DE      | dead        | unused }}
{{OBDtr| 0x188 | char[24] |CACAFF| AD DE      | dead        | unused (not part of the template) }}
|}
|}


==Animation timeline==
:'''NOTE:''' The following assumes animation data sampled at 60 frames per second (i.e., in sync with game ticks). Different frame rates have not been studied, and OniSplit only works with 60 fps TRAMs.
The duration of an animation in game ticks is equal to the number of frames covered by the main animation data, i.e., it extends one tick past the last keyframe of the height track or rotation tracks. Over this last tick, the pelvis height and bone rotations are interpolated to the values supplied by the first frame of the ''following'' animation, whereas the horizontal position is advanced using the last velocity entry of the current animation.


;Direct links
Thus an important note about looping animations is that the poses at the start and end of an animation (a combination of height, bone rotation and the accumulated horizontal velocity) are generally ''not'' identical, but rather one tick apart. The same applies to animation pairs (locomotion loops) or any matching animation sequences (e.g., combos).
:These fields work together with soft pause and hard pause fields when switching animations. When the current animation has a direct link to the new animation the soft pause and hard pause are both considered to be 0.


:Example:
For the current example (KONCOMpunch_heavy), the duration is 80 ticks, and the main animation tracks are as follows:
*The [[/raw0x0C|height]] track has 80 entries that are used to place the character vertically at every tick, starting at tick 0 and ending at tick 79. At tick 80, i.e., at the end of the current animation's duration, the height is supplied by the next animation. Between ticks 79 and 80, the height is interpolated between the last height entry of KONCOMpunch_heavy and the first height entry of the next animation.
*The [[/raw0x10|velocity]] tracks (horizontal motion of the root) also have 80 entries. However, unlike the height values, the velocities correspond not to ticks but to intervals between ticks, and thus span the whole range of the animation, from tick 0 to tick 80. Starting at tick 80, the first velocity entry of the following animation applies.
*The [[/raw0x34|rotation]] tracks are keyed at ticks (like the height track), but (unlike the height track) are typically not keyed at ''every'' tick: there are intervals (gaps) of variable size between the keys, over which the rotation of each bone is interpolated. Even so, the total duration  of the intervals is the same as the time span of the height track, i.e., one tick shorter than the "duration" of the animation. In this example, the first rotation pose corresponds to tick 0 and the last pose corresponds to tick 79. At tick 80, the pose will be read from the following animation, and between ticks 79 and 80, the pose will be interpolated between the last pose of KONCOMpunch_heavy and the first pose of the next animation.
'''NOTE:''' The above description of how heights and rotations are interpolated during the last tick on an animation's duration does not only apply for most of Oni's transitions, which typically involve overlapping timelines and interpolation between two animations playing simultaneously. Nonetheless, the description is useful to understand why the time span of rotation and height data is one tick shorter than the supposed duration of the animation, and also what happens for loops, pairs or combo sequences.


:01855-KONCOMcomb_p_p.TRAM links to:
==Direct links==
:*01856-KONCOMcomb_p_p_p.TRAM (direct animation 0)
These fields work together with soft pause and hard pause fields when switching animations. When the current animation has a direct link to the new animation the soft pause and hard pause are both considered to be 0.
:*01857-KONCOMcomb_p_p_k.TRAM (direct animation 1)
;Example
01855-KONCOMcomb_p_p.TRAM links to:
*01856-KONCOMcomb_p_p_p.TRAM (direct animation 0)
*01857-KONCOMcomb_p_p_k.TRAM (direct animation 1)


:That means that if a p_p_p or p_p_k animation follows after a p_p animation there will be no pause between them but for animations other than p_p_p and p_p_k there may be a pause of 'soft pause' frames between them.  
That means that if a p_p_p or p_p_k animation follows after a p_p animation there will be no pause between them but for animations other than p_p_p and p_p_k there may be a pause of 'soft pause' frames between them.  
 
==Extent info==
The extent information is used by the AI to figure out if an attack can reach the enemy. This information is only present/used if the animation contains attacks. Many of the fields in the extent information can be computed from other available information like the attack/position/extent parts. The only "unique" information here is the "max horizontal extent 0° ... 360°" array and the extent part count/offset fields. The alternate move direction does not appear to be ever used.
 
==From state, to state, animation type, variant, shortcuts==
These are used to find specific animations. Each character has a current animation state and a current "varient". When the engine searches for an animation with a specific type it considers those that have a matching "from state" and "varient". For example both "comb_k_k" and "jump_fw_kick" animations have the type "kick" but one can be executed when the character is in the "standing" state and the other can be executed when the character is in "falling back" or "falling forward" states.
 
==Aiming Type==
Aiming type is used to find the aiming animation in [[TRSC]] and normally it is the same as the animation type. In a couple of cases this type is "none" meaning that no aiming animation should be used. It is pretty much equivalent to setting the "don't aim" flag.
 
==Particles==
While Oni can store a number as large as 255 in 0x187, Oni only allocates memory for 16 particles per TRAM, and it does not check to make sure that the actual number of particles is ≤ 16. Thus you can easily crash Oni by initiating a move which has 17 particles attached.
 
==Limitations on animation length==
Frame counts in Oni's TRAM are either absolute frame counts since the beginning of the animation, or intervals between events or keyframes.
:(The following analysis assumes 60 fps as an animation's frame rate. If the frame rate can be reduced, the limiting time amounts will increase accordingly.)
 
===16-bit frame counts===
Most typically a frame count is an unsigned 16-bit integer, which allows for a comfortable range of 65535 frames = 1092.25 seconds = 18 m 12.25 s. Even if the integer is accidentally parsed as 16-bit ''signed'', the wraparound to negative values only happens after 32767 frames = 546.13̅ seconds = 9 m 6.13̅ s. Oni has other contexts where frame counts are stored as 16-bit integers, e.g., [[OBD:SNDD|SNDD]] and [[OBD:OBAN|OBAN]].
 
===8-bit frame counts===
Some of the frame counts inside a TRAM are stored as 8-bit integers (unsigned), which reduces the range to 255 frames = 4.25 seconds (or, in the event of signed interpretation, 127 frames = 2.116̅ seconds).<br>
The contexts where 8-bit frame counts occur are as follows.
*[[OBD:TRAM/raw0x1C|Motion blur]], "Lifetime" and "Interval", meaning that "ghosts" can be spawned no more than 4.25 seconds apart and can last no more than 4.25 seconds before disappearing (LIMITATION SEVERITY: MINOR)
*[[OBD:TRAM/raw0x34|Rotation data]], intervals between a bone's keyframes, meaning that rotation keyframes for a bone cannot be more than 4.25 seconds apart. (LIMITATION SEVERITY: MINOR)
*"Max/farthest extent info" (main TRAM file, see above): the "attack frame offset from the attack with index 0" is an 8-bit frame interval, meaning that attacks belonging to a same TRAM cannot be more than 4.25 seconds apart, or the extent of the later attacks may not be taken into account properly by the AI. (LIMITATION SEVERITY: Can be an issue for very long special moves or throws, where damage is dealt both at the beginning and at the end of the animation.)
*"Invulnerable" range (main TRAM file, see above): The invulnerability range is a pair of 8-bit frame indices, meaning that the invulnerability range cannot extend past 4.25 seconds. (LIMITATION SEVERITY: Can be an issue for very long crowd-clearing moves, like a much longer "Whirling Dervish" (ELICOMpunch_heavy) or long versions of Muro's "Breakdancer" or "Helicopter" moves; a possible workaround is to set invulnerability for the whole animation rather than for an 8-bit frame range)
 
===16-bit raw data offsets===
Unlike files like [[OBD:AGDB|AGDB]] and [[OBD:SUBT|SUBT]] (which use 32-bit pointers into the .raw data stored in the .dat part), a TRAM's [[OBD:TRAM/raw0x34|rotation data]] starts off with a set of 16-bit offsets, stored in the .raw part and pointing into the following data (typically there are 19 such offsets, one for each bone in a skeleton).
 
For the last offset to work, it must be at most equal to 65535 and, since the first 38 bytes are taken up by the offsets, this leaves at most 65497 bytes for the cumulated size of the 18 first rotation tracks.
 
The raw size of a rotation track depends on the number of keyframe intervals (let's call it N) and on the compression size (either 6 or 16 bytes): a size-6 rotation track takes up 7N+6 bytes, and a size-16 rotation track takes up 17N+16 bytes.
 
For a size-6 animation, the "average N" for the first 18 tracks cannot exceed 518.96, so that 126N+108 stays below 65497. For a size-16 animation, this "average N" for the first 18 tracks must not exceed 213.1013, so that 306N+288 stays below 65497.
 
For an animation that has a keyframe for every bone at each game tick, a 518-frame duration corresponds to 8.63̅ seconds, whereas 213 frames = 3.55 seconds. Typically, however, rotation tracks will have significant keyframe reduction, e.g., Konoko's "Rising Fury!" lasts 80 frames but the pelvis rotation has only 23 keyframe intervals. Assuming 4:1 keyframe reduction for typical animations, this means that the 16-bit offset won't be an issue (for size-6 animations) unless the animation is longer than about 30 seconds.
 
==PS2 implementation==
The PS2 implementation optimizes TRAM storage by splitting off combat-relevant data (extents etc) to a new instance type, TREX (Totoro Animation Extra, see below). As a result, the TRAM size (with header) is reduced from 392 to 80 bytes.
 
{|cellpadding=3 cellspacing=0 style="line-height:13px"
{{HexRow|0x00|
|01|C8|03|00|01|00|00|00|01|45|06|00|00|00|00|00|
|FF|FF|FF|FF|FF|FF|FF|FF|00|00|00|00|FF|FF|FF|FF|
|00|00|00|00|FF|FF|FF|FF|FF|FF|FF|FF|C8|C8|C8|C8|
|00|00|00|00|00|00|00|00|00|00|00|00|C8|C8|C8|C8|
|°È°°°°°°°E°°°°°°
}}
{{HexRow|0x10|
|E0|EE|0F|00|20|F0|0F|00|80|F4|0F|00|A0|F4|0F|00|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|
|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|
|àî°° ð°° ô°° ô°°
}}
{{HexRow|0x20|
|C0|F4|0F|00|40|F7|0F|00|90|00|08|00|00|00|00|00|
|FF|FF|FF|FF|FF|FF|FF|FF|C8|C8|C8|C8|FF|FF|FF|FF|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|C8|C8|C8|C8|
|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|FF|FF|FF|FF|
|Àô°°@÷°° °°°°°°°
}}
{{HexRow|0x30|
|00|00|00|00|01|00|00|00|06|00|16|00|16|00|00|00|
|FF|FF|FF|FF|C8|C8|FF|FF|EE|EE|EE|EE|C5|C5|C5|C5|
|C8|C8|C8|C8|00|00|00|00|DD|DD|DD|DD|FF|FF|FF|FF|
|FF|FF|FF|FF|C8|C8|FF|FF|FF|FF|FF|FF|8A|8A|8A|8A|
|°°°°°°°°°°°°°°°°
}}
{{HexRow|0x40|
|07|00|50|00|00|02|AD|DE|00|00|FF|FF|00|01|02|13|
|C0|C0|FF|FF|FF|FF|FF|FF|71|71|71|71|FF|FF|00|C0|
|C0|C0|00|00|FF|FF|FF|FF|FF|FF|FF|FF|AA|AA|D9|C0|
|C0|C0|80|80|A6|A6|A6|A6|B8|B8|B8|B8|82|82|00|C0|
|°°P°°°-Þ°°ÿÿ°°°°
}}
{{HexRow|0x50|
|AD|DE|AD|DE|AD|DE|AD|DE|AD|DE|AD|DE|AD|DE|AD|DE|
|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|
|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|CA|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|
|-Þ-Þ-Þ-Þ-Þ-Þ-Þ-Þ
}}
|}




;Extent info
{{Table}}
:The extent information is used by the AI to figure out if an attack can reach the enemy. This information is only present/used if the animation contains attacks. Many of the fields in the extent information can be computed from other available information like the attack/position/extent parts. The only "unique" information here is the "max horizontal extent 0° ... 360°" array and the extent part count/offset fields. The alternate move direction does not appear to be ever used.
{{OBDth}}
{{OBDtr| 0x000 | res_id  |FF0000| 01 C8 03 00 | 968        | 00968-KONCOMpunch_heavy.TRAM }}
{{OBDtr| 0x004 | lev_id  |FFFF00| 01 00 00 00 | 0          | level 0 }}
{{OBDtr| 0x008 | link    |00FF00| 01 45 06 00 | 1605        | link to 01605-.TREX (combat-relevant data) }}
{{OBDtr| 0x00C | int32    |FFC8C8| 00 00 00 00 | 0          | runtime only; pointer to animation name }}
{{OBDtr| 0x010 | offset  |FFFFC8| E0 EE 0F 00 | 0x000FEEE0  | .raw-address of the [[OBD:TRAM/raw0x0C|height]] track (Y-position of the pelvis above the root) }}
{{OBDtr| 0x014 | offset  |FFFFC8| 20 F0 0F 00 | 0x000FF020  | .raw-address of the [[OBD:TRAM/raw0x10|horizontal velocities]] of the character root }}
{{OBDtr| 0x018 | offset  |FFFFC8| 80 F4 0F 00 | 0x000FF480  | .raw-address of the [[OBD:TRAM/raw0x20|shortcut data]] }}
{{OBDtr| 0x01C | offset  |FFFFC8| A0 F4 0F 00 | 0x000FF4A0  | .raw-address of the [[OBD:TRAM/raw0x28|footstep data]] }}
{{OBDtr| 0x020 | offset  |FFFFC8| C0 F4 0F 00 | 0x000FF4C0  | .raw-address of the [[OBD:TRAM/raw0x30|position data]] (for basic prediction) }}
{{OBDtr| 0x024 | offset  |FFFFC8| 40 F7 0F 00 | 0x000FF740  | .raw-address of the [[OBD:TRAM/raw0x34|rotations]] (of all body parts) }}
{{OBDtr| 0x028 | bitset32 |C8FFC8| 90 00 08 00 | attack, atomic, dontAim | flags (same as PC/Mac 0x03C) }}
{{OBDtr| 0x02C | bitset32 |FFC8FF| 00 00 00 00 | 0          | used body parts; used mostly by aiming overlays (same as PC/Mac 0x048) }}
{{OBDtr| 0x030 | bitset32 |FFC8FF| 00 00 00 00 | 0          | replaced parts; used by non-aiming overlays (same as PC/Mac 0x04C) }}
{{OBDtr| 0x034 | int16    |C800C8| 01 00      | 1          | moving direction }}
{{OBDtr| 0x036 | int16    |FF00FF| 00 00      | 1          | unknown }}
{{OBDtr| 0x038 | int16    |EEDDFF| 06 00      | 6          | compression size }}
{{OBDtr| 0x03A | int16    |EEDDFF| 16 00      | 22          | animation type (from [[XML:StNA|StNA]]) }}
{{OBDtr| 0x03C | int16    |C5FF8A| 16 00      | 22          | aiming type }}
{{OBDtr| 0x03E | int16    |C5FF8A| 00 00      | 0          | from state }}
{{OBDtr| 0x040 | int16    |C0C0C0| 07 00      | 7          | to state }}
{{OBDtr| 0x042 | int16    |FF0080| 50 00      | 80          | number of frames (animations are locked to 60 fps) }}
{{OBDtr| 0x044 | bitset16 |FFFFA6| 00 02      | 0x0200 <nowiki>=</nowiki> COM| variant (same as PC/Mac 0x170) }}
{{OBDtr| 0x046 | char[2]  |FFFFA6| AD DE      | dead        | "varient end"; ignored by the engine }}
{{OBDtr| 0x048 | uint16  |71FFB8| 00 00      | 0          | atomic start }}
{{OBDtr| 0x04A | uint16  |71FFB8| FF FF      | 65535      | atomic end }}
{{OBDtr| 0x04C | uint8    |FFAA82| 00          | 0          | unknown }}
{{OBDtr| 0x04D | uint8    |FFAA82| 01          | 1          | number of elements in the shortcut part }}
{{OBDtr| 0x04E | uint8    |00D900| 02          | 2          | number of elements in the footstep part }}
{{OBDtr| 0x04F | uint8    |C0C0C0| 13          | 19          | number of body parts? }}
{{OBDtr| 0x050 | char[16] |CACAFF| AD DE      | dead        | unused (not part of the template) }}
|}
At the time of writing, some of the above data is merely an informed guess (not thoroughly confirmed), and the nature of 0x036 (int16?) and 0x04C (uint8?) needs to be clarified more particularly. If 0x036 is always zero, then maybe 0x034 is stored as an int32. We also need to locate "end/maximal interpolation" and possibly other remaining fields from the PC/Mac data, or establish that they are missing from the TRAM/TREX representation of animations on PS2.




;From state, to state, animation type, varient, shortcuts
The TREX file has all the combat-relevant stuff as well as some stuff that isn't necessary combat-related (e.g., vocalizations, turning angle, moving direction).
:These are used to find specific animations. Each character has a current animation state and a current varient. When the engine searches for an animation with a specific type it considers those that have a matching "from state" and "varient". For example both "comb_k_k" and "jump_fw_kick" animations have the type "kick" but one can be executed when the character is in the "standing" state and the other can be executed when the character is in "falling back" or "falling forward" states.


The block between 0x008 and 0x0F0 is exactly the extent block between 0x058 and 0x140 in the PC/Mac TRAM. After that come the other 6 .raw links that were stripped from the reduced TRAM, the impact particle name, and the two direct TRAM links, which accounts for all the data up to 0x150 in the PC/Mac TRAM. Some data fields from the end of PC/Mac TRAM are confirmed to be missing on PS2 (e.g., the frame rate is implied to be 60 Hz), but some of the correspondence is still not documented or thoroughly confirmed.
{|cellpadding=3 cellspacing=0 style="line-height:13px"
{{HexRow|0x000|
|01|45|06|00|01|00|00|00|8D|87|CF|41|DE|E9|1A|40|
|FF|FF|FF|FF|FF|FF|FF|FF|B0|B0|B0|B0|B0|B0|B0|B0|
|00|00|00|00|FF|FF|FF|FF|C3|C3|C3|C3|C3|C3|C3|C3|
|00|00|00|00|00|00|00|00|D4|D4|D4|D4|D4|D4|D4|D4|
|ºEºººººº  ÏAÞéº@
}}
{{HexRow|0x010|
|95|34|D3|41|8D|87|CF|41|8D|87|CF|41|8D|87|CF|41|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
| 4ÓA  ÏA  ÏA  ÏA
}}
{{HexRow|0x020|
|8D|87|CF|41|9D|E4|11|41|14|BA|04|41|6B|77|D4|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|  ÏAºººººººººººº
}}
{{HexRow|0x030|
|50|5A|B3|40|74|4B|9C|40|DF|37|87|40|70|75|84|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x040|
|8E|ED|6A|40|16|40|5F|40|16|40|5F|40|BF|CD|45|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x050|
|34|2B|49|40|34|2B|49|40|34|2B|49|40|5A|D8|6D|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x0060|
|5A|D8|6D|40|5A|D8|6D|40|8F|D9|96|40|8F|D9|96|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x070|
|B7|7B|AB|40|F0|81|BF|40|98|95|E3|40|98|95|E3|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x080|
|98|95|E3|40|98|95|E3|40|98|95|E3|40|98|95|E3|40|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x090|
|ED|E7|14|41|D4|2E|9E|41|8F|FB|CC|41|8D|87|CF|41|
|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|B0|
|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|C3|
|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|D4|
|ºººººººººººººººº
}}
{{HexRow|0x0A0|
|8D|87|CF|41|05|00|00|00|00|00|00|BF|1E|85|6B|BF|
|B0|B0|B0|B0|E7|E7|FF|FF|64|64|64|64|64|64|64|64|
|C3|C3|C3|C3|CE|CE|DD|DD|AA|AA|AA|AA|AA|AA|AA|AA|
|D4|D4|D4|D4|A5|A5|DD|DD|AA|AA|AA|AA|AA|AA|AA|AA|
|ºººººººººººººººº
}}
{{HexRow|0x0B0|
|19|47|0C|41|EB|51|F0|40|D7|A3|14|41|0A|D7|3B|41|
|64|64|64|64|64|64|64|64|64|64|64|64|64|64|64|64|
|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|
|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|AA|
|ºººººººººººººººº
}}
{{HexRow|0x0C0|
|5E|93|BF|40|2F|00|01|16|85|EB|51|BF|E1|7A|7C|C1|
|64|64|64|64|EB|EB|8C|FF|F0|F0|F0|F0|F0|F0|F0|F0|
|AA|AA|AA|AA|EB|EB|8C|00|F0|F0|F0|F0|F0|F0|F0|F0|
|AA|AA|AA|AA|EB|EB|CC|C8|96|96|96|96|96|96|96|96|
|ºººººººººººººººº
}}
{{HexRow|0x0D0|
|69|61|BF|40|70|3D|22|41|47|E1|3A|40|33|33|DB|40|
|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|
|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|F0|
|96|96|96|96|96|96|96|96|96|96|96|96|96|96|96|96|
|ºººººººººººººººº
}}
{{HexRow|0x0E0|
|F7|C0|2E|3E|00|00|00|00|18|00|00|00|60|F3|0F|00|
|F0|F0|F0|F0|00|00|00|00|00|00|00|00|C8|C8|C8|C8|
|F0|F0|F0|F0|C8|C8|C8|C8|C8|C8|C8|C8|00|00|00|00|
|96|96|96|96|64|64|64|64|FF|FF|FF|FF|40|40|40|40|
|ºººººººººººººººº
}}
{{HexRow|0x0F0|
|E0|F2|0F|00|00|00|00|00|A0|F2|0F|00|00|00|00|00|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|
|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|C8|
|ºººººººººººººººº
}}
{{HexRow|0x100|
|00|F3|0F|00|00|00|00|00|6B|6F|6E|66|6C|61|73|68|
|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|FF|
|FF|FF|FF|FF|FF|FF|FF|FF|CD|CD|CD|CD|CD|CD|CD|CD|
|C8|C8|C8|C8|C8|C8|C8|C8|96|96|96|96|96|96|96|96|
|ººººººººkonflash
}}
{{HexRow|0x110|
|31|00|AD|DE|AD|DE|AD|DE|00|00|00|00|00|00|00|00|
|FF|FF|FF|FF|FF|FF|FF|FF|C8|C8|C8|C8|C8|C8|C8|C8|
|CD|CD|CD|CD|CD|CD|CD|CD|FF|FF|FF|FF|FF|FF|FF|FF|
|96|96|96|96|96|96|96|96|FF|FF|FF|FF|FF|FF|FF|FF|
|1ººººººººººººººº
}}
{{HexRow|0x120|
|00|00|00|00|00|00|00|00|00|00|00|00|00|00|12|00|
|FF|FF|FF|FF|00|00|00|00|FF|FF|FF|FF|C8|C8|C8|C8|
|C8|C8|C8|C8|96|96|96|96|80|80|80|80|C8|C8|C8|C8|
|00|00|00|00|C8|C8|C8|C8|C0|C0|C0|C0|64|64|64|64|
|ºººººººººººººººº
}}
{{HexRow|0x130|
|FF|FF|0A|00|06|00|02|00|01|04|01|1C|AD|DE|AD|DE|
|80|80|80|80|C8|C8|80|80|FF|00|FF|FF|CA|CA|CA|CA|
|40|40|40|40|7C|7C|80|80|AA|D9|22|22|CA|CA|CA|CA|
|40|40|40|40|64|64|80|80|82|00|FF|FF|FF|FF|FF|FF|
|ºººººººººººººººº
}}
|}


;Aiming Type
:Aiming type is used to find the aiming animation in [[TRSC]] and normally it is the same as the animation type. In a couple of cases this type is "none" meaning that no aiming animation should be used. It is pretty much equivalent to setting the "don't aim" flag.


;Particles
{{Table}}
:While Oni can store a number as large as 255 in 0x187, Oni only allocates memory for 16 particles per TRAM, and it does not check to make sure that the actual number of particles is ≤ 16. Thus you can easily crash Oni by initiating a move which has 17 particles attached.
{{OBDth}}
{{OBDtr| 0x000 | res_id  |FF0000| 01 49 07 00 | 1532        | 01865-KONCOMpunch_heavy.TREX }}
{{OBDtr| 0x004 | lev_id  |FFFF00| 01 00 00 00 | 0          | level 0 }}
{{OBDtrBK|Extent info}}
{{OBDtr| 0x008 | float    |B0C3D4| 8D 87 CF 41 | 25.941187  | max horizontal extent of the attack }}
{{OBDtr| 0x00C | float    |B0C3D4| DE E9 1A 40 | 2.420524    | min Y of the attack }}
{{OBDtr| 0x010 | float    |B0C3D4| 95 34 D3 41 | 26.400675  | max Y of the attack }}
{{OBDtr| 0x014 | float    |B0C3D4| 8D 87 CF 41 | 25.941187  | max horizontal extent at 0° (front) }}
{{OBDtr| ...  | ...      |B0C3D4| ...        | ...        | ... }}
{{OBDtr| 0x0A0 | float    |B0C3D4| 8D 87 CF 41 | 25.941187  | max horizontal extent at 350° }}
{{OBDtrBK|First extent info - information about the first extent in the extent part}}
{{OBDtr| 0x0A4 | int16    |E7CEA5| 05 00      | 5          | frame; -1 if the attack part does not exist }}
{{OBDtr| 0x0A6 | int8    |FFDDDD| 00          | 0          | attack index; always 0 }}
{{OBDtr| 0x0A7 | int8    |FFDDDD| 00          | 0          | attack frame offset; always 0 }}
{{OBDtr| 0x0A8 | float    |64AAAA| 00 00 00 BF | -0.500000  | x location of the pelvis }}
{{OBDtr| 0x0AC | float    |64AAAA| 1E 85 6B BF | -0.920000  | z location of the pelvis }}
{{OBDtr| 0x0B0 | float    |64AAAA| 19 47 0C 41 | 8.767358    | y location of the pelvis }}
{{OBDtr| 0x0B4 | float    |64AAAA| EB 51 F0 40 | 7.510000    | extent length }}
{{OBDtr| 0x0B8 | float    |64AAAA| D7 A3 14 41 | 9.290000    | extent min Y }}
{{OBDtr| 0x0BC | float    |64AAAA| 0A D7 3B 41 | 11.740000  | extent max Y }}
{{OBDtr| 0x0C0 | float    |64AAAA| 5E 93 BF 40 | 5.986739    | extent angle (in radians) }}
{{OBDtrBK|Farthest extent info - information about the farthest reaching extent in the extent part }}
{{OBDtr| 0x0C4 | int16    |EBEBEB| 2F 00      | 47          | frame; -1 if there is no attack part of if the animation is for a throw target/victim ("_tgt") }}
{{OBDtr| 0x0C6 | int8    |8C8CCC| 01          | 1          | attack index to which the max extent belongs }}
{{OBDtr| 0x0C7 | int8    |FF00C8| 16          | 22          | attack frame offset from the attack with index 0 }}
{{OBDtr| 0x0C8 | float    |F0F096| 85 EB 51 BF | -1.850000  | x location of the pelvis }}
{{OBDtr| 0x0CC | float    |F0F096| E1 7A 7C C1 | -3.900000  | z location of the pelvis }}
{{OBDtr| 0x0D0 | float    |F0F096| 69 61 BF 40 | 16.874636  | y location of the pelvis }}
{{OBDtr| 0x0D4 | float    |F0F096| 70 3D 22 41 | 10.510000  | extent length }}
{{OBDtr| 0x0D8 | float    |F0F096| 47 E1 3A 40 | 8.860000    | extent min Y }}
{{OBDtr| 0x0DC | float    |F0F096| 33 33 DB 40 | 18.460000  | extent max Y }}
{{OBDtr| 0x0E0 | float    |F0F096| F7 C0 2E 3E | 0.055320    | extent angle }}
{{OBDtrBK|End max extent info }}
{{OBDtr| 0x0E4 | int32    |00C864| 00 00 00 00 | 0          | alternative move direction; used only when the previous move direction field is 0, that means never }}
{{OBDtr| 0x0E8 | int32    |00C8FF| 18 00 00 00 | 24          | number of elements in the extent part }}
{{OBDtr| 0x0EC | offset  |C80040| 60 F3 0F 00 | 0x000FF360  | .raw-address of the [[OBD:TRAM/raw0x13C|extent part]] }}
{{OBDtrBK|End extent info}}
{{OBDtr| 0x0F0 | offset  |FFFFC8| E0 F2 0F 00 | 0x000FF2E0  | .raw-address of the [[OBD:TRAM/raw0x1C|motion blur part]] }}
{{OBDtr| 0x0F4 | offset  |FFFFC8| 00 00 00 00 | unused      | .raw-address of the [[OBD:TRAM/raw0x24|throw data]] }}
{{OBDtr| 0x0F8 | offset  |FFFFC8| A0 F2 0F 00 | 0x000FF2A0  | .raw-address of the [[OBD:TRAM/raw0x14|attack part]] }}
{{OBDtr| 0x0FC | offset  |FFFFC8| 00 00 00 00 | unused      | .raw-address of the [[OBD:TRAM/raw0x18|damage part]] (used only by "_tgt" animations (throw targets/victims) }}
{{OBDtr| 0x100 | offset  |FFFFC8| 00 F3 0F 00 | 0x000F0F00  | .raw-address of the [[OBD:TRAM/raw0x2C|particle data]] (trails, dust, etc.) }}
{{OBDtr| 0x104 | offset  |FFFFC8| 00 00 00 00 | unused      | .raw-address of the [[OBD:TRAM/raw0x38|sound data]] }}
{{OBDtr2|0x108 | char[16] |FFCD96| konflash1                | impact particle name (reference to 01018-.[[OBD:ONIA|ONIA]], which is called up in the [[OBD:ONCC|ONCC]] file) }}
{{OBDtr| 0x118 | link    |C8FFFF| 00 00 00 00 | unused      | direct animation 0 (link to a TRAM file) }}
{{OBDtr| 0x11C | link    |C8FFFF| 00 00 00 00 | unused      | direct animation 1 (link to a TRAM file) }}
{{OBDtr| 0x120 | float    |FFC800| 00 00 00 00 | 0.000000    | final rotation in radians (for anims that make you turn) }}
{{OBDtr| 0x124 | int32    |0096C8| 00 00 00 00 | 0          | number of elements in the sound part }}
{{OBDtr| 0x128 | int32    |FF80C0| 00 00 00 00 | 0          | unknown; runtime pointer to the sound? }}
{{OBDtr| 0x12C | uint16  |C8C864| 00 00      | 0          | hard pause in game ticks (1/60 seconds) }}
{{OBDtr| 0x12E | uint16  |C8C864| 12 00      | 18          | soft pause in game ticks (1/60 seconds) }}
{{OBDtr| 0x130 | uint16  |804040| FF FF      | 65535      | action frame }}
{{OBDtr| 0x132 | uint16  |804040| 0A 00      | 10          | first level where the animation is available }}
{{OBDtr| 0x134 | uint16  |C87C64| 06 00      | 6 <nowiki>=</nowiki> superpunch | vocalization type (-1 if unused) }}
{{OBDtr| 0x136 | uint8    |808080| 02          | 2          | number of elements in the attack part }}
{{OBDtr| 0x137 | uint8    |808080| 00          | 0          | number of elements in the take damage part }}
{{OBDtr| 0x138 | uint8    |FFAA82| 01          | 1          | number of elements in the motion blur part }}
{{OBDtr| 0x139 | uint8    |00D900| 04          | 4          | number of elements in the particle part }}
{{OBDtr| 0x13A | uint8    |FF22FF| 01          | 1          | first "invulnerable" frame }}
{{OBDtr| 0x13B | uint8    |FF22FF| 1C          | 28          | last "invulnerable" frame }}
{{OBDtr| 0x13C | char[4]  |CACAFF| AD DE      | dead        | unused (not part of the template) }}
|}
At the time of writing, some of the above data is merely an informed guess (not thoroughly confirmed), and the nature of 0x128 (int32?) needs to be clarified more particularly. We also need to locate "end/maximal interpolation" and possibly other remaining fields from the PC/Mac data, or establish that they are missing from the TRAM/TREX representation of animations on PS2.





Latest revision as of 22:33, 27 October 2023

ONI BINARY DATA
TRAC << Other file types >> TRAS
TRAM : Totoro Animation Sequence
switch to XML:TRAM page
Overview @ Oni Stuff
OBD.png


Tram all.gif


Offset Type Raw Hex Value Description
0x000 res_id 01 49 07 00 1532 01865-KONCOMpunch_heavy.TRAM
0x004 lev_id 01 00 00 00 0 level 0
0x008 int32 00 00 00 00 0 runtime only; pointer to animation name
0x00C offset A0 B4 80 00 0x0080B4A0 .raw-address of the height track (Y-position of the pelvis above the root)
0x010 offset E0 B5 80 00 0x0080B5E0 .raw-address of the horizontal velocities of the character root
0x014 offset 60 B8 80 00 0x0080B860 .raw-address of the attack part
0x018 offset 00 00 00 00 unused .raw-address of the damage part (used only by "_tgt" animations (throw targets/victims)
0x01C offset A0 B8 80 00 0x0080B8A0 .raw-address of the motion blur part
0x020 offset C0 B8 80 00 0x0080B8C0 .raw-address of the shortcut data
0x024 offset 00 00 00 00 unused .raw-address of the throw data
0x028 offset E0 B8 80 00 0x0080B8E0 .raw-address of the footstep data
0x02C offset 00 B9 80 00 0x0080B900 .raw-address of the particle data (trails, dust, etc.)
0x030 offset 60 B9 80 00 0x0080B960 .raw-address of the position data (for basic prediction)
0x034 offset 00 BD 80 00 0x0080BD00 .raw-address of the rotations (of all body parts)
0x038 offset 00 00 00 00 unused .raw-address of the sound data
0x03C bitset32 90 00 08 00 attack, atomic, dontAim flags; same as listed in StNAanim_flags; the bits are as follows:
0x01 00 00 00 - prepared (used at runtime only; marks that the animation was loaded)
0x02 00 00 00 - invulnerable
0x04 00 00 00 - blockHigh
0x08 00 00 00 - blockLow
0x10 00 00 00 - attack
0x20 00 00 00 - dropWeapon
0x40 00 00 00 - inAir (unused)
0x80 00 00 00 - atomic
0x00 01 00 00 - noTurn
0x00 02 00 00 - attackForward
0x00 04 00 00 - attackLeft
0x00 08 00 00 - attackRight
0x00 10 00 00 - attackBackward
0x00 20 00 00 - overlay
0x00 40 00 00 - dontInterpolateVelocity
0x00 80 00 00 - throwSource
0x00 00 01 00 - throwTarget
0x00 00 02 00 - realWorld
0x00 00 04 00 - doAim
0x00 00 08 00 - dontAim
0x00 00 10 00 - canPickup
0x00 00 20 00 - aim360
0x00 00 40 00 - disableShield
0x00 00 80 00 - noAIPickup
invulnerable

This animation makes the character impervious to melee damage and throws. He can still take damage from particles and falls.

blockHigh, blockLow

An animation with one of these flags can block attacks coming from the front if they have the high/low attack bit on in 0x14.

attack, throwSource, throwTarget, realWorld as proxy flags

These flags were looked at by Importer, Bungie West's authoring tool, which assigned the dontAim flag to an animation if any of them were found. Additionally, Importer used throwSource and throwTarget as indicators that an animation should be flagged as noTurn, but Oni itself also refuses to allow turning when it sees these flags. Within Oni, the attack flag has no effect.

throwSource, throwTarget

Besides serving as proxies, throwSource and throwTarget are used in numerous places in the code to handle throws properly, so they should always be assigned appropriately to throw anims. throwTarget in particular allows your teammates to be hurt by an enemy you throw.

realWorld

This flag only served a purpose when the animation was imported from 3ds Max. Animations without this flag had their extents prepared by Importer. Has no effect within Oni except signifying a lack of attack extents data for visual debugging purposes.

atomic

Has no effect within Oni. When seen by Importer during authoring, however, it set the entire animation to atomic by maxing out the range of the atomic start and end frames (0x174, 0x176).

noTurn

This refers to the user's ability to turn with the controls.

attackForward, attackLeft, attackRight, attackBackward

Have no effect within Oni. Used by Importer to set the movement direction at 0x54.

doAim

Applies aiming screen (PIS/RIF) if character has a weapon.

dontAim

Prevents aiming screen from being applied.

aim360

No effect in Oni. Was used by Importer as a cue to mark the attack's direction (0x54) as 360° (but only Forward, Backward, Left and Right seem to be used in the game data).

disableShield

Used on certain Mutant Muro attacks to temporarily remove his supershield (the anims are listed on XML:TRAM under its DisableShield documentation).

0x040 link 00 00 00 00 unused direct animation 0 (link to another TRAM file)
0x044 link 00 00 00 00 unused direct animation 1 (link to another TRAM file); see § Direct links
0x048 bitset32 00 00 00 00 0 used body parts; for original 19-bone hierarchy the bit layout is as follows:
0x00000001 - pelvis
0x00000002 - left thigh
0x00000004 - left calf
0x00000008 - left foot
0x00000010 - right thigh
0x00000020 - right calf
0x00000040 - right foot
0x00000080 - mid
0x00000100 - chest
0x00000200 - neck
0x00000400 - head
0x00000800 - left shoulder
0x00001000 - left arm
0x00002000 - left wrist
0x00004000 - left fist
0x00008000 - right shoulder
0x00010000 - right arm
0x00020000 - right wrist
0x00040000 - right fist

Aiming screen TRAMs use several bones here. Other overlay TRAMs use only "chest". Non-overlay TRAMs use none.

0x04C bitset32 00 00 00 00 0 replaced parts; same bitset layout as above; only overlay TRAMs other than aiming-screen ones replace parts.
0x050 float 00 00 00 00 0.000000 final rotation in radians (for anims that make you turn)
0x054 int16 01 00 1 main moving direction; the following directions are possible:
0 - none
1 - forward
2 - backward
3 - left
4 - right
5 - 360 (unused? even Devil Spin Kick uses "forward")
0x056 uint16 06 00 6 vocalization type (-1 if unused); references one of the 10 vocalization slots in ONCC
0 - taunt
1 - alert
2 - startle
3 - checkbody
4 - pursue
5 - cower
6 - superpunch
7 - superkick
8 - super3
9 - super4

In this case the value 6 triggers Konoko's "superpunch" vocalization, "Rising fury!"

Extent info
See § Extent info for explanation
0x058 float 8D 87 CF 41 25.941187 max horizontal extent of the attack
0x05C float DE E9 1A 40 2.420524 min Y of the attack
0x060 float 95 34 D3 41 26.400675 max Y of the attack
0x064 float 8D 87 CF 41 25.941187 max horizontal extent at 0° (front)
... ... ... ... ...
0x088 float DF 37 87 40 4.225570 max horizontal extent at 90° (left)
... ... ... ... ...
0x0AC float 5A D8 6D 40 3.716330 max horizontal extent at 180° (back)
... ... ... ... ...
0x0D0 float 98 95 E3 40 7.112011 max horizontal extent at 270° (right)
... ... ... ... ...
0x0F0 float 8D 87 CF 41 25.941187 max horizontal extent at 350°
First extent info - information about the first extent in the extent part
0x0F4 int16 05 00 5 frame; -1 if the attack part does not exist
0x0F6 int8 00 0 attack index; always 0
0x0F7 int8 00 0 attack frame offset; always 0
0x0F8 float 00 00 00 BF -0.500000 x location of the pelvis
0x0FC float 1E 85 6B BF -0.920000 z location of the pelvis
0x100 float 19 47 0C 41 8.767358 y location of the pelvis
0x104 float EB 51 F0 40 7.510000 extent length
0x108 float D7 A3 14 41 9.290000 extent min Y
0x10C float 0A D7 3B 41 11.740000 extent max Y
0x110 float 5E 93 BF 40 5.986739 extent angle (in radians)
Farthest extent info - information about the farthest reaching extent in the extent part
0x114 int16 2F 00 47 frame; -1 if there is no attack part of if the animation is for a throw target/victim ("_tgt")
0x116 int8 01 1 attack index to which the max extent belongs
0x117 int8 16 22 attack frame offset from the attack with index 0
0x118 float 85 EB 51 BF -1.850000 x location of the pelvis
0x11C float E1 7A 7C C1 -3.900000 z location of the pelvis
0x120 float 69 61 BF 40 16.874636 y location of the pelvis
0x124 float 70 3D 22 41 10.510000 extent length
0x128 float 47 E1 3A 40 8.860000 extent min Y
0x12C float 33 33 DB 40 18.460000 extent max Y
0x130 float F7 C0 2E 3E 0.055320 extent angle
End max extent info
0x134 int32 00 00 00 00 0 alternative move direction; used only when the previous move direction field is 0, that means never
0x138 int32 18 00 00 00 24 number of elements in the extent part
0x13C offset E0 BB 80 00 00 80 BB E0 at this position starts the extent part in the raw file
End extent info
0x140 char[16] konflash1 impact particle name (reference to 01018-.ONIA, which is called up in the ONCC file)
0x150 uint16 00 00 0 hard pause in game ticks (1/60 seconds)
0x152 uint16 12 00 18 soft pause in game ticks (1/60 seconds)
0x154 int32 00 00 00 00 0 number of elements in the sound part
0x158 int32 00 00 00 00 0 runtime only; pointer to the sound for this animation (from SABD)
0x15C int16 00 00 0 runtime only; sound start frame (from SABD)
0x15E int16 3C 00 60 animation frame rate (always 60?)
0x160 int16 06 00 6 compression size
0x162 int16 16 00 22 animation type (from StNA)
0x164 int16 16 00 22 aiming type from StNA
0x166 int16 00 00 0 from state; see § From state, to state, animation type, variant, shortcuts
0x168 int16 07 00 7 to state
0x16A int16 13 00 19 number of body parts
0x16C int16 50 00 80 number of frames
0x16E int16 50 00 80 duration in game ticks (1/60 seconds)
0x170 bitset16 00 02 0x0200 = COM variant, the following bits are possible (values in hex):
0x0100 - "sprint" (SPRint animation)
0x0200 - "fight" (COMbat animation)
0x0400 - "shoulder" (not used by the engine; apparently used at one time for weapons like rocket launchers)
0x0800 - "righty pistol" (PIStol animation)
0x1000 - "lefty pistol" (NINja PIStol animation)
0x2000 - "righty rifle" (RIFle animation)
0x4000 - "lefty rifle" (NINja RIFle animation)
0x8000 - "panic" (PANic or SCRamble animation)
0x172 char[2] AD DE dead "varient end"; ignored by the engine
0x174 uint16 00 00 0 atomic start
0x176 uint16 FF FF 65535 atomic end
0x178 uint16 00 00 0 end interpolation
0x17A uint16 FF FF 65535 maximum interpolation
0x17C uint16 FF FF 65535 action frame; e.g. when weapon theft occurs in a disarm anim
0x17E uint16 0A 00 10 first level where the animation is available
0x180 uint8 01 1 first "invulnerable" frame
0x181 uint8 1C 28 last "invulnerable" frame
0x182 uint8 02 2 number of elements in the attack part above
0x183 uint8 00 0 number of elements in the take damage part above
0x184 uint8 01 1 number of elements in the motion blur part above
0x185 uint8 01 1 number of elements in the shortcut part above
0x186 uint8 02 2 number of elements in the footstep part above
0x187 uint8 04 4 number of elements in the particle part above
0x188 char[24] AD DE dead unused (not part of the template)

Animation timeline

NOTE: The following assumes animation data sampled at 60 frames per second (i.e., in sync with game ticks). Different frame rates have not been studied, and OniSplit only works with 60 fps TRAMs.

The duration of an animation in game ticks is equal to the number of frames covered by the main animation data, i.e., it extends one tick past the last keyframe of the height track or rotation tracks. Over this last tick, the pelvis height and bone rotations are interpolated to the values supplied by the first frame of the following animation, whereas the horizontal position is advanced using the last velocity entry of the current animation.

Thus an important note about looping animations is that the poses at the start and end of an animation (a combination of height, bone rotation and the accumulated horizontal velocity) are generally not identical, but rather one tick apart. The same applies to animation pairs (locomotion loops) or any matching animation sequences (e.g., combos).

For the current example (KONCOMpunch_heavy), the duration is 80 ticks, and the main animation tracks are as follows:

  • The height track has 80 entries that are used to place the character vertically at every tick, starting at tick 0 and ending at tick 79. At tick 80, i.e., at the end of the current animation's duration, the height is supplied by the next animation. Between ticks 79 and 80, the height is interpolated between the last height entry of KONCOMpunch_heavy and the first height entry of the next animation.
  • The velocity tracks (horizontal motion of the root) also have 80 entries. However, unlike the height values, the velocities correspond not to ticks but to intervals between ticks, and thus span the whole range of the animation, from tick 0 to tick 80. Starting at tick 80, the first velocity entry of the following animation applies.
  • The rotation tracks are keyed at ticks (like the height track), but (unlike the height track) are typically not keyed at every tick: there are intervals (gaps) of variable size between the keys, over which the rotation of each bone is interpolated. Even so, the total duration of the intervals is the same as the time span of the height track, i.e., one tick shorter than the "duration" of the animation. In this example, the first rotation pose corresponds to tick 0 and the last pose corresponds to tick 79. At tick 80, the pose will be read from the following animation, and between ticks 79 and 80, the pose will be interpolated between the last pose of KONCOMpunch_heavy and the first pose of the next animation.

NOTE: The above description of how heights and rotations are interpolated during the last tick on an animation's duration does not only apply for most of Oni's transitions, which typically involve overlapping timelines and interpolation between two animations playing simultaneously. Nonetheless, the description is useful to understand why the time span of rotation and height data is one tick shorter than the supposed duration of the animation, and also what happens for loops, pairs or combo sequences.

Direct links

These fields work together with soft pause and hard pause fields when switching animations. When the current animation has a direct link to the new animation the soft pause and hard pause are both considered to be 0.

Example

01855-KONCOMcomb_p_p.TRAM links to:

  • 01856-KONCOMcomb_p_p_p.TRAM (direct animation 0)
  • 01857-KONCOMcomb_p_p_k.TRAM (direct animation 1)

That means that if a p_p_p or p_p_k animation follows after a p_p animation there will be no pause between them but for animations other than p_p_p and p_p_k there may be a pause of 'soft pause' frames between them.

Extent info

The extent information is used by the AI to figure out if an attack can reach the enemy. This information is only present/used if the animation contains attacks. Many of the fields in the extent information can be computed from other available information like the attack/position/extent parts. The only "unique" information here is the "max horizontal extent 0° ... 360°" array and the extent part count/offset fields. The alternate move direction does not appear to be ever used.

From state, to state, animation type, variant, shortcuts

These are used to find specific animations. Each character has a current animation state and a current "varient". When the engine searches for an animation with a specific type it considers those that have a matching "from state" and "varient". For example both "comb_k_k" and "jump_fw_kick" animations have the type "kick" but one can be executed when the character is in the "standing" state and the other can be executed when the character is in "falling back" or "falling forward" states.

Aiming Type

Aiming type is used to find the aiming animation in TRSC and normally it is the same as the animation type. In a couple of cases this type is "none" meaning that no aiming animation should be used. It is pretty much equivalent to setting the "don't aim" flag.

Particles

While Oni can store a number as large as 255 in 0x187, Oni only allocates memory for 16 particles per TRAM, and it does not check to make sure that the actual number of particles is ≤ 16. Thus you can easily crash Oni by initiating a move which has 17 particles attached.

Limitations on animation length

Frame counts in Oni's TRAM are either absolute frame counts since the beginning of the animation, or intervals between events or keyframes.

(The following analysis assumes 60 fps as an animation's frame rate. If the frame rate can be reduced, the limiting time amounts will increase accordingly.)

16-bit frame counts

Most typically a frame count is an unsigned 16-bit integer, which allows for a comfortable range of 65535 frames = 1092.25 seconds = 18 m 12.25 s. Even if the integer is accidentally parsed as 16-bit signed, the wraparound to negative values only happens after 32767 frames = 546.13̅ seconds = 9 m 6.13̅ s. Oni has other contexts where frame counts are stored as 16-bit integers, e.g., SNDD and OBAN.

8-bit frame counts

Some of the frame counts inside a TRAM are stored as 8-bit integers (unsigned), which reduces the range to 255 frames = 4.25 seconds (or, in the event of signed interpretation, 127 frames = 2.116̅ seconds).
The contexts where 8-bit frame counts occur are as follows.

  • Motion blur, "Lifetime" and "Interval", meaning that "ghosts" can be spawned no more than 4.25 seconds apart and can last no more than 4.25 seconds before disappearing (LIMITATION SEVERITY: MINOR)
  • Rotation data, intervals between a bone's keyframes, meaning that rotation keyframes for a bone cannot be more than 4.25 seconds apart. (LIMITATION SEVERITY: MINOR)
  • "Max/farthest extent info" (main TRAM file, see above): the "attack frame offset from the attack with index 0" is an 8-bit frame interval, meaning that attacks belonging to a same TRAM cannot be more than 4.25 seconds apart, or the extent of the later attacks may not be taken into account properly by the AI. (LIMITATION SEVERITY: Can be an issue for very long special moves or throws, where damage is dealt both at the beginning and at the end of the animation.)
  • "Invulnerable" range (main TRAM file, see above): The invulnerability range is a pair of 8-bit frame indices, meaning that the invulnerability range cannot extend past 4.25 seconds. (LIMITATION SEVERITY: Can be an issue for very long crowd-clearing moves, like a much longer "Whirling Dervish" (ELICOMpunch_heavy) or long versions of Muro's "Breakdancer" or "Helicopter" moves; a possible workaround is to set invulnerability for the whole animation rather than for an 8-bit frame range)

16-bit raw data offsets

Unlike files like AGDB and SUBT (which use 32-bit pointers into the .raw data stored in the .dat part), a TRAM's rotation data starts off with a set of 16-bit offsets, stored in the .raw part and pointing into the following data (typically there are 19 such offsets, one for each bone in a skeleton).

For the last offset to work, it must be at most equal to 65535 and, since the first 38 bytes are taken up by the offsets, this leaves at most 65497 bytes for the cumulated size of the 18 first rotation tracks.

The raw size of a rotation track depends on the number of keyframe intervals (let's call it N) and on the compression size (either 6 or 16 bytes): a size-6 rotation track takes up 7N+6 bytes, and a size-16 rotation track takes up 17N+16 bytes.

For a size-6 animation, the "average N" for the first 18 tracks cannot exceed 518.96, so that 126N+108 stays below 65497. For a size-16 animation, this "average N" for the first 18 tracks must not exceed 213.1013, so that 306N+288 stays below 65497.

For an animation that has a keyframe for every bone at each game tick, a 518-frame duration corresponds to 8.63̅ seconds, whereas 213 frames = 3.55 seconds. Typically, however, rotation tracks will have significant keyframe reduction, e.g., Konoko's "Rising Fury!" lasts 80 frames but the pelvis rotation has only 23 keyframe intervals. Assuming 4:1 keyframe reduction for typical animations, this means that the 16-bit offset won't be an issue (for size-6 animations) unless the animation is longer than about 30 seconds.

PS2 implementation

The PS2 implementation optimizes TRAM storage by splitting off combat-relevant data (extents etc) to a new instance type, TREX (Totoro Animation Extra, see below). As a result, the TRAM size (with header) is reduced from 392 to 80 bytes.

0x00:  01 C8 03 00 01 00 00 00 01 45 06 00 00 00 00 00  °È°°°°°°°E°°°°°°
0x10:  E0 EE 0F 00 20 F0 0F 00 80 F4 0F 00 A0 F4 0F 00  àî°° ð°° ô°° ô°°
0x20:  C0 F4 0F 00 40 F7 0F 00 90 00 08 00 00 00 00 00  Àô°°@÷°° °°°°°°°
0x30:  00 00 00 00 01 00 00 00 06 00 16 00 16 00 00 00  °°°°°°°°°°°°°°°°
0x40:  07 00 50 00 00 02 AD DE 00 00 FF FF 00 01 02 13  °°P°°°-Þ°°ÿÿ°°°°
0x50:  AD DE AD DE AD DE AD DE AD DE AD DE AD DE AD DE  -Þ-Þ-Þ-Þ-Þ-Þ-Þ-Þ


Offset Type Raw Hex Value Description
0x000 res_id 01 C8 03 00 968 00968-KONCOMpunch_heavy.TRAM
0x004 lev_id 01 00 00 00 0 level 0
0x008 link 01 45 06 00 1605 link to 01605-.TREX (combat-relevant data)
0x00C int32 00 00 00 00 0 runtime only; pointer to animation name
0x010 offset E0 EE 0F 00 0x000FEEE0 .raw-address of the height track (Y-position of the pelvis above the root)
0x014 offset 20 F0 0F 00 0x000FF020 .raw-address of the horizontal velocities of the character root
0x018 offset 80 F4 0F 00 0x000FF480 .raw-address of the shortcut data
0x01C offset A0 F4 0F 00 0x000FF4A0 .raw-address of the footstep data
0x020 offset C0 F4 0F 00 0x000FF4C0 .raw-address of the position data (for basic prediction)
0x024 offset 40 F7 0F 00 0x000FF740 .raw-address of the rotations (of all body parts)
0x028 bitset32 90 00 08 00 attack, atomic, dontAim flags (same as PC/Mac 0x03C)
0x02C bitset32 00 00 00 00 0 used body parts; used mostly by aiming overlays (same as PC/Mac 0x048)
0x030 bitset32 00 00 00 00 0 replaced parts; used by non-aiming overlays (same as PC/Mac 0x04C)
0x034 int16 01 00 1 moving direction
0x036 int16 00 00 1 unknown
0x038 int16 06 00 6 compression size
0x03A int16 16 00 22 animation type (from StNA)
0x03C int16 16 00 22 aiming type
0x03E int16 00 00 0 from state
0x040 int16 07 00 7 to state
0x042 int16 50 00 80 number of frames (animations are locked to 60 fps)
0x044 bitset16 00 02 0x0200 = COM variant (same as PC/Mac 0x170)
0x046 char[2] AD DE dead "varient end"; ignored by the engine
0x048 uint16 00 00 0 atomic start
0x04A uint16 FF FF 65535 atomic end
0x04C uint8 00 0 unknown
0x04D uint8 01 1 number of elements in the shortcut part
0x04E uint8 02 2 number of elements in the footstep part
0x04F uint8 13 19 number of body parts?
0x050 char[16] AD DE dead unused (not part of the template)

At the time of writing, some of the above data is merely an informed guess (not thoroughly confirmed), and the nature of 0x036 (int16?) and 0x04C (uint8?) needs to be clarified more particularly. If 0x036 is always zero, then maybe 0x034 is stored as an int32. We also need to locate "end/maximal interpolation" and possibly other remaining fields from the PC/Mac data, or establish that they are missing from the TRAM/TREX representation of animations on PS2.


The TREX file has all the combat-relevant stuff as well as some stuff that isn't necessary combat-related (e.g., vocalizations, turning angle, moving direction).

The block between 0x008 and 0x0F0 is exactly the extent block between 0x058 and 0x140 in the PC/Mac TRAM. After that come the other 6 .raw links that were stripped from the reduced TRAM, the impact particle name, and the two direct TRAM links, which accounts for all the data up to 0x150 in the PC/Mac TRAM. Some data fields from the end of PC/Mac TRAM are confirmed to be missing on PS2 (e.g., the frame rate is implied to be 60 Hz), but some of the correspondence is still not documented or thoroughly confirmed.

0x000:  01 45 06 00 01 00 00 00 8D 87 CF 41 DE E9 1A 40  ºEºººººº ÏAÞéº@
0x010:  95 34 D3 41 8D 87 CF 41 8D 87 CF 41 8D 87 CF 41   4ÓA ÏA ÏA ÏA
0x020:  8D 87 CF 41 9D E4 11 41 14 BA 04 41 6B 77 D4 40   ÏAºººººººººººº
0x030:  50 5A B3 40 74 4B 9C 40 DF 37 87 40 70 75 84 40  ºººººººººººººººº
0x040:  8E ED 6A 40 16 40 5F 40 16 40 5F 40 BF CD 45 40  ºººººººººººººººº
0x050:  34 2B 49 40 34 2B 49 40 34 2B 49 40 5A D8 6D 40  ºººººººººººººººº
0x0060:  5A D8 6D 40 5A D8 6D 40 8F D9 96 40 8F D9 96 40  ºººººººººººººººº
0x070:  B7 7B AB 40 F0 81 BF 40 98 95 E3 40 98 95 E3 40  ºººººººººººººººº
0x080:  98 95 E3 40 98 95 E3 40 98 95 E3 40 98 95 E3 40  ºººººººººººººººº
0x090:  ED E7 14 41 D4 2E 9E 41 8F FB CC 41 8D 87 CF 41  ºººººººººººººººº
0x0A0:  8D 87 CF 41 05 00 00 00 00 00 00 BF 1E 85 6B BF  ºººººººººººººººº
0x0B0:  19 47 0C 41 EB 51 F0 40 D7 A3 14 41 0A D7 3B 41  ºººººººººººººººº
0x0C0:  5E 93 BF 40 2F 00 01 16 85 EB 51 BF E1 7A 7C C1  ºººººººººººººººº
0x0D0:  69 61 BF 40 70 3D 22 41 47 E1 3A 40 33 33 DB 40  ºººººººººººººººº
0x0E0:  F7 C0 2E 3E 00 00 00 00 18 00 00 00 60 F3 0F 00  ºººººººººººººººº
0x0F0:  E0 F2 0F 00 00 00 00 00 A0 F2 0F 00 00 00 00 00  ºººººººººººººººº
0x100:  00 F3 0F 00 00 00 00 00 6B 6F 6E 66 6C 61 73 68  ººººººººkonflash
0x110:  31 00 AD DE AD DE AD DE 00 00 00 00 00 00 00 00  1ººººººººººººººº
0x120:  00 00 00 00 00 00 00 00 00 00 00 00 00 00 12 00  ºººººººººººººººº
0x130:  FF FF 0A 00 06 00 02 00 01 04 01 1C AD DE AD DE  ºººººººººººººººº


Offset Type Raw Hex Value Description
0x000 res_id 01 49 07 00 1532 01865-KONCOMpunch_heavy.TREX
0x004 lev_id 01 00 00 00 0 level 0
Extent info
0x008 float 8D 87 CF 41 25.941187 max horizontal extent of the attack
0x00C float DE E9 1A 40 2.420524 min Y of the attack
0x010 float 95 34 D3 41 26.400675 max Y of the attack
0x014 float 8D 87 CF 41 25.941187 max horizontal extent at 0° (front)
... ... ... ... ...
0x0A0 float 8D 87 CF 41 25.941187 max horizontal extent at 350°
First extent info - information about the first extent in the extent part
0x0A4 int16 05 00 5 frame; -1 if the attack part does not exist
0x0A6 int8 00 0 attack index; always 0
0x0A7 int8 00 0 attack frame offset; always 0
0x0A8 float 00 00 00 BF -0.500000 x location of the pelvis
0x0AC float 1E 85 6B BF -0.920000 z location of the pelvis
0x0B0 float 19 47 0C 41 8.767358 y location of the pelvis
0x0B4 float EB 51 F0 40 7.510000 extent length
0x0B8 float D7 A3 14 41 9.290000 extent min Y
0x0BC float 0A D7 3B 41 11.740000 extent max Y
0x0C0 float 5E 93 BF 40 5.986739 extent angle (in radians)
Farthest extent info - information about the farthest reaching extent in the extent part
0x0C4 int16 2F 00 47 frame; -1 if there is no attack part of if the animation is for a throw target/victim ("_tgt")
0x0C6 int8 01 1 attack index to which the max extent belongs
0x0C7 int8 16 22 attack frame offset from the attack with index 0
0x0C8 float 85 EB 51 BF -1.850000 x location of the pelvis
0x0CC float E1 7A 7C C1 -3.900000 z location of the pelvis
0x0D0 float 69 61 BF 40 16.874636 y location of the pelvis
0x0D4 float 70 3D 22 41 10.510000 extent length
0x0D8 float 47 E1 3A 40 8.860000 extent min Y
0x0DC float 33 33 DB 40 18.460000 extent max Y
0x0E0 float F7 C0 2E 3E 0.055320 extent angle
End max extent info
0x0E4 int32 00 00 00 00 0 alternative move direction; used only when the previous move direction field is 0, that means never
0x0E8 int32 18 00 00 00 24 number of elements in the extent part
0x0EC offset 60 F3 0F 00 0x000FF360 .raw-address of the extent part
End extent info
0x0F0 offset E0 F2 0F 00 0x000FF2E0 .raw-address of the motion blur part
0x0F4 offset 00 00 00 00 unused .raw-address of the throw data
0x0F8 offset A0 F2 0F 00 0x000FF2A0 .raw-address of the attack part
0x0FC offset 00 00 00 00 unused .raw-address of the damage part (used only by "_tgt" animations (throw targets/victims)
0x100 offset 00 F3 0F 00 0x000F0F00 .raw-address of the particle data (trails, dust, etc.)
0x104 offset 00 00 00 00 unused .raw-address of the sound data
0x108 char[16] konflash1 impact particle name (reference to 01018-.ONIA, which is called up in the ONCC file)
0x118 link 00 00 00 00 unused direct animation 0 (link to a TRAM file)
0x11C link 00 00 00 00 unused direct animation 1 (link to a TRAM file)
0x120 float 00 00 00 00 0.000000 final rotation in radians (for anims that make you turn)
0x124 int32 00 00 00 00 0 number of elements in the sound part
0x128 int32 00 00 00 00 0 unknown; runtime pointer to the sound?
0x12C uint16 00 00 0 hard pause in game ticks (1/60 seconds)
0x12E uint16 12 00 18 soft pause in game ticks (1/60 seconds)
0x130 uint16 FF FF 65535 action frame
0x132 uint16 0A 00 10 first level where the animation is available
0x134 uint16 06 00 6 = superpunch vocalization type (-1 if unused)
0x136 uint8 02 2 number of elements in the attack part
0x137 uint8 00 0 number of elements in the take damage part
0x138 uint8 01 1 number of elements in the motion blur part
0x139 uint8 04 4 number of elements in the particle part
0x13A uint8 01 1 first "invulnerable" frame
0x13B uint8 1C 28 last "invulnerable" frame
0x13C char[4] AD DE dead unused (not part of the template)

At the time of writing, some of the above data is merely an informed guess (not thoroughly confirmed), and the nature of 0x128 (int32?) needs to be clarified more particularly. We also need to locate "end/maximal interpolation" and possibly other remaining fields from the PC/Mac data, or establish that they are missing from the TRAM/TREX representation of animations on PS2.


ONI BINARY DATA
TRAC << Other file types >> TRAS
TRAM : Totoro Animation Sequence
Character file