Help & Tutorials => Model Tutorials => Topic started by: BlackJax96 on January 11, 2012, 07:55:16 PM
Title: The MDL0 Thread: Currently Under Construction
Post by: BlackJax96 on January 11, 2012, 07:55:16 PM
The Data Format
I will use spaces so that structures within structures can be defined. How to read: Structure Name (Total byte count): (Offset DataType) Name - Description Sub Structure Name (Total byte count):
Values that start with 0x are hex values, while values that lack 0x are regular decimal values. All offsets have a default base being the start of the structure unless specified otherwise.
int, uint & float are 4 bytes short & ushort are 2 bytes sbyte & byte are 1 byte
Unsigned (uint, ushort, byte) values cannot be negative. Signed values (int, float, short, sbyte) can.
A Vector2 is a group of 2 floats, which is 8 bytes. A Vector3 is a group of 3 floats, which is 12 bytes. A Matrix43 is a group of 12 floats, which is 48 bytes.
MDL0 Header: BRRES Common Header (0x10): (0x0 uint) Tag - 'MDL0' (0x4 int) Size (0x8 int) Version (0xC int) Brres Offset (0x10 int array) Offsets to data - Offsets vary by version. Each offset points to a resource group for the specified data type, which then offset to actual data entries.
MDL0 Properties (0x40): (0x0 uint) Length - always 0x40 (0x4 int) MDL0 Offset (0x8 int) Unknown 1 - usually 0 or 2 (0xC int) Unknown 2 - usually 0 (0x10 int) Number of Vertices (0x14 int) Number of Faces (0x18 int) Unknown 3 - usually 0 (0x1C int) Node Count - The number of influences this model has (0x20 short) Unknown 4 - usually 0x0101 or 0x0100 (0x22 short) Unknown 5 - usually 0 (0x24 uint) Data Offset - always 0x40, base is start of properties (0x28 Vector3) Minimum Extents (0x34 Vector3) Maximum Extents
Node/Influence Table: (0x0 int) Entry Count (0x4 int array) Entries If the influence has multiple bone weights, the value will be -1. If the influence is a single bone, the value will be that bone's index in the bone list.
Definitions:
The size of all definitions is aligned to 4 bytes.
NodeMix: This section defines weights for influences. There are two types of influences: - Single-bind influences: a single bone that influences vertices. - Regular influences: a group of bones that influence vertices. Bones that influence vertices are written first, then the influences are written. Bones that do not influence vertices are not written to NodeMix.
NodeTree (Bones count * 5): Stores bone tree information.
DrawOpa: Stores what objects are attached to each material and the visibility bones for each object. Materials that do not use Blend go in here. Data is written in the order of the materials.
DrawXlu: Stores what objects are attached to each material and the visibility bones for each object. Materials that do use Blend go in here. Data is written in the order of the materials.
Node Type 1 (0x1 - Used at the end of all definitions): (0x0 byte) Terminator - Ends the definition list.
Node Type 2 (0x5 - Used only in NodeTree): (0x0 byte) Entry Tag- Always 2 (0x1 ushort) Bone Index (0x3 ushort) Parent Bone Node Index
Node Type 3 (0x4 - Used only in NodeMix) - Used for regular influences containing multiple bones: (0x0 byte) Entry Tag- Always 3 (0x1 ushort) Influence Node Index (0x3 byte) Influence Weight Count - Used to read entries.
Node Type 3 Entry (0x6) - Stores bone weights. (0x0 ushort) Bone Node Index (0x2 float) Weight value - Ranges from 0.0 to 1.0.
Node Type 4 (0x8, Used only in DrawOpa & DrawXlu): (0x0 byte) Entry Tag- Always 4 (0x1 ushort) Material Index - The material that the object uses. (0x3 ushort) Object Index - The object to assign the bone and material to. (0x5 ushort) Bone Index - The bone for VIS0 object visibility control. (0x7 byte) Pad - Always 0
Node Type 5 (0x5 - Used only in NodeMix) - Used for single-bind bone influences: (0x0 byte) Entry Tag- Always 5 (0x1 ushort) Bone Node Index (0x3 ushort) Bone Index
Bones:
Bone Header: (0x00 int) Header Length (0x04 int) MDL0 Offset (0x08 int) String Offset (0x0C int) Index
(0x10 int) Node Id - Used for weighting. (0x14 uint) Flags - See flags specification below (0x18 uint) Pad 1 - Always 0 (0x1C uint) Pad 2 - Always 0
UVs Header: int _dataLen; //includes header/padding int _mdl0Offset; int _dataOffset; //0x40 int _stringOffset; int _index; int _isST; int _format; byte _divisor; byte _entryStride; ushort _numEntries; Vector2 _min; Vector2 _max; int _pad1, _pad2, _pad3, _pad4;
Colors Header: int _dataLen; //includes header/padding int _mdl0Offset; int _dataOffset; //0x20 int _stringOffset; int _index; int _isRGBA; int _format; byte _entryStride; byte _scale; ushort _numEntries;
Objects Header: (0x00 int) Total Length (0x04 int) MDL0 Offset (0x08 int) Node Id - Only used if all vertices in this object are bound to a single bone
(0x0C uint) CP Vertex Format Lo - Flags for reading vertex facepoints. See flag bitshifts below. (0x10 uint) CP Vertex Format Hi - Flags for reading vertex facepoints. See flag bitshifts below. (0x14 uint) XF Vertex Specs - Flags for normal format, color count and texture count. See flag bitshifts below.
(0x18 int) Def Size - Size of definitions block, including padding. Seems to always be 0xE0. (0x1C int) Def Flags - Usually 0x80, or 0xA0 on occasion (0x20 int) Def Offset - Relative to Def Size value
(0x24 int) Data Length 1 - Size of primitives, including padding at the end. (0x28 int) Data Length 2 - Size of primitives, including padding at the end. Seems to be the same as previous (0x2C int) Data Offset - Relative to either Data Length
(0x30 uint) XF Array Flags - Used to enable element arrays
(0x40 int) Facepoint (AKA vertex) Count (0x44 int) Face Count - Depends on primitives used
The following values link this object to asset arrays. Value is -1 if no array is used. The vertex set index should never be -1 unless using Direct primitives.
(0x48 short) Vertex Set ID - Links object to vertex array. (0x4A short) Normal Set ID - Links object to normal array. (0x4C short) Color Set ID 1 - Links object to primary color array. (0x4E short) Color Set ID 2 - Links object to secondary color array. (0x50 short) UV Set ID 1 - Links object to a UV array. (0x52 short) UV Set ID 2 - Links object to a UV array. (0x54 short) UV Set ID 3 - Links object to a UV array. (0x56 short) UV Set ID 4 - Links object to a UV array. (0x58 short) UV Set ID 5 - Links object to a UV array. (0x5A short) UV Set ID 6 - Links object to a UV array. (0x5C short) UV Set ID 7 - Links object to a UV array. (0x5E short) UV Set ID 8 - Links object to a UV array.
(0x60 int) Unknown - This value is not found in version 9 MDL0s! (0x64 int) Node Table Offset
Node Table: This section lists out all the influences this object uses. If this object is single-bound to a bone, there is no node table and the data length is aligned to 0x20. (0x0 uint) Entry Count (0x0 ushort array) Node Index Entries
How weighting works (sort of an old explanation, I'll rewrite it later): Each object has a vertex node with vertices. Each vertex has an influence, which is either a "hidden" influence or a "bone" influence.
Each bone and hidden influence has a node id. Bone and hidden influences are added to an array called "NodeCache" in the location specified by their nodeId. The NodeCache's size is specified by the nodeCount before the start of the node table at the beginning of the MDL0 (although sometimes it is incorrect for models that aren't v9, so it's safer to correct its size by the highest node id of one of the bones).
Hidden influences have weights, and each weight references its own bone so that the vertices move how you want them to. Bone influences literally make the vertex follow it with a weight of 1.0.
All of the influences, hidden and bone, are stored in the NodeMix.
Type 5 nodes are for bone influences. Type 3 nodes are for hidden influences. This type has entries for each weight.
As you read these, you add the hidden or bone influence to the NodeCache in the location specified by the node id. Once you finish, the NodeCache should be fully populated with hidden or bone influences. We will use this array later to assign the influences to the vertices.
Now when you read the primitives of each object, 0x20 holds the node id that the facepoints will get the influence from.
A 0x20 Matrix is 5 bytes long and is read like this: 1 byte: 0x20 2 bytes (unsigned short): node id 2 bytes (unsigned short): index multiplied by 12 (0x0C)
0x20 matrices can only go up to 9 in count, and then afterwards follows all the facepoints that use one of the 9 node ids in the list above. When you read the vertex id from the facepoint, you create a new vertex by getting its value from the vertex node assigned to that object at the location of the index and then adding it to a new list of vertices, and then give it an influence by reading the pos/norm matrix id.
The pos/norm matrix id is always the first byte of a facepoint if the object is weighted, and it is an index in the 0x20 matrices that is multiplied by 3.
So, to match up a vertex to its influence, you divide the facepoint's pos/norm matrix id by 3 and then match it with one of the 0x20 matrices' indexes divided by 12. You get the node id of the matched matrix and then retrieve the influence from the NodeCache from the location of the node id.
Sometimes facepoints are repeated (like in triangles) so you need to check the new list of vertices if the vertex exists already, and then edit the index to match that vertex instead. This doesn't matter if you're writing the model though.
Materials:
Materials Header: public bint _dataLen; public bint _mdl0Offset; public bint _stringOffset; public bint _index; public buint _isXLU; //0x00 or 0x80000000 for XLU textures public byte _numTexGens; public byte _numLightChans; public byte _activeTEVStages; public byte _numIndTexStages; public bint _cull; //0x02, XLU = 0 public byte _enableAlphaTest; public byte _lightSet; public byte _fogSet; public byte _flag3; public bint _unk1; public bint _unk2; //-1 public bint _shaderOffset; public bint _numTextures; public bint _matRefOffset; //1044, or 1048 for v11 & v10 MDL0 public bint _part2Offset; public bint _dlOffset; //Offset to display list(s). 0 for v11 & v10 public bint _unk3; //0, used as display list offset for v11 & v10
Texture Reference Header: public bint _stringOffset; public bint _secondaryOffset; public bint _unk2; public bint _unk3; public bint _index1; public bint _index2; public bint _uWrap; public bint _vWrap; public bint _minFltr; public bint _magFltr; public bfloat _lodBias; public bint _unk10; public bint _unk11;
Material Texture Settings: public buint LayerFlags; public buint UnkFlags;
public TextureFlags Tex1Flags; public TextureFlags Tex2Flags; public TextureFlags Tex3Flags; public TextureFlags Tex4Flags; public TextureFlags Tex5Flags; public TextureFlags Tex6Flags; public TextureFlags Tex7Flags; public TextureFlags Tex8Flags;
public TextureMatrix Tex1Matrices; public TextureMatrix Tex2Matrices; public TextureMatrix Tex3Matrices; public TextureMatrix Tex4Matrices; public TextureMatrix Tex5Matrices; public TextureMatrix Tex6Matrices; public TextureMatrix Tex7Matrices; public TextureMatrix Tex8Matrices;
Texture Flags Struct: public BVec2 TexScale; public bfloat TexRotation; public BVec2 TexTranslation;
Texture Matrix Struct: public sbyte TexUnk1; public sbyte TexUnk2; public sbyte TexUnk3; public sbyte TexUnk4; public bMatrix43 TexMtx;
Material Pixels Struct: public RGBAPixel c00; public RGBAPixel c01; public RGBAPixel c02; public RGBAPixel c03; public RGBAPixel c04;
public RGBAPixel c10; public RGBAPixel c11; public RGBAPixel c12; public RGBAPixel c13; public RGBAPixel c14;
Shaders:
Header: int _dataLength; //Always 512 int _mdl0Offset; int _index; byte _flag; //Same as material byte _res0, _res1, _res2; //Always 0 sbyte _ref0, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7; int _pad0, _pad1; //Always 0
BP Command: BPMemory Mem - This is a single byte. Int24 Data - This is a group of 3 bytes that forms an integer value. Depending on the BP Memory command, this value contains multiple binary values for the command. Bit shifts for shader BP commands are shown below.
Texture Reference Entry: (0x0 int) Material Offset (0x4 int) Material Reference Offset
Palettes:
Palette Entry: (0x0 int) Reference Count
Palette Reference Entry: (0x0 int) Material Offset (0x4 int) Material Reference Offset
Title: Re: The MDL0 Thread: Currently Under Construction
Post by: BlackJax96 on January 11, 2012, 07:55:24 PM
Materials
Header Values:
Alpha Function/Test:
Blend Mode:
Z Mode / Depth Test:
Color Values:
Texture References
Header Values:
Miscellaneous:
Texture Coordinates:
Texture Matrix:
XF Commands:
Title: Re: The MDL0 Thread: Currently Under Construction
Post by: BlackJax96 on January 11, 2012, 07:55:32 PM
Shaders
KSel Swap Table: There are 4 RGBA swap groups in the table. AlphaTextureSwap and AlphaRasterSwap in a tev stage will manipulate the input colors from the texture and color node by swapping each value with the value specified in the table for the selected swap.
IREF Indirect Texture References: There can be up to 4 indirect texture stages. They use the map and coordinates specified here.
Header Values:
Stages: This specifies how many stages the Wii needs to read. The maximum amount of stages allowed is 16. Stages are read in the order they appear, so the order of them does matter.
Res 0 - 2: I'm not sure what these do, they're always 0...
Texture Reference 0 - 7: This sets which texture references are allowed to be read by the shader.
Stage Settings: Each stage has 5 groups of data: KSel - Controls material color inputs. TRef - Controls texture and raster color inputs. ColorEnv - Controls final color output. Seperate from alpha output. AlphaEnv - Controls final alpha output. Seperate from color output. CMD Ind Tex - Controls indirect texture settings. Only up to 4 stages can use this.
KSel:
These selections take a color from the material's Konstant TEV Block at the specified index. Konstant Color Selection:
Constant1_1 - 1.0 constant for all RGB Constant7_8 - 0.875 constant for all RGB Constant3_4 - 0.75 constant for all RGB Constant5_8 - 0.625 constant for all RGB Constant1_2 - 0.5 constant for all RGB Constant3_8 - 0.375 constant for all RGB Constant1_4 - 0.25 constant for all RGB Constant1_8 - 0.125 constant for all RGB
KSel_0_Value - output RGB from color register 0 KSel_1_Value - output RGB from color register 1 KSel_2_Value - output RGB from color register 2 KSel_3_Value - output RGB from color register 3 KSel_0_Red - output RRR from color register 0 KSel_1_Red - output RRR from color register 1 KSel_2_Red - output RRR from color register 2 KSel_3_Red - output RRR from color register 3 KSel_0_Green - output GGG from color register 0 KSel_1_Green - output GGG from color register 1 KSel_2_Green - output GGG from color register 2 KSel_3_Green - output GGG from color register 3 KSel_0_Blue - output BBB from color register 0 KSel_1_Blue - output BBB from color register 1 KSel_2_Blue - output BBB from color register 2 KSel_3_Blue - output BBB from color register 3 KSel_0_Alpha - output AAA from color register 0 KSel_1_Alpha - output AAA from color register 1 KSel_2_Alpha - output AAA from color register 2 KSel_3_Alpha - output AAA from color register 3
Konstant Alpha Selection: All output RGB values are set to the input value's alpha value.
Constant1_1 - 1.0 constant for all RGB Constant7_8 - 0.875 constant for all RGB Constant3_4 - 0.75 constant for all RGB Constant5_8 - 0.625 constant for all RGB Constant1_2 - 0.5 constant for all RGB Constant3_8 - 0.375 constant for all RGB Constant1_4 - 0.25 constant for all RGB Constant1_8 - 0.125 constant for all RGB
KSel_0_Red - output RRR from alpha register 0 KSel_1_Red - output RRR from alpha register 1 KSel_2_Red - output RRR from alpha register 2 KSel_3_Red - output RRR from alpha register 3 KSel_0_Green - output GGG from alpha register 0 KSel_1_Green - output GGG from alpha register 1 KSel_2_Green - output GGG from alpha register 2 KSel_3_Green - output GGG from alpha register 3 KSel_0_Blue - output BBB from alpha register 0 KSel_1_Blue - output BBB from alpha register 1 KSel_2_Blue - output BBB from alpha register 2 KSel_3_Blue - output BBB from alpha register 3 KSel_0_Alpha - output AAA from alpha register 0 KSel_1_Alpha - output AAA from alpha register 1 KSel_2_Alpha - output AAA from alpha register 2 KSel_3_Alpha - output AAA from alpha register 3
TRef: This controls what texture references are affected by the settings in the stage(s). Up to two textures can be affected in each structure, as specified here. If no texture is referenced, then usually a rasterized stage will be generated with no texture, which is usually used to add overlay affects to textures specified in previous stages (such as a darkening/brightening stage, etc).
This texture is affected by the first stage in the structure. Texture Map Id: The index of the texture reference to be used for texture colors.
Texture Coordinate: The texture coordinate index for the texture reference.
Texture Enabled: Determines whether a texture should be modified or not.
Color Channel: ColorChannel0 = 0 - Assigns the raster selection to color node 0. ColorChannel1 = 1 - Assigns the raster selection to color node 1. BumpAlpha = 5 - Indirect texture bump alpha NormalizedBumpAlpha = 6 - Indirect texture bump alpha, normalized 0-255 Zero = 7 - Sets the color value to 0.
ColorEnv:
Selection A: An RGB value with unsigned 8-bit values. (0 <= a <= 255) Selection B: An RGB value with unsigned 8-bit values. (0 <= b <= 255) Selection C: An RGB value with unsigned 8-bit values. (0 <= c <= 255) Selection D: An RGB value with signed 10-bit values. (-1024 <= d <= 1023)
Color Selection Values: PreviousColor - Takes the previous outputted register color from the last stage. PreviousAlpha - Takes the previous outputted register alpha from the last stage. Color0 - Takes the outputted register color 0 from the last stage. Alpha0 - Takes the outputted register alpha 0 from the last stage. Color1 - Takes the outputted register color 1 from the last stage. Alpha1 - Takes the outputted register alpha 1 from the last stage. Color2 - Takes the outputted register color 2 from the last stage. Alpha2 - Takes the outputted register alpha 2 from the last stage. TextureColor - Takes the color from the assigned texture map. TextureAlpha - Takes the alpha from the assigned texture map. RasterColor - Takes the color from the assigned color channel. RasterAlpha - Takes the alpha from the assigned color channel. One - 1.0 constant. Half - 0.5 constant. KonstantColorSelection - The assigned konstant color selection value. Zero - 0.0 constant.
Bias: Adds, 0.5, subtracts 0.5, or adds nothing to the final RGB values.
Subtract: Determines whether d will be subtracted from or added to.
Clamp: Clamps the final RGB values from 0.0 to 1.0. (1.0 being the same as 255)
Shift: Scales the final value. MultiplyBy1 Multiplies by 1 MultiplyBy2 Multiplies by 2 MultiplyBy4 Multiplies by 4 DivideBy2 Multiplies by 1/2
For output calculation, all input values are converted to decimal by dividing by 255. The color value for this stage is calculated like this: destination register = (d ± ((1 - c) * a + c * b) + bias) * scale
AlphaEnv:
Raster Swap: Swaps raster color values using the shader's KSel Swap Table. Texture Swap: Swaps texture color values using the shader's KSel Swap Table.
Different combinations of these selections seem to do different things. They specify where to get the RGB alpha from. Selection A: An RGB value with unsigned 8-bit values. (0 <= a <= 255) Selection B: An RGB value with unsigned 8-bit values. (0 <= b <= 255) Selection C: An RGB value with unsigned 8-bit values. (0 <= c <= 255) Selection D: An RGB value with signed 10-bit values. (-1024 <= d <= 1023)
Alpha Selection Values: PreviousAlpha - Alpha from the previous register. Alpha0 - Alpha from register 0. Alpha1 - Alpha from register 1. Alpha2 - Alpha from register 2. TextureAlpha - Alpha from the texture. RasterAlpha - Alpha from the color channel. KonstantAlphaSelection - Alpha from the konstant alpha selection. Zero - 0 constant.
Bias: Adds, 0.5, subtracts 0.5, or adds nothing to the final RGB values.
Subtract: Determines whether d will be subtracted from or added to.
Clamp: Clamps the final RGB values from 0.0 to 1.0. (1.0 being the same as 255)
Shift: Scales the final value. MultiplyBy1 Multiplies by 1 MultiplyBy2 Multiplies by 2 MultiplyBy4 Multiplies by 4 DivideBy2 Multiplies by 1/2
For output calculation, all input values are converted to decimal by dividing by 255. The alpha value for this stage is calculated like this: destination register = (d ± ((1 - c) * a + c * b) + bias) * scale
CMD Indirect Texture:
If the raw value is 0, the stage is a direct texture.
Texture Stage: Index of the Indirect texture being bound.
Texture Format: Format of indirect texture offsets.
Bias: Bias added to the texture offsets.
Alpha: Selects indirect texture alpha output.
Matrix: Selects texture offset matrix.
S Wrap: Wrap value of Direct S coordinate.
T Wrap: Wrap value of Direct T coordinate.
Use Previous Stage: Add output from previous stage to texture coords.
Unmodified Level Of Detail: Use the unmodified texture coordinates for LOD.
Title: Re: The MDL0 Thread: Currently Under Construction
Post by: BlackJax96 on January 11, 2012, 07:55:38 PM
Reserved for whatever else
Title: Re: The MDL0 Thread: Currently Under Construction
Post by: BlackJax96 on January 11, 2012, 09:40:27 PM
Reserved another spot, just in case. You never know :P
Title: Re: The MDL0 Thread: Currently Under Construction
Post by: Xiggah on February 10, 2012, 03:17:22 AM
You know what.... I'm bumping this.
Title: Re: The MDL0 Thread: Currently Under Construction
Post by: BlackJax96 on February 10, 2012, 08:10:07 PM