== 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:
- [SSX Tricky mpf GO struct by Erick](<nowiki>https://github.com/Erickson400/TheTrickyModels/blob/main/mpf/MpfStructure.go</nowiki>)
<nowiki><br></nowiki>
- [SSX Tricky mpf GOC# structhandler by ErickGlitcherOG](<nowiki>https://github.com/Erickson400GlitcherOG/TheTrickyModelsSSX-PS2-Collection-Modder/blob/main/mpfFileHandlers/MpfStructureModels/TrickyMPFModelHandler.gocs</nowiki>)<nowiki><br></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]
{| class="wikitable"
|+
!Type
!Description
|-
|Byte[4]
|Unknown (Possibly version or magic)
|-
|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
|-
|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
|-
|UInt32
|Unknown (Unused/Filler)
|-
|UInt32
|Unknown (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
|-
|UInt32
|Filler/Padding
|}
=== Model Data ===
|--------|--------|--------------------------------------|---------------------|
All Offsets Unless Stated Otherwise are relative to the start of model data
==== Material Data ====
| 0x00 | UInt32 | Unknown (Possibly version or magic) | |
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 (Unused In PS2)
|-
|Bytes[4]
|Name/Type of Texture (Unused In PS2)
|-
|Float32
|Unknown float value
|-
|Float32
|Unknown float value
|-
|Float32
|Unknown float value
|}
==== Bone Data ====
| 0x04 | Int16 | Count of **Models** | `mdlCount` |
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
|Contains 6 float values with either -1.0 or 1.0
|}
==== IK Point (Inverse Kinematic) ====
| 0x06 | Int16 | Offset of **Model Header List** | |
Inverse Kinematic Targets this is a list which usually contains 2 points boards use them so the character's boots stick on
{| class="wikitable"
|+
!Type
!Description
|-
|Vector 3 (3 Float32s)
|Location XYZ
|-
|UInt32
|Unknown (Filler)
|}
==== Group Main ====
| 0x08 | UInt32 | Offset of **Model Data List** | `mdlDataListOffset` |
===== Group Main Header =====
| | List | List containing Model Headers | |
{| class="wikitable"
|+
| | List | List containing Model Data | |
!Type
!Description
<nowiki><br></nowiki>
|-
|UInt32
<nowiki>##</nowiki> Model Header
|ID (?)
|-
Section 1 - Bytes[80]
|UInt32
|Material ID
| Offset | Type | Description | Key | Rel |
|-
|UInt32
|-------- |----------- |------------------------------------------------------------ |------------------ |--------------------- |
|Unknown
|-
| 0x00 | Bytes[16] | Name of Model (ASCII string with a max length of 16 bytes) | `mdlName` | |
|UInt32
|Sub Group Offset
| 0x10 | UInt32 | Offset of **Model Data** | `mdlDataOffset` | `mdlDataListOffset` |
|-
|UInt32
| 0x14 | UInt32 | Size of model in bytes or end offset | | `mdlDataOffset` |
|Sub Group Count
|}
| 0x18 | UInt32 | Offset of **Bone Data List** | `boneListOffset` | `mdlDataOffset` |
| 0x1C | UInt32 | Offset of **IK Point List** | | `mdlDataOffset` |
| 0x20 | UInt32 | Offset of **Mesh Group Offset** (Chunk offsets) | | `mdlDataOffset` |
| 0x24 | UInt32 | Offset of **Mesh Data** | | `mdlDataOffset` |
| 0x28 | UInt32 | Offset Of **Material Data**? | | |
| 0x2C | UInt32 | Offset of _Number list reference_ | | `mdlDataOffset` |
| 0x30 | UInt32 | Offset of **Skinning Data** | | `mdlDataOffset` |
| 0x34 | UInt32 | Unknown (Unused/Filler) | | `mdlDataOffset` |
| 0x38 | UInt32 | Unknown (Unused/Filler) | | |
| 0x3C | UInt16 | Count of **Skinning Data** | | |
| 0x3E | UInt16 | Number Ref List Count | | |
| 0x40 | UInt16 | Count of **Chunk Data** | | |
| 0x42 | UInt16 | Count of **Bone Data** | `boneDataCount` | |
| 0x44 | UInt16 | Count of **Material Data** | `matDataCount` | |
| 0x46 | UInt16 | Count of **IK points** | | |
| 0x48 | UInt16 | Count of **Morph Data** | | |
| 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
==== Sub Group ====
{| class="wikitable"
!Type
!Description
|-
|UInt32
|Mesh Group Offset
|-
|UInt32
|Mesh Group Count
|}
| Offset | Type | Description | Key | Rel |
| 0x04 | UInt32 | Mesh Group Count | | |
==== Mesh/Morph Data Group ====
<nowiki>###</nowiki> Sub Sub Mesh Group
{| class="wikitable"
|+
| Offset | Type | Description | Key | Rel |
!Type
!Description
|-------- |-------- |-------------- |----- |----- |
|-
|UInt32
| 0x00 | UInt32 | Model Offset | | |
|Model Offset
|-
| 0x04 | UInt32 | Unknown 1 | | |
|UInt32
|Morph Target Offset Relative to Model Offset
| | UInt32 | Unknown 2 | | |
|-
|UInt32
|Morph Target Entry Size
|}
<nowiki><br></nowiki>
<nowiki>##</nowiki> Bone Weight
<nowiki>###</nowiki> Bone Weight Header
|