Contents

 

Mesh File Format

Created: 2008/08/26 23:08:46 CDT
Last Updated: 2009/12/11 16:46:51 CST

 

Introduction

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.

Tools

Here are some self-written programs that I use for working with meshes (source code is included -- do whatever you want with it). This method is just barely more friendly than hex editing, so don't expect much.

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:

Mesh2CSV input.msh output.csv
Will read "input.msh" and create "output.csv".
Mesh2CSV input.msh output.csv output.tga 512 1024
Will read "input.msh" and create "output.csv" along with "output.tga" with width 512 and height 1024.
CSV2Mesh output.msh input.csv
Will read "input.csv" and create "output.msh".
CSV2Mesh output.msh input1.csv input2.csv [etc]
Will read each input specified in order to create "output.msh". Each file must start and end on an exact section break.
 

Header

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

 

Section 0 - MIF location (Material Information File)

Breakdown
  • First four bytes: total size of string
  • Remaining bytes: ASCII string
Example
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 
Explanation

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").

 

Section 3 - Plain text data

Example
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... 
Explanation

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.

 

Section 4 - Vertices

Section Breakdown
  • First four bytes: Number of integer values preceding the vertex data
  • Second four bytes: Size of a single vertex data entry in bytes
  • Third four bytes: Total number of vertices
  • Remaining bytes: Vertex data
Vertex Breakdown
  • Three floats for the 3D X, Y, and Z position
  • Two floats for the 2D X and Y texture position, expressed as a percentage.
  • Three more floats (unknown usage)
  • Four bytes (unknown usage; not the right format for a float)
  • Four more floats (unknown usage)
  • Six more floats (unknown usage)
Example
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 
Explanation

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.

Section 5 - Triangles

Section Breakdown
  • First four bytes: The total number of triangles
  • Second four bytes: The number of draw calls
  • Remaining bytes: Triangle definitions followed by draw call definitions
Triangle Breakdown
  • First two bytes: First vertex index
  • Second two bytes: Second vertex index
  • Third two bytes: Third vertex index
Draw Call Breakdown
  • First four bytes: Unknown usage
  • Second four bytes: First triangle to draw
  • Third four bytes: Total number of triangles to draw
  • Fourth four bytes: Unknown usage
  • Next 24 bytes: Six floating point values (unknown usage)
  • Next four bytes: The number of integer values before the next draw call (or end of data)
  • Remaining bytes: Integer values (unknown usage)
Example
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... 
Explanation

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.

Section 6 - Bones

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.

Section 8 - Attributes

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.

Section 10 - 3D Extents

Breakdown
Consists of 6 float values indicating X, Y, and Z minimums followed by X, Y, and Z maximums.
Example
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 
Explanation

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.

All Other Sections

Unknown at this time.

 

 

Post your comment

Please be aware that comments are subject to moderation and will not appear immediately.

Comments

  • 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 CST (7 months 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 CDT (1 year ago)

  • I released the 3D Object Converter v4.216 that supports the Titan Quest .msh file type.

    You can update your installed application (version>=4.0) quickly and easily using the auto-update function (Help/Check for updates…).

    http://web.t-online.hu/karpo

    Posted by Zoltan Karpati, 2008/12/21 11:14:21 CST (2 years ago)

  • Nice article, thanks for the downloads. In vertex breakdown, the "Three more floats (unknown usage)" may well be normals, although this is only a guess. I will extend your code & see what I come up with.

    Posted by Matt, 2008/10/31 03:37:30 CDT (2 years ago)