P3D File Format - ODOLV7

From Bohemia Interactive Community
Revision as of 17:14, 18 June 2007 by Raedor (talk | contribs) (ODOL moved to P3D File Format - ODOLV7: ...)
Jump to navigation Jump to search

Template:unsupported-doc

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;

C code

int Decode(unsigned char *in,unsigned char *out,int szin,int szout)
{
       szin = szin > 0? szin: 0x7fffffff;
       int  i, j, k, r = 0, pr, pi = 0,po = 0;
       unsigned int  flags = 0;
       unsigned char buf[0x100F], c;
       for (i = 0; i < 0x100F; buf[i] = 0x20, i++);
       while (pi < szin && po < szout)
       {
               if (((flags >>= 1) & 256) == 0)
               {
                       if(pi >= szin)break;
                       c = in[pi++];
                       flags = c | 0xff00;
               }
               if (flags & 1)
               {
                       if(pi >= szin || po >= szout)break;
                       c = in[pi++];
                       out[po++] = c;
                       buf[r++] = c;
                       r &= 0xfff;
               } else
               {
                       if(pi + 1 >= szin)break;
                       i = in[pi++];
                       j = in[pi++];
                       i |= (j & 0xf0) << 4;
                       j  = (j & 0x0f) + 2;
                       pr = r;
                        for (k = 0; k <= j; k++)
                       {
                               c = buf[(pr - i + k) & 0xfff];
                               if(po >= szout)break;
                               out[po++] = c;
                               buf[r++] = c;
                               r &= 0xfff;
                       }
               }
       }
       return pi;
}