{"name":"P3D File Format - ODOLV40 Obsolete","title":"P3D File Format - ODOLV40 Obsolete","type":"topic","url":"https://community.bistudio.com/wiki/P3D_File_Format_-_ODOLV40_Obsolete","revid":373406,"updated":"2025-05-08T11:27:10Z","aliases":["P3D File Format - ODOLV40"],"markdown":"> **Disclaimer: This page describes internal undocumented structures of Bohemia Interactive software.**\n>\n> This page contains unofficial information.\n>\n> Some usage of this information may constitute a violation of the rights of Bohemia Interactive and is in no way endorsed or recommended by Bohemia Interactive.\n> Bohemia Interactive is not willing to tolerate use of such tools if it contravenes any general licenses granted to end users of this community wiki or BI products.\n\nThe following information has been provided by BxBx and included by Mikero\n\n### Legend\n\n```\n//Legend\n//byte = 1 char = 8 bits\n//int = 4 byte = 32 bits; signed integer\n//ulong = unsigned long, 4 bytes\n//ushort = unsigned short 2 bytes\n//asciiz = variable length zero terminated string.\n//float = 4 bytes (single precision)\n//bool8 = 1 byte = 8 bits; boolean; 0 or 1\n```\n\n### basics\n\n```\nBlocks in Odol V40 are quite similar to Odol v7 but placed in reverse order.\n\nResolution table,\nLOD tables last to first\n\nThe same LZ compression is used for LODs as ODOL v7\n\nknown data:\n\nBeginning of file (Header signature)\n```\n\n### HeaderTop\n\n```\nstruct OdolV40\n{\nchar signature[4]  //ODOL\nlong Version        //0x28, 40 dec\nlong lod_count\n```\n\n### other\n\n```\nfloat resolutions[lod_count]\n{\n long  u1;\n float u2,u3,u4\n} // unknown data, same data follows on end of ODOL v7\n\nbyte   u5[139];      // unknown data , still same length as v7\nAsciiz skeleton_name // Note: A Skeleton may not exist\nif (*skeleton_name)\n{\n bool    u6 // 8bit boolean // value 1 or 0\n int     bone_count\n struct  bones[bone_count]\n {\n   Asciiz bone1,bone2;\n }\n}\n\nchar u7[0x26]     // unknown data\nAsciiz modelclass, modelparent // I think purpose this data found values 'houseno'\n                               //housebuilding',....\nchar u8[5]        // unknown data\nbool8 exist_anims\nif (exist_anims)\n{\n int anims_count\n struct anims[anims_count]\n {\n   int  type        // 0,4,9 // rotation,move,.., i dont check it yet\n    Asciiz name,parent\n   float tr[6]  // transformations values\n   if (type!=9) int u9\n }\n}\n\nunknowdata[unknowlength] // handle seek\n\nstruct lod[lod_count]\n{\n int     vertices count\n bool8   ub1\n if (ub1) char uch[11]  // unknow data\n char    uch[0x29]   // unknow data\n int     textures_count\n Asciiz  texture[textures_count]\n int     materials_count\n struct  materials[materials_count]\n {\n  Asciiz  name\n  char    uch[0x85] // unknowdata // some float values\n  int     textures_count\n  struct  textures_in_material[textres_count]\n  {\n   int    u10 // value 3 still\n   Asciiz t_name\n   int    u11 // self increment value // 0,1,2,3,4,...\n  }\n  char uch[0x34*textres_count] // some struct with same length\n       //as textures_in_material\n       // I dont work with material now, I skip it.\n }\n if ( textures_count>0 ) char uch[7];\n bool8 ub // unknown value\n int faces_count\n char u12[6]\n struct faces[6]\n {\n  char dot_count\n  unsigned short dot_vertice_index[dot_count]\n }\n unknowdata[ubknowlength]\n int components_count\n struct components[components_count]\n {\n  char *name;\n  int selected_faces_count\n  ushort selected_faces[selected_faces_count] // if selected_faces_count > 0x100\n          // then compresed by LZ\n  int    u14;\n  ushort u15[u14]\n  bool8 ub\n  if (ub) int u16\n  char uch[3]\n  bool8 ub2\n  int selected_vertices_count\n  ushort selected_vertices[selected_vertices_count] // if selected_vertices_count > 0x100\n//  then compresed by LZ\n  int   u17\n  char  uch[u17];\n }\n int named_properties_count\n struct named_properties[named_properties_count]\n {\n  char * name,*value\n }\n\n unknowdata[mostly 0x15 , but not every time]\n\n int vertices_count // again same value\n bool8 ub\n if (ub)\n {\n   struct UV[vertices_count] {float u,v} if count > 127 then LZ\n }\n else char uch[8]\n int u[18]\n int vertices_count\n struct vertices_pos[verices_count]{float x,y,z}\n\nnormals and the other data follow ,but this is in progress\n}\n```\n\nI cannot find face.texture_index information, in M16A4 are only 2 textures and I texture it handly by original UVsets.\n\n##### links\n\n```\n1st ARMA MLOD M16A4 on BIForum (dead link)\nOFP ODOLv7\nMore about LZ compresion ODOLv7\n```","sections":[{"heading":null,"level":1,"markdown":"> **Disclaimer: This page describes internal undocumented structures of Bohemia Interactive software.**\n>\n> This page contains unofficial information.\n>\n> Some usage of this information may constitute a violation of the rights of Bohemia Interactive and is in no way endorsed or recommended by Bohemia Interactive.\n> Bohemia Interactive is not willing to tolerate use of such tools if it contravenes any general licenses granted to end users of this community wiki or BI products.\n\nThe following information has been provided by BxBx and included by Mikero"},{"heading":"Legend","level":3,"markdown":"```\n//Legend\n//byte = 1 char = 8 bits\n//int = 4 byte = 32 bits; signed integer\n//ulong = unsigned long, 4 bytes\n//ushort = unsigned short 2 bytes\n//asciiz = variable length zero terminated string.\n//float = 4 bytes (single precision)\n//bool8 = 1 byte = 8 bits; boolean; 0 or 1\n```"},{"heading":"basics","level":3,"markdown":"```\nBlocks in Odol V40 are quite similar to Odol v7 but placed in reverse order.\n\nResolution table,\nLOD tables last to first\n\nThe same LZ compression is used for LODs as ODOL v7\n\nknown data:\n\nBeginning of file (Header signature)\n```"},{"heading":"HeaderTop","level":3,"markdown":"```\nstruct OdolV40\n{\nchar signature[4]  //ODOL\nlong Version        //0x28, 40 dec\nlong lod_count\n```"},{"heading":"other","level":3,"markdown":"```\nfloat resolutions[lod_count]\n{\n long  u1;\n float u2,u3,u4\n} // unknown data, same data follows on end of ODOL v7\n\nbyte   u5[139];      // unknown data , still same length as v7\nAsciiz skeleton_name // Note: A Skeleton may not exist\nif (*skeleton_name)\n{\n bool    u6 // 8bit boolean // value 1 or 0\n int     bone_count\n struct  bones[bone_count]\n {\n   Asciiz bone1,bone2;\n }\n}\n\nchar u7[0x26]     // unknown data\nAsciiz modelclass, modelparent // I think purpose this data found values 'houseno'\n                               //housebuilding',....\nchar u8[5]        // unknown data\nbool8 exist_anims\nif (exist_anims)\n{\n int anims_count\n struct anims[anims_count]\n {\n   int  type        // 0,4,9 // rotation,move,.., i dont check it yet\n    Asciiz name,parent\n   float tr[6]  // transformations values\n   if (type!=9) int u9\n }\n}\n\nunknowdata[unknowlength] // handle seek\n\nstruct lod[lod_count]\n{\n int     vertices count\n bool8   ub1\n if (ub1) char uch[11]  // unknow data\n char    uch[0x29]   // unknow data\n int     textures_count\n Asciiz  texture[textures_count]\n int     materials_count\n struct  materials[materials_count]\n {\n  Asciiz  name\n  char    uch[0x85] // unknowdata // some float values\n  int     textures_count\n  struct  textures_in_material[textres_count]\n  {\n   int    u10 // value 3 still\n   Asciiz t_name\n   int    u11 // self increment value // 0,1,2,3,4,...\n  }\n  char uch[0x34*textres_count] // some struct with same length\n       //as textures_in_material\n       // I dont work with material now, I skip it.\n }\n if ( textures_count>0 ) char uch[7];\n bool8 ub // unknown value\n int faces_count\n char u12[6]\n struct faces[6]\n {\n  char dot_count\n  unsigned short dot_vertice_index[dot_count]\n }\n unknowdata[ubknowlength]\n int components_count\n struct components[components_count]\n {\n  char *name;\n  int selected_faces_count\n  ushort selected_faces[selected_faces_count] // if selected_faces_count > 0x100\n          // then compresed by LZ\n  int    u14;\n  ushort u15[u14]\n  bool8 ub\n  if (ub) int u16\n  char uch[3]\n  bool8 ub2\n  int selected_vertices_count\n  ushort selected_vertices[selected_vertices_count] // if selected_vertices_count > 0x100\n//  then compresed by LZ\n  int   u17\n  char  uch[u17];\n }\n int named_properties_count\n struct named_properties[named_properties_count]\n {\n  char * name,*value\n }\n\n unknowdata[mostly 0x15 , but not every time]\n\n int vertices_count // again same value\n bool8 ub\n if (ub)\n {\n   struct UV[vertices_count] {float u,v} if count > 127 then LZ\n }\n else char uch[8]\n int u[18]\n int vertices_count\n struct vertices_pos[verices_count]{float x,y,z}\n\nnormals and the other data follow ,but this is in progress\n}\n```\n\nI cannot find face.texture_index information, in M16A4 are only 2 textures and I texture it handly by original UVsets."},{"heading":"links","level":5,"markdown":"```\n1st ARMA MLOD M16A4 on BIForum (dead link)\nOFP ODOLv7\nMore about LZ compresion ODOLv7\n```"}],"categories":["ArmA: Armed Assault: File Formats","Real Virtuality File Formats"],"groups":["Tools and File Formats"]}