PEW File Format: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
(massive grammar and formatting cleanup; also removing some "of course", "by inference", etc., since that assumes I can infer ;-))
Line 3: Line 3:
== Introduction ==
== Introduction ==


Pew are Visitor's project files. Visitor is BI's tool for creating Islands.
PEW files are [[Visitor 3|Visitor]]'s project files. Visitor is [[BI]]'s tool for creating Islands.


Visitor is a Gui tool interface that interacts with Bulldozer, an inbuilt 'world' viewer inside any Armed Assault engine.
Visitor is a GUI tool interface that interacts with [[Bulldozer]], an in-built 'world' viewer inside any [[Armed Assault]] engine.


The contents of the project file, pew, are not directly related to the ultimate output, a wrp file. However, that data, of course, contains all similar elements, such as road networks, elevations, cell matrices, models (p3d files) and textures (rvmat files).
The contents of the PEW project file are not directly related to the ultimate output, a WRP file. However, that data contains all similar elements, such as road networks, elevations, cell matrices, models (P3D files) and textures (RVMAT files).


Exporting a pew file into wrp format, involves the use of Bulldozer, since it is Bulldozer that decides how it wants that data presented, rather than anything visitor might like to decide. It is Bulldozer that determines the format and version of the resulting wrp file (in 8WVR format), and consequently, that, is a reflection of the Arma Engine itself.
Exporting a PEW file into WRP format involves the use of Bulldozer, since it is Bulldozer that decides how it wants that data presented rather than anything Visitor might like to decide. It is Bulldozer that determines the format and version of the resulting WRP file (in 8WVR format), so the WRP version is based on the version of the [[Real Virtuality]] engine used to create it.


While there have been several pew versions, the one's listed here are
While there have been several PEW versions, the ones listed here are:
*POSEW59 and
*POSEW59 and
*POSEW60
*POSEW60


there are only a few subtle differences to their makeup.
There are only a few subtle differences to their makeup.
 
=== Legend ===
=== Legend ===
see [[Generic FileFormat Data Types]]
 
See [[Generic FileFormat Data Types]]


== File Format ==
== File Format ==


::*This file format is principally used with Armed Assault v1.09 and later plus the ArmA Tools Suite Final release (v1.14).
::*This file format is principally used with Armed Assault v1.09 and later, with the ArmA Tools Suite final release (v1.14).


   POSEW59
   POSEW59
Line 99: Line 101:
*IslandDataPath
*IslandDataPath


Rvmat file references in the Layers structure are listed as RELATIVE addresses. Relative to the Island Data Path.
RVMAT file references in the Layers structure are listed as ''relative'' addresses to the Island Data Path. Traditionally, an RVMAT data path is declared as "Layers\some.rvmat". It is expected, therefore, that you do indeed have a "P:\SomePboPrefix\SomeIsland\data\Layers" folder.  Put another way, the ''prefix'' of the PBO must be "SomePboPrefix\SomeIsland".
Traditionally, an rvmat is declared as "Layers\some.rvmat".
It is expected, therefore, that you do indeed have a  
 
"P:\SomePboPrefix\SomeIsland\data\Layers" folder


Or, put another way. The PREFIX of the pbo must be "SomePboPrefix\SomeIsland"
All RVMAT files must be located in '''one''' PBO (generally, but not necessarily, within the the same PBO as the WRP file). With the above mechanism, you cannot pull RVMAT data from multiple PBOs.  This is in contradiction to most of the engine mechanics where everything is a hard reference to any PBO of your choosing.


By inference then, ALL rvmat files must be located in ONE pbo (generally, but not necessarily, the same pbo as the wrp file) Witj the above mechanism, you CANNOT pull rvmats from multiple pbo's. This is in contradistinction to most of the engine mechanics where everything (else) is a hard reference to any pbos of your choosing. P3d's eg.
In P3D files,


*IslandObjectPath
*IslandObjectPath
*IslandClassname
*IslandClassname


IslandObjectPath uses the same mechanics as above. However, since p3d files can, and are, declared from multiple locations (any pbo, including ca) it's use is *probably* deprecated.
IslandObjectPath uses the same mechanics as above. However, since P3D files can be declared from multiple locations (any PBO, including the base 'CA' PBO included in the game) its use is probably deprecated.


Pew files are not known to contain anything in IslandObjectPath or IslandClassname. This statement, subject to revision.
PEW files are not known to contain anything in IslandObjectPath or IslandClassname. <!-- This statement is subject to revision. -->


===OFPTexture===
===OFPTexture===
Line 164: Line 162:
   }
   }


