Ripping Dead Space 1-3 models with animations and textures. - Page 12 (2024)

I've had some breakthroughs! Finally figured out a large amount of the animation structure, I'll document my findings here:

Animation files are split up into two main types of chunks: what I've been referring to as "definitions" and "data blocks".

Definition
Each definition corresponds to a certain animation. It first points to a name string, and then to a branching tree structure. Below is a simple definition:

Code: Select all

0x0070 | 80 00 00 00 90 00 00 00 5F 5F 5F 5F 5F 5F 5F 5F0x0080 | 67 72 69 70 5F 70 6F 73 65 00 5F 5F 5F 5F 5F 5F | "grip_pose"0x0090 | 02 01 00 00 A0 00 00 00 00 00 00 00 B0 00 00 000x00A0 | 00 00 00 00 00 00 00 00 5F 5F 5F 5F 5F 5F 5F 5F0x00B0 | 16 00 01 00 C0 00 00 00 00 00 00 00 D0 00 00 000x00C0 | 00 00 00 00 00 00 00 40 00 00 00 40 5F 5F 5F 5F

Between 0x0090 and 0x00CF is the sample tree; the two nodes in the tree start with 0x0201 and 0x1600. The first byte in each node is the type--a few types I've discovered so far are 0x02 (the root), 0x05 (a parent node), and 0x16 (an animated node). The second byte in each node is the number of children, which will then be defined at the end of the node (notice that line 0x0090 ends with 0xB0, the address of its child). Animated nodes are special in that they also (or perhaps instead?) have an pointer to a data block at the end. So in this case, the animated node points to a data block at 0xD0. In this way, it's possible for a single definition to point to multiple data blocks.

Data blocks
Each data block defines some keyframes for the animation; naturally, this is where the bulk of the animation file comes from. It first starts with three lines of header, and then it goes into keyframes. Below is a simple data block:

Code: Select all

0x00D0 | 7E 62 11 DF 00 00 00 09 00 00 00 00 00 00 00 000x00E0 | FF FF FF FF 3D 72 94 8B 02 00 00 00 00 00 00 000x00F0 | 01 00 00 80 00 00 00 00 00 00 00 00 00 00 00 000x0100 | 2C 00 2C 00 2C 00 2D 00 2C 00 2C 00 2C 00 2C 000x0110 | 2C 00 2C 00 2D 00 2C 00 20 00 8B ED AF 2C 00 5F

I still don't actually understand most of the header, haha. But the most important thing is the integer 0x3D72948B from the second line. This actually corresponds to data from the corresponding RCB file:

Code: Select all

0x0160 | 74 01 00 00 3D 72 94 8B 7C 01 00 00 74 01 00 000x0170 | 00 00 00 00 7C 01 00 00 00 00 00 00 84 01 00 000x0180 | 02 00 00 00 03 00 00 00 00 00 00 00 90 01 00 00

As you can see, the first line contains the same integer, 0x3D72948B! The value immediately after this points to the tuple (0x0184, 0x02), which itself points to 0x03. It's not necessarily clear from this example, but 2 is the number of bones in this model, and 3 is a bitmask for the bones that will have keyframes defined in this data block. Since 3 in binary is just "11", this effectively means that all 2 bones in the model will have definitions in the current data block.

After the header in the data block, it then goes right into animation data. This is the part that starts with some 0x2C values. I had been referring to these as "commands" before, but it turns out that this is actually frame data for each axis! Specifically, it lists out the XYZW quaternion axes, and then the XYZ position axes for each bone in the bitmask mentioned above.

Frame data can be listed out as either singletons or as multiple keyframes.

Singletons
Singletons, i.e. single keyframes, will start with the 3 nibbles that immediately comes after the important integer mentioned above. In the example above, the 3 nibbles immediately after 0x3D72948B are 0x020 (i.e. 0x002). (The endianness makes it a bit hard to read, but you just kind of have to flip the order around in your head) As you can see, the above example exclusively contains singletons: 0x2C00, 0x2D00, 0x2000. It's important to note that this 3-nibble prefix doesn't necessarily need to start with 0s; it can be arbitrary hex.

The value to use in the single keyframe is identified by the last nibble:
- 0xC: 0
- 0xD: 1 (primarily used for the W axis of the quaternion)
- 0x0: The reader will step back a byte and then read a 4-byte float. Since it steps back, this float will actually contain part of the 3-nibble prefix mentioned above!

So here's how you can interpret the above animation data:

Code: Select all

- Bone 1: - Quaternion X: 0 (0x2C00) - Quaternion Y: 0 (0x2C00) - Quaternion Z: 0 (0x2C00) - Quaternion W: 1 (0x2D00) - Position X: 0 (0x2C00) - Position Y: 0 (0x2C00) - Position Z: 0 (0x2C00) - Bone 2: - Quaternion X: 0 (0x2C00) - Quaternion Y: 0 (0x2C00) - Quaternion Z: 0 (0x2C00) - Quaternion W: 1 (0x2D00) - Position X: 0 (0x2C00) - Position Y: -4.320881e-10 (0x20008BEDAF) - Position Z: 0 (0x2C00) 

