GlitcherOG (talk | contribs) (Created page with "<nowiki>#</nowiki> MPF File (PS2 Models) - Contents: - [Overview](#overview) - [Structure](#structure) <nowiki><br></nowiki> <nowiki>***</nowiki> <nowiki><br></nowiki> <nowiki>#</nowiki> Overview An **MPF** file contains model names, bones, UV maps, normals, vertices and other model data. <nowiki><br></nowiki> Used for boards, characters and accessories. <nowiki><br></nowiki> Here is the structure made in programming languages for easy code impleme...") |
GlitcherOG (talk | contribs) No edit summary |
||
(8 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
== Overview == |
|||
<nowiki>#</nowiki> MPF File (PS2 Models) |
|||
An MPF file contains model names, bones, UV maps, normals, vertices and other model data. |
|||
- Contents: |
|||
- [Overview](#overview) |
|||
- [Structure](#structure) |
|||
<nowiki><br></nowiki> |
|||
<nowiki>***</nowiki> |
|||
<nowiki><br></nowiki> |
|||
<nowiki>#</nowiki> Overview |
|||
An **MPF** file contains model names, bones, UV maps, normals, vertices and other model data. <nowiki><br></nowiki> |
|||
Used for boards, characters and accessories. |
|||
<nowiki><br></nowiki> |
|||
Here is the structure made in programming languages for easy code implementation: |
Here is the structure made in programming languages for easy code implementation: |
||
- [https://github.com/GlitcherOG/SSX-Collection-Multitool/blob/main/FileHandlers/Models/Tricky/TrickyPS2MPF.cs SSX Tricky MPF C# handler by GlitcherOG] |
|||
<nowiki><br></nowiki> |
|||
- [SSX Tricky mpf GO struct by Erick](<nowiki>https://github.com/Erickson400/TheTrickyModels/blob/main/mpf/MpfStructure.go</nowiki>) |
- [SSX Tricky mpf GO struct by Erick](<nowiki>https://github.com/Erickson400/TheTrickyModels/blob/main/mpf/MpfStructure.go</nowiki>) |
||
== Structure == |
|||
- [SSX Tricky mpf C# handler by GlitcherOG](<nowiki>https://github.com/GlitcherOG/SSX-PS2-Collection-Modder/blob/main/FileHandlers/Models/TrickyMPFModelHandler.cs</nowiki>)<nowiki><br></nowiki> |
|||
<nowiki>#</nowiki> Structure |
|||
<nowiki><br></nowiki> |
|||
<nowiki>**</nowiki>File contents:** |
|||
- [File Header](#file-header) |
|||
- Model Header List |
|||
- [Model Header](#model-header) |
|||
- Model Data List |
|||
- [Model Data](#model-data) |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> File Header |
|||
=== File Header === |
|||
Section 0 - Bytes[12] |
Section 0 - Bytes[12] |
||
{| class="wikitable" |
|||
|+ |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Byte[4] |
|||
|Version ID (Version 8) |
|||
|- |
|||
|UInt16 |
|||
|Model Header Count |
|||
|- |
|||
|UInt16 |
|||
|Offset To Model Headers |
|||
|- |
|||
|UInt32 |
|||
|Offset To Model Data List Start |
|||
|} |
|||
=== Model Header === |
|||
| Offset | Type | Description | Key | |
|||
All Offsets Within the file are relative to the start of the Model Data |
|||
{| class="wikitable" |
|||
|--------|--------|--------------------------------------|---------------------| |
|||
!Type |
|||
!Description |
|||
| 0x00 | UInt32 | Unknown (Possibly version or magic) | | |
|||
|- |
|||
|Bytes[16] |
|||
| 0x04 | Int16 | Count of **Models** | `mdlCount` | |
|||
|Name of Model (ASCII string with a max length of 16 bytes) |
|||
|- |
|||
| 0x06 | Int16 | Offset of **Model Header List** | | |
|||
|UInt32 |
|||
| |
|Offset to Model Data which is relative to Model Data List Start Offset |
||
|- |
|||
|UInt32 |
|||
| | List | List containing Model Headers | | |
|||
|Size of model in bytes |
|||
|- |
|||
| | List | List containing Model Data | | |
|||
|UInt32 |
|||
|Offset of **Bone Data List** |
|||
<nowiki><br></nowiki> |
|||
|- |
|||
|UInt32 |
|||
<nowiki>##</nowiki> Model Header |
|||
|Offset of **IK Point List** |
|||
|- |
|||
Section 1 - Bytes[80] |
|||
|UInt32 |
|||
|Offset of **Mesh Group Offset** |
|||
| Offset | Type | Description | Key | Rel | |
|||
|- |
|||
|UInt32 |
|||
|-------- |----------- |------------------------------------------------------------ |------------------ |--------------------- | |
|||
|Offset of **Mesh Data** |
|||
|- |
|||
| 0x00 | Bytes[16] | Name of Model (ASCII string with a max length of 16 bytes) | `mdlName` | | |
|||
|UInt32 |
|||
|Offset Of **Material Data** |
|||
| 0x10 | UInt32 | Offset of **Model Data** | `mdlDataOffset` | `mdlDataListOffset` | |
|||
|- |
|||
|UInt32 |
|||
| 0x14 | UInt32 | Size of model in bytes or end offset | | `mdlDataOffset` | |
|||
|Offset of Weight List Reference |
|||
|- |
|||
| 0x18 | UInt32 | Offset of **Bone Data List** | `boneListOffset` | `mdlDataOffset` | |
|||
|UInt32 |
|||
|Offset of Bone Weights |
|||
| 0x1C | UInt32 | Offset of **IK Point List** | | `mdlDataOffset` | |
|||
|- |
|||
|Byte[8] |
|||
| 0x20 | UInt32 | Offset of **Mesh Group Offset** (Chunk offsets) | | `mdlDataOffset` | |
|||
|Unused/Filler |
|||
|- |
|||
| 0x24 | UInt32 | Offset of **Mesh Data** | | `mdlDataOffset` | |
|||
|UInt16 |
|||
|Num of Bone Weights |
|||
| 0x28 | UInt32 | Offset Of **Material Data**? | | | |
|||
|- |
|||
|UInt16 |
|||
| 0x2C | UInt32 | Offset of _Number list reference_ | | `mdlDataOffset` | |
|||
|Num of Weight List Refrence |
|||
|- |
|||
| 0x30 | UInt32 | Offset of **Skinning Data** | | `mdlDataOffset` | |
|||
|UInt16 |
|||
|Num Of Mesh Groups |
|||
| 0x34 | UInt32 | Unknown (Unused/Filler) | | `mdlDataOffset` | |
|||
|- |
|||
|UInt16 |
|||
| 0x38 | UInt32 | Unknown (Unused/Filler) | | | |
|||
|Num Of Bone Data |
|||
|- |
|||
| 0x3C | UInt16 | Count of **Skinning Data** | | | |
|||
|UInt16 |
|||
|Num Of Materials |
|||
| 0x3E | UInt16 | Number Ref List Count | | | |
|||
|- |
|||
|UInt16 |
|||
| 0x40 | UInt16 | Count of **Chunk Data** | | | |
|||
|Num Of IK Points |
|||
|- |
|||
| 0x42 | UInt16 | Count of **Bone Data** | `boneDataCount` | | |
|||
|UInt16 |
|||
|Num Of Morph Keys |
|||
| 0x44 | UInt16 | Count of **Material Data** | `matDataCount` | | |
|||
|- |
|||
|UInt16 |
|||
| 0x46 | UInt16 | Count of **IK points** | | | |
|||
|Internal File ID. This is used in conjunction with weights so that it can access bones within another file |
|||
|- |
|||
| 0x48 | UInt16 | Count of **Morph Data** | | | |
|||
|Byte[4] |
|||
|Filler/Padding |
|||
| 0x4A | UInt16 | Unknown ID/Count (Related to Skeleton/Animation) | | | |
|||
|} |
|||
| 0x4C | UInt32 | Filler/Padding | | | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> Model Data |
|||
| Name | Description | |
|||
|----------------------|----------------------------------------------------------| |
|||
| Material Data Lists | Contains this `matDataCount` many materials | |
|||
| Bone Data List | Contains this `boneDataCount` many bones | |
|||
| Bone Weight Headers | | |
|||
| Number List Ref | | |
|||
| Unknown Data | | |
|||
| Internal Mesh Ref | | |
|||
| Internal Mesh | | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> Material Data |
|||
| Offset | Type | Description | Key | |
|||
|--------|-----------|-----------------------------------------------------------------------|----------------| |
|||
| 0x00 | Bytes[4] | Name of main Texture map/file | | |
|||
| 0x04 | Bytes[4] | Name/Type of Texture | | |
|||
| 0x08 | Bytes[4] | Name/Type of Texture | | |
|||
| 0x0C | Bytes[4] | Name/Type of Texture | | |
|||
| 0x04 | Bytes[4] | Name/Type of Texture | | |
|||
| 0x14 | Float32 | Unknown float value | | |
|||
| 0x18 | Float32 | Unknown float value | | |
|||
| 0x1C | Float32 | Unknown float value | | |
|||
If a slot has 0x00202020 it may be a placeholder |
|||
<nowiki>**</nowiki>Texture types:** |
|||
<nowiki>**</nowiki> = first and last letter of main texture name |
|||
- **_b - Bump/Normal map (Xbox) <nowiki><br></nowiki> |
|||
- **_g - Shadow/Light? |
|||
- �nvr - Environment/Reflection? (Might be leftover) |
|||
- envr - Environment/Reflection? (Xbox) |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> Bone Data |
|||
Size - Bytes[84] |
|||
| Offset | Type | Description | Key | |
|||
|--------|-----------|---------------------------------------------------------------|----------------| |
|||
| 0x00 | Bytes[16] | Name of Bone (ASCII string with a maximum length of 16 bytes) | `boneName` | |
|||
| 0x10 | UInt16 | Unknown (First bone always has 0xFFFF) | | |
|||
| 0x12 | UInt16 | ID of Parent Bone (First bone always has 0xFFFF) | `boneParentID` | |
|||
| 0x14 | UInt16 | Unknown | | |
|||
| 0x16 | UInt16 | ID of Bone | `boneID` | |
|||
| 0x18 | Float32 | Location X | | |
|||
| 0x1C | Float32 | Location Y | | |
|||
| 0x20 | Float32 | Location Z | | |
|||
| 0x24 | Float32 | Rotation Euler Radian X | | |
|||
| 0x28 | Float32 | Rotation Euler Radian Y | | |
|||
| 0x2C | Float32 | Rotation Euler Radian Z | | |
|||
| 0x30 | Float32 | Rotation Euler Radian X | | |
|||
| 0x34 | Float32 | Rotation Euler Radian Y | | |
|||
| 0x38 | Float32 | Rotation Euler Radian Z | | |
|||
| 0x3C | Bytes[24] | Contains 6 float values with either -1.0 or 1.0 | | |
|||
Location and Rotation is relative to parent bone. |
|||
<nowiki><br></nowiki> |
|||
<!-- Inverse Kinematic bones/tagets/points |
|||
This is a list which usually contains 2 points |
|||
Boards use them so the character's boots stick on |
|||
--> |
|||
<nowiki>##</nowiki> IK Point (Inverse Kinematic) |
|||
| Offset | Type | Description | Key | Rel | |
|||
|--------|-----------|--------------------------------|-----|-----| |
|||
| 0x00 | Float32 | Location X | | | |
|||
| 0x04 | Float32 | Location Y | | | |
|||
| 0x08 | Float32 | Location Z | | | |
|||
| 0x0C | UInt32 | Unknown (Filler) | | | |
|||
<nowiki>##</nowiki> Group Main |
|||
<nowiki>###</nowiki> Group Main Header |
|||
| Offset | Type | Description | Key | Rel | |
|||
|-------- |-------- |------------------ |----- |----- | |
|||
| 0x00 | UInt32 | ID | | | |
|||
| 0x04 | UInt32 | Material ID | | | |
|||
| 0x08 | UInt32 | Unknown | | | |
|||
| | UInt32 | Sub Group Offset | | | |
|||
| | UInt32 | Sub Group Count | | | |
|||
<nowiki>###</nowiki> Group Sub Group |
|||
| Offset | Type | Description | Key | Rel | |
|||
|-------- |-------- |---------------------- |----- |----- | |
|||
| 0x00 | UInt32 | Mesh Group Offset | | | |
|||
| 0x04 | UInt32 | Mesh Group Count | | | |
|||
<nowiki>###</nowiki> Sub Sub Mesh Group |
|||
| Offset | Type | Description | Key | Rel | |
|||
|-------- |-------- |-------------- |----- |----- | |
|||
| 0x00 | UInt32 | Model Offset | | | |
|||
| 0x04 | UInt32 | Unknown 1 | | | |
|||
| | UInt32 | Unknown 2 | | | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> Bone Weight |
|||
<nowiki>###</nowiki> Bone Weight Header |
|||
| Offset | Type | Description | Key | Rel | |
|||
|--------|--------|----------------------------|-----|-----| |
|||
| 0x00 | UInt32 | Length of array/list | | | |
|||
| 0x04 | UInt32 | Offset to Bone weight list | | | |
|||
| 0x08 | UInt32 | Unknown | | | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>###</nowiki> Bone Weight |
|||
| Offset | Type | Description | Key | Rel | |
|||
|--------|--------|------------------------|-----|-----| |
|||
| 0x00 | UInt16 | Bone weight (0 to 100) | | | |
|||
| 0x02 | UInt8 | Bone ID | | | |
|||
| 0x03 | UInt8 | Unknown | | | |
|||
<nowiki>##</nowiki> Number List Ref |
|||
<nowiki>###</nowiki> Number List Ref Header |
|||
| Offset | Type | Description | Key | Rel | |
|||
|--------|--------|-----------------------------|-----|-----| |
|||
| 0x00 | UInt32 | Sub Number List Ref Count | | | |
|||
| 0x04 | UInt32 | Sub Number List Ref Offset | | | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>###</nowiki> Sub Number List Ref |
|||
| Offset | Type | Description | Key | Rel | |
|||
|--------|--------|------------------------|-----|-----| |
|||
| | UInt16 | Unknown | | | |
|||
| | UInt16 | Unknown2 | | | |
|||
<nowiki><br></nowiki> |
|||
<!-- |
|||
Row Count Header |
|||
Hex examples: |
|||
01000010 00000000 00000000 00000000 |
|||
^ 1 row |
|||
06000096 00000000 00000000 00000000 |
|||
^ 6 rows |
|||
--> |
|||
<!-- THIS IS ALSO A COMMENT |
|||
Model Data List[ |
|||
Model Data 1 [ |
|||
Material Data List[ |
|||
Material 1 |
|||
Material 2 |
|||
] |
|||
Bone Data List[ |
|||
Bone 1 |
|||
Bone 2 |
|||
] |
|||
Bone Weights List 1[ |
|||
] |
|||
Bone Weights List 2[ |
|||
] |
|||
Offsets/Count List[ |
|||
Offset/Count 1 List[ |
|||
] |
|||
Offset/Count 1 List[ |
|||
] |
|||
] |
|||
Mesh Data List[ |
|||
Mesh Data 1 List[ |
|||
Mesh 1 |
|||
Mesh 2 |
|||
] |
|||
Mesh Data 2 List[ |
|||
Mesh 1 |
|||
Mesh 2 |
|||
] |
|||
] |
|||
] |
|||
] |
|||
There's multiple mesh groups in the mesh section |
|||
Mesh Data List [ # the model's header leads here |
|||
Mesh Data 1 List [ # offset/count section leads here |
|||
Mesh 1 # mesh info, tristrips, uvs, nrm, vtx |
|||
Mesh 2 |
|||
etc... |
|||
] # footer Hex: 00000000 00000010 00000000 00000014 |
|||
Mesh Data 2 List[ # offset/count section leads here |
|||
Mesh 1 |
|||
etc... |
|||
] # footer Hex: 00000000 00000010 00000000 00000014 |
|||
Test |
|||
--> |
|||
<nowiki>##</nowiki> Mesh Data |
|||
| Offset | Type | Description | Key | |
|||
|--------|-----------|-----------------------------------------------------------------------------------------------------------------|-----| |
|||
| 0x00 | UInt24 | Count of total rows | | |
|||
| 0x03 | Byte | Size of individual rows (Always 16) | | |
|||
| 0x04 | Bytes[12] | Unknown (Filler/Padding) | | |
|||
| 0x10 | Bytes[13] | Unknown (Always 0x00000000010100010000000000) | | |
|||
| 0x1D | Byte | Prefix of count (0x80) | | |
|||
| 0x1E | Byte | Count of total mesh info rows (sum of the amount of mesh info rows and the amount of triangle strip count rows) | | |
|||
| 0x1F | Byte | Suffix of count (0x6c) | | |
|||
| 0x20 | Bytes[16] | Mesh Info Row 1 | | |
|||
| 0x30 | Bytes[16] | Mesh Info Row 2 | | |
|||
| | List | List of Triangle Strip Count Rows | | |
|||
- **Triangle Strip Count Row** |
|||
The amount of triangle strip rows can be found inside Mesh Info Row 2 <nowiki><br></nowiki> |
|||
_First type is assumed to be either UInt32 or Byte_ |
|||
| Type | Description | |
|||
|-----------|-----------------------------------------| |
|||
| UInt32 | Count of vertices | |
|||
| Bytes[12] | Padding/Unknown | |
|||
_mesh data continued:_ |
|||
| Type | Description | |
|||
|-----------|-----------------------------------------| |
|||
| UInt24 | Count of rows | |
|||
| Byte | Unknown (Always 16) | |
|||
| Bytes[12] | Unknown | |
|||
| List | UV Block | |
|||
| List | Normal Block | |
|||
| List | Vertex Block | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> UV Block |
|||
| Type | Desc | Key | |
|||
|-----------|----------------------------------------------------------------|-----| |
|||
| Bytes[16] | Header of UV Block (Hex: 00100000 00100000 00000020 50505050) | | |
|||
| Bytes[12] | Unknown | | |
|||
| Byte | Unknown | | |
|||
| Byte | Prefix of UV count (0x80) | | |
|||
| Byte | Count of UVs | | |
|||
| Byte | Suffix of UV count (0x6D) | | |
|||
| List | List of UV values | | |
|||
<nowiki>**</nowiki>UV value** |
|||
| Type | Description | |
|||
|-----------|-----------------------------------------| |
|||
| UInt16 | UV map U (X translation) | |
|||
| UInt16 | UV map V (Y translation) | |
|||
| UInt16 | UV map U distance | |
|||
| UInt16 | UV map V distance | |
|||
<nowiki><br></nowiki> |
|||
<nowiki>##</nowiki> Normal Block |
|||
| Type | Desc | Key | |
|||
|-----------|-------------------------------------------------------------------|-----| |
|||
| Bytes[16] | Header of normal Block (Hex: 00000000 00800000 00000020 40404040) | | |
|||
| Bytes[12] | Unknown | | |
|||
| Byte | Unknown | | |
|||
=== Model Data === |
|||
| Byte | Prefix of Normal Count (0x80) | | |
|||
All Offsets Unless Stated Otherwise are relative to the start of each model data |
|||
==== <u>Material Data</u> ==== |
|||
| Byte | Count of Normals | | |
|||
Unused Slots use 0x00202020 as a place holder |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Bytes[4] |
|||
|Name of Main Texture map/file |
|||
|- |
|||
|Bytes[4] |
|||
|Name/Type of Texture (Unused In PS2) |
|||
|- |
|||
|Bytes[4] |
|||
|Name/Type of Texture (Unused In PS2) |
|||
|- |
|||
|Bytes[4] |
|||
|Name/Type of Texture (Used To Tell Game If Material Has Gloss **_g) |
|||
|- |
|||
|Bytes[4] |
|||
|Name/Type of Texture (Used To Tell Game If The Object uses Environment Reflection envr) |
|||
|- |
|||
|Float32 |
|||
|Flag Factor |
|||
|- |
|||
|Float32 |
|||
|Unknown float value |
|||
|- |
|||
|Float32 |
|||
|Unknown float value |
|||
|} |
|||
==== <u>Bone Data</u> ==== |
|||
| Byte | Suffix of Normal count (0x79) | | |
|||
Location and Rotation are relative to parent |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Bytes[16] |
|||
|Name of Bone (ASCII string with a maximum length of 16 bytes) |
|||
|- |
|||
|UInt16 |
|||
|Internal File ID of Parent Bone(First bone always has 0xFFFF) |
|||
|- |
|||
|UInt16 |
|||
|ID of Parent Bone (First bone always has 0xFFFF) |
|||
|- |
|||
|UInt16 |
|||
|Bone ID (?) |
|||
|- |
|||
|UInt16 |
|||
|Unknown |
|||
|- |
|||
|Vector 3 (3 Float32s) |
|||
|XYZ Position Of the Bone |
|||
|- |
|||
|Vector 3 (3 Float32s) |
|||
|XYZ Radian Rotation of the bone |
|||
|- |
|||
|Vector 3 (3 Float32s) |
|||
|XYZ Radian 2 |
|||
|- |
|||
|6 Float32s |
|||
|6 Floats either being -1 or 1 |
|||
|} |
|||
==== <u>IK Points</u> ==== |
|||
| List | List Normal values | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Vector 3 (3 Float32s) |
|||
|Location XYZ |
|||
|- |
|||
|UInt32 |
|||
|Unknown (Filler) |
|||
|} |
|||
==== <u>Group Main</u> ==== |
|||
<nowiki>**</nowiki>Normal value:** |
|||
===== Group Main Header ===== |
|||
| Type | Description | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Group Type (1 Standard, 17 Shadow, 256 Morph) |
|||
|- |
|||
|UInt32 |
|||
|Material ID |
|||
|- |
|||
|UInt32 |
|||
|Unknown (Always -1) |
|||
|- |
|||
|UInt32 |
|||
|Weight Reference Group Offset |
|||
|- |
|||
|UInt32 |
|||
|Weight Reference Group Count |
|||
|} |
|||
==== Weight Reference Group ==== |
|||
|-----------|-------------------------------| |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Mesh Group Offset |
|||
|- |
|||
|UInt32 |
|||
|Mesh Group Count |
|||
|} |
|||
==== Mesh/Morph Data Group ==== |
|||
Each one of these in order references a Weight Reference and all points within it will use that weight reference |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Model Offset |
|||
|- |
|||
|UInt32 |
|||
|Morph Target Offset Relative to Model Offset |
|||
|- |
|||
|UInt32 |
|||
|Morph Target Entry Size |
|||
|} |
|||
==== <u>Bone Weight</u> ==== |
|||
| UInt16 | Normal X direction | |
|||
===== Bone Weight Header ===== |
|||
| UInt16 | Normal Y direction | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Length of array/list |
|||
|- |
|||
|UInt32 |
|||
|Offset to Bone weight list |
|||
|- |
|||
|UInt32 |
|||
|Unknown (Always 36) |
|||
|} |
|||
===== Bone Weight ===== |
|||
| UInt16 | Normal Z direction | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt16 |
|||
|Bone weight (0 to 100) |
|||
|- |
|||
|UInt8 |
|||
|Bone ID |
|||
|- |
|||
|UInt8 |
|||
|Bone Internal File ID |
|||
|} |
|||
==== <u>Weight List Ref</u> ==== |
|||
<nowiki><br></nowiki> |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Weight Reference Count |
|||
|- |
|||
|UInt32 |
|||
|Weight Reference Offset |
|||
|- |
|||
|Int32 List |
|||
|WeightIDs |
|||
|} |
|||
==== <u>Mesh Data</u> ==== |
|||
<nowiki>##</nowiki> Vertex Block |
|||
The mesh data within the mpf can be very complex and is chunked meaning there can be multiple data chunks within a Mesh/Morph Data Group |
|||
Depending on the group type (Located in the mesh group) can effect what information is in here. |
|||
| Type | Desc | Key | |
|||
* If Group Type is Standard there will be UV/Weight Block, Normal Block and, Vertex Block. |
|||
|-----------|-------------------------------------------------------------------|-----| |
|||
* If Group Type is Shadow There will be Shadow Vertex Block |
|||
* If Group Type is Morph the data will be the same as standard however there will be no data chunking |
|||
Bytes[48] Unimportant Data for Exporting |
|||
| Bytes[16] | Header of Vertex Block (Hex: 00000000 0000803F 00000020 40404040) | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Strip Count |
|||
|- |
|||
|UInt32 |
|||
|Starting Weight Ref ID (Generally Always 14) |
|||
|- |
|||
|UInt32 |
|||
|Unknown2 (If group type is shadow this will be 0) |
|||
|- |
|||
|UInt32 |
|||
|Vertex Count |
|||
|} |
|||
===== Tristrip Data ===== |
|||
| Bytes[12] | Unknown | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt32 |
|||
|Count of vertices |
|||
|- |
|||
|Bytes[12] |
|||
|Padding |
|||
|} |
|||
==== UV/Weight Block ==== |
|||
| Byte | Unknown | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Bytes[16] |
|||
|Header of UV Block (Hex: 00100000 00100000 00000020 50505050) |
|||
|- |
|||
|Bytes[12] |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Prefix List Start (0x80) |
|||
|- |
|||
|Byte |
|||
|Count of UVs |
|||
|- |
|||
|Byte |
|||
|Suffix of UV count (0x6D) |
|||
|- |
|||
|List of '''''UV value''''' |
|||
|List Of UV/Weights Values |
|||
|} |
|||
'''''UV value''''' |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|UInt16 |
|||
|UV map U (X translation) (In order to get the float value you do Number / 4096) |
|||
|- |
|||
|UInt16 |
|||
|UV map V (Y translation) (In order to get the float value you do Number / 4096) |
|||
|- |
|||
|UInt16 |
|||
|Bone Weight Ref ID (In order to get ID you do (Number - 14)/4) |
|||
|- |
|||
|Uint16 |
|||
|Bone Weight Ref ID (In order to get ID you do (???)) |
|||
|} |
|||
===== Normal Block ===== |
|||
| Byte | Prefix of Vertex count (0x80) | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Bytes[16] |
|||
|Header of normal Block (Hex: 00000000 00800000 00000020 40404040) |
|||
|- |
|||
|Bytes[12] |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Prefix List Start (0x80) |
|||
|- |
|||
|Byte |
|||
|Count of Normals |
|||
|- |
|||
|Byte |
|||
|Suffix of Normal count (??) |
|||
|- |
|||
|List of Vector 3 (3 Int16s) |
|||
|List of normals (In order to get the float value you do Number / 4096(???)) |
|||
|} |
|||
==== Vertex Block ==== |
|||
| Byte | Count of Vertices | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Bytes[16] |
|||
|Header of Vertex Block (Hex: 00000000 0000803F 00000020 40404040) |
|||
|- |
|||
|Bytes[12] |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Prefix List Start (0x80) |
|||
|- |
|||
|Byte |
|||
|Count of Vertices |
|||
|- |
|||
|Byte |
|||
|Suffix of Vertex count (0x78) |
|||
|- |
|||
|List of Vector 3 (3 Float32) |
|||
|List Of Vertex values |
|||
|} |
|||
==== Shadow Vertex Block ==== |
|||
| Byte | Suffix of Vertex count (0x78) | | |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Bytes[16] |
|||
|Header of Vertex Block (Hex: 00000000 0000803F 00000020 40404040) |
|||
|- |
|||
|Bytes[12] |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Unknown |
|||
|- |
|||
|Byte |
|||
|Prefix List Start (0x80) |
|||
|- |
|||
|Byte |
|||
|Count of Vertices |
|||
|- |
|||
|Byte |
|||
|Suffix of Vertex count (??) |
|||
|- |
|||
|List of '''''Shadow Vertex''''' |
|||
|List Of Shadow Vertex values |
|||
|} |
|||
'''''Shadow Vertex value''''' |
|||
{| class="wikitable" |
|||
!Type |
|||
!Description |
|||
|- |
|||
|Vector 3 (3 Float32) |
|||
|Location XYZ |
|||
|- |
|||
|Uint16 |
|||
|Bone Weight Ref ID (In order to get ID you do (Number - 14)/4) |
|||
|} |
|||
<syntaxhighlight lang="c#" line="1" start="0"> |
|||
public int U1; |
|||
public int HeaderCount; |
|||
public int HeaderOffset; |
|||
public int FileStart; |
|||
public List<MPFModelHeader> ModelList = new List<MPFModelHeader>(); |
|||
public struct MPFModelHeader |
|||
| List | List Vertex values | | |
|||
{ |
|||
//Main Header |
|||
public string FileName; |
|||
public int DataOffset; |
|||
public int EntrySize; |
|||
public int BoneDataOffset; |
|||
public int IKPointOffset; |
|||
public int MeshGroupOffset; |
|||
public int MeshDataOffset; |
|||
public int MaterialOffset; |
|||
public int NumberListOffset; |
|||
public int BoneWeightOffet; |
|||
//Counts |
|||
<nowiki>**</nowiki>Vertex value:** |
|||
public int BoneWeightCount; |
|||
public int NumberListCount; |
|||
public int MeshGroupCount; |
|||
public int BoneDataCount; |
|||
public int MaterialCount; |
|||
public int IKCount; |
|||
public int MorphKeyCount; |
|||
public int FileID; |
|||
public List<MaterialData> materialDatas; |
|||
| Type | Description | |
|||
public List<BoneData> boneDatas; |
|||
public List<Vector3> iKPoints; |
|||
public List<GroupMainHeader> MeshGroups; |
|||
public List<BoneWeightHeader> boneWeightHeader; |
|||
public List<WeightRefList> numberListRefs; |
|||
} |
|||
public struct WeightRefList |
|||
|-----------|-------------------------------| |
|||
{ |
|||
public int SubCount; |
|||
public int Offset; |
|||
public List<int> WeightIDs; |
|||
| Float32 | Location X | |
|||
} |
|||
public struct MaterialData |
|||
| Float32 | Location Y | |
|||
{ |
|||
public string MainTexture; |
|||
public string Texture1; |
|||
public string Texture2; |
|||
public string Texture3; |
|||
public string Texture4; |
|||
public float FactorFloat; |
|||
| Float32 | Location Z | |
|||
public float Unused1Float; |
|||
public float Unused2Float; |
|||
} |
|||
public struct BoneData |
|||
<nowiki>##</nowiki> Shadow Vertex Block |
|||
{ |
|||
public string BoneName; |
|||
public int ParentFileID; |
|||
public int ParentBone; |
|||
public int Unknown2; |
|||
public int BoneID; |
|||
public Vector3 Position; |
|||
| Type | Desc | Key | |
|||
public Vector3 Radians; |
|||
public float XRadian2; |
|||
|-----------|-------------------------------------------------------------------|-----| |
|||
public float YRadian2; |
|||
public float ZRadian2; |
|||
public float UnknownFloat1; |
|||
| Bytes[16] | Header of Vertex Block (Hex: 00000000 0000803F 00000020 40404040) | | |
|||
public float UnknownFloat2; |
|||
public float UnknownFloat3; |
|||
public float UnknownFloat4; |
|||
public float UnknownFloat5; |
|||
public float UnknownFloat6; |
|||
public int FileID; |
|||
| Bytes[12] | Unknown | | |
|||
public int BonePos; |
|||
} |
|||
| Byte | Unknown | | |
|||
public struct GroupMainHeader |
|||
| Byte | Prefix of Vertex count (0x80) | | |
|||
{ |
|||
public int GroupType; //1 Standard, 17 Shadow, 256 Morph |
|||
public int MaterialID; |
|||
public int Unknown; |
|||
public int LinkCount; |
|||
public int LinkOffset; |
|||
public List<WeightRefGroup> meshGroupSubs; |
|||
| Byte | Count of Vertices | | |
|||
} |
|||
public struct WeightRefGroup |
|||
| Byte | Suffix of Vertex count (0x6C) | | |
|||
{ |
|||
public List<int> weights; |
|||
public int LinkOffset; |
|||
| List | List Vertex values | | |
|||
public int LinkCount; |
|||
public List<MeshMorphHeader> MeshGroupHeaders; |
|||
<nowiki>**</nowiki>Vertex value:** |
|||
} |
|||
public struct MeshMorphHeader |
|||
| Type | Description | |
|||
{ |
|||
public int ModelOffset; |
|||
public int MorphKeyOffset; //Morph Target Offset |
|||
public int MorphKeyEntrySize; //Morph Target Entry Size |
|||
public int WeightRefGroup; |
|||
public List<MeshChunk> staticMesh; |
|||
|-----------|-------------------------------| |
|||
public List<MorphKey> MorphKeyList; |
|||
} |
|||
public struct MorphKey |
|||
| Float32 | Location X | |
|||
{ |
|||
public int MorphPointDataCount; |
|||
public List<Vector3> morphData; |
|||
| Float32 | Location Y | |
|||
} |
|||
public struct BoneWeightHeader |
|||
| Float32 | Location Z | |
|||
{ |
|||
public int Length; |
|||
public int WeightListOffset; |
|||
public int unknown; //Always 36 |
|||
public List<BoneWeight> boneWeights; |
|||
| UInt32 | Unknown | |
|||
} |
|||
public struct BoneWeight |
|||
<nowiki><br></nowiki> |
|||
{ |
|||
public int Weight; |
|||
public int BoneID; |
|||
public int FileID; |
|||
} |
|||
public struct MeshChunk |
|||
<nowiki>***</nowiki> |
|||
{ |
|||
public int StripCount; |
|||
public int Unknown1; |
|||
public int Unknown2; |
|||
public int VertexCount; |
|||
public List<int> Strips; |
|||
public List<Vector4> uv; |
|||
<nowiki><br></nowiki> |
|||
public List<Vector3> vertices; |
|||
public List<int> Weights; |
|||
public List<Face> faces; |
|||
public List<Vector3> uvNormals; |
|||
public List<MorphKey> MorphKeys; |
|||
} |
|||
<nowiki>**</nowiki>End of MPF Structure** |
|||
</syntaxhighlight> |
|||
<nowiki><br></nowiki> |
Latest revision as of 02:54, 5 March 2023
Overview
An MPF file contains model names, bones, UV maps, normals, vertices and other model data.
Here is the structure made in programming languages for easy code implementation:
- SSX Tricky MPF C# handler by GlitcherOG
- [SSX Tricky mpf GO struct by Erick](https://github.com/Erickson400/TheTrickyModels/blob/main/mpf/MpfStructure.go)
Structure
File Header
Section 0 - Bytes[12]
Type | Description |
---|---|
Byte[4] | Version ID (Version 8) |
UInt16 | Model Header Count |
UInt16 | Offset To Model Headers |
UInt32 | Offset To Model Data List Start |
Model Header
All Offsets Within the file are relative to the start of the Model Data
Type | Description |
---|---|
Bytes[16] | Name of Model (ASCII string with a max length of 16 bytes) |
UInt32 | Offset to Model Data which is relative to Model Data List Start Offset |
UInt32 | Size of model in bytes |
UInt32 | Offset of **Bone Data List** |
UInt32 | Offset of **IK Point List** |
UInt32 | Offset of **Mesh Group Offset** |
UInt32 | Offset of **Mesh Data** |
UInt32 | Offset Of **Material Data** |
UInt32 | Offset of Weight List Reference |
UInt32 | Offset of Bone Weights |
Byte[8] | Unused/Filler |
UInt16 | Num of Bone Weights |
UInt16 | Num of Weight List Refrence |
UInt16 | Num Of Mesh Groups |
UInt16 | Num Of Bone Data |
UInt16 | Num Of Materials |
UInt16 | Num Of IK Points |
UInt16 | Num Of Morph Keys |
UInt16 | Internal File ID. This is used in conjunction with weights so that it can access bones within another file |
Byte[4] | Filler/Padding |
Model Data
All Offsets Unless Stated Otherwise are relative to the start of each model data
Material Data
Unused Slots use 0x00202020 as a place holder
Type | Description |
---|---|
Bytes[4] | Name of Main Texture map/file |
Bytes[4] | Name/Type of Texture (Unused In PS2) |
Bytes[4] | Name/Type of Texture (Unused In PS2) |
Bytes[4] | Name/Type of Texture (Used To Tell Game If Material Has Gloss **_g) |
Bytes[4] | Name/Type of Texture (Used To Tell Game If The Object uses Environment Reflection envr) |
Float32 | Flag Factor |
Float32 | Unknown float value |
Float32 | Unknown float value |
Bone Data
Location and Rotation are relative to parent
Type | Description |
---|---|
Bytes[16] | Name of Bone (ASCII string with a maximum length of 16 bytes) |
UInt16 | Internal File ID of Parent Bone(First bone always has 0xFFFF) |
UInt16 | ID of Parent Bone (First bone always has 0xFFFF) |
UInt16 | Bone ID (?) |
UInt16 | Unknown |
Vector 3 (3 Float32s) | XYZ Position Of the Bone |
Vector 3 (3 Float32s) | XYZ Radian Rotation of the bone |
Vector 3 (3 Float32s) | XYZ Radian 2 |
6 Float32s | 6 Floats either being -1 or 1 |
IK Points
Type | Description |
---|---|
Vector 3 (3 Float32s) | Location XYZ |
UInt32 | Unknown (Filler) |
Group Main
Group Main Header
Type | Description |
---|---|
UInt32 | Group Type (1 Standard, 17 Shadow, 256 Morph) |
UInt32 | Material ID |
UInt32 | Unknown (Always -1) |
UInt32 | Weight Reference Group Offset |
UInt32 | Weight Reference Group Count |
Weight Reference Group
Type | Description |
---|---|
UInt32 | Mesh Group Offset |
UInt32 | Mesh Group Count |
Mesh/Morph Data Group
Each one of these in order references a Weight Reference and all points within it will use that weight reference
Type | Description |
---|---|
UInt32 | Model Offset |
UInt32 | Morph Target Offset Relative to Model Offset |
UInt32 | Morph Target Entry Size |
Bone Weight
Bone Weight Header
Type | Description |
---|---|
UInt32 | Length of array/list |
UInt32 | Offset to Bone weight list |
UInt32 | Unknown (Always 36) |
Bone Weight
Type | Description |
---|---|
UInt16 | Bone weight (0 to 100) |
UInt8 | Bone ID |
UInt8 | Bone Internal File ID |
Weight List Ref
Type | Description |
---|---|
UInt32 | Weight Reference Count |
UInt32 | Weight Reference Offset |
Int32 List | WeightIDs |
Mesh Data
The mesh data within the mpf can be very complex and is chunked meaning there can be multiple data chunks within a Mesh/Morph Data Group
Depending on the group type (Located in the mesh group) can effect what information is in here.
- If Group Type is Standard there will be UV/Weight Block, Normal Block and, Vertex Block.
- If Group Type is Shadow There will be Shadow Vertex Block
- If Group Type is Morph the data will be the same as standard however there will be no data chunking
Bytes[48] Unimportant Data for Exporting
Type | Description |
---|---|
UInt32 | Strip Count |
UInt32 | Starting Weight Ref ID (Generally Always 14) |
UInt32 | Unknown2 (If group type is shadow this will be 0) |
UInt32 | Vertex Count |
Tristrip Data
Type | Description |
---|---|
UInt32 | Count of vertices |
Bytes[12] | Padding |
UV/Weight Block
Type | Description |
---|---|
Bytes[16] | Header of UV Block (Hex: 00100000 00100000 00000020 50505050) |
Bytes[12] | Unknown |
Byte | Unknown |
Byte | Prefix List Start (0x80) |
Byte | Count of UVs |
Byte | Suffix of UV count (0x6D) |
List of UV value | List Of UV/Weights Values |
UV value
Type | Description |
---|---|
UInt16 | UV map U (X translation) (In order to get the float value you do Number / 4096) |
UInt16 | UV map V (Y translation) (In order to get the float value you do Number / 4096) |
UInt16 | Bone Weight Ref ID (In order to get ID you do (Number - 14)/4) |
Uint16 | Bone Weight Ref ID (In order to get ID you do (???)) |
Normal Block
Type | Description |
---|---|
Bytes[16] | Header of normal Block (Hex: 00000000 00800000 00000020 40404040) |
Bytes[12] | Unknown |
Byte | Unknown |
Byte | Prefix List Start (0x80) |
Byte | Count of Normals |
Byte | Suffix of Normal count (??) |
List of Vector 3 (3 Int16s) | List of normals (In order to get the float value you do Number / 4096(???)) |
Vertex Block
Type | Description |
---|---|
Bytes[16] | Header of Vertex Block (Hex: 00000000 0000803F 00000020 40404040) |
Bytes[12] | Unknown |
Byte | Unknown |
Byte | Prefix List Start (0x80) |
Byte | Count of Vertices |
Byte | Suffix of Vertex count (0x78) |
List of Vector 3 (3 Float32) | List Of Vertex values |
Shadow Vertex Block
Type | Description |
---|---|
Bytes[16] | Header of Vertex Block (Hex: 00000000 0000803F 00000020 40404040) |
Bytes[12] | Unknown |
Byte | Unknown |
Byte | Prefix List Start (0x80) |
Byte | Count of Vertices |
Byte | Suffix of Vertex count (??) |
List of Shadow Vertex | List Of Shadow Vertex values |
Shadow Vertex value
Type | Description |
---|---|
Vector 3 (3 Float32) | Location XYZ |
Uint16 | Bone Weight Ref ID (In order to get ID you do (Number - 14)/4) |
public int U1;
public int HeaderCount;
public int HeaderOffset;
public int FileStart;
public List<MPFModelHeader> ModelList = new List<MPFModelHeader>();
public struct MPFModelHeader
{
//Main Header
public string FileName;
public int DataOffset;
public int EntrySize;
public int BoneDataOffset;
public int IKPointOffset;
public int MeshGroupOffset;
public int MeshDataOffset;
public int MaterialOffset;
public int NumberListOffset;
public int BoneWeightOffet;
//Counts
public int BoneWeightCount;
public int NumberListCount;
public int MeshGroupCount;
public int BoneDataCount;
public int MaterialCount;
public int IKCount;
public int MorphKeyCount;
public int FileID;
public List<MaterialData> materialDatas;
public List<BoneData> boneDatas;
public List<Vector3> iKPoints;
public List<GroupMainHeader> MeshGroups;
public List<BoneWeightHeader> boneWeightHeader;
public List<WeightRefList> numberListRefs;
}
public struct WeightRefList
{
public int SubCount;
public int Offset;
public List<int> WeightIDs;
}
public struct MaterialData
{
public string MainTexture;
public string Texture1;
public string Texture2;
public string Texture3;
public string Texture4;
public float FactorFloat;
public float Unused1Float;
public float Unused2Float;
}
public struct BoneData
{
public string BoneName;
public int ParentFileID;
public int ParentBone;
public int Unknown2;
public int BoneID;
public Vector3 Position;
public Vector3 Radians;
public float XRadian2;
public float YRadian2;
public float ZRadian2;
public float UnknownFloat1;
public float UnknownFloat2;
public float UnknownFloat3;
public float UnknownFloat4;
public float UnknownFloat5;
public float UnknownFloat6;
public int FileID;
public int BonePos;
}
public struct GroupMainHeader
{
public int GroupType; //1 Standard, 17 Shadow, 256 Morph
public int MaterialID;
public int Unknown;
public int LinkCount;
public int LinkOffset;
public List<WeightRefGroup> meshGroupSubs;
}
public struct WeightRefGroup
{
public List<int> weights;
public int LinkOffset;
public int LinkCount;
public List<MeshMorphHeader> MeshGroupHeaders;
}
public struct MeshMorphHeader
{
public int ModelOffset;
public int MorphKeyOffset; //Morph Target Offset
public int MorphKeyEntrySize; //Morph Target Entry Size
public int WeightRefGroup;
public List<MeshChunk> staticMesh;
public List<MorphKey> MorphKeyList;
}
public struct MorphKey
{
public int MorphPointDataCount;
public List<Vector3> morphData;
}
public struct BoneWeightHeader
{
public int Length;
public int WeightListOffset;
public int unknown; //Always 36
public List<BoneWeight> boneWeights;
}
public struct BoneWeight
{
public int Weight;
public int BoneID;
public int FileID;
}
public struct MeshChunk
{
public int StripCount;
public int Unknown1;
public int Unknown2;
public int VertexCount;
public List<int> Strips;
public List<Vector4> uv;
public List<Vector3> vertices;
public List<int> Weights;
public List<Face> faces;
public List<Vector3> uvNormals;
public List<MorphKey> MorphKeys;
}