As opposed to layers (material rvmat surfaces) 'Objects' are p3d's placed ONTO the map.
As opposed to layers (material RVMAT surfaces), 'objects' are instances of models placed onto the map. Irrespective of the number of objects there is only one reference to the model used, which is then referenced as often as needed.
 
Irrespective of the number of objects (thousands++) there is only one reference to THE model used. referenced, potentially, multiple times. (grass.p3d eg)


ModelFilename, ModelName, and ModelID are unique unduplicated entries.
ModelFilename, ModelName, and ModelID are unique unduplicated entries.


The ModelID is not zero based, it's value is incremental according to the number of times ANY model has been added, subsequently deleted, while editing.
The ModelID is not zero based; its value is incremental according to the number of times ''any'' model has been added while editing, even if previous models have been deleted; model IDs do not rearrange themselves and deleted IDs are not recycled for re-use.
The ObjectID illustrated on maps is, in contrast, the unique InstanceID of each object in the objects structure below.
The ObjectID illustrated on maps is, in contrast, the unique InstanceID of each object in the objects structure below.


Line 249: Line 245:
   }
   }


MeterType
{| class="wikitable"
:Type Straights Curves
|-
:0     6         25   meters
! colspan="3"| MeterType Values
:1     12         50
|-
:2     25         75
! Type
:3               100
! Straights
 
! Curves
Broadly speaking, there are a few basic road types
|-
 
| 0 ||  6 m || 25 m
*asfalt  bitumen.
|-
*silnice  Paved
| 1 || 12 m || 50 m
*cesta    dirt
|-
| 2 || 25 m || 75 m
|-
| 3 ||      ||100 m
|-
|}


Each RoadType describes the general characteristics of a Dirt Road as opposed to (say) an Asphalt one.
Broadly speaking, there are a few basic road types:
* '''asfalt''': Bitumen
* '''silnice''': Paved
* '''cesta''': Dirt


Each of these RoadTypes  (such as asphalt) can have multiple curved, straight, special, and termination p3d models associated with them.
Each RoadType describes the general characteristics of the corresponding road, and can have multiple curved, straight, special, and termination P3D models associated with it.


Generally speaking, there are  
Generally speaking, there are:
*3 'straight' models, approximately 6,12, and 25 meters long respectively.
* 3 'straight' models, approximately 6, 12, and 25 meters long respectively.
*4 'curved' models, 25,50,75 and 100 meters long.
* 4 'curved' models, approximately 25, 50, 75, and 100 meters long.
*1 'terminaton type.
* 1 'termination' type.
The termination type is a road like any other but tends to be a fixed 6 meter fade out of the general road texture.
The termination type is a road like any other but tends to be a fixed 6 meter fade out of the general road texture.


Line 283: Line 287:
  }
  }


Although CrossRoads could, conceivably, have any number of intersections, only two types are handled.
Although "CrossRoads" could conceivably have any number of intersections, only two types are handled.


*Type 1: A T_Junction (3 intersections)
*Type 1: A T_Junction (3 intersections)
*Type 3: A Genuine crossroad (4 way intersection)
*Type 3: A genuine crossroad (4 way intersection)


For T_Junctions, there is, obviously, no 4th intersection and this is null filled.
For T_Junctions, there is obviously no 4th intersection and this is null filled.


Without taking too literal an interpretation, there are some major types of road.
Without taking too literal an interpretation, there are some major types of road.
Line 332: Line 336:
</nowiki></code>
</nowiki></code>


*ObjectID
* ObjectID
 
EVERY object entry has a zero based, linear sequential ObjectID. EVEN WHEN IT IS NOT PRESENT.
 
ObjectID is unique for every object and is the value displayed on a map for all p3d's placed on it (including roads, grass, etc).
 
Every tree, every road section, has it's own, unique, ObjectID.
 
The first Object in the pew file is ObjectID==0, the next 1,2,3,4 etc.


Whether an object is really there (IsPresent=true) or not, that entry, retains a unique object ID. (when not present, it is by inference).
Every object entry has a zero-based, linear sequential ObjectID.  ObjectID is unique for every object and is the value displayed on a map for all models placed on it (including roads, grass, etc.).  Thus, every tree and every road section has its own unique ObjectID.


The next 'real' object (one that IsPresent) is, the Nth ObjectID because the number increases by the number of object entries, present or not.
The first Object in the PEW file is ObjectID==0, the next 1,2,3,4 etc.


The reason for this is to maintain consistent ID's for objects so that missions can rely on a bush having the same NearestObject ID as it always had, irrespective of map upgrades.
If an object has been deleted, that entry retains its unique object ID, even though the ObjectID is no longer stored.  If an object is not present (IsPresent is false), the ObjectID is calculated based on the last used object ID.  The next real object (IsPresent is true) will always be the ''N''th ObjectID because the number always increases by the number of object entries, present or not.  The reason for this is to maintain consistent IDs for objects so that missions can rely on a bush having the same NearestObject ID as it always had, irrespective of map upgrades.


