P3D File Format - MLOD: Difference between revisions
| mNo edit summary | m (made a combined page) | ||
| Line 1: | Line 1: | ||
| {{unsupported-doc}} | |||
| =Acknowledgments= | |||
| This information comes largely from the long defunct 'ofpinternals', who in turn acknowledge | |||
|  Thanks to FlipeR ([email protected]) for helping in research | |||
| This is archive material is held at http:\\www.ofpec.com | |||
| = Legend = | |||
| see [[Generic FileFormat Data Types]] | |||
| = Introduction = | |||
| Any given P3D file is THE 3 dimensional model reference for a specific model. Tank, Man, House, sausage. The P3d contains references to pac/paa files which are individual 'surfaces' for *this* model. Some / Most / All of the pac/paa files *might* also be used in other models, but this p3d is THE T80 tank, THE civilian man, or THE tangerine sausage with pink spots. | |||
| Arma P3D files also contain references to materials (rvmats). | |||
| There are two basic P3D types | |||
| *ODOL: A binarised and compressed version as used by various engines. (OFP, ARMA eg) | |||
| *MLOD: An editable version as used by Oxygen2/3 eg. | |||
| The FILE header defines which, of the two types, this P3D is.  | |||
| This document describes MLOD P3D's | |||
| Every LOD in an MLOD containts a LOD Header which defines the type of lod as being  | |||
| * SP3X used in OFP: Uses O2Light for editing | |||
| * P3DM used in ARMA:Uses O2PE for editing | |||
| Arma can read EITHER. | |||
| Because each of the contiguous lods declares what 'type' it is (SP3X, or P3DM), architecturally, you could have mixtures of both types. Materials however, can only be defined by P3DM lods. | |||
| 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. | |||
| ------------ | |||
| =File Format= | |||
|  MLOD_P3D | |||
|  { | |||
|    P3DHeader P3DHeader; | |||
|    MLOD_LOD  MLOD_LODs[Header.NoOfLods]; | |||
|    char      SP3X_DefaultPath[32]; // optional OFP only | |||
|  } | |||
| *SP3X Lods contain a rarely encountered, optional, Default File path (probably for the editor) | |||
| ==P3DHeader== | |||
|  P3DHeader | |||
|  { | |||
|   char   Signature[4];        //"MLOD" | |||
|   ulong  Version;             // 0x101 see note | |||
|   ulong  NoOfLods;            // at least one | |||
|  }; | |||
| ===OdolExplorer=== | |||
| OdolExplorer sets the version to a float value of 1.1 with no ill-effect | |||
| ==MLOD_LOD== | |||
|  Struct | |||
|  { | |||
|    char[4]                     Signature;           //"SP3X" or "P3DM" | |||
|    ulong                       MajorVersion;        //28 (x1C) | |||
|    ulong                       MinorVersion;        //0x99 (SP3X) or 0x100 (P3DM) | |||
|    ulong                       NoOfPoints; | |||
|    ulong                       NoOfNormals;         //(perpendicular) | |||
|    ulong                       NoOfFaces; | |||
|    ulong                       UnknownFlagBits;     //Probably 'Model Flags' - Unused. | |||
|    Point                       Points[NoOfPoints]; | |||
|    XYZTriplet                  Normals[NoOfNormals]; | |||
|    Faces                       Faces[NoOfFaces];    //see [[P3D Lod Faces]] | |||
|    char                        TagSig;              //Always 'TAGG' | |||
|    Tagg[]                      Taggs;               //Always, minimum of #EndOfFile# tag exists. | |||
|    float                       Resolution;          //See [[P3D_Model_Info]]  | |||
|  } | |||
| The end of each structure *always* contains an #EndOfFile# TAGG followed by the resolution (of that lod) | |||
| ===Points=== | |||
|  struct | |||
|  { | |||
|     XYZTriplet    Position | |||
|     ulong         PointFlags;// see [[P3D Point and Face Flags]] | |||
|  } | |||
| ===Normals=== | |||
| Normals must be inverted (-X, -Y, -Z) for clockwise vertex order (default for DirectX), and not changed for counterclockwise order. | |||
| ==Taggs== | |||
|   struct | |||
|   { | |||
|     //////// P3DM ONLY /////////// | |||
|     TinyBool Active;            // always 1 | |||
|     Asciiz   TaggName;          // "#EndOfFile#\0" eg | |||
|     ///////  SP3X ONLY /////////// | |||
|     Asciiz   TaggName[64];      // "#EndOfFile#\0" eg | |||
|     ////////////////////////////// | |||
|     ulong    NoOfBytes;        | |||
|     byte     TaggData[NoOfBytes];// arbitrary data | |||
|   }; | |||
| ===TagNames=== | |||
| Every Lod contains one or more Tagname entries. The #EndOfFile# tag is a mandatory entry in every Lod to indicate no more tags! | |||
| The contiguous tags that make up the tag section are always in the above format. The actual structure of the 'ArbitraryData' is dependant on the TagName (eg the tag type). | |||
| TaggNames consist of a mixure of pre-defined Taggs indicated with  #.....#  marks, and 'Named Selections' | |||
| *There are 8 predefined tags | |||
| The #Mass# tag is mandatory for Geometry LODs.  | |||
| Named Selection taggs names can contain space characters. Proxy names contain 'proxy:' + ProxyName + '.' + ProxyNumber ('01' .. )  | |||
| 'Official' tagnames listed below are a mish mash of obsolete, and still used, commands. This because, the p3d was a still in development at time of CWC release. | |||
| ==== #EndOfFile# ==== | |||
|  ulong   NoOfBytes; //always 0 | |||
| Mandatory for every Lod. This is the last tag of '''current''' LOD. It contains no data. | |||
| ==== #SharpEdges# ==== | |||
|  ulong          NoOfBytes; | |||
|  ulong          PointsIndex[NoOfIndexes][2]; // NoOfIndexes= NoOfBytes /  2 * sizeof(ulong)..// 1st and 2nd indexes into the VertexTable  | |||
| Sharp edge means that these vertices normals are not calculated as average (normalized) between polygons. | |||
| ==== #Property# ==== | |||
|   ulong                      NoOfBytes;            //Always 128 | |||
|   Asciiz                     TokenKey[64];         //"lodnoshadow" (=) "1" | |||
|   Asciiz                     TokenValue[64];       // | |||
| Additional Properties (if any) for the lod are contained in a series of one or more property tags. Each one contains one, and one only Token-Pair. The Asciiz strings each have a fixed length of 64 characters. Regardless, they are null terminated. | |||
| Examples: | |||
|  damage=tree; | |||
|  CanOcclude=0; | |||
| ==== #Mass# (only for Geometry LOD)==== | |||
|  ulong          NoOfBytes; | |||
|  float          PointsMass[NoOfPoints];  // == NoOfBytes / sizeof(float).. same as Lod.NoOfPoints | |||
| '''Must''' be present for Geometry LOD, and '''only''' for Geometry lod. It refers to the mass of each Point entry. | |||
| ==== #UVSet# ARMA ==== | |||
|  ulong       NoOfBytes;            //sizeof(float)+2*sizeof(float)*(NoOfTrianglss*3)+(NoOfQuads*4)) | |||
|  ulong       ID; | |||
|  float       FaceUV[NoOfFaces][FaceType][2]; //see [[P3D Lod Faces]] | |||
| used with multiple UV sets. | |||
| NB: There can be as many as 8 Distinct #UVSets# per LOD. | |||
| ====#Lock# (only in O2L)==== | |||
|  ulong      NoOfBytes;                   // ==Lod.NoOfPoints + lod.NoOfFaces | |||
|  TinyBool   LockedPoints[NoOfPoints]; | |||
|  TinyBool   LockedFaces[NoOfFaces];     | |||
| NB: The byte array's indicate a zero-based offset into the corresponding '''Points''' & '''Face''' structures. | |||
| ====#Selected# (only in O2L)==== | |||
|  ulong      NoOfBytes;                     // ==Lod.NoOfPoints + lod.NoOfFaces | |||
|  TinyBool   PointTableFlag[NoOfPoints];    // 1 = true == selected | |||
|  TinyBool   FaceTableFlag[NoOfFaces];      // ditto | |||
| NB: These flag tables correspond to each entry of Points and Faces respectively and indicate whether that Point (or Face) at that index is 'selected' or not is a persisted selection within the P3DM at this time. It serves no other purpose outside of editing the model in O2. | |||
| ====#Hide# (only in O2L)==== | |||
|  ulong      NoOfBytes;                  //  ==Lod.NoOfPoints + lod.NoOfFaces | |||
|  byte       PointsIndex[NoOfPoints];    // nonzero = true | |||
|  TinyBool   FaceIndex[NoOfFaces];  | |||
| These 3 are used so that O2L can save your last selections in the edited file.  | |||
| ==== #Animation# ARMA ==== | |||
|  ulong         NoOfBytes;            //==sizeof(float)+Lod.NoOfPoints*sizeof(XYZTriplet) | |||
|  float         FrameTime; | |||
|  ////////// SP3X ONLY /////////// | |||
|  ulong         NoOfPoints; // Must be the same as the LOD header.  | |||
|  ///////////////////////////////// | |||
|  XYZTriplet    FramePoints[NoOfPoints]; | |||
| 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. | |||
| ====#MaterialIndex# (only in O2L)==== | |||
| Unknown tag. Used only in O2L. This tag contains a 16-byte structure:  | |||
| Seems, this tag contains 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 | |||
| ====#Named Selection#==== | |||
| See [[P3D Named Selections]] | |||
| [[Category:BIS_File_Formats]] | |||
| [[Category:ArmA: File Formats]] | |||
Revision as of 16:59, 16 May 2010
Acknowledgments
This information comes largely from the long defunct 'ofpinternals', who in turn acknowledge
Thanks to FlipeR ([email protected]) for helping in research
This is archive material is held at http:\\www.ofpec.com
Legend
see Generic FileFormat Data Types
Introduction
Any given P3D file is THE 3 dimensional model reference for a specific model. Tank, Man, House, sausage. The P3d contains references to pac/paa files which are individual 'surfaces' for *this* model. Some / Most / All of the pac/paa files *might* also be used in other models, but this p3d is THE T80 tank, THE civilian man, or THE tangerine sausage with pink spots.
Arma P3D files also contain references to materials (rvmats).
There are two basic P3D types
- ODOL: A binarised and compressed version as used by various engines. (OFP, ARMA eg)
- MLOD: An editable version as used by Oxygen2/3 eg.
The FILE header defines which, of the two types, this P3D is.
This document describes MLOD P3D's
Every LOD in an MLOD containts a LOD Header which defines the type of lod as being
- SP3X used in OFP: Uses O2Light for editing
- P3DM used in ARMA:Uses O2PE for editing
Arma can read EITHER.
Because each of the contiguous lods declares what 'type' it is (SP3X, or P3DM), architecturally, you could have mixtures of both types. Materials however, can only be defined by P3DM lods.
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.
File Format
MLOD_P3D
{
  P3DHeader P3DHeader;
  MLOD_LOD  MLOD_LODs[Header.NoOfLods];
  char      SP3X_DefaultPath[32]; // optional OFP only
}
- SP3X Lods contain a rarely encountered, optional, Default File path (probably for the editor)
P3DHeader
P3DHeader
{
 char   Signature[4];        //"MLOD"
 ulong  Version;             // 0x101 see note
 ulong  NoOfLods;            // at least one
};
OdolExplorer
OdolExplorer sets the version to a float value of 1.1 with no ill-effect
MLOD_LOD
Struct
{
  char[4]                     Signature;           //"SP3X" or "P3DM"
  ulong                       MajorVersion;        //28 (x1C)
  ulong                       MinorVersion;        //0x99 (SP3X) or 0x100 (P3DM)
  ulong                       NoOfPoints;
  ulong                       NoOfNormals;         //(perpendicular)
  ulong                       NoOfFaces;
  ulong                       UnknownFlagBits;     //Probably 'Model Flags' - Unused.
  Point                       Points[NoOfPoints];
  XYZTriplet                  Normals[NoOfNormals];
  Faces                       Faces[NoOfFaces];    //see P3D Lod Faces
  char                        TagSig;              //Always 'TAGG'
  Tagg[]                      Taggs;               //Always, minimum of #EndOfFile# tag exists.
  float                       Resolution;          //See P3D_Model_Info 
}
The end of each structure *always* contains an #EndOfFile# TAGG followed by the resolution (of that lod)
Points
struct
{
   XYZTriplet    Position
   ulong         PointFlags;// see P3D Point and Face Flags
}
Normals
Normals must be inverted (-X, -Y, -Z) for clockwise vertex order (default for DirectX), and not changed for counterclockwise order.
Taggs
 struct
 {
   //////// P3DM ONLY ///////////
   TinyBool Active;            // always 1
   Asciiz   TaggName;          // "#EndOfFile#\0" eg
   ///////  SP3X ONLY ///////////
   Asciiz   TaggName[64];      // "#EndOfFile#\0" eg
   //////////////////////////////
   ulong    NoOfBytes;       
   byte     TaggData[NoOfBytes];// arbitrary data
 };
TagNames
Every Lod contains one or more Tagname entries. The #EndOfFile# tag is a mandatory entry in every Lod to indicate no more tags!
The contiguous tags that make up the tag section are always in the above format. The actual structure of the 'ArbitraryData' is dependant on the TagName (eg the tag type).
TaggNames consist of a mixure of pre-defined Taggs indicated with #.....# marks, and 'Named Selections'
- There are 8 predefined tags
The #Mass# tag is mandatory for Geometry LODs.
Named Selection taggs names can contain space characters. Proxy names contain 'proxy:' + ProxyName + '.' + ProxyNumber ('01' .. ) 
'Official' tagnames listed below are a mish mash of obsolete, and still used, commands. This because, the p3d was a still in development at time of CWC release.
#EndOfFile#
ulong NoOfBytes; //always 0
Mandatory for every Lod. This is the last tag of current LOD. It contains no data.
#SharpEdges#
ulong NoOfBytes; ulong PointsIndex[NoOfIndexes][2]; // NoOfIndexes= NoOfBytes / 2 * sizeof(ulong)..// 1st and 2nd indexes into the VertexTable
Sharp edge means that these vertices normals are not calculated as average (normalized) between polygons.
#Property#
ulong NoOfBytes; //Always 128 Asciiz TokenKey[64]; //"lodnoshadow" (=) "1" Asciiz TokenValue[64]; //
Additional Properties (if any) for the lod are contained in a series of one or more property tags. Each one contains one, and one only Token-Pair. The Asciiz strings each have a fixed length of 64 characters. Regardless, they are null terminated.
Examples:
damage=tree; CanOcclude=0;
#Mass# (only for Geometry LOD)
ulong NoOfBytes; float PointsMass[NoOfPoints]; // == NoOfBytes / sizeof(float).. same as Lod.NoOfPoints
Must be present for Geometry LOD, and only for Geometry lod. It refers to the mass of each Point entry.
#UVSet# ARMA
ulong NoOfBytes; //sizeof(float)+2*sizeof(float)*(NoOfTrianglss*3)+(NoOfQuads*4)) ulong ID; float FaceUV[NoOfFaces][FaceType][2]; //see P3D Lod Faces
used with multiple UV sets.
NB: There can be as many as 8 Distinct #UVSets# per LOD.
#Lock# (only in O2L)
ulong NoOfBytes; // ==Lod.NoOfPoints + lod.NoOfFaces TinyBool LockedPoints[NoOfPoints]; TinyBool LockedFaces[NoOfFaces];
NB: The byte array's indicate a zero-based offset into the corresponding Points & Face structures.
#Selected# (only in O2L)
ulong NoOfBytes; // ==Lod.NoOfPoints + lod.NoOfFaces TinyBool PointTableFlag[NoOfPoints]; // 1 = true == selected TinyBool FaceTableFlag[NoOfFaces]; // ditto
NB: These flag tables correspond to each entry of Points and Faces respectively and indicate whether that Point (or Face) at that index is 'selected' or not is a persisted selection within the P3DM at this time. It serves no other purpose outside of editing the model in O2.
#Hide# (only in O2L)
ulong NoOfBytes; // ==Lod.NoOfPoints + lod.NoOfFaces byte PointsIndex[NoOfPoints]; // nonzero = true TinyBool FaceIndex[NoOfFaces];
These 3 are used so that O2L can save your last selections in the edited file.
#Animation# ARMA
ulong NoOfBytes; //==sizeof(float)+Lod.NoOfPoints*sizeof(XYZTriplet) float FrameTime; ////////// SP3X ONLY /////////// ulong NoOfPoints; // Must be the same as the LOD header. ///////////////////////////////// XYZTriplet FramePoints[NoOfPoints];
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.
#MaterialIndex# (only in O2L)
Unknown tag. Used only in O2L. This tag contains a 16-byte structure:
Seems, this tag contains 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
