ArmA 1 Forum, ArmA 1 Home, ArmA 1 Config, ArmA 1 Tools, ArmA 1 File Formats, ArmA 1 Missions, ArmA 1 3D Modeling, ArmA 1 Terrain, ArmA 1 Texturing, ArmA 1 Scripting
ArmA 1 aka Armed Assault (ArmA)
Although the overall structure of a P3DM MLOD model file is similar to SP3X MLOD model files there are some notable differences. Namely, Materials, Multiple UVSets and Animations.
Legend
Type | Description |
---|---|
byte | 8 bit (1 byte) |
short | 16 bit signed short (2 bytes) |
int | 32 bit signed integer (4 bytes) |
float | 32 bit signed single precision floating point value (4 bytes) |
asciiz | Null terminated (0x00) variable length ascii string |
The following is a mix of pseudo-code and structure references that could be used to describe the file format of MLOD P3DM model files. It may or may not be accurate.
MLOD_P3DM { structHeader Header; structLOD[] Lods; }
structHeader
struct structHeader { char[4] Filetype; //eg. MLOD int Version; //eg. 0x0101 0000 = 257 int NoOfLods; }
structLOD
struct structLOD { char[4] LODType; //eg. P3DM int MajorVersion; //eg. 0x1C00 0000 = 28 int MinorVersion; //eg. 0x0001 0000 = 256 int NoOfPoints; int NoOfNormals; int NoOfFaces; int Unknown; //Probably 'Model Flags' - Unused. structPoint[NoOfPoints] Points; structNormal[NoOfNormals] Normals; structFace[NoOfFaces] Faces; char[4] Tagg; //eg. Always 'TAGG' structTag[] Tags; //eg. Always, minimum of #UVSet# & #EndOfFile# tags exists. float Resolution; }
structPoint
struct structPoint { float x; float y; float z; int PointFlags; }
structNormal
struct structNormal { float x; float y; float z; }
structFace
struct structFace { int NoOfVerts; structVertex[4] Vertices; int FaceFlags; asciiz Texture; asciiz Material; }
NB: Irrespective whether a Face has 3 or 4 vertices. There are always 4 vertex points described. In the case of a triangle the 4th vertex will have all zero entries.
structVertex
struct structVertex { int PointIndex; int NormalIndex; float U; float V; }
structEdge
struct structEdge { int 1st_PointIndex; int 2nd_PointIndex; }
NB: This structure is only relevant in “#SharpEdges#” tag set.
structTag
struct structTag { byte Active; //eg. Always \x01 asciiz TagName; int NoOfBytes; ArbitraryData[NoOfBytes] TagData; //If NoOfBytes == Zero then Non-existent }
Processing of a TAGG section of a P3DM MLOD file is dependable on the type of tag being processed. A tag will always be in the following format. The actual structure of the “ArbitraryData” is dependable on the tag type.
#EndOfFile#
struct structTag_EndOfFile { byte Active; //eg. Always \x01 asciiz "#EndOfFile#\x00"; int NoOfBytes; //eg. Always \x00000000 = Zero }
#Selected#
struct structTag_SelectedWeighted { byte Active; //eg. Always \x01 asciiz "#Selected#\x00"; int NoOfBytes; //eg. Will always be NoOfPoints + NoOfFaces byte[NoOfPoints] SelectedWeightedPoints; byte[NoOfFaces] SelectedFaces; }
NB: The byte array's indicate a zero-based offset into the corresponding Points & Faces structures.
Each byte in the SelectedWeightedPoints array denotes a value 0 to 255 (0 to FF hex).
And, serves a dual purpose in…
Any value other than zero indicates that the point is not only part of the selection but also has a weighting value.
Every value between 2 and 255 (0x02 to 0xFF hex) indicates the percentage weight of the corresponding point and that it is part of the selection. Two (2) being almost 100% weighted and 255 being almost 0% weighted.
Following is some appropriate pseudo-code to illustrate.
byte2weight
float32 byte2weight = (256 - weight)/255; if (byte2weight > 1.0) then byte2weight = 0;
Where “weight” is a unit8 (single byte) in the range… 0 >= weight ⇐ 255 or 0x00 >= weight ⇐ 0xFF.
weight2byte
unit8 weight2byte = round(256 - (255 x weight),0); if (weight2byte == 256) then weight2byte = 0;
Where “weight” is a float32 in the range… 0.0 >= weight ⇐ 1.0.
#SharpEdges#
struct structTag_SharpEdges { byte Active; //eg. Always \x01 asciiz "#SharpEdges#\x00"; int NoOfBytes; structEdge[NoOfBytes / 8] Edges; }
#Mass#
struct structTag_Mass { byte Active; //eg. Always \x01 asciiz "#Mass#\x00"; int NoOfBytes; float[NoOfPoints] Mass; }
NB: #Mass# tag is only present in the “Geometry LOD”.
#Property#
struct structTag_Property { byte Active; //eg. Always \x01 asciiz "#Property#\x00"; int NoOfBytes; //eg. Always \x8000 0000 = 128 char[64] Name; //eg. lodnoshadow char[64] Value; //eg. 1 }
#UVSet#
struct structTag_UVSet { byte Active; //eg. Always \x01 asciiz "#UVSet#\x00"; int NoOfBytes; //eg. (NoOfTris*24)+(NoOfQuads*32)+4 structUV[NoOfFaces] UVSet; } struct structUV { structPointUV[NoOfVerts] FaceUVs; } struct structPointUV { float U; float V; }
NB: There can be as many as 8 Distinct UVSets per LOD.
#Lock#
struct structTag_Lock { byte Active; //eg. Always \x01 asciiz "#Lock#\x00"; int NoOfBytes; //eg. Will always be NoOfPoints + NoOfFaces byte[NoOfPoints] LockedPoints; //eg. \x01 = true, \x00 = false byte[NoOfFaces] LockedFaces; //eg. \x01 = true, \x00 = false }
NB: The byte array's indicate a zero-based offset into the corresponding Points & Faces structures.
#Animation#
struct structTag_Animation { byte Active; //eg. Always \x01 asciiz "#Animation#\x00"; int NoOfBytes; //eg. Will always be (NoOfPoints*12)+4 float FrameTime; structXYZ[NoOfPoints] FramePoints; } struct structXYZ { float x; float y; float z; }
NB: There will be 1 “#Animation#” chunk per Frame. This can result in VERY large P3DM MLOD models. A model with three thousand (3,000) odd frames (eg. ActsPercMstpSnonWnonDnon_DancingStefan.rtm) will be approx. 200 Megabytes on disk.
This type of data format for Animation is commonly known as a “Point Cache” or an “MDD Point Cache”. It describes the exact location of every point in the LOD in 3D “Model Space” for each frame.
<Named Selection>
struct structTag_Selection { byte Active; //eg. Always \x01 asciiz "<Any Ascii Characters>x00"; int NoOfBytes; //eg. Will always be NoOfPoints + NoOfFaces byte[NoOfPoints] SelectedPoints; //eg. \x01 = true, \x00 = false byte[NoOfFaces] SelectedFaces; //eg. \x01 = true, \x00 = false }
NB: The byte array's indicate a zero-based offset into the corresponding Points & Faces structures.