From this, you can infer that when you add a new object, it ALWAYS is added to end of table, and when you Remove and object, it remains, as a phantom.
When you add a new object, it is thus always is added to end of table with a new object ID.  When you remove an object, the object ID remains reserved even though the object no longer exists.


This mechanisim works well WITHIN the arma engine, but fails to help at all for conversion of OFP islands, unless you methodically enter all 100,000 entries in the correct order. (yeah, right)
This mechanism works well within the ArmA engine, but fails to help at all for conversion of OFP islands unless you methodically and manually enter all of the entries in the correct order. With upwards of 100,000 entries per island, this is practically impossible.


*ModelID
* ModelID


Note that this is the unique ID of the ModelID in the object Template. It is NOT, an index INTO the template structures. Unusual, and slow as a result.
Note that this is the unique ID of the ModelID in the object Template. It is not an index into the template structures. Unusual, and slow as a result. <!-- This should be explained in more detail.  Why is it unusual?  Why is it slow? -->


===Layer===
===Layer===
Line 384: Line 380:


TableSize = Terrain.GridSize>> SizeType;
TableSize = Terrain.GridSize>> SizeType;




Line 396: Line 391:
   ulong    Unknown[12];  
   ulong    Unknown[12];  
             /* typical data
             /* typical data
             **00 00 00 00 00  
             ** 00 00 00 00 00 00 00 F0
00 00 F0 2C  
            ** 2C 46 00 98 23 46 C6 6F
46 00 98 23  
            ** C6 42 0E 01 00 00 01 00
46 C6 6F C6  
            ** 00 F0 2C 46 00 98 23 46
42 0E 01 00  
            ** C6 6F C6 42 0E 01 00 00
00 01 00 00  
            ** 4B 00 00 00 00 00 00 00
F0 2C 46 00  
98  
23 46 C6 6F  
C6 42 0E 01  
00 00 4B 00  
00 00 00 00  
00 00  
             */
             */
   ushort    Type;            // 0,1,2,3
   ushort    Type;            // 0,1,2,3
Line 419: Line 407:
   ulong    Unknown[27];
   ulong    Unknown[27];
             /* typical data
             /* typical data
             **FA D4 30 BF 94 58 08 3D 00 00 C8 C0 00 00 60 C0  
             ** FA D4 30 BF 94 58 08 3D 00 00 C8 C0 00 00 60 C0
             **00 00 00 00 00 00 48 C1 00 00 60 40 00 00 00 00  
             ** 00 00 00 00 00 00 48 C1 00 00 60 40 00 00 00 00
             **00 00 48 C1 00 00 60 C0 00 00 00 00 00 00 00 00  
             ** 00 00 48 C1 00 00 60 C0 00 00 00 00 00 00 00 00
             **00 00 60 40 00 00 00 00 00 00 00 00 00 00 C8 C0  
             ** 00 00 60 40 00 00 00 00 00 00 00 00 00 00 C8 C0
             **00 00 00 00 00 00 30 C0 00 00 C8 C0 00 00 00 00  
             ** 00 00 00 00 00 00 30 C0 00 00 C8 C0 00 00 00 00
             **00 00 1C C1 04 01 00 00 00 00 00 00 00 00 00 00  
             ** 00 00 1C C1 04 01 00 00 00 00 00 00 00 00 00 00
             **09 00 00 00 0B 80 00 00 04 00 00 00  
             ** 09 00 00 00 0B 80 00 00 04 00 00 00
             */
             */
   ulong    Count;     
   ulong    Count;     
Line 431: Line 419:
   }
   }
  }
  }
Type
 
*0 Road Ending with FamilyName and it's ModelName_konec
{| class="wikitable"
*1 TJunction ModelName Only
|-
*2 Road similar to type 0
! colspan="2"| Type
*3 Xroad with ModelName Only
! Description
|-
| 0 || Road Ending with FamilyName and its ModelName_konec
|-
| 1 || TJunction ModelName Only
|-
| 2 || Road similar to type 0
|-
| 3 || Xroad with ModelName Only
|-
|} <!-- Documentation is like air; when it's bad, it's better than nothing... -->


====FamilyList====
====FamilyList====
Line 444: Line 442:
  }
  }


This struct is principally used for Xroads and Tjunctions. It typically lists the order of all RoadFamilyName's required
This struct is principally used for XRoads and T_Junctions. It typically lists the order of all RoadFamilyName values required.


