Formats/SSXTricky:MPF(PS2 Model): Difference between revisions

From SSX Modding Wiki
(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...")
 
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>)<nowiki><br></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 

| 0x08   | UInt32 | Offset of **Model Data List**        | `mdlDataListOffset` |
|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;
        }