P3D File Format - ODOLV4x – Talk

From Bohemia Interactive Community
Revision as of 20:16, 31 January 2021 by Lou Montana (talk | contribs) (Text replacement - " (={2,})([^ = ])(.*)([^ = ])(={2,}) * " to " $1 $2$3$4 $5 ")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

In structSkeleton the data type bool is used. Is it 1 byte with possible values 0 and 1? --Vektorboson 22:55, 19 July 2008 (CEST)

Yes, I believe it is. Amended, article to a 'byte' with 0x00=false, 0x01=true. -- Sy 04:56, 20 July 2008 (CEST)

I will use this page to keep track of some of my thoughts: --T_D 23:56, 3 January 2009 (CET)

  1. ModelProxies should be part of structResolution imo
  2. byteArrayUnknown1 could consist of at least a few floats
  3. Unknown could contain something like modelCenter or boundingBox
  4. Mass data should be somewhere

Yeah, sorry, haven't updated this article in a long time. Quite, alot of extra info. could be added but tbh haven't had the motivation and of course some or all of the stuff may or may not be accurate.
Here's the area 'tween the Header and the Skeleton...
Information moved into main text Mikero (nee Ook?) 07:40, 10 January 2009 (CET)
btw... the ModelInfo.ModelMassVector1_blah's are inaccurately identified, just old placeholder names that have never been updated.
Cheers, -- Sy 10:59, 6 January 2009 (CET)

Stage UVtransforms

i have altered the struct from

float aside[3]; //this doesn't appear to be correct
float up[3];    //it looks more like a direct X transform matrix
float dir[3];   //
float pos[3];   //


float Transform[3][4];  

because it appears to closely match the directX as per other p3d type files (MLOD for ofp eg)

Mikero (nee Ook?) 12:20, 10 January 2009 (CET)

Determining stage count

the values for PixelShaderID's 8,10 and 0x3C are 'wrong' for some few official arma p3d's

it *seems* to be dependent on the VertexShaderId

pond.p3d par exemple

type 10 needs to be +1 if VertexShaderId==8 and perhaps any other non-zero value (only ever seen 0, or 8)

type 8 needs to be +1 only a VertexShaderId==8 ever seen

jablon.p3d eg

type 0x3c needs to be = 3 (not 0) for all files encountered (all files encountered have a non zero VertexShaderId of varying counts)

the correct value for Stagecount has has been found Mikero (nee Ook?) 07:08, 15 January 2009 (CET)


BMP2.p3d has some cases where isPresent is true but the unknownArray is empty. So it probably serves another purpose. --T_D 11:16, 22 January 2009 (CET)

ah I found out that isPresent is true when the Component is listed in the sections list of model.cfg --T_D 11:38, 22 January 2009 (CET)

What is LodComponentCfgModels? --T_D 11:41, 23 January 2009 (CET)

sorry about that. have no idea how that slipped in. Removed Mikero (nee Ook?) 04:38, 26 January 2009 (CET)


I agree that the value found in these 4 bytes can successfully be used to 'skip' ahead to the 'Sections' structure using the formula (Value - NoOfPolygons). However, I believe that this is a side effect of what the value stands for. I think it's more likely that it's the memory size that the engine would allocate to store an internal array of polygons. For example. Take the an m1_abrams.p3d, lod 1.0.

NoOfPolygons=10065, PolyArraySize=83232 bytes.

After reading these 2 values the engine would know 2 things obviously. How many poly's make up this lod and the allocation size needed to store them. But it obviously does not know how many of these 10065 poly's are tri's or quads. Only after iterating through the poly's file structure would this ultimatelty be determined. It just so happens that this particular lod has 8709 tri's and 1356 quads. Internally, the engine needs to know 2 things about a poly. 1. the verts and 2. the section it belongs too. A vert index takes 2 bytes (ushort). A tri then would require 6 bytes for it's verts and the remainging 2 bytes would be a ushort for the section index it belongs too, totalling 8 bytes. A quad would require 8 bytes + 2 bytes for the section index = 10 bytes. Hence the 8 & 10 byte situations when reading a section.

Given the example above. 8709 tri's * 8 bytes = 69672 bytes. 1356 quads * 10 bytes = 13560 bytes. 69672 bytes + 13560 bytes = 83232 bytes. It's a side effect (well, actually it's quite logical if you think about it...) that 83232 bytes - 10065 = 73167 bytes is the offset to the sections area in this lod. Also, if reading the poly's from the file one would imagine that they would possibly ultimately end up stored in memory in the following manner.

[ [10065 bytes] [73167 bytes] ]

[ 83232 bytes ]

The first 10065 bytes would get filled with all the poly's 'NoOfVerts' 1-byte values and the remaining 73167 bytes would be populated with all the 2-byte vert index's. In assembly language it's incredibly fast to navigate a data structure like this, but that's just supposition and I digress.

Anyhoo, I think this value should be called 'PolyArraySize' or something similar. And, btw, nice deducement... good one. And, TD, the component isSectional boolean deducement is great too... :) -- Sy 12:52, 23 January 2009 (CET)