====ModelList====
====ModelList====
  ModelList
  ModelList
  {
  {
   ulong      Count;          //15 eg
   ulong      Count;          //for example, 15
   BlockModel BlockModel[Count];
   BlockModel BlockModel[Count];
   String    FamilyName;      //"silnice hlavni silnic\0"
   String    FamilyName;      //"silnice hlavni silnic\0"
Line 497: Line 495:
   }[nPoints/4];
   }[nPoints/4];
             /* Typical Data
             /* Typical Data
             **00 00 61 45 00 78 1B 46 00 20 64 45 00 20 19 46  
             **00 00 61 45 00 78 1B 46 00 20 64 45 00 20 19 46  
             **00 20 64 45 00 78 1B 46 00 40 67 45 00 58 18 46  
             **00 20 64 45 00 78 1B 46 00 40 67 45 00 58 18 46  
             **00 40 67 45 00 78 1B 46 00 60 6A 45 00 58 18 46  
             **00 40 67 45 00 78 1B 46 00 60 6A 45 00 58 18 46  
             **00 60 6A 45 00 78 1B 46 00 80 6D 45 00 90 17 46  
             **00 60 6A 45 00 78 1B 46 00 80 6D 45 00 90 17 46  
             **00 80 6D 45 00 B0 1A 46 00 A0 70 45 00 C8 16 46  
             **00 80 6D 45 00 B0 1A 46 00 A0 70 45 00 C8 16 46  
             **00 A0 70 45 00 E8 19 46 00 C0 73 45 00 00 16 46  
             **00 A0 70 45 00 E8 19 46 00 C0 73 45 00 00 16 46  
             */
             */
   ulong    ID;            // 0,1,2,3,4....
   ulong    ID;            // 0,1,2,3,4....
Line 525: Line 523:
   ShortBool Visible;  
   ShortBool Visible;  
   float    Offset[2];  // map relative
   float    Offset[2];  // map relative
   float    Size[2];    // 250 x 250.0 eg (widht and height)
   float    Size[2];    // 250 x 250.0 eg (width and height)
   ulong    ID;        // 0,1,2,3,4,5,6....
   ulong    ID;        // 0,1,2,3,4,5,6....
   BisString TownName;  //"Lipany", "Hill"
   BisString TownName;  //"Lipany", "Hill"
Line 547: Line 545:
"La Refuge Des Chassuers"
"La Refuge Des Chassuers"


(Type Viewpoints and Marine eg) do not have names associated with them. There is no "place" in the sea.
Viewpoint and Marine types do not have names associated with them. There is no "place" in the sea.


===Background===
===Background===

Revision as of 23:19, 9 November 2009

Template:unsupported-doc

Introduction

PEW files are Visitor's project files. Visitor is BI's tool for creating Islands.

Visitor is a GUI tool interface that interacts with Bulldozer, an in-built 'world' viewer inside any Armed Assault engine.

The contents of the PEW project file are not directly related to the ultimate output, a WRP file. However, that data contains all similar elements, such as road networks, elevations, cell matrices, models (P3D files) and textures (RVMAT files).

Exporting a PEW file into WRP format involves the use of Bulldozer, since it is Bulldozer that decides how it wants that data presented rather than anything Visitor might like to decide. It is Bulldozer that determines the format and version of the resulting WRP file (in 8WVR format), so the WRP version is based on the version of the Real Virtuality engine used to create it.

While there have been several PEW versions, the ones listed here are:

  • POSEW59 and
  • POSEW60

There are only a few subtle differences to their makeup.

Legend

See Generic FileFormat Data Types

