|
|
« on: January 11, 2012, 07:55:16 PM » |
|
The Data FormatI 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. v08: Definitions, Bones, Vertices, Normals, Colors, UVs, Materials, Shaders, Objects, None, Textures, None, None v09: Definitions, Bones, Vertices, Normals, Colors, UVs, Materials, Shaders, Objects, Textures, Palettes v10: Definitions, Bones, Vertices, Normals, Colors, UVs, None, None, Materials, Shaders, Objects, Textures, Palettes, None, None v11: Definitions, Bones, Vertices, Normals, Colors, UVs, None, None, Materials, Shaders, Objects, Textures, None, None ((0x10 + Offset count * 4) int) String Offset Resource Group: How to generate a resource entry: 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: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 (0x20 Vector3) Scale (0x2C Vector3) Rotation (0x38 Vector3) Translation (0x44 Vector3) Minimum Box (0x50 Vector3) Maximum Box (0x5C int) Parent Bone Offset (0x60 int) First Child Bone Offset (0x64 int) Next Bone Offset (0x68 int) Previous Bone Offset (0x6C int) Part 2 Offset (0x70 Matrix43) Transform Matrix (0xA0 Matrix43) Inverse Transform Matrix Bone Flags: Vertex Data:Normal Data:UV Data:Color Data:Objects: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 (0x34 int) Unknown - Always 0 (0x38 int) String Offset (0x3C int) Index (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 Definitions: Primitives: Flag bit shifts: How to read: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: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 Structure: byte BPReg1; //0x61 BPCommand command1; byte BPReg2; //0x61 BPCommand command2; byte BPReg3; //0x61 BPCommand command3; byte BPReg4; //0x61 BPCommand command4; byte BPReg5; //0x61 or 0 BPCommand command5; byte BPReg6; //0x61 BPCommand command6; byte BPReg7; //0x61 or 0 BPCommand command7; byte BPReg8; //0x61 BPCommand command8; byte BPReg9; //0x61 or 0 BPCommand command9; 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. BP Memory Values: BPMEM_GENMODE = 0x00,
BPMEM_DISPLAYCOPYFILER0 = 0x01, BPMEM_DISPLAYCOPYFILER1 = 0x02, BPMEM_DISPLAYCOPYFILER2 = 0x03, BPMEM_DISPLAYCOPYFILER3 = 0x04, BPMEM_DISPLAYCOPYFILER4 = 0x05,
BPMEM_IND_MTXA0 = 0x06, BPMEM_IND_MTXB0 = 0x07, BPMEM_IND_MTXC0 = 0x08, BPMEM_IND_MTXA1 = 0x09, BPMEM_IND_MTXB1 = 0x0A, BPMEM_IND_MTXC1 = 0x0B, BPMEM_IND_MTXA2 = 0x0C, BPMEM_IND_MTXB2 = 0x0D, BPMEM_IND_MTXC2 = 0x0E, BPMEM_IND_IMASK = 0x0F,
BPMEM_IND_CMD0 = 0x10, BPMEM_IND_CMD1 = 0x11, BPMEM_IND_CMD2 = 0x12, BPMEM_IND_CMD3 = 0x13, BPMEM_IND_CMD4 = 0x14, BPMEM_IND_CMD5 = 0x15, BPMEM_IND_CMD6 = 0x16, BPMEM_IND_CMD7 = 0x17, BPMEM_IND_CMD8 = 0x18, BPMEM_IND_CMD9 = 0x19, BPMEM_IND_CMDA = 0x1A, BPMEM_IND_CMDB = 0x1B, BPMEM_IND_CMDC = 0x1C, BPMEM_IND_CMDD = 0x1D, BPMEM_IND_CMDE = 0x1E, BPMEM_IND_CMDF = 0x1F,
BPMEM_SCISSORTL = 0x20, BPMEM_SCISSORBR = 0x21, BPMEM_LINEPTWIDTH = 0x22, BPMEM_PERF0_TRI = 0x23, BPMEM_PERF0_QUAD = 0x24,
BPMEM_RAS1_SS0 = 0x25, BPMEM_RAS1_SS1 = 0x26, BPMEM_IREF = 0x27,
BPMEM_TREF0 = 0x28, BPMEM_TREF1 = 0x29, BPMEM_TREF2 = 0x2A, BPMEM_TREF3 = 0x2B, BPMEM_TREF4 = 0x2C, BPMEM_TREF5 = 0x2D, BPMEM_TREF6 = 0x2E, BPMEM_TREF7 = 0x2F, BPMEM_SU_SSIZE0 = 0x30, BPMEM_SU_TSIZE0 = 0x31, BPMEM_SU_SSIZE1 = 0x32, BPMEM_SU_TSIZE1 = 0x33, BPMEM_SU_SSIZE2 = 0x34, BPMEM_SU_TSIZE2 = 0x35, BPMEM_SU_SSIZE3 = 0x36, BPMEM_SU_TSIZE3 = 0x37, BPMEM_SU_SSIZE4 = 0x38, BPMEM_SU_TSIZE4 = 0x39, BPMEM_SU_SSIZE5 = 0x3A, BPMEM_SU_TSIZE5 = 0x3B, BPMEM_SU_SSIZE6 = 0x3C, BPMEM_SU_TSIZE6 = 0x3D, BPMEM_SU_SSIZE7 = 0x3E, BPMEM_SU_TSIZE7 = 0x3F,
BPMEM_ZMODE = 0x40, BPMEM_BLENDMODE = 0x41, BPMEM_CONSTANTALPHA = 0x42, BPMEM_ZCOMPARE = 0x43, BPMEM_FIELDMASK = 0x44, BPMEM_SETDRAWDONE = 0x45, BPMEM_BUSCLOCK0 = 0x46, BPMEM_PE_TOKEN_ID = 0x47, BPMEM_PE_TOKEN_INT_ID = 0x48,
BPMEM_EFB_TL = 0x49, BPMEM_EFB_BR = 0x4A, BPMEM_EFB_ADDR = 0x4B,
BPMEM_MIPMAP_STRIDE = 0x4D, BPMEM_COPYYSCALE = 0x4E,
BPMEM_CLEAR_AR = 0x4F, BPMEM_CLEAR_GB = 0x50, BPMEM_CLEAR_Z = 0x51,
BPMEM_TRIGGER_EFB_COPY = 0x52, BPMEM_COPYFILTER0 = 0x53, BPMEM_COPYFILTER1 = 0x54, BPMEM_CLEARBBOX1 = 0x55, BPMEM_CLEARBBOX2 = 0x56,
BPMEM_UNKNOWN_57 = 0x57, BPMEM_REVBITS = 0x58, BPMEM_SCISSOROFFSET = 0x59,
BPMEM_UNKNOWN_60 = 0x60, BPMEM_UNKNOWN_61 = 0x61, BPMEM_UNKNOWN_62 = 0x62,
BPMEM_TEXMODESYNC = 0x63, BPMEM_LOADTLUT0 = 0x64, BPMEM_LOADTLUT1 = 0x65, BPMEM_TEXINVALIDATE = 0x66, BPMEM_PERF1 = 0x67, BPMEM_FIELDMODE = 0x68, BPMEM_BUSCLOCK1 = 0x69,
BPMEM_TX_SETMODE0_A = 0x80, BPMEM_TX_SETMODE0_B = 0x81, BPMEM_TX_SETMODE0_C = 0x82, BPMEM_TX_SETMODE0_D = 0x83, BPMEM_TX_SETMODE1_A = 0x84, BPMEM_TX_SETMODE1_B = 0x85, BPMEM_TX_SETMODE1_C = 0x86, BPMEM_TX_SETMODE1_D = 0x87,
BPMEM_TX_SETIMAGE0_A = 0x88, BPMEM_TX_SETIMAGE0_B = 0x89, BPMEM_TX_SETIMAGE0_C = 0x8A, BPMEM_TX_SETIMAGE0_D = 0x8B, BPMEM_TX_SETIMAGE1_A = 0x8C, BPMEM_TX_SETIMAGE1_B = 0x8D, BPMEM_TX_SETIMAGE1_C = 0x8E, BPMEM_TX_SETIMAGE1_D = 0x8F,
BPMEM_TX_SETIMAGE2_A = 0x90, BPMEM_TX_SETIMAGE2_B = 0x91, BPMEM_TX_SETIMAGE2_C = 0x92, BPMEM_TX_SETIMAGE2_D = 0x93,
BPMEM_TX_SETIMAGE3_A = 0x94, BPMEM_TX_SETIMAGE3_B = 0x95, BPMEM_TX_SETIMAGE3_C = 0x96, BPMEM_TX_SETIMAGE3_D = 0x97,
BPMEM_TX_SETTLUT_A = 0x98, BPMEM_TX_SETTLUT_B = 0x99, BPMEM_TX_SETTLUT_C = 0x9A, BPMEM_TX_SETTLUT_D = 0x9B,
BPMEM_TX_SETMODE0_4_A = 0xA0, BPMEM_TX_SETMODE0_4_B = 0xA1, BPMEM_TX_SETMODE0_4_C = 0xA2, BPMEM_TX_SETMODE0_4_D = 0xA3,
BPMEM_TX_SETMODE1_4_A = 0xA4, BPMEM_TX_SETMODE1_4_B = 0xA5, BPMEM_TX_SETMODE1_4_C = 0xA6, BPMEM_TX_SETMODE1_4_D = 0xA7,
BPMEM_TX_SETIMAGE0_4_A = 0xA8, BPMEM_TX_SETIMAGE0_4_B = 0xA9, BPMEM_TX_SETIMAGE0_4_C = 0xAA, BPMEM_TX_SETIMAGE0_4_D = 0xAB,
BPMEM_TX_SETIMAGE1_4_A = 0xAC, BPMEM_TX_SETIMAGE1_4_B = 0xAD, BPMEM_TX_SETIMAGE1_4_C = 0xAE, BPMEM_TX_SETIMAGE1_4_D = 0xAF,
BPMEM_TX_SETIMAGE2_4_A = 0xB0, BPMEM_TX_SETIMAGE2_4_B = 0xB1, BPMEM_TX_SETIMAGE2_4_C = 0xB2, BPMEM_TX_SETIMAGE2_4_D = 0xB3,
BPMEM_TX_SETIMAGE3_4_A = 0xB4, BPMEM_TX_SETIMAGE3_4_B = 0xB5, BPMEM_TX_SETIMAGE3_4_C = 0xB6, BPMEM_TX_SETIMAGE3_4_D = 0xB7,
BPMEM_TX_SETLUT_4_A = 0xB8, BPMEM_TX_SETLUT_4_B = 0xB9, BPMEM_TX_SETLUT_4_C = 0xBA, BPMEM_TX_SETLUT_4_D = 0xBB,
BPMEM_UNKNOWN_BC = 0xBC, BPMEM_UNKNOWN_BB = 0xBB, BPMEM_UNKNOWN_BD = 0xBD, BPMEM_UNKNOWN_BE = 0xBE, BPMEM_UNKNOWN_BF = 0xBF,
BPMEM_TEV_COLOR_ENV_0 = 0xC0, BPMEM_TEV_ALPHA_ENV_0 = 0xC1, BPMEM_TEV_COLOR_ENV_1 = 0xC2, BPMEM_TEV_ALPHA_ENV_1 = 0xC3, BPMEM_TEV_COLOR_ENV_2 = 0xC4, BPMEM_TEV_ALPHA_ENV_2 = 0xC5, BPMEM_TEV_COLOR_ENV_3 = 0xC6, BPMEM_TEV_ALPHA_ENV_3 = 0xC7, BPMEM_TEV_COLOR_ENV_4 = 0xC8, BPMEM_TEV_ALPHA_ENV_4 = 0xC9, BPMEM_TEV_COLOR_ENV_5 = 0xCA, BPMEM_TEV_ALPHA_ENV_5 = 0xCB, BPMEM_TEV_COLOR_ENV_6 = 0xCC, BPMEM_TEV_ALPHA_ENV_6 = 0xCD, BPMEM_TEV_COLOR_ENV_7 = 0xCE, BPMEM_TEV_ALPHA_ENV_7 = 0xCF, BPMEM_TEV_COLOR_ENV_8 = 0xD0, BPMEM_TEV_ALPHA_ENV_8 = 0xD1, BPMEM_TEV_COLOR_ENV_9 = 0xD2, BPMEM_TEV_ALPHA_ENV_9 = 0xD3, BPMEM_TEV_COLOR_ENV_A = 0xD4, BPMEM_TEV_ALPHA_ENV_A = 0xD5, BPMEM_TEV_COLOR_ENV_B = 0xD6, BPMEM_TEV_ALPHA_ENV_B = 0xD7, BPMEM_TEV_COLOR_ENV_C = 0xD8, BPMEM_TEV_ALPHA_ENV_C = 0xD9, BPMEM_TEV_COLOR_ENV_D = 0xDA, BPMEM_TEV_ALPHA_ENV_D = 0xDB, BPMEM_TEV_COLOR_ENV_E = 0xDC, BPMEM_TEV_ALPHA_ENV_E = 0xDD, BPMEM_TEV_COLOR_ENV_F = 0xDE, BPMEM_TEV_ALPHA_ENV_F = 0xDF,
BPMEM_TEV_REGISTER_L_0 = 0xE0, BPMEM_TEV_REGISTER_H_0 = 0xE1, BPMEM_TEV_REGISTER_L_1 = 0xE2, BPMEM_TEV_REGISTER_H_1 = 0xE3, BPMEM_TEV_REGISTER_L_2 = 0xE4, BPMEM_TEV_REGISTER_H_2 = 0xE5, BPMEM_TEV_REGISTER_L_3 = 0xE6, BPMEM_TEV_REGISTER_H_3 = 0xE7, BPMEM_TEV_FOG_RANGE = 0xE8, BPMEM_TEV_FOG_PARAM_0 = 0xEE, BPMEM_TEV_FOG_B_MAGNITUDE = 0xEF, BPMEM_TEV_FOG_B_EXPONENT = 0xF0, BPMEM_TEV_FOG_PARAM_3 = 0xF1, BPMEM_TEV_FOG_COLOR = 0xF2,
BPMEM_ALPHACOMPARE = 0xF3, BPMEM_BIAS = 0xF4, BPMEM_ZTEX2 = 0xF5,
BPMEM_TEV_KSEL0 = 0xF6, BPMEM_TEV_KSEL1 = 0xF7, BPMEM_TEV_KSEL2 = 0xF8, BPMEM_TEV_KSEL3 = 0xF9, BPMEM_TEV_KSEL4 = 0xFA, BPMEM_TEV_KSEL5 = 0xFB, BPMEM_TEV_KSEL6 = 0xFC, BPMEM_TEV_KSEL7 = 0xFD,
BPMEM_BP_MASK = 0xFE
ColorEnv Bit Shifts: AlphaEnv Bit Shifts: TRef Bit Shifts: KSel Bit Shifts: CMD Bit Shifts: Textures:
|