Jump to content
Sign in to follow this  

P3D MLOD Format Description

Recommended Posts

Hello everyone.

I am not sure if people remember this, but quite some time ago the OFP Internals-crew released the file format description for the P3D MLOD format.

It was available on their site (which is closed down now) and on OFPEC as well (which as you may know suffered a crash and lost all that data), but now I am unable to locate it.

I am writing this topic in the hopes that one kind soul on this forum has the documentation saved away someplace safe, or knows where it can still be accessed.

The reason for this is that I am interested in writing a P3D import/export plugin for the Blender 3D modeling package, and I obviously cannot do that if I do not know how to read (and write) the P3D MLOD format smile_o.gif

Thank you.

Share this post

Link to post
Share on other sites


I'm very new to the community and though my head is spinning trying to figure out the Dance for OFP add-ons, I came across something that might help you out.

I noticed that your OFPEC website got lost when I was looking for ECP stuff and the links were broken. Not too long ago I discovered an amazing site that documents a ridiculous number of websites (to a limited degree). It's called The Internet Archive Wayback Machine and if you know about it already then excuse my post.

If you haven't seen it, a large amount of your site is stored there and can be recovered if you wish. Before you get your hopes up too much, the system seems to pretty much completely ignore forums and images, unfortunately. However, there's still a large amount of stuff there preserved in it's original format (sans images). Just pick a date, usually the newest is best but you may mine stuff you want out of older archives as well (e.g. front page news). Links are all clickable and will either work or give you a "not archived" message. You can also directly append path info to the URL in the address bar (i.e. typing in a link by hand).

Anyway here's a link to your site's archive:

OFPEC Site (sorta)

I hope this helps you folks get your site back on your feet.


Share this post

Link to post
Share on other sites

if you got any questions, you may PM me; but anyway, here you are:

Quote[/b] ]



This is the preliminary unofficial description.

Table of Contents


1. Introduction.

2. File Structure.

Appendix A. LOD Resolution.

Appendix B. Vertex Flags.

Appendix C. Polygon Flags.




Thanks to FlipeR (filipus@hotmail.com) for helping in reserch.

1. Introduction


Type Explanation


byte - 8-bit unsigned integer

integer - 32-bit signed integer

float32 - 32-bit float number (single precision)

zstring32 - zero-terminated string, data length is fixed = 32 bytes (so max. string length is 31)

zstring64 - zero-terminated string, data length is fixed = 64 bytes (so max. string length is 63)

Polygons Vertex Order


Let's we have visible 3-vertex polygon:



It's the clockwise order. And:



- counterclockwise order:

The same for 4-vertex polygon:



- clockwise, and



- counterclockwise.

Main thing is your 3D device culls invisible polygons. Invisible polygon is polygon that have other direction order. For example, DirectX default setting is 'cull counterclockwise polygons', so clockwise is visible.

2. File Structure



Size (Type) Explanation