File Format

  • This file format is principally used with Armed Assault v1.09 and later, with the ArmA Tools Suite final release (v1.14).
 POSEW59
 POSEW60
 {
   PoseHeader               Header;
   ulong                    nOFPTextures           // none in Arma;
   OFPTexture               OFPTextures[nOFPTextures];
   ulong                    nObjectTemplates;
   ObjectTemplate           ObjectTemplates[nObjectTemplates];
   shortBool                NoOfpTerrains;
   if  (!NoOfpTerrains)
   {
   ulong                    nOFPTerrains;         //  none in Arma;
   OFPTerrain               OFPTerrains[nOFPTerrains];
   }
   shortBool                NoOFPForests;         //  none in Arma;
   if  (!NoOFPForests)
   {
   ulong                    nOFPForests;          
   OFPForest                OFPForests[nOFPForests];
   }
   RoadNets                 RoadNets[...];
   Elevation                Elevation[...];
   ulong                    NoOfObjects;
   Object                   Objects[NoOfObjects];

   ulong                    NoOfLayers;
   String                   LayerName;           //"Base"
   Layer                    Layers[[NoOfLayers] ;

   if (POSEW60)
   {
    ulong                   Unknown;
   }
   else // pose59
   {
     ulong                  nNamedZones;
     NamedZone              NamedZones[nNamedZones];
   }

   ulong                    nRoadBlocks;
   RoadBlock                RoadBlocks[nRoadBlocks];

   if (POSEW60)
   {
     ulong                  nNamedZones;
     NamedZone              NamedZones[nNamedZones];
   }
   else // pose59
   {
    ulong                   Unknown;
   }
   ulong                    nKeyPoints;
   KeyPoint                 KeyPoints[nKeyPoints];    
   ulong                    NoOfBackgrounds;
   Background               Backgrounds[NoOfBackgrounds] ;// not checked for 59
   ulong                    TotalSizeOfSelections; // from here, to end of file
   ulong                    nSelections;
   Selection                Selections[nSelections];
 }


PoseHeader

Header
{
 char     Signature[7];        // "POSEW59" or "POSEW60" note: NOT null terminated
 ulong    Length;              // of PEW file;
 ulong    UnknownLong;         // typically 0
 String   IslandDataPath;      //"SomePboPrefix\SomeIsland\data\0" see below
 String   IslandObjectPath;    //""
 float	  GridSize;            //50.0
 float	  SegmentSize;         //400.0 (==SegmentSize - SegmentOverlap)
 String   IslandClassname;     //""
};
  • IslandDataPath

RVMAT file references in the Layers structure are listed as relative addresses to the Island Data Path. Traditionally, an RVMAT data path is declared as "Layers\some.rvmat". It is expected, therefore, that you do indeed have a "P:\SomePboPrefix\SomeIsland\data\Layers" folder. Put another way, the prefix of the PBO must be "SomePboPrefix\SomeIsland".

All RVMAT files must be located in one PBO (generally, but not necessarily, within the the same PBO as the WRP file). With the above mechanism, you cannot pull RVMAT data from multiple PBOs. This is in contradiction to most of the engine mechanics where everything is a hard reference to any PBO of your choosing.

In P3D files,

  • IslandObjectPath
  • IslandClassname

IslandObjectPath uses the same mechanics as above. However, since P3D files can be declared from multiple locations (any PBO, including the base 'CA' PBO included in the game) its use is probably deprecated.

PEW files are not known to contain anything in IslandObjectPath or IslandClassname.

OFPTexture

OFPTexture
{
 ulong	    TextureID;
 String    TextureFileName;	// "snih3.paa"
 String    TextureName;	// "snih3"
 String    RvmatName;		// "snih3.rvmat"
 byte      UnknownBytes[14];	// (typically 0)
 RGBAColor Colour;
}

ObjectTemplate

 ObjectTemplate
 {
     String       ModelFilename; //"SomePrefixRoot\data\jablon.p3d\0"
     String       ModelName;     //"jablon"
     ulong        ObjectType;    // 0..5
                                 // 0 Natural
                                 // 1 Artificial
                                 // 2 ???
                                 // 3 Road (RoadFlag will be true)
                                 // 4 ???
                                 // 5 ArtificialAndDefinedInRoad
     RGBAColor    OutlineColour; 
     RGBAColor    ObjectColour;  
     double	  GeometryBounds[2];            // 50.0
     ulong	  ModelID;                      // uniqueID, used by objects to lookup this model(p3d)
     XYZTriplet   GeometryAutocenterPos;
     double	  ResolutionBounds[2];          // 50.0
     XYZTriplet   ResolutionAutoCenterPos;
     shortBool	  Generally0x01;   
     shortBool	  RandomScaleFlag;
     double	  RandomScaleMinMax[2];         // 50.0
     shortBool	  RandomRotateFlag;
     double	  RandomRotateMinMax[2];        // 20.0
     shortBool	  RandomOrientationFlag;     
     double	  RanmdomOrientationMinMax[2];  // 180.0
     shortBool	  RoadFlag;
     if (RoadFlag) 
     {
           TransformMatrix RoadNamedSelections; // (LB, PB, LE, PE)
           TransformMatrix XRoadNamedSelections;// (LD, LH, PD, PH)
     };
     ulong            nArtificialObjects;
     ArtificialObject ArtificialObjects[nArtificialObjects];
     ulong            MarkerType;	                // Rectangular = 0, Elliptical = 1 
 }

As opposed to layers (material RVMAT surfaces), 'objects' are instances of models placed onto the map. Irrespective of the number of objects there is only one reference to the model used, which is then referenced as often as needed.

ModelFilename, ModelName, and ModelID are unique unduplicated entries.

The ModelID is not zero based; its value is incremental according to the number of times any model has been added while editing, even if previous models have been deleted; model IDs do not rearrange themselves and deleted IDs are not recycled for re-use. The ObjectID illustrated on maps is, in contrast, the unique InstanceID of each object in the objects structure below.

ArtificialObject

 ArtificialObject
 {
    String     Name;       //"pohrada"
    LongBool   Unknown;
    ulong      nTriplets; // always 2
    XYZTriplet StartEndPos[nTriplets];
 }

OFPTerrain

OFPTerrain
{
 String  TerrainName;
 byte    UnknownBytes[11];
 ulong	  nSurfaces;
 OFPSurface OFPSurfaces[nSurfaces];
}

OFPSurface

OFPSurface
{
 String SurfaceName;
 float	 Surfacefloat[4];
 byte   UnknownBytes[16];
}

OFPForest

OFPForest
{
 String    ForestName;
 RGBAColor OutlineColour;
 RGBAColor ObjectColour;
 ulong	    SquareFillModelID;
 ulong	    SquareModelID;
 ulong	    TriangleModelID;
 ulong	    Unknown1;	// (typically 0)
 ulong	    Unknown2;	// (typically 0)
}

RoadNet

   shortBool NoRoads;
   if  (!NoRoads)
   {
     ulong    nTypes;
     RoadType RoadTypes[nTypes];
     ulong    nXRoads;
     XRoad    XRoads[nXRoads];
   }

RoadType

 RoadType
 {
   String       FamilyName;        // "cesta","silnice",etc
   RGBA         KeyPartsColour;    
   RGBA         NormalPartsColour; 
   shortBool    FilledLine;        // 0 or 1
   double       MaxAngle;          // 25.0 degrees 
   double       MaxBankAngle;      // 5.0 degrees
   ulong        nStraights;
   RoadList     Straights[nStraights];
   ulong        nCurves;
   RoadList     Curves[nCurves];
   ulong        nSpecials;
   RoadList     Specials[nSpecials];
   ulong        nTerminators;
   RoadList     Terminators[nTerminators];
   }
 }
