Created: 2008/08/26 23:08:46 EDT
Updated: 2009/12/11 16:46:51 EST
A tool set to work with .msh files in Titan Quest was never released. However, I have taken some time to investigate the format for some of my own modifications. Please note that this is a very incomplete work. I do not know all the details of the file format, but will share what I do know.
Mesh2CSV - This program will take a .msh file and convert it to a human readable .csv file. It can also optionally create a .tga file of the 2D texture mapping points. This can be overlayed onto an actual texture in order to visualize the actual triangles used in game.
CSV2Mesh - This program will take a .csv file (or multiple .csv files split by section) and construct a .msh file from them.
Warning: Do not re-save the .csv with a program like Microsoft Excel that expects every row to have the same number of columns or you will corrupt the file and be unable to translate back to a .msh.
These programs are command line only. They are NOT resilient and are probably quite prone to breaking. In particular, if a bad .csv file is used to create a mesh, it is quite likely that the program will simply go into an infinite loop and create a bigger and bigger file. If the CSV2Mesh does not complete within a few seconds, just hit CRTL+C or CTRL+BREAK to stop it.
The usage is as follows:
The file header is a single integer value 0x0B48534D (the letters "MSH" followed by a vertical tab).
After the header there are a number of sections denoted by a single integer, followed by the total byte size of the section. These sections appear to be optional and probably do not have to occur in any order; the game will read them if they are present. Information about the data inside each section follows
0x0000: 00 00 00 00 26 00 00 00 22 00 00 00 ; Integers 0, 38, 34
0x000C: 43 72 65 61 74 75 72 65 73 5C 50 43 5C 46 65 6D ; String "Creatures\PC\Fem
0x001C: 61 6C 65 5C 46 65 6D 61 6C 65 50 43 30 31 2E 6D ; String "ale\FemalePC01.m
0x002C: 69 66 ; String "if
FYI, this appears to be useless without the original tools used to create meshes.
In the example, the integers 0, 38 denote Section 0 of 38 total bytes. The integer 34 indicates a string of 34 characters ("Creatures\PC\Female\FemalePC01.mif").
0x0000: 03 00 00 00 3B 70 00 00 ; Integers 3, 28731
0x0008: 41 74 74 61 63 68 50 6F 69 6E 74 0D 0A 7B 0D 0A ; String "AttachPoint\r\n{\r\n
0x0018: 20 20 20 20 6E 61 6D 65 20 20 20 3D 20 22 4C 20 ; String " name = "L
0x0028: [...] Lots more...
The data in this block is ASCII and easily readable. Possibly just documentation.
In the example, the integers 3, 28731 denote Section 3 of 28731 total bytes.
0x0000: 04 00 00 00 34 CE 03 00 ; Integers 4, 249396
0x0008: 07 00 00 00 4C 00 00 00 D1 0C 00 00 ; Integers 7, 76, 3281
0x0014: 00 00 00 00 04 00 00 00 01 00 00 00 06 00 00 00 ; Integers 0, 4, 1, 6
0x0024: 05 00 00 00 02 00 00 00 03 00 00 00 ; Integers 5, 2, 3
0x0030: DE 86 31 BE 12 89 B3 3F 5C 82 1C BE ; Floats -0.17, 1.40, -0.15
0x003C: 2E AA 55 3F 8A E1 F0 3E ; Floats 0.83, 0.47
0x0044: C4 D3 2F BF BC 1B CD 3E B8 40 1B BF ; Floats -0.69, 0.40, -0.61
0x0050: 00 01 02 FF ; Bytes 0, 1, 2, 255
0x0054: CD CC CC 3E CD CC CC 3E CD CC 4C 3E 00 00 00 00 ; Floats 0.40, 0.40, 0.20, 0.00
0x0064: 4F 4E 34 3F D6 AD 24 3E 54 01 31 BF ; Floats 0.70, 0.16, -0.69
0x0070: 1D 15 8F 3E 28 72 6A 3F 35 B0 93 3E ; Floats 0.28, 0.92, 0.29
I do not know what the values marked "unknown usage" represent, though I suspect they are material and lighting information. I have broken them out into the groups listed above due to certain similarities. For example, the "four more floats" tends to be nice round values like 0, 0.25, and 0.5, while none of the others are ever particularly nice.
In the example, the integers 4, 249396 denote Section 4 of 249396 total bytes. There are 7 integers before the actual vertex data, each vertex data is 76 bytes, and there are 3281 total vertices. The 7 integers 0, 4, 1, 6, 5, 2, 3 come next, though I do not know what they represent.
In the example vertex, the point is located at -0.17 x 1.40 x -0.15 in 3D space. It is mapped to the 2D texture point located 83% from left to right and 47% from top to bottom. For example, given a 512x512 texture, this would be the point located at 425x241. What the rest of the data represents, I do not know.
0x0000: 05 00 00 00 AC 2E 00 00 ; Integers 5, 11948
0x0008: A2 07 00 00 02 00 00 00 ; Integers 1954, 2
0x0010: 02 00 01 00 00 00 05 00 04 00 03 00 ; Short Ints 2, 1, 0, 5, 4, 3
0x001D: [...] More...
0x2DDC: 00 00 00 00 00 00 00 00 2C 07 00 00 00 00 00 00 ; Integers 0, 0, 1836, 0
0x2DEC: D0 F2 F7 BD E7 DA 98 3F E0 E6 CC BB ; Floats -0.12, 1.19, -0.01
0x2DF8: DA 94 7A 3F AD 38 99 3F DF 65 59 3E ; Floats 0.98, 1.20, 0.21
0x2E04: 1A 00 00 00 ; Integer 26
0x2E08: 03 00 00 00 05 00 00 00 04 00 00 00 0E 00 00 00 ; Integers (26 in total)
0x2E18: [...] More...
In the example, the integers 5, 11948 denote Section 5 of 11948 total bytes. There are 1954 total triangles and 2 total draw calls.
In the triangle example, the first two triangles are shown. The first one connects vertices 2, 1, and 0, and the second connects 5, 4, and 3.
In the draw call example, the call will draw 1836 triangles starting at 0. Since there are 1954 total triangles and only 2 draw calls, it is likely that the next draw call will start with the 1837th triangle and draw the remaining 118 triangles. I do not know what the rest of the data is used for.
This section describes the bones, which are viewable using "Viewer.exe" supplied with TQ. I have not attempted to decipher this section at this time.
This section contains various name/value pairs including default texture information, shaders and parameters, and the like. I have not attempted to decipher this section at this time.
0x0000: 0A 00 00 00 18 00 00 00 ; Integers 10, 24
0x0008: 9A C9 8C BF 07 8E 3B BB 99 96 24 BF ; Floats -1.099902, -0.002862, -0.642923
0x0014: 99 C9 8C 3F CF D5 1A 40 79 1A 5D 3E ; Floats 1.099902, 2.419300, 0.215921
The size of this section should always be 24.
In the example, the integers 10, 28731 denote Section 10 of 24 total bytes. The values state that X coordinates will range between -1.1 and 1.1, the Y will range between 0 and 2.4, and the Z will range between -0.6 and 0.2.
Unknown at this time.
Please be aware that comments are subject to moderation and will not appear immediately.
The Skeleon Emitter given in section 3 does not appear to be used at all.
Some scenery meshes have a long Section 2 instead of Section 3 after the shader section. They don't use a MIF, and so have no need of Section 3. Section 2 contains a mix of integers and floats (probably vectors - they seem to be in multiples of 3.) No idea yet what info is in here - it doesn't seem critical to a simple import of the mesh and textures. HOWEVER, the texture coords for these verts don't seem to be normalized like creature meshes are. Some info for that may be hidden in here, or it may not matter if the textures are tiled. Haven't looked closely at this yet.
Also note: parsing Attach Points out of the MIF data is needed for some of the CallBacks in the .ANM files for creatures. Some of those (spawns and transformations mainly) are CreateEntity calls for attached FX, so if you want to use those in some way, you'll have to parse the AP's eventually.
I have Gmax scripts that do all this so far for importing into Dungeon Siege. They result in a completely boned and weighted mesh. I am currently testing the animation script, but import works (in most cases.) If you can script enough it would be simple to change to keep it more generic for possible import back into TQ. Dunno if we'll ever have enough info for that to be seamless, but I can send the script if you have a place to host it and are interested. Let me know (anybody!) at bjsmith72032 at hotmail dot com.
I'll keep updating here as I figure out more info. I want the meshes as intact as possible, but my final destination is Dungeon Siege 2, so that influences the final form of my tools, but most of the code is general if somebody is technical enough to modify it for their purposes.
Posted by Graagh, 2010/10/23 19:13:45 EDT (1 year ago)
Section 8 contains the Hit Box info, though I haven't deciphered it yet beyond the basics:
Integer: number of boxes
32-byte String: box name
15 floats: there's bound to be a position and rotation in there, but I can't figure out why you'd need the extra 3, unless instead of position it's a min/max. Haven't looked very closely at this one yet.
Integer: unknown
Posted by Graagh, 2010/10/18 11:00:43 EDT (1 year ago)
Section 3, the plain text data, is the contents of the MIF file given in Section 0. It contains definitions of all the Attach Points and attached Entities, Rigid Bodies, Joints, and sometimes a Skeleton Emitter. If you save the contents into the file name given in Section 0 in your data path, the Viewer (and I assume other TQ apps) will recognize all this data.
Posted by Graagh, 2010/10/18 10:38:15 EDT (1 year ago)
Section 7:
Integer: number of textures
Integer: length of shader name
ASCII String: shader name
Integer: number of parameters for this shader
all parameters in this format:
Integer: length of parameter name
ASCII String: parameter name
Integer: data type of parameter value - 7=string, 9=color, 10=float, possibly others I haven't seen
Type: parameter value - strings are integer length followed by string, colors are 3 floats (RGB), and floats are (obviously) a 4-byte float.
Posted by Graagh, 2010/10/18 10:35:10 EDT (1 year ago)
Additionally, since the first 4 bytes of the drawcall are the texture index, then for each vert that forms a corner of one of the triangles of this drawcall, its texture coordinates from Section 4 map into the referenced texture from Section 7 - the whole shader is referenced, but I just map to the filename given in the shader's "baseTexture" parameter. I guess I should explain section 7 next... :-)
Posted by Graagh, 2010/10/18 10:24:40 EDT (1 year ago)
More info on vert weighting:
In the drawcalls, the first 4 bytes are the index of the texture to use for this drawcall. The textures are given in Section 7 as a shader call and its associated parameters.
After the triangle data, all the drawcall data is given, and THEN the "Fourth 4 bytes unknown usage". It's not really the 4th word unless, as in this case, there's only one drawcall. There will be as many of these sections as there are drawcalls. If this initial word is 0, then it is followed by the 6 floats, otherwise the count and list of integers follows immediately. This is the number of bones, and the order of their indexes, for this drawcall. So in your example, there are 26 bones for the first drawcall, bone 0 is bone 3 from Section 6, bone 1 is bone 5 from Section 6, bone 2 is bone 4 from Section 6, etc. These indexes (NOT the ones from Section 6) correspond to the bone indexes given in the verts. So for each vert that makes a corner of one of the tris from this drawcall, if its bone indexes in Section 4 are 01 00 02 03, then the actual bones you would weight to from Section 6 are: 05 03 04 0E. Repeat for each draw call. Still no idea what the 6 floats are used for.
Posted by Graagh, 2010/10/18 10:18:28 EDT (1 year ago)
More research: The 8th component of the vert in the empusa mesh is not component number 7, but number 14. It appears to be a 4-byte vertex color stored as unsigned byte R, G, B, A values.
Posted by Graagh, 2010/09/19 23:00:51 EDT (1 year ago)
The problem you're having with verts is that they're not always in that format.
The "integer values preceding the data" are the components of the vert - generally non-boned meshes have 5 and boned have 7 (adding the bones and weights), and the empusa from IT has 8! The integers themselves give the layout of the vert data.
Component 0 = position
Component 1 = normal
Component 2,3 = unknown, but appear to be 3 floats each
Component 4 = tex coords
Component 5 = bone weights
Component 6 = bone indexes
Component 7 = unknown, haven't looked at this one yet
These components can be given in any order and appear in that order in the vert data - so it's not a fixed format...
I'm working on decoding the format as completely as I can. Reach me with any questions at bjsmith72032 at hotmail dot com
Posted by Graagh, 2010/09/19 22:24:00 EDT (1 year ago)
additional info about the vertices:
- the next 3 floats (after the 3 for position and 2 for tex coords) are the vertex normal - it is normalized: nx*nx + ny*ny + nz*nz = 1).
- the next 4 bytes are indexes of up-to 4 bones to which the vertex is attached and the following 3 floats are the corresponding attachment weights. Their sum is 1.
Note: bone index of 255 and/or attachment weight of 0 means no bone attachment; the format supports maximum 4 attachments per vertex, but can be less than that for each individual vertex.
Posted by shade, 2010/02/12 17:21:45 EST (2 years ago)
Section Bones
4 byte for number of bones.
A bone consists of:
32 byte for name
4 byte (integer) for index of child bone
4 byte (integer) for number of childs
3 * 3 floats for axis of the bone
3 floats for position of bone
I think that should work.
Posted by Nobsta, 2009/07/27 15:19:59 EDT (3 years ago)