Multiple keyframes
From what I've seen, lists of multiple keyframes will start with some nibble and then 5, i.e. 0xB500. The first nibble actually corresponds to the number of keyframes that will be defined--in this case, it would be 11 (0xB). It then lists out the keyframes immediately afterward. Below is an example of a data block that contains an axis with multiple keyframes:

Code: Select all

0x01C0 | 59 E1 D9 E0 00 00 00 09 01 00 00 00 00 00 00 000x01D0 | FF FF FF FF 39 B5 AF 45 C2 01 00 00 00 00 00 000x01E0 | 01 00 00 80 00 00 00 00 00 00 00 00 00 00 00 000x01F0 | 2C 1C 2C 1C 2C 1C 2D 1C 2C 1C 2C 1C 2C 1C 2C 1C0x0200 | 2C 1C 2C 1C 2D 1C 2C 1C 2C 1C 2C 1C 2C 1C B5 000x0210 | 23 03 01 D2 34 E5 19 B8 9C 80 BB 89 7E BB 23 030x0220 | C4 A5 34 08 B3 37 B6 9A BB FC 73 BE 23 03 D4 2C0x0230 | 35 09 AC B7 79 0A 39 E4 C3 BE 22 03 D3 F8 37 3C0x0240 | 2A 3B D6 B3 BE 23 03 39 63 B4 6C 92 37 92 AC 3B0x0250 | 50 1D BE 22 03 8F E0 B7 CB BA 3B CB F6 3D 82 020x0260 | 81 36 B8 86 3E 3B 51 AB 3E B0 00 EF C3 3E 23 030x0270 | E7 95 34 F9 90 B8 B2 C5 39 BF C3 3E 93 03 8D CA0x0280 | 34 3F E7 B7 94 8E BB 0F 89 3E 21 00 44 7C BB 440x0290 | 7C 3B 2C 1C 95 00 22 03 E1 56 B7 56 26 38 F7 7F0x02A0 | 3F 23 03 7F 89 34 B0 13 B7 DC 95 BA 9E 78 3F 230x02B0 | 03 68 82 34 12 F3 B6 D2 1D 38 88 6C 3F 22 03 140x02C0 | 7B B5 B9 94 3A 87 6F 3F 22 03 2F 85 B7 9D 64 3A0x02D0 | EC 7C 3F 22 03 77 80 B6 F8 64 BA 51 7E 3F 23 030x02E0 | 7D 18 B4 E1 C9 37 83 9F BA 5E 71 3F 23 03 01 7F0x02F0 | B4 5F 05 38 A4 3F B9 90 6C 3F A2 03 3E 4C B7 B40x0300 | AF 3A 8C 76 3F 20 1C 00 40 3D 20 1C EF DA 3D 200x0310 | 1C 87 FF 3D 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F 5F

In this case, the multiple keyframes begin on line 0x200, with 0xB500. (To be explicitly clear, this is a substitute for a singleton; this clump of multiple keyframes will all be used within a single axis.) I haven't fully worked out the keyframes format, but I've noticed some key patterns. They start with two nibbles: one for the number of frames corresponding to their length, and another for the type of keyframe. Then, it lists off some data, and finally the value of the keyframe. I'm not entirely sure what this extra data means, but I'm assuming it's things like tangents for easing.

In the above example, the keyframes after 0xB500 look like this:

Code: Select all

23 03 01 D2 34 E5 19 B8 9C 80 BB 89 7E BB23 03 C4 A5 34 08 B3 37 B6 9A BB FC 73 BE 23 03 D4 2C 35 09 AC B7 79 0A 39 E4 C3 BE 22 03 D3 F8 37 3C 2A 3B D6 B3 BE 23 03 39 63 B4 6C 92 37 92 AC 3B 50 1D BE 22 03 8F E0 B7 CB BA 3B CB F6 3D 82 02 81 36 B8 86 3E 3B 51 AB 3E B0 00 EF C3 3E 23 03 E7 95 34 F9 90 B8 B2 C5 39 BF C3 3E 93 03 8D CA 34 3F E7 B7 94 8E BB 0F 89 3E 21 00 44 7C BB 44 7C 3B

As mentioned above, the first nibble of each row is the length of the keyframe and the second is the type. The data immediately after is presumably for things like easing--the amount of extra data depends on the type. A type of 0 has no extra data, 1 has 3 bytes, 2 has 6 bytes, and 3 has 9. The last four bytes are the float value for that keyframe.

I'm currently working on a parser for this format and will continue researching this to see what else I find out, but I thought I might as well share my findings for posterity. Hopefully this all made sense and is useful to you folks!

Ripping Dead Space 1-3 models with animations and textures. - Page 12 (2024)

References

Top Articles
Latest Posts
Article information

Author: Sen. Emmett Berge

Last Updated:

Views: 6062

Rating: 5 / 5 (80 voted)

Reviews: 87% of readers found this page helpful

Author information

Name: Sen. Emmett Berge

Birthday: 1993-06-17

Address: 787 Elvis Divide, Port Brice, OH 24507-6802

Phone: +9779049645255

Job: Senior Healthcare Specialist

Hobby: Cycling, Model building, Kitesurfing, Origami, Lapidary, Dance, Basketball

Introduction: My name is Sen. Emmett Berge, I am a funny, vast, charming, courageous, enthusiastic, jolly, famous person who loves writing and wants to share my knowledge and understanding with you.