P3D File Format - ODOLV7: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
mNo edit summary
(Undo of removal in agreement with mikero)
(14 intermediate revisions by one other user not shown)
Line 1: Line 1:
{{unsupported-doc}}
{{unsupported-doc}}


===Legend===
 
=General=
==Legend==
see [[Generic FileFormat Data Types]]
see [[Generic FileFormat Data Types]]
==CompressedStructures==


===Intro===
(potentially) compressed arrays are endemic to most blocks contained in a p3d.
 
====CompressedStruct====
 
ODOL7 uses (potentially) compressed arrays.
 
This obviously slows the engine down during loading. At the time of CWC development, game file sizes were important.
 
(potentially) compressed arrays are contained in a CompressedStruct
 
CompressedStructs are endemic to most blocks contained in the p3d.


  CompressedStruct
  CompressedStruct
Line 31: Line 24:


Thus for various Array <types>
Thus for various Array <types>
*ulong Array:    > 255  // 1024 /  sizeof(ulong)
*ulong Array:    > 255  // 1024 /  sizeof(ulong)
*float thing[2]: > 127  // 1024 / 2*sizeof(float)
*float thing[2]: > 127  // 1024 / 2*sizeof(float)
*SomeStructure:  >      // count * sizeof (SomeStructure) > 1023
*SomeStructure:  >      // count * sizeof (SomeStructure) > 1023
 


Note that potentially compressed arrays in these structures only have an known output length. the decompressor therefore must work on infinite input length.


Note that potentially compressed arrays in these structures only have an known output length.
the decompressor therefore must work on infinite input length.
see example decompression at end of document


===Odol7Stuct===
=Odol7Stuct=
  ODOLV7
  ODOLV7
  {
  {
   StandardP3DHeader Header;
   StandardP3DHeader Header;
   LodStruct Lods[LodCount];
   LodStruct         Lods[Header.LodCount];
   float    Resolution[LodCount];
   [[P3D Model Info|ModelInfo]]         ModelInfo;
  struct    ModelInfo;
  };
  };


====StandardP3DHeader====
==StandardP3DHeader==
  StandardP3DHeader
  StandardP3DHeader
  {
  {
   char      Signature[4];      ''//"ODOL"''
   char      Signature[4];      ''//"ODOL" (vs MLOD eg)''
   ulong    Version;          ''// 7''
   ulong    Version;          ''// 7''
   ulong    LodCount;          ''// at least one''
   ulong    LodCount;          ''// at least one''
  }
  }


