3D model format: Difference between revisions
No edit summary |
No edit summary |
||
Line 40: | Line 40: | ||
|} | |} | ||
== | == Offsets table == | ||
You have to add '''0x148''' to each value to get proper pointers | You have to add '''0x148''' to each value to get proper pointers | ||
Line 48: | Line 48: | ||
Some of these are either unused or possibly repurposed | Some of these are either unused or possibly repurposed | ||
All blocks seems to be 32-bit | All blocks seems to be 32-bit aligned. | ||
If the offset/size address is empty it's always set to zero. | |||
{| class="wikitable mw-collapsible mw-collapsed" | {| class="wikitable mw-collapsible mw-collapsed" | ||
!ID | !ID | ||
Line 113: | Line 115: | ||
|'''0x4c''' | |'''0x4c''' | ||
|'''0xe0''' | |'''0xe0''' | ||
|LOD | |[[3D model format#LOD metadata|LOD metadata]], maybe something more | ||
|- | |- | ||
|'''12''' | |'''12''' | ||
Line 121: | Line 123: | ||
|- | |- | ||
|''13'' | |''13'' | ||
| | | | ||
| | | | ||
| | | | ||
|- | |- | ||
Line 128: | Line 130: | ||
|''0x58'' | |''0x58'' | ||
| | | | ||
|'' | |''offset marks end of file'' | ||
|- | |- | ||
|15 | |15 | ||
Line 242: | Line 244: | ||
== Basic elements == | == Basic elements == | ||
Each model contains these elements | |||
=== LOD metadata === | |||
I'm skipping most of this block, as it's unused or used directly by the engine to store some of the calculated addresses | |||
If the number of LODs is set to less than 3, later ones just copy id from previous ones | |||
{| class="wikitable mw-collapsible mw-collapsed" | |||
!Offset | |||
!Type | |||
!Description | |||
|- | |||
|0x0 | |||
|short | |||
|Same as file type at 0x18 | |||
|- | |||
|0x2 | |||
|short | |||
|Unknown, always set to 1 for normal files, 2 for tracks and 4 for cars | |||
|- | |||
|0x1C | |||
|float | |||
|Always 1.0 | |||
|- | |||
|0x20 | |||
|byte | |||
|unknown | |||
|- | |||
|0x21 | |||
|byte | |||
|unknown | |||
|- | |||
|0x22 | |||
|short | |||
|unknown | |||
|- | |||
|0x24 | |||
|int | |||
|number of meshes (surfaces) for each LOD | |||
|- | |||
|0x48 | |||
|int | |||
|ID of first mesh for LOD 0 | |||
|- | |||
|0x4c | |||
|int | |||
|ID of first mesh for LOD 1 | |||
|- | |||
|0x50 | |||
|int | |||
|ID of first mesh for LOD 2 | |||
|- | |||
|0x54 | |||
|int | |||
|ID of first mesh for LOD 3 | |||
|- | |||
|0x58 | |||
|int | |||
|Number of additional LODs, can be 0-3 | |||
|} | |||
=== Vertex === | === Vertex === | ||
Line 415: | Line 476: | ||
== Track data == | == Track data == | ||
=== Block 15 === | === Block 15 === | ||
Line 510: | Line 513: | ||
Long, each element 0x90 bytes long | Long, each element 0x90 bytes long | ||
=== Block 21/22 === | === Block 21 / 22 === | ||
Block 21 holds list of vertices, possibly defining track for AI. | Block 21 holds list of vertices, possibly defining track for AI. | ||
Line 519: | Line 522: | ||
Chall1 only has one curve. | Chall1 only has one curve. | ||
=== Block 22 === | |||
Holds the same number of elements as is the number of curves. | |||
Each element is 0x1C long | |||
WIP, so far hardcoded data from one track | |||
WIP, so far data from one track | |||
{| class="wikitable mw-collapsible mw-collapsed" | {| class="wikitable mw-collapsible mw-collapsed" | ||
!Offset | !Offset | ||
Line 557: | Line 561: | ||
| | | | ||
|} | |} | ||
Block 23 | |||
Block 24 | |||
Block 25 | |||
Block 26 | |||
Block 27 | |||
Block 28 | |||
Block 29 | |||
Block 30 | |||
Block 31 | |||
Block 32 |
Revision as of 22:51, 26 January 2021
Stores 3D models, more investigation needed.
If "signed" was not added assume unsigned value
Current analysis: https://docs.google.com/spreadsheets/d/1Hk_EIYk2E6hVd747JJmC9pqqqh_dVafM3dqOkeRp3No/edit?usp=sharing
Thanks to Martin for initial format reversing.
- Magic -
PMD V1.83
- some files use version
1.82
instead, but they aren't used by the game, the engine in PC version won't recognise anything other than 1.83 - There is one unused mention of
PMD V1.71
in the game binary
- some files use version
Offset | Size | Description |
---|---|---|
0x0 | 0x18? | Magic - PMD V1.83
|
0x18 | 0x4 | Type - 0 = shadow & skybox; 1 = track; 2 = car |
0x1C | 0x4 | Zeroes? |
0x20 | 0x94? | offsetsTable |
0xB4 | 0x94? | offsetsTable sizes |
Offsets table
You have to add 0x148 to each value to get proper pointers
Bold IDs are in all files, rest of them are specific for tracks
Some of these are either unused or possibly repurposed
All blocks seems to be 32-bit aligned.
If the offset/size address is empty it's always set to zero.
ID | offset | size offset | Description |
---|---|---|---|
0 | 0x20 | 0xb4 | Martin think it might be some sort of colider |
1 | 0x24 | 0xb8 | polygons data? |
2 | 0x28 | 0xbc | UV texture data? |
3 | 0x2c | 0xc0 | vertex data? |
4 | 0x30 | 0xc4 | faces data? |
5 | 0x34 | 0xc8 | Textures names |
6 | 0x38 | 0xcc | Offsets to texture names, absolute addresses in file |
7 | 0x3c | 0xd0 | Each element is 16B long, ?, ?, float, float |
8 | 0x40 | 0xd4 | Holds IDs of elements in 7 |
9 | 0x44 | 0xd8 | surface transforms data? |
10 | 0x48 | 0xdc | surfaces data? |
11 | 0x4c | 0xe0 | LOD metadata, maybe something more |
12 | 0xe4 | for non-tracks it's size of 1 divided by 16, unknown for tracks | |
13 | |||
14 | 0x58 | offset marks end of file | |
15 | 0x5c | 0xf0 | |
16 | 0x60 | 0xf4 | |
17 | 0x64 | 0xf8 | |
18 | 0xfc | stores size of 20 divided by 0x90 | |
19 | 0x100 | ||
20 | 0x70 | 0x104 | |
21 | 0x74 | 0x108 | List of points, looks like AI curve |
22 | 0x78 | 0x10c | |
23 | 0x7c | 0x110 | |
24 | 0x80 | 0x114 | |
25 | 0x84 | 0x118 | |
26 | 0x88 | 0x11c | |
27 | 0x8c | 0x120 | |
28 | 0x90 | 0x124 | |
29 | 0x94 | 0x128 | |
30 | 0x98 | 0x12c | |
31 | 0x9c | 0x130 | |
32 | 0xa0 | 0x134 | |
33 | |||
34 | |||
35 | |||
36 |
Basic elements
Each model contains these elements
LOD metadata
I'm skipping most of this block, as it's unused or used directly by the engine to store some of the calculated addresses
If the number of LODs is set to less than 3, later ones just copy id from previous ones
Offset | Type | Description |
---|---|---|
0x0 | short | Same as file type at 0x18 |
0x2 | short | Unknown, always set to 1 for normal files, 2 for tracks and 4 for cars |
0x1C | float | Always 1.0 |
0x20 | byte | unknown |
0x21 | byte | unknown |
0x22 | short | unknown |
0x24 | int | number of meshes (surfaces) for each LOD |
0x48 | int | ID of first mesh for LOD 0 |
0x4c | int | ID of first mesh for LOD 1 |
0x50 | int | ID of first mesh for LOD 2 |
0x54 | int | ID of first mesh for LOD 3 |
0x58 | int | Number of additional LODs, can be 0-3 |
Vertex
Offset | Type | Description |
---|---|---|
0x0 | float | X |
0x4 | float | Y |
0x8 | float | Z |
0xC | float | unknown, might be weight |
Polygon
Offset | Type | Description |
---|---|---|
0x0 | byte | X |
0x1 | byte | Y |
0x2 | byte | Z |
0x3 | byte | unknown, might be weight |
0x4 | short | vertices index? |
0x6 | short | face table start index |
UV mapping
Offset | Type | Description |
---|---|---|
0x0 | float | X |
0x4 | float | Y |
0x8 | short | vertex index |
0x10 | short | unknown, might be texture index |
0x12 | int | normal vector? |
Face
Offset | Type | Description |
---|---|---|
0x0 | short | index ? |
Transform
Offset | Type | Description |
---|---|---|
0x0 | float[4][4] | some kind of matrix |
0x40 | int[4] ? | unknown four ints? |
Surface
Probably not surface, Martin used that name in his script, but it feels more like a singular mesh by the look of binary file itself
Offset | Type | Description |
---|---|---|
0x0 | short[4] | unknown |
0x8 | short | transform index? |
0xA | short[3] | unknown |
0x10 | int[3] | unknown |
0x1C | float | weight? |
0x20 | short | unknown (index?) |
0x22 | short | unknown (index?) |
0x24 | short | polys count |
0x26 | short | UVs count |
0x28 | int | vertices count |
0x2C | int | UVs start index |
0x30 | int | vertices start index |
0x34 | int | polys start index |
0x38 | int[2] | unknown |
Track data
Block 15
Offset | Type | Description |
---|---|---|
0x0 | signed int | If there is any data it's set to 1, last one is always set to -1 |
0x4 | ||
0x8 | ||
0xC | float | unknown |
0x10 | float | unknown |
Block 16
12 floats and 4 ints, seems similar to 3 points (each 4th float is always 1.0)
Block 17
0x28 bytes, seems like there are 4 floats (perhaps intensity/R/G/B values?), rest unused?
Block 20
Long, each element 0x90 bytes long
Block 21 / 22
Block 21 holds list of vertices, possibly defining track for AI.
There are 5 curves in this block, 255 points each.
Curve 0, 2-4 are track curves, curve 1 is for the charging station.
Chall1 only has one curve.
Block 22
Holds the same number of elements as is the number of curves.
Each element is 0x1C long
WIP, so far hardcoded data from one track
Offset | Type | Description |
---|---|---|
0x0 | int | id |
0x4 | int | starting vertex offset |
0x8 | int | length? |
0xC | int | 0x1 |
0x10 | int | 0x2 |
0x14 | int | 0xa |
0x18 | float? |
Block 23
Block 24
Block 25
Block 26
Block 27
Block 28
Block 29
Block 30
Block 31
Block 32