MDL file format (FS9 scenery)
From FSDeveloper Wiki
This article describes the format of the Fs2004 scenery MDL (RIFF) objects (Also known as the MDL9 format). This is certainly not a complete description of the format yet, there are still many parts that would have to be investigated further. When new information becomes available this article will be updated again.
The information in this article can be of use for designers who want to do advanced source code tweaking or who want to read the MDL object into a tool they are creating directly. For the normal scenery designer this information is probably less relevant.
The knowledge contained in this article has been gained by analyzing the hexadecimal MDL file format and by evaluating the ASM source file created by GMax (with the Fs2004 gamepack).
 RIFF sections
This section lists the different sections that can be found in the RIFF format. For each of them the basic header information will be provided and also a description of their content.
db 'R','I','F','F' dd size of RIFF data db 'MDL9'
This is the main header of the MDL file. The 'MDL9' indicates that this MDL file is a Fs9 (Fs2004) MDL file. Aircraft MDL files for example use 'MDL8' here. This is because the Fs2002 and Fs2004 aircraft MDL format are the same (this type of aircraft RIFF MDL object will not be discussed further in this article).
db 'M','D','L','H' dd size to end of MDLH block dd size to end of MDLH block dd 0 dd 0 dd radius of object, like v2 before dd 0 dd 0 dd 152, seems fixed value, also found in default scenery db 'FS80' dd 2304, seems fixed value, also found in default scenery
This is the MDL object header and it contains basic information about the object. Most of the parameters are still unknown.
db 'I','S','F','T' dd size to end of ISFT block db string with MakeMDL version information
This section can store string information. MakeMDL for example stores the information about the version used to create the MDL object in this string.
db 'B','B','O','X' dd size to end of BBOX block real4 x_min,z_min,y_min bounding box real4 x_max, z_max, y_max bounding box
This section stores the bounding box of the object. This is thus the closest fitting box around the total object. The bounding box does not have to be centered around the 0,0,0 point. Setting the bounding box wrong can result in display problems in FS, for example the disappear of the object while it should still be visible.
db 'C','R','A','S' dd size to end of BBOX block
This section contains the crash information of the object. Inside this section the BGL_CRASH_OCTTREE commands can be used to describe the crash information.
db 'E','X','T','E' dd size to end of EXTE block
This section defines the external model of the object. All sections from the TEXT section downwards can be nested in the EXTE section.
db 'S','H','A','D' dd size to end of SHAD block
This section defines the shadow model of the object. All sections from the TEXT section downwards can be used nested in the SHAD section.
db 'T','E','X','T' dd size to end of TEXT block
This section contains a list of all textures used in the object. The only commands valid in this section seems to be the TEXTURE_LIST commands as described in the BGL_FP SDK of Fs2002. This section ends with a BGL_RETURN command.
db 'M','A','T','E' dd size to end of MATE block
This section contains a list of all materials used in the object. The only commands valid in this section seems to be the MATERIAL_LIST commands as described in the BGL_FP SDK of Fs2002. This section ends with a BGL_RETURN command.
db 'V','E','R','T' dd size to end of VERT block
This section contains a list of all vertices used in the object. The only commands valid in this section seems to be the VERTEX_LIST commands as described in the BGL_FP SDK of Fs2002. This section ends with a BGL_RETURN command.
db 'B','G','L',' ' dd size to end of BGL block
This section contains the actual drawing code of the object. The DRAW_TRI commands, as described in the BGL_FP SDK of Fs2002, are used to define the triangles that should be drawn.
Almost all other commands listed in previous scenery SDKs can still be used in this section. For example the IFIN1 command to define conditions.
This section ends with a BGL_END and a BGL_RETURN command.
db 'T','R','A','N' dd size to end of TRAN block
This section is called the static animation block by GMax. Each matrix is given by 16 real4 elements. There is no index number attached to the matrix, each set of 16 real4 commands is probably seen as one matrix automatically (where an index number is set automatically).
db 'A','N','I','P' dd size to end of ANIP block
This section is called the animation parameter block by GMax. This section contains animation tables. These are used in the ANIC section to form the actual animation matrices.
MakeMDL writes the following tables into this section (you can use different tables of course).
First there are two tables that are used to transform the TICK18 variable into a frame number. MakeMDL uses two tables here because that is more efficient. The first table splits the value that runs between -32767 and 32767 into segments of 16 times the animation length. The second table then splits this new variable into the actual frame count. You can see those two tables as a sawtooth to transform the TICK18 variable into a frame counter repeating the number of frames of your animation all the time. The third table is then used to convert the frame number into a float.
Following these basic tables are the tables that define the actual animation. This table has the following header format:
dw 1 (translation) or 3 rotation real4 previous panim value, usually -1.0 real4 cached matrix , usually 16 dup (0.0) dw number of entries
For a translation each entry consists of:
real4 frame real4 x real4 y real4 z
For a rotation each entry consists of:
real4 frame real4 x real4 y real4 z real4 w
When an object has both a translation and a rotation table, the basic part of the first three table (to interpolate the frame number) is not repeated for the rotation, only the table for the movement itself is given.
db 'A','N','I','C' dd size to end of ANIC block
This section is called the animation command block by GMax. In this section the actual animation matrix is interpolated using the tables defined in the ANIP section and the current frame number. This is done using the BGL_TRANSFORM_INDIRECT command.
db 'S','C','E','N' dd size to end of SCEN block dw number of definitions
This section is called scene graph riff block by GMax. This table defines the relation between different animation matrices. The scene number defined in this table is called in the BGL section when the matrix is applied to the object.
Each definition is given by a BGL_SCENEGRAPH_ENTRY command, this command has the following five parameters:
db 'A','T','T','A' dd size to end of ATTA block dd number of attachpoints
This section lists the different attachpoints that are available in the object. Each attachpoint is defined with the BGL_ATTACHPOINT_ENTRY opcode. This opcode has two parameters, the first is the scenegraph node that the attachpoint is located at and the second is the offset to the memory space where the name is defined. This name is a zero terminated character string.
db 'A','T','T','O' dd size to end of ATTO block
The ATTO section defines the attached objects and relates them to a certain attachpoint (by name). Below the data structure for the different types of attached objects are listed. Both effects and library objects have the following basic information:
dd unknown dw type dw length dw offset attachpoint name dw unknown dd unknown dd unknown dd unknown dd unknown
Effects have type 4. The "header" is followed by a string that contains the effect filename and the parameters. These are separated by null characters. After that is the string with the attachpoint name that this effect uses.
Library objects have type 2. The "header" is followed by the GUID of the object. Following the GUID is the scale of the object as a single precision float. After that is the string with the attachpoint name that this effect uses.
db 'P','L','A','T' dd size to end of PLAT block dd number of platform definitions
This section defines platforms (hardened platforms) of the object. Each platform plane is defined using a BGL_PLATFORM_ENTRY command. An example of such a command is:
BGL_PLATFORM_ENTRY 1, platform_vertex_start_test_0, 3, 0
The first parameter seem to be used to link entries that belong to the same plane (they have the same number there), the second parameter is the position after which the points are defined. The last two parameters are always the same, I have no idea what they are. I tried if the 3 referred to the amount of vertices that would follow, but when I made it as a rectangle the platform failed to work. After the given position a triangle is defined with the BGL_PLATFORM_VERTEX_ENTRY command, this command has a x, z and y position (as floats) as parameters.
I have tried to use different surfacetypes, as available in the GMax script, but the output source seems the same for all of them. This is probably a feature not yet implemented in Fs2004.
When using the Gmax script a lot of other code also appears in the MDL file. These have no relation to the hard surface (sort of bug in MakeMDL). The only thing that makes it hard is the PLAT section itself. No other code is used to call this section.