-
Notifications
You must be signed in to change notification settings - Fork 18
Mod3 Structure Notes
This section is the product of research by CrazyT, AsteriskAmpersand, PredatorCZ, Ubergrainy and Jodo.
- The 010 templates for the mod3 format can be found on CrazyT Research Repo.
- The python mod3 class can be found AsteriskAmpersand's Mod3 Importer Repo.
As the template itself is pretty descriptive of structures involved this section only lists the bizarre parts of the specification that require clarification.
Within the mod3 each meshpart has a different blocktype which determines the binary structure of the vertices. In Monster Hunter World in particular there are 14 vertex buffer types. For the most part the Vertex Buffer Name is descriptive enough of the properties the type has on top of of the usual geometry header.
Vertex Types
Blocktype Hash | Vertex Buffer Name | Weight Type |
---|---|---|
a756f2f9 | IANonSkin1UV | None |
a5104ca0 | IANonSkin2UV | None |
c3ac03a1 | IANonSkin3UVColor | None |
c9690ab8 | IANonSkin4UVColor | None |
818904dc | IANonSkin1UVColor | None |
f06033f | IANonSkin2UVColor | None |
f637401c | IASkin4wt1UV | 3x10bit Weights + ComplementWeight |
f471fe45 | IASkin4wt2UV | 3x10bit Weights + ComplementWeight |
3c730760 | IASkin4wt1UVColor | 3x10bit Weights + ComplementWeight |
b2fc0083 | IASkin4wt2UVColor | 3x10bit Weights + ComplementWeight |
81f58067 | IASkin8wt1UV | 3x10bit Weights + 4x8bit Weights + ComplementWeight |
83b33e3e | IASkin8wt2UV | 3x10bit Weights + 4x8bit Weights + ComplementWeight |
366995a7 | IASkin8wt1UVColor | 3x10bit Weights + 4x8bit Weights + ComplementWeight |
b8e69244 | IASkin8wt2UVColor | 3x10bit Weights + 4x8bit Weights + ComplementWeight |
Component Types When present components occur in the order listed here.
Property | C Type |
---|---|
Geometry | |
Position | float[3] |
Normal | byte[4] |
Tangent | byte[4] |
UV | halffloat[2] |
Weights | |
3x10bitWeights | UInt32 |
4x8bitWeights | UInt32 |
BoneIDs | |
BoneIDs(4 Weight) | UByte[4] |
BoneIDs(8 Weight) | UByte[8] |
Extra | |
Colour | ubyte[4] |
While the weight is stored as a UInt32 according to the shader, the underlying structure is more complex. 3x10bit Weights are 3 10bit unsigned values that have to be normalized by dividing by 2^9-1. 4x8bit Weights are 4 8bit unsigned values that have to be normalized by dividing by 2^7-1. The "remaining" weight for n=4 and n=8 is 1-sum(weight[i] for i in [0,n-1)). This "weight" can be negative.
For each weight there's a corresponding bone id. A vertex can have repeated bone ids. In this cases it appears that the way animations operate is by adding the weights assigned to one bone but this is not confirmed through reverse engineering of code but simply model experimentation. Additionally negative weights animate as such and are used by some of the game models.
The astute reader might notice that there's 2 "unused" bits on the 3x10bit Weights. Of the game's 5002 models, 2 models have non-null bits on this 2 bits: a Xeno'Jiiva model that's not the monster's model but a stage asset and Zorah Magadaros Carapace which corresponds to map geometry.
This bizarre 2-bits and the repeated structure of weights means that importing it to a 3d modelling program (and exporting) results in loss of data unless "non-traditional" structures are used for the import/export process.
As a final coup de grace to the bizarre hellscape that weights represent in the mod3 format, the order in which the weights are listed within the vertex structure is relevant to animations for specific models (at the time only Geralt's model is known to suffer from this). This goes beyond the negative additional weight but also on the "normal" weights.
For GPU rendering optimization purposes meshes are ordered by Vertex Buffer block size. As a result meshes with equal block size are lumped together and their vertex and face arrays can be processed with fixed size buffers applied to the biggest amount of entries. To account for this structure each meshpart header stores 3 different variables: Vertex Base, Sub and Offset. Vertex Base and Sub are vertex counts while offset is a binary offset. Vertex Sub is the sum of vertices of the same blocksize up to the current meshpart. If Vertex Sub plus the current meshpart vertex count would exceed 2^16 VertexSub is instead reset to 0 and VertexBase is added the previous VertexSub.
When there's a change of blocksize VertexBase and VertexSub are added up, multiplied by the previous blocksize and added to VertexOffset and Sub and Base are reset to 0.
Additionally Faces are relative to the start of the current VertexSub block. As a result to get a mapping of face indices to current meshpart indices it's necessary to substract the meshpart VertexSub from each face's vertex indices.
Each bone on the armature has a fixed struct.
Property | C Type |
---|---|
boneTableId | short |
parentId | ubyte |
symmetricPairID | ubyte |
unkn2 | float |
length | float |
position | float[3] |
boneTableId corresponds to a 1 to 1 mapping with the remap table entries. So if remap entry 22 is bone 15, bone 15 will have boneTableId 22. The remap table is the one that determines animations and the boneTableId appears to help with reference optimization but not be actually necessary for changes on the bone table to take effect.
The symmetric pair links one bone as the opposite to another through a symmetry plane (Right and Left hands for example).
After the section composed of bones follows the LMatrices and AMatrices. For every bone there's an LMatrix and an AMatrix (LMatrix from Local Matrix and AMatrix from Absolute Matrix). LMatrix are sequentially stored and then followed by AMatrices (after both of them comes the BoneMap).
In MTFramework bones are really "Nodes" which is roughly equivalent to tail oriented bones (instead of head oriented bones like those used by engineering software and blender). The LMatrix it the Matrix corresponding to the transformation relative to the parent. The AMatrix is the inverse of the Absolute Matrix of the bone.
In modelling software the correct structure results in a natural importing operation. Dummies in 3dsmax and Empties in blender have a transform and matrix_local property respectively which can be directly assigned the respective LMatrix.
To calculate the AMatrices Imagine a chain of bones that starts with p0 and ends in pn (p{j-1} is the parent of p{j})
amatrix[p{j}] = lmatrix[p{j}].inverted() * amatrix[p{j-1}]
Yields the correct value (within floating point error).
To show this is the inverse of the absolute coordinates it suffices to know unparented bones have an AMatrix of Identity and derive as follows.
amatrix[p{j}] = lmatrix[p{j}].inverted() * lmatrix[p{j-1}].inverted() * amatrix[p{j-2}]
amatrix[p{j}] = lmatrix[p{j}].inverted() *...* lmatrix[p{j{0}].inverted() * amatrix[p{0}]
amatrix[p{0}] is always the identity
amatrix[p{j}] = lmatrix[p{j}].inverted() *...* lmatrix[p{j{0}].inverted()
amatrix[p{j}].inverted() = lmatrix[p{j{0}] *...* lmatrix[p{j}]
which means that the inverse of the absolute matrix is the product of all local matrices. In other words the inverse of the world matrix gives you the absolute position of the node.
Used by the game for controlling miscellaneous details. Nekotaga Yuhatora found out Nergigante projectile spikes are based on his model's UnknGroupStuff values, similar parameters might be contained on this section for different monsters.
General Tutorials
Animation Tutorials
Audio Tutorials
File & In Game IDs
- Accessory and Specialized Tool IDs (Asset)
- Armor IDs (Asset)
- Decorations IDs
- EFX IDs
- Endemic Critter IDs (Asset)
- Face IDs (Asset)
- Furniture IDs (Asset)
- Gimmick IDs (Asset)
- Hairstyle IDs (Asset)
- Item IDs
- LMT IDs
- Material IDs
- Medal IDs
- Model Bone Function IDs
- Monster IDs
- Monster Shell IDs (A-P)
- Monster Shell IDs (Q-Z)
- NPC IDs (Asset)
- NPC Base Model (Asset)
- Palico Equipment IDs (Asset)
- Pendant IDs (Asset)
- Poogie Clothes IDs
- Quest IDs
- Skill IDs
- Stage IDs (Asset)
- Player Weapon Action IDs
- Weapon IDs (Asset)
- Weapon ID Dump (GS,SnS,DB)
- Weapon ID Dump (LS,Ham,HH)
- Weapon ID Dump (Lan,GL)
- Weapon ID Dump (SA,CB)
- Weapon ID Dump (Bow,HBG,LBG)
Model Tutorials
- Quick Guide to Importing Models (Blender 2.79)
- Walkthrough of a Weapon Import
- Basics of Exporting Into the .mod3 Format
- How To Fix UVs Sharing a Seam
- How To Separate Mesh Parts in Blender
- Rotating, Moving and Resizing in Blender
- How to Split a Single Mesh Outfit into Player Equippable Parts
- Jigglebone Chains (.ctc) and Colliders (.ccl)
- Axial CTC Rotations
- Editing Hair Models and Materials
- Useful Blender Scripts
- [external page] How to Make All Polygons Into Triangles (Required for MHW models)
- [external page] How to Convert Triangles Back Into Quads
- [external page] How to Change The View-port clipping Parameters For Large Models
- [external page] How to Set Origin to Vertex in Edit Mode
- [external page] Shortcut to repeat the last operation in Blender
- [external page] Transferring Rig Weights From One Mesh To Another
- [external page] How to Copy Paint Weights From One Object to Another
- [external page] How to Remove All Zero-Weight Vertex Groups
- [external page] How to Weight Paint Against Current Pose
- [external page] Making a Hair Rig
- [external page] Physics Transfer
EFX Tutorials
FSM Editing
MRL3 Tutorials
NPC Editing
Plugins and Memory Editing
Monster AI Editing
General Texture Tutorials
- Obtaining, Converting and Replacing Textures
- Textures with Paint NET
- How To Open DDS Files
- Editing Textures
- Understanding Alpha Channels
- Exporting Textures with Transparency
- How To Achieve Glass Texture
- How to create Crystal materials with Alpha Textures
- Working Around the Mip Map Loading Bug
- [external page] Extracting a UV Layout
Specific Texture Tutorials
Asterisk's Plugin Notes
Miscellaneous Tutorials
Outdated Tutorials
- How to Make an NPC Skin Material Support Skin Color Customization
- Plugin Comparison
- A Theoretical Proposal on Skeleton Extension
- Monster Hunter World Save Editor Tutorial
- Making Copies of a Save Slot
- Making a Green Screen
- Notes on CTC Physics Jiggle Files
- Opening MRL3 file with a template
- Transferring MRL3 Files Between Models
- Expanding mrl3 Reference List
- How to Edit Eye Color in mrl3 Files