Difference between revisions of "CMDL (Tropical Freeze)"
(→Model Header) |
(→Format) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 9: | Line 9: | ||
All three share the same basic format, with SMDL and WMDL each containing an extra data chunk at the start of the file. | All three share the same basic format, with SMDL and WMDL each containing an extra data chunk at the start of the file. | ||
− | {{research|2|There's | + | {{research|2|There's a lot of unknown data.}} |
__TOC__ | __TOC__ | ||
Line 15: | Line 15: | ||
== Format == | == Format == | ||
− | + | File layout: | |
+ | |||
+ | {| class="wikitable" | ||
+ | ! Type/Name | ||
+ | ! Notes | ||
+ | |- | ||
+ | | [[Form Descriptor (Tropical Freeze)|Form Descriptor]] | ||
+ | | Form ID is <code>CMDL</code>, <code>SMDL</code>, or <code>WMDL</code>. | ||
+ | |- | ||
+ | | [[#Skinned Model Header|Skinned Model Header]] | ||
+ | | '''Only present in SMDL files''' | ||
+ | |- | ||
+ | | [[#World Model Header|World Model Header]] | ||
+ | | '''Only present in WMDL files''' | ||
+ | |- | ||
+ | | [[#Model Header|Model Header]] | ||
+ | | | ||
+ | |- | ||
+ | | [[#Material Data|Material Data]] | ||
+ | | | ||
+ | |- | ||
+ | | [[#Render Meshes|Render Meshes]] | ||
+ | | | ||
+ | |- | ||
+ | | [[#Vertex Buffers|Vertex Buffers]] | ||
+ | | | ||
+ | |- | ||
+ | | [[#Index Buffers|Index Buffers]] | ||
+ | | | ||
+ | |- | ||
+ | | [[#GPU Data|GPU Data]] | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | === Skinned Model Header === | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Offset | ||
+ | ! Type | ||
+ | ! Count | ||
+ | ! Name | ||
+ | ! Notes | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]] | ||
+ | | 1 | ||
+ | | '''SKHD Chunk Descriptor''' | ||
+ | | Data type is <code>SKHD</code> | ||
+ | |- | ||
+ | | 0x18 | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown}} | ||
+ | | | ||
+ | |- | ||
+ | | 0x1C | ||
+ | | colspan=5 {{unknown|End of Skinned Model Header}} | ||
+ | |} | ||
+ | |||
+ | === World Model Header === | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Type | ||
+ | ! Count | ||
+ | ! Name | ||
+ | ! Notes | ||
+ | |- | ||
+ | | [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]] | ||
+ | | 1 | ||
+ | | '''WDHD Chunk Descriptor''' | ||
+ | | Chunk ID is <code>WDHD</code> | ||
+ | |- | ||
+ | | u8 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown}} | ||
+ | | | ||
+ | |- | ||
+ | | [[#Render Octree|Render Octree]] | ||
+ | | 1 | ||
+ | | '''Render Octree''' | ||
+ | | | ||
+ | |- | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown AABox Count}} | ||
+ | | | ||
+ | |- | ||
+ | | {{AABox}} | ||
+ | | ''Unknown AABox Count'' | ||
+ | | {{unknown|Unknown AABox Array}} | ||
+ | | | ||
+ | |- | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown Float Count}} | ||
+ | | | ||
+ | |- | ||
+ | | float | ||
+ | | ''Unknown Float Count'' | ||
+ | | {{unknown|Unknown Float Array}} | ||
+ | | | ||
+ | |} | ||
+ | |||
+ | ==== Render Octree ==== | ||
+ | |||
+ | This seems to be an updated version of the [[AROT (MREA Section)|AROT]] format seen in previous Retro games. | ||
+ | |||
+ | {| class="wikitable" | ||
+ | ! Offset | ||
+ | ! Type | ||
+ | ! Count | ||
+ | ! Name | ||
+ | ! Notes | ||
+ | |- | ||
+ | | 0x0 | ||
+ | | {{FourCC}} | ||
+ | | 1 | ||
+ | | '''Magic''' | ||
+ | | Always <code>AROT</code> (Area Octree) | ||
+ | |- | ||
+ | | 0x4 | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown}} | ||
+ | | Always 1. Version number? | ||
+ | |- | ||
+ | | 0x8 | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown}} | ||
+ | | | ||
+ | |- | ||
+ | | 0xC | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown}} | ||
+ | | | ||
+ | |- | ||
+ | | 0x10 | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown}} | ||
+ | | | ||
+ | |- | ||
+ | | 0x14 | ||
+ | | {{AABox}} | ||
+ | | 1 | ||
+ | | '''Octree Bounding Box''' | ||
+ | | Bounds of the entire octree; matches the bounding box from the main model header. | ||
+ | |- | ||
+ | | 0x2C | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown Count A}} | ||
+ | | | ||
+ | |- | ||
+ | | 0x30 | ||
+ | | u32 | ||
+ | | ''Unknown Count A'' | ||
+ | | {{unknown|Unknown Array A}} | ||
+ | | | ||
+ | |- | ||
+ | | {{none}} | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown Count B}} | ||
+ | | | ||
+ | |- | ||
+ | | {{none}} | ||
+ | | u8 | ||
+ | | ''Unknown Count B'' | ||
+ | | {{unknown|Unknown Array B}} | ||
+ | | | ||
+ | |- | ||
+ | | {{none}} | ||
+ | | u32 | ||
+ | | 1 | ||
+ | | {{unknown|Unknown AABox Count}} | ||
+ | | | ||
+ | |- | ||
+ | | {{none}} | ||
+ | | {{AABox}} | ||
+ | | ''Unknown AABox Count'' | ||
+ | | {{unknown|Unknown AABox Array}} | ||
+ | | | ||
+ | |} | ||
=== Model Header === | === Model Header === | ||
Line 215: | Line 400: | ||
| ''Unknown Count C'' | | ''Unknown Count C'' | ||
| {{unknown|Unknown Array C}} | | {{unknown|Unknown Array C}} | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
| | | | ||
|} | |} | ||
Line 621: | Line 658: | ||
|} | |} | ||
− | === Meshes === | + | === Render Meshes === |
− | The MESH section | + | The MESH section defines render meshes. |
{| class="wikitable" | {| class="wikitable" | ||
− | ! | + | ! Type |
− | ! | + | ! Count |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
− | | | + | | [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]] |
− | + | | 1 | |
− | + | | '''MESH Chunk Descriptor''' | |
+ | | Chunk ID is <code>MESH</code> | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | | + | | '''Render Mesh Count''' |
+ | | | ||
|- | |- | ||
− | | | + | | [[#Render Mesh|Render Mesh]] |
− | | | + | | ''Render Mesh Count'' |
+ | | '''Render Mesh Array''' | ||
+ | | | ||
|} | |} | ||
− | + | ==== Render Mesh ==== | |
− | {|class="wikitable" | + | {| class="wikitable" |
! Offset | ! Offset | ||
− | ! | + | ! Type |
− | ! | + | ! Count |
+ | ! Name | ||
+ | ! Notes | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
− | | | + | | u32 |
− | | {{unknown| | + | | 1 |
+ | | {{unknown}} | ||
+ | | Always 3? | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
− | | | + | | u16 |
− | | '''Material | + | | 1 |
+ | | '''Material Index''' | ||
+ | | | ||
|- | |- | ||
| 0x6 | | 0x6 | ||
+ | | u8 | ||
| 1 | | 1 | ||
− | | '''Vertex | + | | '''Vertex Buffer Index''' |
+ | | | ||
|- | |- | ||
| 0x7 | | 0x7 | ||
+ | | u8 | ||
| 1 | | 1 | ||
− | | '''Index | + | | '''Index Buffer Index''' |
+ | | | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
− | | | + | | u32 |
− | | '''Start | + | | 1 |
+ | | '''Start Index''' | ||
+ | | This is basically an offset into the selected index buffer. | ||
|- | |- | ||
| 0xC | | 0xC | ||
− | | | + | | u32 |
− | | '''Index | + | | 1 |
+ | | '''Index Count''' | ||
+ | | Number of indices for this mesh in the index buffer. | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
− | | | + | | u32 |
− | | {{unknown | + | | 1 |
+ | | {{unknown}} | ||
+ | | | ||
|- | |- | ||
| 0x14 | | 0x14 | ||
+ | | bool | ||
| 1 | | 1 | ||
− | | {{unknown | + | | {{unknown}} |
+ | | | ||
|- | |- | ||
| 0x15 | | 0x15 | ||
− | | colspan= | + | | colspan=4 {{unknown|End of Render Mesh}} |
|} | |} | ||
Line 688: | Line 748: | ||
The VBUF section defines vertex buffers; each buffer can have different vertex types, with different strides and attributes. | The VBUF section defines vertex buffers; each buffer can have different vertex types, with different strides and attributes. | ||
− | |||
− | |||
{| class="wikitable" | {| class="wikitable" | ||
− | ! | + | ! Type |
− | ! | + | ! Count |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
− | | | + | | [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]] |
− | + | | 1 | |
− | + | | '''VBUF Chunk Descriptor''' | |
+ | | Chunk ID is <code>VBUF</code> | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | Vertex | + | | '''Vertex Buffer Count''' |
+ | | | ||
|- | |- | ||
− | | | + | | [[#Vertex Buffer|Vertex Buffer]] |
− | | | + | | ''Vertex Buffer Count'' |
+ | | '''Vertex Buffer Array''' | ||
+ | | The model will contain a separate vertex buffer for every unique vertex configuration needed. | ||
|} | |} | ||
==== Vertex Buffer ==== | ==== Vertex Buffer ==== | ||
− | {|class="wikitable" | + | {| class="wikitable" |
− | ! | + | ! Type |
− | ! | + | ! Count |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | '''Vertex | + | | '''Vertex Count''' |
+ | | Number of vertices in the buffer. | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | ''' | + | | '''Vertex Component Count''' |
+ | | Number of components in each vertex. | ||
|- | |- | ||
− | | | + | | [[#Vertex Component|Vertex Component]] |
− | | | + | | ''Vertex Component Count'' |
− | | '''Vertex | + | | '''Vertex Component Array''' |
− | | | + | | Definitions for each component in the vertex. |
− | + | ||
|} | |} | ||
− | ==== Vertex | + | ==== Vertex Component ==== |
− | {|class="wikitable" | + | {| class="wikitable" |
! Offset | ! Offset | ||
− | ! | + | ! Type |
− | ! | + | ! Count |
+ | ! Name | ||
+ | ! Notes | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
− | | | + | | u32 |
− | | {{unknown | + | | 1 |
+ | | {{unknown}} | ||
+ | | | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
− | | | + | | u32 |
+ | | 1 | ||
| '''Offset''' | | '''Offset''' | ||
+ | | Offset of this component within the vertex. | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
− | | | + | | u32 |
+ | | 1 | ||
| '''Stride''' | | '''Stride''' | ||
+ | | Distance in bytes between elements of this component within the vertex buffer. (This is equivalent to the full size of a single vertex.) | ||
|- | |- | ||
| 0xC | | 0xC | ||
− | | | + | | u32 |
− | | {{unknown | + | | 1 |
+ | | {{unknown}} | ||
+ | | | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
− | | | + | | u32 |
− | |{{unknown| | + | | 1 |
+ | | {{unknown}} | ||
+ | | Likely component type/format | ||
|- | |- | ||
| 0x14 | | 0x14 | ||
− | | colspan= | + | | colspan=4 {{unknown|End of Vertex Component}} |
|} | |} | ||
=== Index Buffers === | === Index Buffers === | ||
− | Just like how the VBUF section defines vertex buffers, the IBUF section defines index buffers. Each index buffer only has one value associated with it, so it's fairly simple, and you generally will only see one or two index buffers per file. | + | Just like how the VBUF section defines vertex buffers, the IBUF section defines index buffers. Each index buffer only has one value associated with it, so it's fairly simple, and you generally will only see one or two index buffers per file (as there's only two possible index buffer configurations). |
− | + | ||
− | + | ||
{| class="wikitable" | {| class="wikitable" | ||
− | ! | + | ! Type |
− | ! | + | ! Count |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
− | | | + | | [[Chunk Descriptor (Tropical Freeze)|Chunk Descriptor]] |
− | + | | 1 | |
− | + | | '''IBUF Chunk Descriptor''' | |
+ | | Chunk Descriptor is <code>IBUF</code> | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | Index | + | | '''Index Buffer Count''' |
+ | | | ||
|- | |- | ||
− | | | + | | [[#Index Buffer|Index Buffer]] |
− | | | + | | ''Index Buffer Count'' |
+ | | '''Index Buffer Array''' | ||
+ | | | ||
|} | |} | ||
Line 788: | Line 868: | ||
{| class="wikitable" | {| class="wikitable" | ||
! Offset | ! Offset | ||
− | ! | + | ! Type |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
− | | | + | | u32 |
− | | '''Format''' | + | | '''Format''' |
+ | | 1 means unsigned short; 2 means unsigned long. | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
− | | colspan= | + | | colspan=3 {{unknown|End of Index Buffer}} |
|} | |} | ||
Line 807: | Line 889: | ||
== PAK Metadata == | == PAK Metadata == | ||
− | The | + | The PAK metadata for the model formats contains mainly information related to the size and layout of the GPU section, and the metadata required to locate and decompress specific buffers within it. |
{| class="wikitable" | {| class="wikitable" | ||
− | ! | + | ! Type |
− | ! | + | ! Count |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | {{unknown| | + | | {{unknown}} |
+ | | Always 4? | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | '''GPU | + | | '''GPU Section Offset''' |
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | ''' | + | | '''Read Buffer Count''' |
+ | | Number of read buffers making up the GPU section. | ||
|- | |- | ||
− | | | + | | [[#Read Buffer Info|Read Buffer Info]] |
− | | | + | | ''Read Buffer Count'' |
− | | ''' | + | | '''Read Buffer Array''' |
+ | | Definitions for each read buffer. | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | ''' | + | | '''Vertex Buffer Count''' |
+ | | Number of vertex buffers in the model. | ||
|- | |- | ||
− | | | + | | [[#Buffer Info|Buffer Info]] |
− | | | + | | ''Vertex Buffer Count'' |
− | | '''Vertex | + | | '''Vertex Buffer Info Array''' |
+ | | Array containing all data needed to decompress each vertex buffer. | ||
|- | |- | ||
− | | | + | | u32 |
− | | | + | | 1 |
− | | ''' | + | | '''Index Buffer Count''' |
− | | | + | | Number of index buffers in the model. |
− | + | ||
− | + | ||
− | + | ||
|- | |- | ||
− | | | + | | [[#Buffer Info|Buffer Info]] |
+ | | ''Index Buffer Count'' | ||
+ | | '''Index Buffer Info Array''' | ||
+ | | Array containing all data needed to decompress each index buffer. | ||
|} | |} | ||
− | === | + | === Read Buffer Info === |
− | For large models, the GPU section | + | For large models, the GPU section may be split into multiple read buffers. All offsets into the GPU section will be relative to the beginning of the chosen buffer. |
{| class="wikitable" | {| class="wikitable" | ||
! Offset | ! Offset | ||
− | ! | + | ! Type |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
− | | | + | | u32 |
| '''Size''' | | '''Size''' | ||
+ | | Size of the buffer. | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
− | | | + | | u32 |
| '''Offset''' | | '''Offset''' | ||
+ | | Offset of the buffer within the GPU section. | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
− | | colspan= | + | | colspan=3 {{unknown|End of Read Buffer Info}} |
|} | |} | ||
− | === | + | === Buffer Info === |
− | + | This structure is used for both vertex and index buffers. | |
{| class="wikitable" | {| class="wikitable" | ||
! Offset | ! Offset | ||
− | ! | + | ! Type |
− | ! | + | ! Name |
+ | ! Notes | ||
|- | |- | ||
| 0x0 | | 0x0 | ||
− | | | + | | u32 |
− | | ''' | + | | '''Read Buffer Index''' |
+ | | The read buffer that this buffer is inside of. | ||
|- | |- | ||
| 0x4 | | 0x4 | ||
− | | | + | | u32 |
− | | '''Start | + | | '''Start Offset''' |
+ | | Starting offset of this buffer, relative to the start of the chosen read buffer. | ||
|- | |- | ||
| 0x8 | | 0x8 | ||
− | | | + | | u32 |
− | | '''Compressed | + | | '''Compressed Size''' |
+ | | Size of the compressed data. | ||
|- | |- | ||
| 0xC | | 0xC | ||
− | | | + | | u32 |
− | | '''Decompressed | + | | '''Decompressed Size''' |
+ | | Size of the data after being decompressed. | ||
|- | |- | ||
| 0x10 | | 0x10 | ||
− | | colspan= | + | | colspan=3 {{unknown|End of Buffer Info}} |
|} | |} | ||
[[Category:File Formats]] | [[Category:File Formats]] | ||
[[Category:Donkey Kong Country: Tropical Freeze]] | [[Category:Donkey Kong Country: Tropical Freeze]] |
Latest revision as of 13:40, 14 November 2016
See CMDL (File Format) for the other revisions of this format.
Tropical Freeze features a new model format (necessitated by the hardware jump from Wii to Wii U) that bears little-to-no resemblance to the CMDL format of past games. There are three extensions used for models:
- CMDL: Generic models
- SMDL: Skinned models (ie. animated characters)
- WMDL: World models (ie. level geometry)
All three share the same basic format, with SMDL and WMDL each containing an extra data chunk at the start of the file.
This file format needs more research There's a lot of unknown data. |
Contents
Format
File layout:
Type/Name | Notes |
---|---|
Form Descriptor | Form ID is CMDL , SMDL , or WMDL .
|
Skinned Model Header | Only present in SMDL files |
World Model Header | Only present in WMDL files |
Model Header | |
Material Data | |
Render Meshes | |
Vertex Buffers | |
Index Buffers | |
GPU Data |
Skinned Model Header
Offset | Type | Count | Name | Notes | |
---|---|---|---|---|---|
0x0 | Chunk Descriptor | 1 | SKHD Chunk Descriptor | Data type is SKHD
| |
0x18 | u32 | 1 | Unknown | ||
0x1C | End of Skinned Model Header |
World Model Header
Type | Count | Name | Notes |
---|---|---|---|
Chunk Descriptor | 1 | WDHD Chunk Descriptor | Chunk ID is WDHD
|
u8 | 1 | Unknown | |
Render Octree | 1 | Render Octree | |
u32 | 1 | Unknown AABox Count | |
AABox | Unknown AABox Count | Unknown AABox Array | |
u32 | 1 | Unknown Float Count | |
float | Unknown Float Count | Unknown Float Array |
Render Octree
This seems to be an updated version of the AROT format seen in previous Retro games.
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | FourCC | 1 | Magic | Always AROT (Area Octree)
|
0x4 | u32 | 1 | Unknown | Always 1. Version number? |
0x8 | u32 | 1 | Unknown | |
0xC | u32 | 1 | Unknown | |
0x10 | u32 | 1 | Unknown | |
0x14 | AABox | 1 | Octree Bounding Box | Bounds of the entire octree; matches the bounding box from the main model header. |
0x2C | u32 | 1 | Unknown Count A | |
0x30 | u32 | Unknown Count A | Unknown Array A | |
u32 | 1 | Unknown Count B | ||
u8 | Unknown Count B | Unknown Array B | ||
u32 | 1 | Unknown AABox Count | ||
AABox | Unknown AABox Count | Unknown AABox Array |
Model Header
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | Chunk Descriptor | 1 | HEAD Chunk Descriptor | Chunk ID is HEAD
|
0x18 | u32 | 1 | Unknown | |
0x1C | u32 | 1 | Unknown | |
0x20 | u32 | 1 | Unknown | |
0x24 | u32 | 1 | Unknown | |
0x28 | u32 | 1 | Unknown | |
0x2C | AABox | 1 | Model Bounding Box | |
0x44 | u32 | 1 | Model Data Source Count | |
0x48 | Model Data Source | Model Data Source Count | Model Data Source Array |
Model Data Source
Offset | Type | Name | Notes |
---|---|---|---|
0x0 | u32 | Model Data Source Type | Controls the type of data present in this data source. Valid values are 0, 1, 2, or 3. |
0x4 | Model Data Source Data | Structure and size varies depending on Model Data Source Type. See below. |
Type 0: UV Animation
To do: Needs research. The loader function doesn't reveal much because the game just loads all the data into a couple big buffers. |
Type 1: Wind
Type | Count | Name | Notes |
---|---|---|---|
u32 | 1 | Wind Set Count | Count of Wind Set elements in the next array. |
Wind Set | Wind Set Count | Wind Set Array | |
u32 | 1 | Unknown Count | |
u8 | Unknown Count | Unknown Data |
Wind Set
Offset | Type | Name | Notes |
---|---|---|---|
0x0 | Vector3f | Unknown | |
0xC | Vector3f | Unknown | |
0x18 | float | Unknown | |
0x1C | End of Wind Set |
Type 2: Caustic
Type | Count | Name | Notes |
---|---|---|---|
u32 | 1 | Unknown Count | |
u32 | Unknown Count | Unknown Array |
Type 3: Fur
Type | Count | Name | Notes |
---|---|---|---|
u32 | 1 | Unknown Count A | |
float | Unknown Count A | Unknown Array A | |
u32 | 1 | Unknown Count B | |
float | Unknown Count B | Unknown Array B | |
u32 | 1 | Unknown Count C | |
float | Unknown Count C | Unknown Array C |
Material Data
The MTRL section has a 32-bit material count, then lays out its materials one after the other. Materials are composed of basically a MTRL asset ID which contains the shader the material is rendered with, then per-instance material parameters (textures, scalar/color parameters, etc).
Type | Count | Name | Notes |
---|---|---|---|
string | 1 | Material Name | Zero-terminated string |
Asset ID (MTRL) | 1 | Material Shader Asset ID | Points to the MTRL file containing the shader for this material. |
FourCC | 1 | Material Type | Can be PHNG (Phong), LAMB (Lambert), SURF (Surface), FURM (Fur), or REFL (Reflect). REFL may be unused.
|
u32 | 1 | Material Flags | Bitfield used to toggle various settings on the material. None of the flags are known. |
u32 | 1 | Parameter Count | Count of parameters in this material definition. |
Material Parameter | Parameter Count | Parameter Array |
Material Parameter
Each parameter has a fourCC parameter ID as well as a parameter type enum. There are five possible parameter types that each have a different layout in the file.
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | FourCC | 1 | Parameter ID | |
0x4 | u32 | 1 | Parameter Type | Determines what type of data this parameter contains. Can be either 0, 1, 2, 4, or 5. (Note: 3 is an invalid value, not an unused type.) |
0x8 | Parameter Data | Structure and size varies depending on Parameter Type. See below. |
Type 0: Texture Token Data
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | Asset ID (TXTR) | 1 | Texture ID | Texture asset ID. |
0x10 | Texture Usage Info | 1 | Texture Usage Info | Note: Not present if the TXTR asset ID is invalid. |
End of Texture Token Data |
Type 1: Color Data
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | Color4f | 1 | Color Value | |
0x10 | End of Color Data |
Type 2: Scalar Data
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | float | 1 | Scalar Value | |
0x4 | End of Scalar Data |
Type 4: Layered Texture Data
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | u32 | 1 | Unknown | |
0x4 | Color4f | 1 | Unknown Color | |
0x14 | Color4f | 1 | Unknown Color | |
0x24 | Color4f | 1 | Unknown Color | |
0x34 | u8 | 1 | Unknown | |
0x35 | Texture Token Data | 1 | Unknown Texture Token Data | |
Texture Token Data | 1 | Unknown Texture Token Data | ||
Texture Token Data | 1 | Unknown Texture Token Data | ||
End of Layered Texture Data |
Type 5: Int4 Data
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | u32 | 4 | Int4 Value | |
0x10 | End of Int4 Data |
Texture Usage Info
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | u32 | 1 | Unknown | |
0x4 | u32 | 1 | Unknown | |
0x8 | u32 | 1 | Unknown | |
0xC | u32 | 1 | Unknown | |
0x10 | u32 | 1 | Unknown | |
0x14 | End of Texture Usage Info |
Render Meshes
The MESH section defines render meshes.
Type | Count | Name | Notes |
---|---|---|---|
Chunk Descriptor | 1 | MESH Chunk Descriptor | Chunk ID is MESH
|
u32 | 1 | Render Mesh Count | |
Render Mesh | Render Mesh Count | Render Mesh Array |
Render Mesh
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | u32 | 1 | Unknown | Always 3? |
0x4 | u16 | 1 | Material Index | |
0x6 | u8 | 1 | Vertex Buffer Index | |
0x7 | u8 | 1 | Index Buffer Index | |
0x8 | u32 | 1 | Start Index | This is basically an offset into the selected index buffer. |
0xC | u32 | 1 | Index Count | Number of indices for this mesh in the index buffer. |
0x10 | u32 | 1 | Unknown | |
0x14 | bool | 1 | Unknown | |
0x15 | End of Render Mesh |
Vertex Buffers
The VBUF section defines vertex buffers; each buffer can have different vertex types, with different strides and attributes.
Type | Count | Name | Notes |
---|---|---|---|
Chunk Descriptor | 1 | VBUF Chunk Descriptor | Chunk ID is VBUF
|
u32 | 1 | Vertex Buffer Count | |
Vertex Buffer | Vertex Buffer Count | Vertex Buffer Array | The model will contain a separate vertex buffer for every unique vertex configuration needed. |
Vertex Buffer
Type | Count | Name | Notes |
---|---|---|---|
u32 | 1 | Vertex Count | Number of vertices in the buffer. |
u32 | 1 | Vertex Component Count | Number of components in each vertex. |
Vertex Component | Vertex Component Count | Vertex Component Array | Definitions for each component in the vertex. |
Vertex Component
Offset | Type | Count | Name | Notes |
---|---|---|---|---|
0x0 | u32 | 1 | Unknown | |
0x4 | u32 | 1 | Offset | Offset of this component within the vertex. |
0x8 | u32 | 1 | Stride | Distance in bytes between elements of this component within the vertex buffer. (This is equivalent to the full size of a single vertex.) |
0xC | u32 | 1 | Unknown | |
0x10 | u32 | 1 | Unknown | Likely component type/format |
0x14 | End of Vertex Component |
Index Buffers
Just like how the VBUF section defines vertex buffers, the IBUF section defines index buffers. Each index buffer only has one value associated with it, so it's fairly simple, and you generally will only see one or two index buffers per file (as there's only two possible index buffer configurations).
Type | Count | Name | Notes |
---|---|---|---|
Chunk Descriptor | 1 | IBUF Chunk Descriptor | Chunk Descriptor is IBUF
|
u32 | 1 | Index Buffer Count | |
Index Buffer | Index Buffer Count | Index Buffer Array |
Index Buffer
Offset | Type | Name | Notes |
---|---|---|---|
0x0 | u32 | Format | 1 means unsigned short; 2 means unsigned long. |
0x4 | End of Index Buffer |
GPU Data
The GPU section contains raw buffer data that's fed to the GPU. It's essentially just a giant blob with all the vertex and index buffers laid out next to each other. The tricky part is, all the buffer data is LZSS-compressed, and the metadata needed to decompress it is stored in the pak rather than in the files themselves; not only that, but that metadata is also the only way to distinguish the different buffers from each other.
As such, this section can't be read correctly if the model file is unpacked and completely left as-is; it needs to be either read directly from the pak, or the metadata needs to be added to the file in some way. A good unpacker should append the metadata to the end of the file; a pre-decompressed file needs the buffer sizes or offsets inserted into the file data somewhere.
PAK Metadata
The PAK metadata for the model formats contains mainly information related to the size and layout of the GPU section, and the metadata required to locate and decompress specific buffers within it.
Type | Count | Name | Notes |
---|---|---|---|
u32 | 1 | Unknown | Always 4? |
u32 | 1 | GPU Section Offset | |
u32 | 1 | Read Buffer Count | Number of read buffers making up the GPU section. |
Read Buffer Info | Read Buffer Count | Read Buffer Array | Definitions for each read buffer. |
u32 | 1 | Vertex Buffer Count | Number of vertex buffers in the model. |
Buffer Info | Vertex Buffer Count | Vertex Buffer Info Array | Array containing all data needed to decompress each vertex buffer. |
u32 | 1 | Index Buffer Count | Number of index buffers in the model. |
Buffer Info | Index Buffer Count | Index Buffer Info Array | Array containing all data needed to decompress each index buffer. |
Read Buffer Info
For large models, the GPU section may be split into multiple read buffers. All offsets into the GPU section will be relative to the beginning of the chosen buffer.
Offset | Type | Name | Notes |
---|---|---|---|
0x0 | u32 | Size | Size of the buffer. |
0x4 | u32 | Offset | Offset of the buffer within the GPU section. |
0x8 | End of Read Buffer Info |
Buffer Info
This structure is used for both vertex and index buffers.
Offset | Type | Name | Notes |
---|---|---|---|
0x0 | u32 | Read Buffer Index | The read buffer that this buffer is inside of. |
0x4 | u32 | Start Offset | Starting offset of this buffer, relative to the start of the chosen read buffer. |
0x8 | u32 | Compressed Size | Size of the compressed data. |
0xC | u32 | Decompressed Size | Size of the data after being decompressed. |
0x10 | End of Buffer Info |