P3D File Format - ODOLV7

From Bohemia Interactive Community
Revision as of 14:43, 20 May 2007 by Jakub BXBX Horyna (talk | contribs) (odol file format)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Overall

// uint unsigned integer 32bit
// word unsigned short integer 16bit
struct ODOL
  {
  char Signature[4]; //"ODOL"
  uint Version;     // 7
  uint LodCount;    // at least one
  struct Lod[LodCount]
  {
    uint VerticesCount;
    uint VerticesAttribs[VerticesCount]; // if VerticesCount > 255 then array is compresed by LZ algorithm. see LZ in ODOL.
 
    uint VerticesCount; // again same value
    struct UVset[VerticesCount]; // if VerticesCount > 127 then array is compresed by LZ algorithm. see LZ in ODOL.
 
    uint VerticesCount; // again same value
    struct VerticesPosition[VerticesCount];
 
    uint VerticesCount; // again same value
    struct VerticesNormal[VerticesCount];
 
    float fvalue[12];  // unknown values // containts some max/min vertices positions and so far
 
    uint TexturesCount;
    char Textures[...]; // zero ended 'C' strings 'd','a','t','a','\','1','.','p','a','a','\0','d','a','t','a','\','2','.','p','a','a','\0'...
    //read until count of founded char('\0') equil TexturesCount;
 
    uint Table1stCount;
    word Table1st[Table1stCount];// if Table1stCount > 511 then array is compresed by LZ algorithm. see LZ in ODOL.
 
    uint Table2ndCount; // Table2ndCount is same value like VerticesCount
    word Table2nd[Table2ndCount];// if Table2ndCount > 511 then array is compresed by LZ algorithm. see LZ in ODOL.
    //tables can by used to join vertices, each face has got 3 or 4 vertices that are seperated for each face in odol format
    //every vertex is owned only by 1 face
    //mlodvertexindex = Table1st[ Table2nd[ odolvertexindex ] ];
 
    uint FacesCount;
    uint uvalue;  // unknown value
    struct Face[FacesCount];
 
    uint uvalue2; // unknown value
    char uchar[18*uvalue2]; // unknown value
 
    uint NamedSelectionCount 
    struct NamedSelection[NamedSelectionCount]
 
    uint NamedPropetiesCount;
    struct NamedPropeties[NamedPropetiesCount]
 
    uint uvalue7;// unknown value
    struct ustruct[uvalue7]; // unknown value
 
    uint ProxiCount;
    struct Proxi[ProxiCount];
  }; // end of lod
uint ResolutionCount; // same as LODCount
float  Resolution[ResolutionCount];
.
.
. // folows some unknow data.
}; // end of ODOL;

Faces

  struct Face
    {
      uint Attribs;
      word TextureIndex; //if ((int)TextureIndex==-1) no texture;
      char CountOfVertices;  // 3 or 4
      word VerticesIndex[CountOfVertices]; //! size of array is not constant.
    };

NamedSelection

  struct NamedSelection
    {
      char name[...]; // zero ended string
 
      uint VerticesSelectedCount;
      word VerticesSelected[VerticesSelectedCount];// if VerticesSelectedCount > 511 then array is compresed by LZ algorithm. see LZ in ODOL.
 
      uint uvalue3; // unknown value
      word uarray[uvalue3];// unknown value
 
      uint uvalue4; // unknown value
      uint uarray[uvalue4];// unknown value // if VerticesSelectedCount > 255 then array is compresed by LZ algorithm. see LZ in ODOL.
 
      char uchar; // unknown value 
  
      uint uvalue5; // unknown value
      uint uarray[uvalue5];// unknown value
 
      uint FacesSelectedCount;
      word FacessSelected[FacesSelectedCount]// if FacesSelectedCount > 511 then array is compresed by LZ algorithm. see LZ in ODOL.
 
      uint uvalue6; // unknown value
      char uarray[uvalue6];// unknown value
    };

VerticesPosition

   struct VerticesPosition
    {
      float x,y,z;
    };

VerticesNormal

   struct VerticesNormal
    {
      float x,y,z;
    };

UVset

   struct UVset
    {
      float U,V;
    };

Proxi

  struct Proxi
    {
      char Name[...] // zero ended  string
      struct ustruct {...};// size same as char[56]; // unknown value
    };

ustruct

  struct ustruct // unknown value
    {
      uint uvalue8;// unknown value
      uint uvalue9;// unknown value
      char uarray[12*uvalue9];// unknown value :-( i know nothing about it
    };

NamedPropeties

  struct NamedPropeties
    {
      char Name[...];
      char Value[...]; // 'n','o','s','h','a','d','o','w','\0','1','\0'...
    };

LZ in ODOL

//Lempel-Ziv compression
// pascal code
function LZBlockRead(var F:file; var outdata:array of byte;szout:integer):byte;
var
k, r, pr, pi,po,i,j:integer;
flags:word;
buf:array[0..$100e] of byte;
c:byte;
crc:integer;
begin
po:=0;
pi:=0;
flags:=0;
r:=0;
for k := 0 to $100F-1 do buf[k] := $20;
       while (po < szout) do
        begin
           flags:= flags shr 1;
           if ((flags and $100)= 0) then
               begin
                 BlockRead(F,c,1);   // direct reading from file
                 inc(pi);
                 flags := c or $ff00;
               end;
           if (flags and 1)=1 then
                begin
                  if (po >= szout)then break;
                  BlockRead(F,c,1);   // direct reading from file
                  inc(pi);
                  outdata[po] := c;
                  inc(po);
                  buf[r] := c;
                  inc(r);
                  r :=r and $fff;
                end
           else
                begin
                  i:=0;
                  BlockRead(F,i,1);  // direct reading from file
                  inc(pi);
                  j:=0;
                  BlockRead(F,j,1); // direct reading from file
                  inc(pi);
                  i :=i or ((j and $f0) shl 4);
                  j := (j and $0f) + 2;
                  pr := r;
                  for k := 0 to j do
                    begin
                      c := buf[(pr - i + k) and $fff];
                      if (po >= szout) then break;
                      outdata[po]:= c;
                      inc(po);
                      buf[r]:= c;
                      inc(r);
                      r :=r and $fff;
                    end;
             end;
       end;
     BlockRead(F,crc,4);   // unknow 4bytes data on end of record , I suppose that it is some like CRC or MD5 checksum .
     result:= pi;
end;