4 (integer) Model File Signature ($444f4c4d = 'MLOD'wink_o.gif

4 (integer) Model File Version (0x00000101 = 1.1)

4 (integer) LODs Count

- (LOD Data) 1st LOD Data

- (LOD Data) 2nd LOD Data


- (LOD Data) Nth LOD Data

32 (zstring32) Default Path to Textures - can be not present (see O2L 'Options'wink_o.gif

<end_of_file />

LOD Data:

Size (Type) Explanation


4 (integer) LOD Data Signature (0x58335053 = 'SP3X'wink_o.gif

4 (integer) LOD Data Major Version (0x0000001c)

4 (integer) LOD Data Minor Version (0x00000099)

4 (integer) Vertices Count

4 (integer) Normals (Perpendicular) Count

4 (integer) Polygons Count

4 (integer) LOD Flags (unknown values)

- (Vertex Array) Vertex Table

- (Normal (Perpendicular) Array) Normal (Perpendicular) Table

- (Polygons Array) Polygon Table

4 (integer) Tags Signature (0x47474154 = 'TAGG'wink_o.gif

- (Tags Set) Tags Set

4 (float) LOD Resolution (see Appendix A)


Size (Type) Explanation


4 (float32) X value

4 (float32) Y value

4 (float32) Z value

4 (integer) Vertex Flags (see Appendix B)

Normal (Perpendicular)

Size (Type) Explanation


4 (float32) X value

4 (float32) Y value

4 (float32) Z value

Important Notes: normals must be inverted (-X, -Y, -Z) for clockwise vertex order (default for DirextX), and not changed for counterclockwise order.


Size (Type) Explanation


32 (zstring32) TextureName

4 (integer) Polygon Vertices Count (valid values: 3 or 4)

16 (PolygonVertex) 1st vertice descriptor

16 (PolygonVertex) 2nd vertice descriptor

16 (PolygonVertex) 3rd vertice descriptor

16 (PolygonVertex) 4th vertice descriptor - always present, even if polygon have only 3 vertex (must be filled by 0 value)

4 (integer) Polygon Flags (see Appendix C)

Important Notes: Order of vertices


Vertices must be reordered for clockwise vertex order (default for DirextX), and not changed for counterclockwise order:

for 3-vertices polygon:

1. 1st vertice descriptor

2. 3rd vertice descriptor

3. 2rd vertice descriptor

4. (not used, filled by 0 value)

for 4-vertices polygon:

1. 1st vertice descriptor

2. 4th vertice descriptor

3. 3rd vertice descriptor

4. 2th (not used, filled by 0 value)


Size (Type) Explanation


4 (integer) Vertex Index (zero based) - see Vertex Table

4 (integer) Normal (Perpendicular) Index (zero based) - see Normal Table

4 (float32) U-value for texture mapping

4 (float32) V-value for texture mapping

Tags Set:

Size (Type) Explanation


4 (zstring64) Tag Name

4 (integer) Tag Size (in bytes)

Tag Size (-) Tag Data

Tag Name Valid Values:




'#MaterialIndex#' (only in O2L)

'#Animation#' (obsolete)

'#Mass#' (only for Geometry LOD)

'#Selected#' (only in O2L)

'#Hide#' (only in O2L)

'#Lock#' (only in O2L)


Other value is a component (named selections) name.

All tags can be skiped except '#EndOfFile#' (also Geometry LOD must have '#Mass#' tag). Actually, you must read all tags until you found '#EndOfFile#' tag. To skip unknown/unuseful/obsolete tag you must use 'Tag Size' field. Don't forget that 'Tag Size' value does not includes 'Tag Name' and 'Tag Size' fields sizes.

Component name can contain space characters. Proxy names contains 'proxy:' + ProxyName + '.' + ProxyNumber ('01' .. )

Tag '#SharpEdges#'


This tag contains the array of structure:

4 (integer) 1st Vertex Index of 1st edge (zero based) - see Vertex Table

4 (integer) 2nd Vertex Index of 1st edge(zero based) - see Vertex Table

4 (integer) 1st Vertex Index of 2nd edge

4 (integer) 2nd Vertex Index of 2nd edge


4 (integer) 1st Vertex Index of Nth edge

4 (integer) 2nd Vertex Index of Nth edge

Sharp edge means that these vertices normals are not calculates as average (normalized) between polygons.

Tag '#Property#'


This tag contains the array of structure:

64 (zstring64) 1st property name

64 (zstring64) 1st property value

64 (zstring64) 2nd property name

64 (zstring64) 2nd property value


64 (zstring64) Nth property name

64 (zstring64) Nth property value

Tag '#MaterialIndex'


Unknown tag. Used only in O2L. This tag contains the 16-bytes length structure:

Seems, this tag contais material properties:

4 (RGBA or BGRA) diffuse

4 (RGBA or BGRA) ambient

4 (RGBA or BGRA) specular

4 (RGBA or BGRA) emissive

By default, O2L write down this values:

51, 75, 55, 0

0, 0, 0, 0

255, 255, 255, 255

255, 255, 255, 255

Tag '#Animation#'


Obsolete tag. MLOD animation is per-vertex animation and not used now.

4 (float32) KeyFrame time. Valid Values: 0.0 (start) - 1.0 (stop). Used to change duration of animation playing.

4 (integer) Vertices Count. Must be the same as Vertices Count in the LOD header.

- (Vertex Array) Vertex Array. This data replaces main LOD Vertex Table.

Tag '#Mass#'


Must be present only for Geometry LOD.

4 (integer) Vertices Count. Must be the same as Vertices Count in the LOD header.

- (float32 Array) Vertex Mass Array.

Tags '#Selected#', '#Hide#', '#Lock#'


These tags have the same structure and used only on editing-time. So O2L can save your last selection in edited file. There are:

Vertex Count (byte) Non-zero value if vertex selected/hidden/locked or 0 else.

Polygons Count (byte) Non-zero value if polygon selected/hidden/locked or 0 else.

So this tag size is 'Vertex Count' + 'Polygons Count' bytes. Use 'Vertex Count' and 'Polygons Count' values from current LOD header.

Example: if VertexCount=5, PolygonsCount=3 and selected tag contains values:

2, 2, 0, 2, 0, 0, 1, 1

then Vertex 0, 1, 3 is selected (indices of Vertex Table entries) and Polygon 1, 2 selected (indices of Polygon Table entries).

Common values for vertices and polygons are the 2 and 1 respectively. But I recommend to compare it only with zero value (for example I saw early this value was 6 instead of 2 or 1).

Tag '#EndOfFile#'


Must be present. This is the last tag of current LOD Data. Not contains any data. So 'Tag Size' field is 0.


Appendix A. LOD Resolution


Valid Values for LOD Resolution are:

1.0e3 = 1'100.0 = View - Gunner

1.1e3 = 1'100.0 = View - Pilot

1.2e3 = 1'200.0 = View - Cargo

1.0e13 = 10'000'000'000'000.0 = Geometry

1.0e15 = 1'000'000'000'000'000.0 = Memory

2.0e15 = 2'000'000'000'000'000.0 = LandContact

3.0e15 = 3'000'000'000'000'000.0 = Roadway

4.0e15 = 4'000'000'000'000'000.0 = Paths

5.0e15 = 5'000'000'000'000'000.0 = Hitpoints

6.0e15 = 6'000'000'000'000'000.0 = View Geometry

7.0e15 = 7'000'000'000'000'000.0 = Fire Geometry

8.0e15 = 8'000'000'000'000'000.0 = View - Cargo - Geometry

9.0e15 = 9'000'000'000'000'000.0 = View - Cargo - Fire Geometry

1.0e16 = 10'000'000'000'000'000.0 = View - Commander

1.1e16 = 11'000'000'000'000'000.0 = View - Commander - Geometry

1.2e16 = 12'000'000'000'000'000.0 = View - Commander - Fire Geometry

1.3e16 = 13'000'000'000'000'000.0 = View - Pilot - Geometry

1.4e16 = 14'000'000'000'000'000.0 = View - Pilot - Fire Geometry

1.5e16 = 15'000'000'000'000'000.0 = View - Gunner - Geometry

1.6e16 = 16'000'000'000'000'000.0 = View - Gunner - Fire Geometry

Other values (< 1100.0) are extact LOD's resolution.

LOD selected for displaying if

DistanceToObject * LODCoef * M <= LODResolution


- LODCoef is value from OFP preferences (I have LODCoef = 0.019).

- M is some value that changed by OFP developers (I use M=1 in WRPEdit and M=2 in P3DEdot).

Appendix B. Vertex Flags


See also O2L 'Point Properties'.



(0x0000000f mask)

0x00000000 - normal

0x00000001 - on surface

0x00000002 - above surface

0x00000004 - undersurface

0x00000008 - keep height (fence)



(0x00000300 mask)

0x00000000 - normal

0x00000100 - decal

0x00000200 - radio12



(0x00003000 mask)

0x00000000 - normal

0x00001000 - none

0x00002000 - sky



(0x000000f0 mask)

0x00000000 - normal

0x00000010 - shining

0x00000020 - always in shadow

0x00000040 - fully lighted

0x00000080 - half lighted



(0x00ff0000 mask)

0x00ff0000 - user additional mark value (0..255)

Appendix C. Polygon Flags


See also O2L 'face properties'.

Enable shadow


0x00000010 - off (disable shadow)

Enable texture merging


0x01000000 - off (disable texture merging)



(0x00000300 mask)

0x00000000 - none

0x00000100 - low

0x00000200 - middle

0x00000300 - high



(0x003000a0 mask)

0x00000020 - both sides

0x00000080 - position

0x00200000 - flat

0x00100000 - reversed (transpared)



(0xfe000000 mask)

0xfe000000 - user additional mark value (0..127)

Share this post

Link to post
Share on other sites

Aah, excellent vektorboson! That's just what I was looking for. Thanks a lot.

Share this post

Link to post
Share on other sites

Did you not see what I posted about recovering your site? Or it's not helpful? Some sort of reply would be appreciated since I'm just trying to help your group out.


Share this post

Link to post
Share on other sites

When I was writing 3DSMax <-> MLOD converter, I ran into some problems with that MLOD format description not being completely accurate. I can see if I find my old notes...

I eventually abandoned the converter though because there was no way you could get selection and UV data into 3DSMax and then export it back to Oxygen intact. And MaxScript was pain in the ass to code icon_rolleyes.gif

Share this post

Link to post
Share on other sites

Hm, I see now, that named selections are not completely described in this document; they are basically like #selected#; but instead of being just boolean values the bytes are weights to each selection.

Otherwise the document was fairly accurate for me (I've got a working MLOD-viewer along with textures). Perhaps you mean the 4WVR-document which was false in some parts.

Share this post

Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in

Sign In Now
Sign in to follow this