RoadList
 RoadList     
 {
      String      ModelName;      // "cesta25"
      ulong       ObjectID;       // in the model list
      ushort      MeterType;      // 0,1,2,3 not present for Terminators
      shortBool   CanChangeAngle; // not present for Terminators or Curves
 }
MeterType Values
Type Straights Curves
0 6 m 25 m
1 12 m 50 m
2 25 m 75 m
3 100 m

Broadly speaking, there are a few basic road types:

  • asfalt: Bitumen
  • silnice: Paved
  • cesta: Dirt

Each RoadType describes the general characteristics of the corresponding road, and can have multiple curved, straight, special, and termination P3D models associated with it.

Generally speaking, there are:

  • 3 'straight' models, approximately 6, 12, and 25 meters long respectively.
  • 4 'curved' models, approximately 25, 50, 75, and 100 meters long.
  • 1 'termination' type.

The termination type is a road like any other but tends to be a fixed 6 meter fade out of the general road texture.

XRoad

XRoad
{
 String    Name;	      //kr_asfaltka_asfaltka_t.
 ushort    Shape;            //1 or 3
 RGBA      color;	      //FF FF FF FF 
 shortBool CanChangeBankAngle;
 ulong     ObjectID;
 String    Intersections[4]; //"asfaltka","silnice","cesta",Type=3 "silnice" else ""
}

Although "CrossRoads" could conceivably have any number of intersections, only two types are handled.

  • Type 1: A T_Junction (3 intersections)
  • Type 3: A genuine crossroad (4 way intersection)

For T_Junctions, there is obviously no 4th intersection and this is null filled.

Without taking too literal an interpretation, there are some major types of road.

  • asfaltka:bitumen (sealed)
  • silnice: Paved
  • cesta: Dirt

Thus the names of each intersection reflect the road type of that intersection, sometimes resulting in (up to) four identical names.

The overall name of the crossroad itself, tries to reflect the nature of it's makeup thus kr_asfaltka_asfaltka_t: an bitumen T_Junction kr_silince_x_cesta: a crossroad of paved and dirt roads.

Elevation

Elevation
{
   XYPair   GridSize; // 256 x 256 eg
   float    Heights[GridSize];
   float    BlueEdgeTerrainHeights[NoOfBlueFloats]  ; //Always zero values 
   // NoOfBlueFloats = (GridSize_Y * GridSize_X)/16;
   ulong    Always0;
}

Object