===LodStruct===
==LodStruct==
  LodStruct
  LodStruct
  {
  {
   '''struct'''  VerticesStruct;
   [[#VertexTable|VertexTable]]    VertexTable;
   '''struct'''  UnknownStruct; // contains some max/min vertices positions
  float          UnknownFloat1;
   '''struct'''  TexturesStruct;
   float          UnknownFloat2;
   '''struct'''  VertexIndices;  
  XYZTriplet    MinPos;
   '''ulong'''  NoOfFaces;
  XYZTriplet    MaxPos;
   '''ulong'''  OffsetToSectionStruct;
  XYZTriplet    AutoCenterPos;
   Face          Faces[NoOfFaces];
  float          UnknownFloat3;
  '''ulong'''  nSections;
   [[#Textures|Textures]]      Textures;
   LODSection   LODSections[nSections];
   [[P3D Lod Edges|LodEdges]]      LodEdges;        
   ulong         NoOfFaces;
   ulong         OffsetToLodSections;
   [[P3D Lod Faces|LodFace]]        LodFaces[NoOfFaces];               // ie polygons
  ulong         nSections;
   [[P3D Lod Sections|LODSection]]    LODSections[nSections];
   ulong          nNamedSelections;
   ulong          nNamedSelections;
   NamedSelection NamedSelections[nNamedSelections];
   [[P3D Named Selections|NamedSelection]] NamedSelections[nNamedSelections];
   ulong          nNamedProperties;
   ulong          nTokens;
   NamedProperty  NamedProperties[nNamedProperties];
   [[#NamedProperty|NamedProperty]] NamedProperties[nTokens];
   ulong          nFrames;
   ulong          nFrames;
   Frame          Frames[nFrames];
   [[P3D Lod Frames|Frame]]         Frames[nFrames];  
    
   ulong          IconColor;
   '''ulong'''   Unknown[3];
   ulong         SelectedColor;
   '''ulong'''  nProxies;
   ulong          Unknown;
   ProxyStruct  ProxyStructs[nProxies];  
   ulong         nProxies;
   [[P3D Lod Proxies|LodProxy]]      LodProxies[nProxies];
  };
  };


===VerticesStruct===
===VertexTable===
   VerticesStruct
   struct
   {  
   {  
     CompressedStruct PointFlags //(vertices)
     ulong      Count;             
     {
     ulong       PointFlags[Count]; // compressed. see [[P3D Point and Face Flags]]
    ulong Count;             // see [[P3D Point(Vertex) Flags]]
    ulong       Count;            
    ulong PointFlag[Count];    
     UVPair     UV1[Count];         // compressed
     }
     ulong       Count;               
    CompressedStruct UVset
    XYZTriplet Points[Count];     // UNcompressed
    {
     ulong       Count;             
    ulong  Count;              ''// if > 127 then array is compressed
    XYZTriplet  Normals[Count];     // UNcompressed
     UVPair UVsets[Count];      
    }
    struct Points // (Vertices)
     {
    ulong     Count;               
    XYZTriplet Point[Count];  
     }
    struct Normals
    {
    '''ulong''' Count;             
    '''float''' Normals[Count][3]; ''// XZY
    }
   }
   }


*Count is the same value for all four tables.
*Count is the same value for all four tables.
*The Position and Normals tables appear to be always uncompressed raw data.


====UVPair====
===Textures===
UVSet
   struct
{
  float U,V;
}
===UnKnownStruct===
UnKnownStruct
{
  UVPair      UnknownUV; // just a guess         
  XYZTriplet  MinPos;
  XYZTriplet  MaxPos;
  XYZTriplet  AutoCenterPos;
  float        UnknownFloat;
}
 
===TexturesStruct===
   struct Textures
   {
   {
   '''ulong'''  Count;
   '''ulong'''  Count;
Line 134: Line 102:
Count corresponds to the number of concatenated strings. It is required, since, architecturally at least, one of more of the asciiz strings could be null.
Count corresponds to the number of concatenated strings. It is required, since, architecturally at least, one of more of the asciiz strings could be null.


===VertexIndices===
VertexIndices
{
  CompressedStruct
  {
  '''ulong'''  Count;            ''// if > 511 etc'' 
  '''ushort''' MlodIndex[Count];
  }
  CompressedStruct
  {
  '''ulong'''  Count;          ''// this Count is same value as any of the Vertices.Counts''
  '''ushort''' OdolIndex[Count];''//
  }
}
Tables are used to join vertices. Each face has got 3 or 4 vertices that are unique for each face Eg. Every vertex is owned only by 1 face.
'''MLOD'''vertexindex = MlodIndex[ OdolIndex['''ODOL'''vertexindex] ];''


===Face===
===NamedProperty===
Face
   struct
{
  '''ulong'''  FaceFlags;
  '''short'''  TextureIndex;
  '''byte'''  nVertices;  // 3==Triangle or 4==Box
  '''ushort''' VerticesIndex[nVertices];
}
 
 
===LODSection===
   LODSection
   {
   {
    ulong  FaceLowerIndex;
    Asciiz Property;// "noshadow" = "1" eg
    ulong  FaceUpperIndex;
    Asciiz Value;
    ulong  UserValue;
    short  TextureIndex;      // as per Face struct
    ulong  (ODOL)FaceFlags;   // as per Face struct
   }
   }


The TextureIndex is a zero based array. If set to -1, there are no textures for this face or section


===NamedSelection===
=Related Page(s)=
NamedSelection
==LZ in ODOL==
{
  '''asciiz''' name;
  CompressedStruct VerticesIndexes
  {
  '''ulong'''  Count;                  ''// if > 511 then array is compressed
  '''ushort''' Vertices[Count];
  }
  CompressedStruct UnknownUshort
  {
  '''ulong'''  Count;                ''// if > 511 then array is compressed
  '''ushort'''  Unknown[Count];
  }
  CompressedStruct UnknownUlong
  {
  '''ulong''' Count;                    ''// if > 255 then array is compressed
  '''ulong''' Unknown[Count];
  }
  '''byte''' IsSectional;
  CompressedStruct UnknownUlong2
  {
  '''ulong''' Count;                    ''// if etc
  '''ulong''' Unknown[Count];
  }
  CompressedStruct Faces
  {
  '''ulong''' Count;                    ''// if etc
  '''ushort''' Faces[Count];
  }
  CompressedStruct TextureWeights      // probably
  {
  '''ulong''' Count;                    ''// if etc
  '''byte''' TextureWeights[Count];
  }
};
 
see NamedSelection in [[P3D File Format - MLOD P3DM]] for description of TextureWeights
 
===NamedProperty===
 
  NamedProperty
  {
    '''asciiz''' Name;  ''// "noshadow\0"
    '''asciiz''' Value; ''//"1\0"'
  };
 
===Frame===
    Frame
    {
      float FrameTime;
      ulong nBones;
      XYZTriplet [nBones];
    };
 
===ProxyStruct===
ProxyStruct
{
  asciiz          Name;
  TransformMatrix Transform;//see [[Generic FileFormat Data Types]]
  ulong          Indices[2];
}
 
==ModelInfo==
ModelInfo
{
  ulong      Index;            // typically 02 01 00 00
  float      Pair[2];          // typically 48 74 07 3F  : 48 74 07 3F . pair is often the same
  XYZTriplet Unknown;          // typically 00 00 00 00 00 00 00 00 00 00 B0 0D
  XYZTriplet offset;            // model offset (unknown functionality)
  ulong      mapIconColor;      // RGBA 32 color
  ulong      mapSelectedColor;  // RGBA 32 color
  ulong      unknownValue;
  XYZTriplet bboxMinPosition;  // minimum coordinates of bounding box
  XYZTriplet bboxMaxPosition;  // maximum coordinates of bounding box
  XYZTriplet wrpModelOffset;    // offset value to apply when object is placed on a WRP
  XYZTriplet offset2;          // another offset value (unknown functionality)
  XYZTriplet offset3;          // another offset value (unknown functionality)
  float      fArray[9];        // a mixture of floats and index values
  bytes      UnknownFlags[6];  // typically 01 00 00 01 00 16
  ulong      Count;
  float      Array[Count];      // potentially compressed
  float      Mass;
  XYZTriplet Unknown1;          // almost consistently  F9 02 15 50 : 00 00 48 43 : 0A D7 A3 3B
  XYZTriplet Unknown2;          // generally FF FF FF FF FF FF FF FF FF FF FF FF
}
 
===LZ in ODOL===
see [[Compressed LZSS File Format]]
see [[Compressed LZSS File Format]]
=Related Page(s)=


[[BIS_File_Formats#3D_Model_File_Formats|Model File Formats]]
[[BIS_File_Formats#3D_Model_File_Formats|Model File Formats]]
[[Category:BIS_File_Formats]]
[[Category:BIS_File_Formats]]

Revision as of 18:14, 16 January 2017

Template:unsupported-doc


General

Legend

see Generic FileFormat Data Types

CompressedStructures

(potentially) compressed arrays are endemic to most blocks contained in a p3d.

CompressedStruct
{
  ulong  Count;
  <type> Array[Count];
};


if Count * sizeof(<type>) exceeds 1023 bytes the array is compressed. The resulting array will be expanded using lzh compression exactly as found in pbo's (for instance)

After de-compression, the Count remains the same because it is a count of the arraytype.

For uncompressed arrays (byte count < 1024) the Count and data are treated 'as is'.


Thus for various Array <types>

  • ulong Array: > 255 // 1024 / sizeof(ulong)
  • float thing[2]: > 127 // 1024 / 2*sizeof(float)
  • SomeStructure: > // count * sizeof (SomeStructure) > 1023


Note that potentially compressed arrays in these structures only have an known output length. the decompressor therefore must work on infinite input length.


Odol7Stuct

ODOLV7
{
  StandardP3DHeader Header;
  LodStruct         Lods[Header.LodCount];
  ModelInfo         ModelInfo;
};

StandardP3DHeader

StandardP3DHeader
{
  char      Signature[4];      //"ODOL" (vs MLOD eg)
  ulong     Version;           // 7
  ulong     LodCount;          // at least one
}

LodStruct

LodStruct
{
 VertexTable    VertexTable;
 float          UnknownFloat1;
 float          UnknownFloat2;
 XYZTriplet     MinPos;
 XYZTriplet     MaxPos;
 XYZTriplet     AutoCenterPos;
 float          UnknownFloat3;
 Textures       Textures;
 LodEdges       LodEdges;         
 ulong          NoOfFaces;
 ulong          OffsetToLodSections;
 LodFace        LodFaces[NoOfFaces];               // ie polygons
 ulong          nSections;
 LODSection     LODSections[nSections];
 ulong          nNamedSelections;
 NamedSelection NamedSelections[nNamedSelections];
 ulong          nTokens;
 NamedProperty  NamedProperties[nTokens];
 ulong          nFrames;
 Frame          Frames[nFrames]; 
 ulong          IconColor;
 ulong          SelectedColor;
 ulong          Unknown;
 ulong          nProxies;
 LodProxy       LodProxies[nProxies];
};

VertexTable

 struct
 { 
   ulong       Count;              
   ulong       PointFlags[Count];  // compressed. see P3D Point and Face Flags
   ulong       Count;             
   UVPair      UV1[Count];         // compressed 
   ulong       Count;              
   XYZTriplet  Points[Count];      // UNcompressed
   ulong       Count;             
   XYZTriplet  Normals[Count];     // UNcompressed
 }
  • Count is the same value for all four tables.

Textures

 struct
 {
  ulong  Count;
  asciiz Textures[...];          // "data/1.paa\0data/2.paa\0"...
 }

Count corresponds to the number of concatenated strings. It is required, since, architecturally at least, one of more of the asciiz strings could be null.


NamedProperty

 struct
 {
    Asciiz Property;// "noshadow" = "1" eg
    Asciiz Value;
 }


Related Page(s)

LZ in ODOL

see Compressed LZSS File Format

Model File Formats