OBD:CRSA
Jump to navigation
Jump to search
Main Page >> Oni Binary Data >> File Types >> CRSA File
Corpse Array - Level File
Array header
CRSA - Corpse Array
Related : Level files Oni Binary Data
The array consists of a 32-byte header, followed by a number of fixed-size corpse chunks (1100 bytes each).
The resulting file is completed to a 32-byte multiple with the 0xADDE blank filler
Since the capacity of the array is always the same (20 corpses), CRSA files are all the same size (0x5620 bytes). The array actually takes up 0x5610 bytes : the last 16 bytes are filled with the blank filler 0xADDE.
Header
- What's in the header?
- File ID and level ID as usual : 4 bytes each
- A blank field filled with 0xADDE (dead) : 12 bytes
- Array size (number of corpses) duplicated : 2x4 bytes
- Array capacity (maximum number of corpses, always 20) : another 4 bytes
- Example
- 00565-.CRSA in level3_Final.dat
Offset | Raw hex/string | Value | Meaning |
---|---|---|---|
0x00 | 01 35 02 00 | 565 | File ID for 00565-.CRSA |
0x04 | 01 00 00 06 | 3 | Level ID |
0x08 0x0C 0x010 |
AD DE AD DE AD DE AD DE AD DE AD DE |
DEAD | blank filler |
0x14 | 11 00 00 00 | 17 | 17 corpses (array size) |
0x18 | 11 00 00 00 | 17 | 17 corpses (array size again) |
0x1C | 14 00 00 00 | 20 | Room for 20 corpses (array capacity) |
Corpse chunks
They follow the header directly
- What's in a corpse?
- A space for notes (160 bytes) : often the name of the file the corpse was taken from when packing the array.
- A link to the ONCC (model that should be used for the corpse) : that's 4 bytes as usual.
- Then, 19 bones, each of them defined by absolute orientation and position (unlike in a TRAM, where orientations are relative)
Every bone is (3x3 + 3)x4 = 48 bytes, so that's 19x48 = 912 bytes. - Finally, an axis-aligned bounding box (2x3x4 = 24 bytes)
The total size of a corpse is thus 1100 bytes.
- What's in a bone?
- The absolute orientation is defined in a "heavy" way via an orthonormal trihedron :
- three 3D vectors x, y and z, each of length 1, at right angles with each other, and ordered "directly"
- (like Oni's world axes : if x points left and y points up then z points to front, not back).
- Each one of those vectors is stored as 3 floats (3x4 bytes), first x, then y, then z (so 3x3x4 = 36 bytes in total).
- The absolute position R of a bone (of its parent node, actually) is stored as 3 floats right after the orientation trihedron.
- That's another 12 bytes, so 48 bytes in total.
Reminder : the 2nd coordinate of R aka y is the height; same for x, y and z.
- Example
- first corpse of 00565-.CRSA in level3_Final.dat.
- Offsets are measured from the start of the corpse chunk.
Offset | Raw hex/string | Value | Meaning |
---|---|---|---|
0x00 | _lvl_3_Intro_TCL_A_corpse.dat | probably the name of the source file | |
0xA0 | 01 36 02 00 | 566 | Link to 00566-TCTF_lite_1.ONCC |
Offset | Bone | Raw hex | Value/Meaning |
---|---|---|---|
0xA4 | Pelvis | C1 74 66 3F 00 78 3E 3D 45 AB DD 3E A6 8B 7D 3D 19 73 7F BF EE 67 B0 BC 03 AE DC 3E 82 2C 3D 3D 8D B2 66 BF C5 FA E7 41 2E 2B CB C1 58 B4 45 C1 |
x = (0.900219, 0.046501, 0.432947) y = (0.061901, -0.997850, -0.021534) z = (0.431015, 0.0461850, -0.901162) R = (28.997446, -25.396084, -12.356529) |
0xD4 | Lt Thigh | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x104 | Lt Calf | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x134 | Lt Foot | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x164 | Rt Thigh | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x194 | Rt Calf | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x1C4 | Rt Foot | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x1F4 | Mid | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x224 | Chest | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x254 | Neck | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x284 | Head | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x2B4 | Lt Shoulder | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x2E4 | Lt Arm | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x314 | Lt Wrist | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x344 | Lt Fist | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x374 | Rt Shoulder | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x3A4 | Rt Arm | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x3D4 | Rt Wrist | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
0x404 | Rt Fist | ... | x = (, , ) y = (, , ) z = (, , ) R = (, , ) |
Offset | Raw hex/string | Value | Meaning |
---|---|---|---|
0x434 | D4 22 8C 41 95 50 E9 C1 BC 31 9C C1 | (17.517006, -29.164347, -19.524284) | "minimal" corner of the AABB |
0x440 | 75 E6 14 42 2E 20 B1 C1 07 B1 D3 C0 | (37.225056, -22.140713, -6.615360) | "maximal" corner of the AABB |