OBD:CRSA: Difference between revisions

From OniGalore
Jump to navigation Jump to search
Line 2: Line 2:
==CRSA - Corpse Array==
==CRSA - Corpse Array==
Related :
Related :
[[OBD:File types|File types]]
[[OBD:File types/Level|Level files]]
[[OBD:File types/Level|Level files]]
[[OBD:Oni Binary Data|Oni Binary Data]]
[[OBD:Oni Binary Data|Oni Binary Data]]

Revision as of 17:44, 17 February 2006

ssg's version is here

CRSA - Corpse Array

Related : File types Level files Oni Binary Data

The array consists of

  • a 32-byte header
  • a number of fixed-size corpse chunks (1100 bytes each)
  • a number of unused corpse chunks integrally set to 0 (1100 bytes each)

(used chunks and unused chunks add up to the capacity of the array : 20 chunks in the original binaries)

  • 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) : actual arrays take up 0x5610 bytes, and 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 : 2*4 bytes
  • Array capacity (maximum number of corpses, always 20) : another 4 bytes

The total size of a header is thus 0x20 = 32 bytes.

Example
00565-.CRSA in level3_Final.dat
Header of the corpse array
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 (3*3 + 3)*4 = 48 bytes, so that's 19*48 = 912 bytes.
  • Finally, an axis-aligned bounding box (2*3*4 = 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 (3*4 bytes), first x, then y, then z (so 3*3*4 = 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 : add 0x20 for the offset from the start of file.
Notes and ONCC link
Offset Raw hex 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


Bone orientation and position
Offset Bone Raw hex Value/Meaning
0xA4
0xB0
0xBC
0xC8
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
0xE0
0xEC
0xF8
Lt Thigh ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x104
0x110
0x11C
0x128
Lt Calf ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x134
0x140
0x14C
0x158
Lt Foot ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x164
0x170
0x17C
0x188
Rt Thigh ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x194
0x1A0
0x1AC
0x1B8
Rt Calf ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x1C4
0x1D0
0x1DC
0x1E8
Rt Foot ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x1F4
0x200
0x20C
0x218
Mid ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x224
0x230
0x23C
0x248
Chest ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x254
0x260
0x26C
0x278
Neck ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x284
0x290
0x29C
0x2A8
Head ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x2B4
0x2C0
0x2CC
0x2D8
Lt Shoulder ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x2E4
0x2F0
0x2FC
0x308
Lt Arm ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x314
0x320
0x32C
0x338
Lt Wrist ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x344
0x350
0x35C
0x368
Lt Fist ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x374
0x380
0x38C
0x398
Rt Shoulder ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x3A4
0x3B0
0x3BC
0x3C8
Rt Arm ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x3D4
0x3E0
0x3EC
0x3F8
Rt Wrist ... x = (, , )
y = (, , )
z = (, , )
R = (, , )
0x404
0x410
0x41C
0x428
Rt Fist ... x = (, , )
y = (, , )
z = (, , )
R = (, , )


Axis-aligned bounding box
Offset Raw hex 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



Screenshot

The example is the same as above : 00565-.CRSA in level3_Final.dat

The first corpse chunk has been outlined in black.

crsa_a.gif