Object { ShortBool IsPresent; if (IsPresent) { ShortBool Moveable; // always 0 ulong ObjectID; // See Below float TransformColumn[3][4]; // this is a standard DirectX Transform matrix but in COLUMN format double ObjectRelativeSize; // decimal percentage String InstanceName; // "" mostly. "minimalStrelPos" eg for artifical objects float RelativeSurfaceElevation; RGBA OutlineColour; RGBA ObjectColour; ulong ModelID; // See below }; };

  • ObjectID

Every object entry has a zero-based, linear sequential ObjectID. ObjectID is unique for every object and is the value displayed on a map for all models placed on it (including roads, grass, etc.). Thus, every tree and every road section has its own unique ObjectID.

The first Object in the PEW file is ObjectID==0, the next 1,2,3,4 etc.

If an object has been deleted, that entry retains its unique object ID, even though the ObjectID is no longer stored. If an object is not present (IsPresent is false), the ObjectID is calculated based on the last used object ID. The next real object (IsPresent is true) will always be the Nth ObjectID because the number always increases by the number of object entries, present or not. The reason for this is to maintain consistent IDs for objects so that missions can rely on a bush having the same NearestObject ID as it always had, irrespective of map upgrades.

When you add a new object, it is thus always is added to end of table with a new object ID. When you remove an object, the object ID remains reserved even though the object no longer exists.

This mechanism works well within the ArmA engine, but fails to help at all for conversion of OFP islands unless you methodically and manually enter all of the entries in the correct order. With upwards of 100,000 entries per island, this is practically impossible.

  • ModelID

Note that this is the unique ID of the ModelID in the object Template. It is not an index into the template structures. Unusual, and slow as a result.

Layer

   Layer
   {
       ulong           SizeType;         //0..2 //see below
       String          Name;             //"Base"
       shortBool       DefaultIndicator; // 0 ... 1
       if (DefaultIndicator == 0)
       {
           ulong  SurfaceTable[TableSize.x*y];
           ulong  TextureTable[TableSize.x*y];
           byte   UnknownTable[(TableSize.x*y/4)];
           ushort UnknownShort;
       };
       if (DefaultIndicator == 1)
       {
           ulong           NoOfTerrainMaterials;
           TerrainMaterial[NoOfTerrainMaterials]
           {
               ulong  BitFlags;     // 1 = label, 0x40 = rvmatfile,,,,
               String MaterialName; // "---sea---","Layers\P_000-000_L00.rvmat"
               ulong  TypeID;       // 0..3
           };
           ulong RvmatTable[TableSize.x*y];
       };
   };

TableSize = Terrain.GridSize>> SizeType;


RoadBlock

RoadBlock
{
 ShortBool IsPresent; 
 if IsPresent
 {
 ShortBool Always1; 
 ulong     Unknown[12]; 
           /* typical data
           ** 00 00 00 00  00 00 00 F0
           ** 2C 46 00 98  23 46 C6 6F
           ** C6 42 0E 01  00 00 01 00
           ** 00 F0 2C 46  00 98 23 46
           ** C6 6F C6 42  0E 01 00 00
           ** 4B 00 00 00  00 00 00 00
           */
 ushort    Type;             // 0,1,2,3
 String    RoadFamilyName;   //"hlavni silnice"
 String    RoadModelName;    //"kr_silnice_cesta_t"
 RGBA      color;            
 ShortBool Always1; 
 ulong     Count; 
 FamilyList FamilyLists[Count];
 ulong     Unknown[27];
           /* typical data
           ** FA D4 30 BF  94 58 08 3D  00 00 C8 C0  00 00 60 C0
           ** 00 00 00 00  00 00 48 C1  00 00 60 40  00 00 00 00
           ** 00 00 48 C1  00 00 60 C0  00 00 00 00  00 00 00 00
           ** 00 00 60 40  00 00 00 00  00 00 00 00  00 00 C8 C0
           ** 00 00 00 00  00 00 30 C0  00 00 C8 C0  00 00 00 00
           ** 00 00 1C C1  04 01 00 00  00 00 00 00  00 00 00 00
           ** 09 00 00 00  0B 80 00 00  04 00 00 00
           */
 ulong     Count;    
 ModelList ModelLists[Count];
 }
}
Type Description
0 Road Ending with FamilyName and its ModelName_konec
1 TJunction ModelName Only
2 Road similar to type 0
3 Xroad with ModelName Only

FamilyList

FamilyList
{
  ulong  Unknown[4];// Typically 00 00 C8 C0 00 00 C8 C0 00 00 00 00 0E 01 00 00
  String Name;     // "silnice hlavni silnic\0"
}

This struct is principally used for XRoads and T_Junctions. It typically lists the order of all RoadFamilyName values required.

ModelList

ModelList
{
 ulong      Count;           //for example, 15
 BlockModel BlockModel[Count];
 String     FamilyName;      //"silnice hlavni silnic\0"
 ulong      Unknown[4];      //Typically 00 00 C8 C0 00 00 C8 C0 00 00 00 00 0E 01 00 00
 RGBA       color[2];         
 ShortBool  Always01;        //01
 ulong      buf2[4];         // Typically 00 00 00 00 00 00 39 40 00 00 00 00 00 00 24 40
}
BlockModel
   BlockModel 
   {
       ulong	   ModelFlag;   // 0x000001 ... 0x00010001
       XYZTriplet Position;      // Model coordinates
       float	   ModelDirection;
       ulong	   ObjectID;
       ushort     Type;               //0,1,2,3
       String     ModelName;          //"silnice10 100\0"
       ulong      unknown[25];
          /*typical data
          **00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
          **C4 76 C2 3F 0E EB 8A C1 00 00 00 00 BE 00 00 00 
          **CC ED 26 BE CA 0F 12 40 56 30 28 3F 00 00 00 00 
          **18 CA 04 C1 48 8B 3D C0 00 00 00 00 2D 3D 91 C1 
          **06 01 C0 40 00 00 00 00 EE 98 84 C1 99 99 91 C0 
          **00 00 00 00 64 4A 5F 35 99 99 91 40 00 00 00 00 
          **64 4A 5F B5 01 00 
          */
       ShortBool  ok; // 0 or 1
}

NamedZone

NamedZone
{
 ShortBool IsPresent;
 if IsPresent
 {
  ShortBool Movable;        // Always0;
  BisString Name1;          //"Les_new"
  ulong     AreaColor,OutlineColor;
  ulong     DisplayStyle;
  ulong     nPoints;
  PointsRectangle
  { 
      float TopLeft.xy;
      float BottomRight.xy;
  }[nPoints/4];
            /* Typical Data
            **00 00 61 45  00 78 1B 46  00 20 64 45  00 20 19 46 
            **00 20 64 45  00 78 1B 46  00 40 67 45  00 58 18 46 
            **00 40 67 45  00 78 1B 46  00 60 6A 45  00 58 18 46 
            **00 60 6A 45  00 78 1B 46  00 80 6D 45  00 90 17 46 
            **00 80 6D 45  00 B0 1A 46  00 A0 70 45  00 C8 16 46 
            **00 A0 70 45  00 E8 19 46  00 C0 73 45  00 00 16 46 
            */
  ulong     ID;             // 0,1,2,3,4....
  if POSEW60
  {
   LongBool  Visible; // always
  }
  else
  {
   BisString Name2;          //Les_new Name2==Name1
  }
 }
};

KeyPoint

KeyPoint
{
 LongBool  Always1; 
 String    ClassName;  //"Noe_Lany"
 RGBA      AreaColor,OutlineColor;
 ulong     DisplayStyle;
 ShortBool Visible; 
 float     Offset[2];  // map relative
 float     Size[2];    // 250 x 250.0 eg (width and height)
 ulong     ID;         // 0,1,2,3,4,5,6....
 BisString TownName;   //"Lipany", "Hill"
 BisString LocaleType; //"NameCity" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf,Hill,Marine,ViewPoint
 BisString ClassText;  // "canOcclude=1; BumbleButt='FlowControl2"; ++=)#4555Semi"
}

Each of these locales have a LocaleType. Some of which are:

  • NameCity
  • NameCityCapital
  • NameVillage
  • VegetationBroadLeaf (Forest)


There is always a classname associated with this locale,

  • Forest_Owls
  • Abel_LaTrinite

and in most cases a text name

"La Refuge Des Chassuers"

Viewpoint and Marine types do not have names associated with them. There is no "place" in the sea.

Background

 Background // this structure has not been seen
 {
      String BackgroundFilename;//"sat_lco.bmp"
      String BackgroundName; //"overlay1"
      float  OffsetXY[2];
      float  SizeXY[2];
      ulong  Transparency;
      shortBool Visible; // or ulong?
 }


Selection

Selection
{
 ushort       strlen;
 char[]       SelectionName[strlen];  // NOT null terminated
 ulong        nSubSelections;
 SubSelection SubSelections[nSubSelections]
}

SubSelection

SubSelection
{
 ulong ObjectId;
 byte  Type;
 byte  Unknown[7];

}

Enums

ObjectClassEnum

enum ObjectClassEnum { Natural = 1, Artificial = 2, Road = 3, Forest = 4, ArtificialAndDefinedInRoad = 5 }

MarkerTypeEnum

enum MarkerTypeEnum { Rectangular = 0, Elliptical = 1 }