PEW File Format: Difference between revisions

From Bohemia Interactive Community
Jump to navigation Jump to search
m (named zones)
(18 intermediate revisions by 3 users not shown)
Line 9: Line 9:
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).
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.
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. This is not the same thing as saying the VERSION of the engine. It is the engine, that decides, the VERSION of wrp it needs to generate.
 
Furthermore, the resulting Wrp file is (for want of a better expression) 'unbinarised' 8WVR format. It is nothing more or less, than a (modified) copy of texture, elevations and models. Period. Roadnetworks and other ancilliary data is only processed into a 'binarised' OPRW format wrp, using Bi's binarizer tool.
 
Note that it is possible to generate 8WVR format without involving bulldozer (or arma) using [[http://dev-heaven.net/projects/list_files/mikero-pbodll|3rd party tools]].
 


While there have been several PEW versions, the ones listed here are:
While there have been several PEW versions, the ones listed here are:
Line 45: Line 50:
     OFPForest                OFPForests[nOFPForests];
     OFPForest                OFPForests[nOFPForests];
     }
     }
     RoadNets                RoadNets[...];
     RoadNetworkTemplate      RoadNetworkTemplates[...];
     Elevation                Elevation[...];
     Elevation                Elevation[...];
     ulong                    NoOfObjects;
     ulong                    NoOfObjects;
Line 51: Line 56:
   
   
     ulong                    NoOfLayers;
     ulong                    NoOfLayers;
     String                  LayerName;          //"Base"
     String                  CurrentLayerName;          //"Base"
     Layer                    Layers[[NoOfLayers] ;
     Layer                    Layers[NoOfLayers] ;
   
   
     if (POSEW60)
     ulong                   nNamedZones;// almost never present on pose60
    {
     NamedZone               NamedZones[nNamedZones];
    ulong                   Unknown;
 
    }
     ulong                     nRoadNetworks;
    else // pose59
     if (nRoadNetworks > 0)
     {
        RoadNetwork          RoadNetworks[nRoadNetworks];
      ulong                  nNamedZones;
      NamedZone             NamedZones[nNamedZones];
    }
     ulong                   nRoadBlocks;
     RoadBlock                RoadBlocks[nRoadBlocks];
   
   
    if (POSEW60)
    {
      ulong                  nNamedZones;
      NamedZone              NamedZones[nNamedZones];
    }
    else // pose59
    {
    ulong                  Unknown;
    }
     ulong                    nKeyPoints;
     ulong                    nKeyPoints;
     KeyPoint                KeyPoints[nKeyPoints];     
     KeyPoint                KeyPoints[nKeyPoints];     
Line 92: Line 82:
   ulong    Length;              // of PEW file;
   ulong    Length;              // of PEW file;
   ulong    UnknownLong;        // typically 0
   ulong    UnknownLong;        // typically 0
   String  IslandDataPath;     //"SomePboPrefix\SomeIsland\data\0" see below
   String  IslandRvMatPath;     //"SomePboPrefix\SomeIsland\data\0" see below
   String  IslandObjectPath;   //""
   String  IslandP3dPath;       //"" (objects)
   float   MaterialsCellSize;   //10.0 (terrain)
   float   TerrainGridSize;     //10.0 metres
   float   SegmentSize;        //400.0 (==SegmentSize - SegmentOverlap)
   float   SegmentSize;        //400.0 (==SegmentSize - SegmentOverlap)
   String  IslandClassname;    //""
   String  IslandClassname;    //""
  };
  };


*IslandDataPath
====Texture And Terrain Sizes====
 
*Pew files deal with '''terrain'''. There is no 'texture' size as such. Therefore the gridsize specified in the header pertains to '''terrain''' cells.
 
*In contrast, the gridsize specified in a WRP pertains to TEXTURE(rvmat) cells.
 
 
"Texture", 'Material','Surface', 'Layer' are synonomous to rvmat files. They are the island's unique surface as generated by importing from a sat mask image. There can be, multipler layers of rvmat files.
 
''Terrain'', are the cell grids of the map and as often as not specified at a different (larger) dimension.
 
Unlike Wrp files, Textures and Terrain sizes are not declared in a pew directly. At least, not, in the header.
 
The Terrain (Map) Size is declared in the elevations structure.
 
TextureSizeS (plural) are derived, not declared, in each surface 'Layer' of pew. Since, ultimately, each layer must 'fit' onto the map. Each layer contains a shift value of how much SMALLER the surface is, relative to the map. For OFP, and OFP converted-to-arma, islands,  this is 0 (there is no difference betweem a 256x256 cell Terrain and a 256x256 cell Texture.
 
For Arma,it is *generally* x 4 (shift value=2).
 
*TerrainGridSize
 
A wrp file's GridSize is the OPPOSITE of a PewFile's GridSize.
 
In a wrp, it defines the size (in meters) of each cell of the TEXTURE (rvmats).
 
In a pew, there is no direct TEXTURE dimension since there can be multiple layers, each with different (derived) dimensions.
 
So this value, in a pew, is the TERRAIN dimension.
 
 
*IslandRvMatPath


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".
RVMAT file references in the Layers structure are listed as ''relative'' addresses to the IslandRvMatPath. This is in contradistinction to the general Bis way-of-doing-things where all references are hard references.


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 PBOsThis is in contradiction to most of the engine mechanics where everything is a hard reference to any PBO of your choosing (like with P3D files).
Traditionally, an RVMAT(Island) data path is declared as "Layers\some.rvmat"It is expected, therefore, that you do indeed have a "P:\SomePboPrefix\SomeIsland\...\Layers" folderPut another way, the ''prefix'' of the PBO must be "SomePboPrefix\SomeIsland\...".


*MaterialsCellSize
The SubFolder 'Layers' is hard wired by Visitor. It is generated automatically when importing a satmask image. Thus, all relative reverences to the rvmats that Visitor produces, are prefaced by 'Layers\'.


The MaterialsCellSize is the OPPOSITE of the wrp file's GridSize. This value refers to the Terrain Dimension rather than the TextureDimension. Often the same, as likley, not.
Using 3rd party tools, you can, should you wish to, alter this prefixing and location of the rvmats to anywhere at all, including no path at all (Visitor, the engine, and the binarizer don't actually care). The purpose in doing so is somewhat moot, since, unlike p3d's, rvmat's for an island are unique to an island. The chances or need of referencing them by something else is zilch. Hence, unlike p3d's, they may just as well stay in the wrp's pbo. Point being, they don't have to.


*IslandObjectPath
*IslandObjectPath uses the same mechanics as above.  However, since P3D files are almost inevitable declared from multiple locations (any PBO, including the base 'CA' PBO included in the game) its use is moot. Be that as it may, the mechanism exists and works, identically to IslandRvMatPath.
*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. <!-- This statement is subject to revision. -->
PEW files are not known to contain anything in IslandObjectPath or IslandClassname. <!-- This statement is subject to revision. -->
Line 132: Line 150:
       String      ModelFilename; //"SomePrefixRoot\data\jablon.p3d\0"
       String      ModelFilename; //"SomePrefixRoot\data\jablon.p3d\0"
       String      ModelName;    //"jablon"
       String      ModelName;    //"jablon"
       ulong        ObjectType;    // 0..5
       ulong        ObjectType;    // 0..5 (so far...)
                                   // 0 Natural
                                   // 0 Undefined - This type should never be encountered.
                                   // 1 Artificial
                                   // 1 Natural
                                   // 2 ???
                                   // 2 Artificial
                                   // 3 Road (RoadFlag will be true)
                                   // 3 Road (RoadFlag will be true)
                                   // 4 ???
                                   // 4 Forest
                                   // 5 ArtificialAndDefinedInRoad
                                   // 5 Road2 (RoadFlag will be false)
       RGBAColor   OutlineColour;  
       RGBAColor     OutlineColour;  
       RGBAColor   ObjectColour;   
       RGBAColor     ObjectColour;   
       double   GeometryBounds[2];            // 50.0
       double   GeometryBounds[2];            // 50.0
       ulong   ModelID;                      // uniqueID, used by objects to lookup this model(p3d)
       ulong   ModelID;                      // uniqueID, used by objects to lookup this model(p3d)
       XYZTriplet   GeometryAutocenterPos;
       XYZTriplet   GeometryAutocenterPos;
       double   ResolutionBounds[2];          // 50.0
       double   ResolutionBounds[2];          // 50.0
       XYZTriplet   ResolutionAutoCenterPos;
       XYZTriplet   ResolutionAutoCenterPos;
       shortBool   Generally0x01;   
       shortBool   Generally0x01;   
       shortBool   RandomScaleFlag;
       shortBool   RandomScaleFlag;
       double   RandomScaleMinMax[2];        // 50.0
       double   RandomScaleMinMax[2];        // 50.0
       shortBool   RandomRotateFlag;
       shortBool   RandomRotateFlag;
       double   RandomRotateMinMax[2];        // 20.0
       double   RandomRotateMinMax[2];        // 20.0
       shortBool   RandomOrientationFlag;     
       shortBool   RandomOrientationFlag;     
       double   RanmdomOrientationMinMax[2];  // 180.0
       double   RanmdomOrientationMinMax[2];  // 180.0
       shortBool   RoadFlag;
       shortBool   RoadFlag;
       if (RoadFlag)  
       if (RoadFlag)  
       {
       {
Line 159: Line 177:
             TransformMatrix XRoadNamedSelections;// (LD, LH, PD, PH)
             TransformMatrix XRoadNamedSelections;// (LD, LH, PD, PH)
       };
       };
       ulong           nArtificialObjects;
       ulong       nNamedVectors;               // Usually 0 (zero)
       ArtificialObject ArtificialObjects[nArtificialObjects];
       NamedVector  NamedVectors[nNamedVectors];
       ulong           MarkerType;                 // Rectangular = 0, Elliptical = 1  
       ulong       MarkerType;                 // Rectangular = 0, Elliptical = 1  
   }
   }


Line 169: Line 187:


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 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.
'Road2' type cannot be defined with Visitor3 Personal Edition. It's a type specific to VBS2 V3 edition.


====ArtificialObject====
====NamedVector====
   ArtificialObject
   NamedVector
   {
   {
     String    Name;      //"pohrada"
     String    Name;      //"pohrada"
Line 179: Line 198:
     XYZTriplet StartEndPos[nTriplets];
     XYZTriplet StartEndPos[nTriplets];
   }
   }
As of v60 a rarely used sub structure with ObjTemplates.


===OFPTerrain===
===OFPTerrain===
Line 206: Line 227:
   ulong     Unknown1; // (typically 0)
   ulong     Unknown1; // (typically 0)
   ulong     Unknown2; // (typically 0)
   ulong     Unknown2; // (typically 0)
}
===NamedZone===
NamedZone
{
  ushort    IsPresent;
  ushort    Moveable;
  String    Name;//Les_new
  RGBAColor AreaColor;
  RGBAColor OutlineColor;
  ulong     DisplayStyle;
  ulong     nFloats;
  float    Floats[nFloats];
  ulong     ID;
  String    Name2;
}
===AltNamedZone===
AltNamedZone:
{
  ushort    IsPresent;
  ushort    Moveable;
  String    Name;//Les_new
  RGBAColor AreaColor;
  RGBAColor OutlineColor;
  ulong     DisplayStyle;
  ulong     nFloats;
  float    Floats[nFloats];
  ulong     ID;
  ulong     Visible
  }
  }


===RoadNet===
===RoadNetworkTemplates===
    shortBool NoRoads;
  RoadNetworkTemplates
    if (!NoRoads)
  {
     {
      shortBool               RoadNetworkTemplatesDefined;
       ulong   nTypes;
      if (!RoadNetworkTemplatesDefined)
       RoadType RoadTypes[nTypes];
      {
       ulong   nXRoads;
          //RoadNetworkTemplates
       XRoad    XRoads[nXRoads];
          ulong              NoOfRoadNetworkTemplates;
     }
          if (NoOfRoadNetworkTemplates > 0)
          {
====RoadType====
              RoadNetTemplate     RoadNetTemplates[NoOfRoadNetworkTemplates];
   RoadType
          }
         
          //CrossroadTemplates
          ulong              NoOfCrossroadTemplates;
          if (NoOfCrossroadTemplates > 0)
          {
              CrossroadTemplate  CrossroadTemplates[NoOfCrossroadTemplates];
          }
      }
  }
 
====RoadNetTemplate====
  RoadNetTemplate
  {
      String              TemplateName;
      RGBAColor          KeyPartsColour;
      RGBAColor          NormalPartsColour;
      shortBool          FilledLine;
      double              MaxAngle;
      double              MaxBankAngle;
     
      ulong              NoOfStraightParts;
      if (NoOfStraightParts > 0)
          StraightPart        StraightParts[NoOfStraightParts];
     
      ulong              NoOfCurveParts;
      if (NoOfCurveParts > 0)
          CurvePart          CurveParts[NoOfCurveParts];
     
       ulong               NoOfSpecialParts;
       if (NoOfSpecialParts > 0)
          SpecialPart        SpecialParts[NoOfSpecialParts];
     
       ulong               NoOfTerminatorParts;
       if (NoOfTerminatorParts > 0)
          TerminatorPart      TerminatorParts[NoOfTerminatorParts];
  }
 
=====StraightPart=====
  StraightPart
  {
      String              StraightPartName;
      ulong              ObjectTemplateID;
      StraightPartEnum    StraightPartType;
      shortBool          CanChangeBankAngle;
  }
 
=====CurvePart=====
  CurvePart
  {
      String              CurvePartName;
      ulong              ObjectTemplateID;
      CurvePartEnum      CurvePartType;
  }
 
=====SpecialPart=====
  SpecialPart
  {
      String              SpecialPartName;
      ulong              ObjectTemplateID;
      SpecialPartEnum     SpecialPartType;
  }
 
=====TerminatorPart=====
   TerminatorPart
   {
   {
    String       FamilyName;        // "cesta","silnice",etc
      String             TerminatorPartName;
    RGBA        KeyPartsColour;   
       ulong               ObjectTemplateID;
    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=====
====CrossroadTemplate====
   RoadList   
   CrossroadTemplate
   {
   {
      String     ModelName;     // "cesta25"
      String             TemplateName;
      ulong      ObjectID;      // in the model list
      CrossroadTypeEnum  Shape;
      ushort      MeterType;     // 0,1,2,3 not present for Terminators
      RGBAColor          Color;
      shortBool  CanChangeAngle; // not present for Terminators or Curves
      shortBool          FilledLine;
      ulong               ObjectTemplateID;
       String              Net_A;
       String              Net_B;
      String              Net_C;
      String              Net_D;
   }
   }


Line 277: Line 382:
* 1 'termination' 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.
====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.
Although "CrossRoads" could conceivably have any number of intersections, only two types are handled.
Line 319: Line 413:


===Object===
===Object===
<code><nowiki>
<code>
   Object
   Object
   {
   {
Line 327: Line 421:
         ShortBool Moveable;              // always 0
         ShortBool Moveable;              // always 0
         ulong    ObjectID;              // See Below
         ulong    ObjectID;              // See Below
         float    TransformColumn[3][4]; // See [[Generic FileFormat Data Types]] in COLUMN format
         [[Generic FileFormat Data Types|TransformMatrix]]   ColumnFormat;
         double    ObjectRelativeSize;    // decimal percentage
         double    ObjectRelativeSize;    // decimal percentage
         String    InstanceName;          // "" mostly. "minimalStrelPos" eg for artifical objects
         String    InstanceName;          // "" mostly. "minimalStrelPos" eg for artifical objects
Line 336: Line 430:
       };
       };
   };
   };
</nowiki></code>
</code>
 
*TransformMatrix
 
Note that a '''pew''' TransformMatrix is the only instance in the entire repertoire of bis file formats where the transform is specified in columns. All other TransformMatrices of BI (notably models) are in Row format. It makes diddly squat difference to the '''values''' in the matrix, only the positions of those values are different.
 
The XYZ positional component is the absolute position. If a relative elevation has been specified in the pew, that value has been added to the component at this storage time.


* ObjectID
* ObjectID
Line 395: Line 495:
  10 C 8 4
  10 C 8 4


vs wrp
vs WRP


  D E F 10
  D E F 10
Line 409: Line 509:
*2 quarter
*2 quarter


===RoadBlock===
====Rvmat Conventions====
RoadBlock
 
{
Naming of rvmat files (generally) follows a simple convention largely because the files are auto_generated when importing the satmask.
  ShortBool IsPresent;
The resolved Texture size (dependent on the pixels and resoltion wanted) are divided into x and y numbered co-ordinates thus
  if IsPresent
 
  {
p_(x)00..(x)nn_(y)00..nn_L00..zz
  ShortBool Always1;
 
  ulong    Unknown[12];
where:
            /* typical data
 
            ** 00 00 00 00  00 00 00 F0
(x) and (y) are the cellgrid position (and not part of the label)
            ** 2C 46 00 98  23 46 C6 6F
 
            ** C6 42 0E 01  00 00 01 00
Lzz is the layer
            ** 00 F0 2C 46  00 98 23 46
 
            ** C6 6F C6 42  0E 01 00 00
For a mythical single layer island with an 8x8 TEXTURE , files names will range from
            ** 4B 00 00 00  00 00 00 00
 
            */
p_00_00_L00 to p_07_07_L00
  ushort    Type;            // 0,1,2,3
 
  String    RoadFamilyName;  //"hlavni silnice"
 
  String    RoadModelName;    //"kr_silnice_cesta_t"
 
  RGBA      color;           
 
  ShortBool Always1;
PxxPyy
  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];
  }
}


{| class="wikitable"
===RoadNetworks===
|-
! colspan="2"| 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
|-
|} <!-- Documentation is like air; when it's bad, it's better than nothing... -->


====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.
A 'RoadNetwork' essentially is comprised of a 'KeyPart' and 1-4 Directions. A Direction comprsises 0 to 'N' number of 'Parts'.
When the Visitor3 user starts placing a 'RoadNetwork' on a map they are 'forced' to place a 'KeyPart'. Each 'RoadNetwork' has at least 1 'Direction' defined. A 'Direction' may have zero 'RoadParts' placed on the map.


====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=====
  RoadNetworks
     BlockModel
  {
    shortBool            NetworkDefined;
     if (NetworkDefined)
     {
     {
         ulong   ModelFlag;   // 0x000001 ... 0x00010001
        shortBool        Always0x01;
         XYZTriplet Position;     // Model coordinates
        shortBool        Movable;
         float   ModelDirection;
         ulong             NetworkID;
         ulong   ObjectID;
        float            Network_XZY[3];
         ushort    Type;               //0,1,2,3
        float            Direction;
         String    ModelName;         //"silnice10 100\0"
        shortBool        KeyPartDefined;         // Should always be 1=Yes 'cause you cant start a road without placing a KeyPart
         ulong     unknown[25];
         float            KeyPart_XZY[3];
          /*typical data
         float             KeyPart_Direction;
          **00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
         ulong             KeyPart_TemplateObjectID;
          **C4 76 C2 3F 0E EB 8A C1 00 00 00 00 BE 00 00 00
        KeyPartTypeEnum  KeyPart_Type;
          **CC ED 26 BE CA 0F 12 40 56 30 28 3F 00 00 00 00
         ushort           KeyPart_FamilyType;
          **18 CA 04 C1 48 8B 3D C0 00 00 00 00 2D 3D 91 C1
        String            KeyPart_RoadNetworkTemplateName;
          **06 01 C0 40 00 00 00 00 EE 98 84 C1 99 99 91 C0
        String            KeyPart_ModelName;
           **00 00 00 00 64 4A 5F 35 99 99 91 40 00 00 00 00
        RGBAColor        KeyPart_Color;
          **64 4A 5F B5 01 00
        shortBool        DirectionsDefined;     // Should always be 0x0100=yes because every RoadNetwork has at least 1 direction.
          */
        ulong            NoOfDirections;
        ShortBool  ok; // 0 or 1
        ulong            Direction_A_Something; //Always 0x0000 0000
}
        ulong            Direction_B_Something; //Always 0x0000 0000
        ulong            Direction_C_Something; //Always 0x0000 0000
         ulong            Direction_D_Something; //Always 0x0000 0000
        DirectionHeader  DirectionHeaders[NoOfDirections];
        byte              Unknown[92];
         ulong             NoOfDirections;
        Direction        Directions[NoOfDirections];
    }
  }
 
====DirectionHeader====
  DirectionHeader
  {
      String              RoadNetworkTemplateName;
      float              DirectionOffsetXZY[3];
      float              DirectionOffsetDirection; // 180.0 degrees.
  }
 
====Direction====
  Direction
  {
      ulong              NoOfParts;
      RoadPart           RoadParts[NoOfParts];
      String              RoadNetworkTemplateName;
      float              DirectionOffsetXZY[3];
      float              DirectionOffsetDirection; // 180.0 degrees.
      RGBAColor          KeyPartColor;
      RGBAColor          NormalPartColor;
      shortBool          FilledLine;
      double              MaxAngle;
      double              MaxBankAngle;
  }


===NamedZone===
=====RoadPart=====
NamedZone
   RoadPart
{
  ShortBool IsPresent;
   if IsPresent
   {
   {
  ShortBool Movable;        // Always0;
      shortBool          Defined;
  BisString Name1;         //"Les_new"
      shortBool          Enabled; // Possibly incorrect.
  ulong    AreaColor,OutlineColor;
      float              RoadPartXZY[3];
  ulong    DisplayStyle;
      float              RoadPartDirection;
  ulong     nPoints;
      ulong               RoadPart_ObjectTemplateID;
  PointsRectangle
      ushort              PartTypeUIListboxIndex;
  {
      String              ModelName;
      float TopLeft.xy;
      byte                Unknown[102];
      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===
  KeyPoint
  KeyPoint
  {
  {
   LongBool Always1;  
   ShortBool IsPresent;  
   String    ClassName;  //"Noe_Lany"
   if (IsPresent)
  RGBA      AreaColor,OutlineColor;
  {
  ulong    DisplayStyle;
  ShortBool  Always0;
  ShortBool Visible;  
  String    ClassName;  //"Noe_Lany"
  float    Offset[2];  // map relative
  RGBA      AreaColor,OutlineColor;
  float    Size[2];    // 250 x 250.0 eg (width and height)
  ulong    DisplayStyle; //0 solid
  ulong    ID;        // 0,1,2,3,4,5,6....
                          //1..6 hatch-horz,vert,cross,skew right,skew left,skewcross
  BisString TownName;  //"Lipany", "Hill"
                          //7 standard
  BisString LocaleType; //"NameCity" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf,Hill,Marine,ViewPoint
  ShortBool Visible;  
  BisString ClassText;  // "canOcclude=1; BumbleButt='FlowControl2"; ++=)#4555Semi"
  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:
There is '''always''' a classname associated with this Keypoint,
*NameCity
*NameCityCapital
*NameVillage
*VegetationBroadLeaf (Forest)
 
 
There is always a classname associated with this locale,
*Forest_Owls
*Forest_Owls
*Abel_LaTrinite
*Abel_LaTrinite
*MyPinkElephant


and in most cases a text name
and in most cases a text name that is 'seen' on the map


"La Refuge Des Chassuers"
"La Refuge Des Chassuers"


Viewpoint and Marine types do not have names associated with them.  There is no "place" in the sea.
Viewpoint and Marine types normally don't have names associated with them.  There is no "place" in the sea.
 
Each of these Keypoints have a Locale '''Type'''. Some of which are:
*NameCity
*NameCityCapital
*NameVillage
*VegetationBroadLeaf (Forest)


===Background===
===Background===
Line 590: Line 662:
  Selection
  Selection
  {
  {
   ushort       strlen;
   ushort               strlen;
   char[]       SelectionName[strlen];  // NOT null terminated
   char[]               SelectionName[strlen];  // NOT null terminated
   ulong       nSubSelections;
   ulong               nObjects;
   SubSelection SubSelections[nSubSelections]
   SelectionObject      SelectionObjects[nObjects]
  }
  }
====SubSelection====
====SelectionObject====
  SubSelection
  SelectionObject
  {
  {
   ulong ObjectId;
   ulong ObjectInstanceID;
  byte  Type;
   byte  Unknown[8];
   byte  Unknown[7];
}
}


Line 606: Line 677:




=== ObjectClassEnum ===
=== ObjectTemplateTypeEnum ===


<code><nowiki>
<code><nowiki>
   enum ObjectClassEnum
   enum ObjectTemplateTypeEnum
   {
   {
    Undefined = 0,
     Natural = 1,
     Natural = 1,
     Artificial = 2,
     Artificial = 2,
     Road = 3,
     Road = 3,
     Forest = 4,
     Forest = 4,
     ArtificialAndDefinedInRoad = 5   
     Road2 = 5   
   }
   }
</nowiki></code>
</nowiki></code>
Line 627: Line 699:
     Elliptical = 1
     Elliptical = 1
   }
   }
</nowiki></code>
===StraightPartEnum===
<code><nowiki>
    enum StraightPartEnum : ushort
    {
        SixBy25,      // 6,25m
        TwelveBy5,    // 12,5m
        TwentyFive    // 25m
    }
</nowiki></code>
===CurvePartEnum===
<code><nowiki>
    enum CurvePartEnum : ushort
    {
        Radius25m,
        Radius50m,
        Radius75m,
        Radius100m
    }
</nowiki></code>
===SpecialPartEnum===
<code><nowiki>
    enum SpecialPartEnum : ushort
    {
        SixBy25,      // 6,25m
        TwelveBy5,    // 12,5m
        TwentyFive    // 25m
    }
</nowiki></code>
===KeyPartTypeEnum===
<code><nowiki>
    enum KeyPartTypeEnum
    {
        Crossroad,
        Straight,
        Special,
        Terminator
    }
</nowiki></code>
</nowiki></code>


[[Category:BIS_File_Formats]]
[[Category:BIS_File_Formats]]

Revision as of 06:04, 31 October 2014

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. This is not the same thing as saying the VERSION of the engine. It is the engine, that decides, the VERSION of wrp it needs to generate.

Furthermore, the resulting Wrp file is (for want of a better expression) 'unbinarised' 8WVR format. It is nothing more or less, than a (modified) copy of texture, elevations and models. Period. Roadnetworks and other ancilliary data is only processed into a 'binarised' OPRW format wrp, using Bi's binarizer tool.

Note that it is possible to generate 8WVR format without involving bulldozer (or arma) using [party tools].


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];
   }
   RoadNetworkTemplate      RoadNetworkTemplates[...];
   Elevation                Elevation[...];
   ulong                    NoOfObjects;
   Object                   Objects[NoOfObjects];

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

   ulong                    nNamedZones;// almost never present on pose60
   NamedZone                NamedZones[nNamedZones];
 
   ulong                      nRoadNetworks;
   if (nRoadNetworks > 0)
       RoadNetwork          RoadNetworks[nRoadNetworks];

   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   IslandRvMatPath;     //"SomePboPrefix\SomeIsland\data\0" see below
 String   IslandP3dPath;       //"" (objects)
 float	  TerrainGridSize;     //10.0 metres 
 float	  SegmentSize;         //400.0 (==SegmentSize - SegmentOverlap)
 String   IslandClassname;     //""
};

Texture And Terrain Sizes

  • Pew files deal with terrain. There is no 'texture' size as such. Therefore the gridsize specified in the header pertains to terrain cells.
  • In contrast, the gridsize specified in a WRP pertains to TEXTURE(rvmat) cells.


"Texture", 'Material','Surface', 'Layer' are synonomous to rvmat files. They are the island's unique surface as generated by importing from a sat mask image. There can be, multipler layers of rvmat files.

Terrain, are the cell grids of the map and as often as not specified at a different (larger) dimension.

Unlike Wrp files, Textures and Terrain sizes are not declared in a pew directly. At least, not, in the header.

The Terrain (Map) Size is declared in the elevations structure.

TextureSizeS (plural) are derived, not declared, in each surface 'Layer' of pew. Since, ultimately, each layer must 'fit' onto the map. Each layer contains a shift value of how much SMALLER the surface is, relative to the map. For OFP, and OFP converted-to-arma, islands, this is 0 (there is no difference betweem a 256x256 cell Terrain and a 256x256 cell Texture.

For Arma,it is *generally* x 4 (shift value=2).

  • TerrainGridSize

A wrp file's GridSize is the OPPOSITE of a PewFile's GridSize.

In a wrp, it defines the size (in meters) of each cell of the TEXTURE (rvmats).

In a pew, there is no direct TEXTURE dimension since there can be multiple layers, each with different (derived) dimensions.

So this value, in a pew, is the TERRAIN dimension.


  • IslandRvMatPath

RVMAT file references in the Layers structure are listed as relative addresses to the IslandRvMatPath. This is in contradistinction to the general Bis way-of-doing-things where all references are hard references.

Traditionally, an RVMAT(Island) data path is declared as "Layers\some.rvmat". It is expected, therefore, that you do indeed have a "P:\SomePboPrefix\SomeIsland\...\Layers" folder. Put another way, the prefix of the PBO must be "SomePboPrefix\SomeIsland\...".

The SubFolder 'Layers' is hard wired by Visitor. It is generated automatically when importing a satmask image. Thus, all relative reverences to the rvmats that Visitor produces, are prefaced by 'Layers\'.

Using 3rd party tools, you can, should you wish to, alter this prefixing and location of the rvmats to anywhere at all, including no path at all (Visitor, the engine, and the binarizer don't actually care). The purpose in doing so is somewhat moot, since, unlike p3d's, rvmat's for an island are unique to an island. The chances or need of referencing them by something else is zilch. Hence, unlike p3d's, they may just as well stay in the wrp's pbo. Point being, they don't have to.

  • IslandObjectPath uses the same mechanics as above. However, since P3D files are almost inevitable declared from multiple locations (any PBO, including the base 'CA' PBO included in the game) its use is moot. Be that as it may, the mechanism exists and works, identically to IslandRvMatPath.


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 (so far...)
                                 // 0 Undefined - This type should never be encountered.
                                 // 1 Natural
                                 // 2 Artificial
                                 // 3 Road (RoadFlag will be true)
                                 // 4 Forest
                                 // 5 Road2 (RoadFlag will be false)
     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        nNamedVectors;                // Usually 0 (zero)
     NamedVector  NamedVectors[nNamedVectors];
     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. 'Road2' type cannot be defined with Visitor3 Personal Edition. It's a type specific to VBS2 V3 edition.

NamedVector

 NamedVector
 {
    String     Name;       //"pohrada"
    LongBool   Unknown;
    ulong      nTriplets; // generally 2 sometimes 1
    XYZTriplet StartEndPos[nTriplets];
 }

As of v60 a rarely used sub structure with ObjTemplates.

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)
}

NamedZone

NamedZone
{
 ushort    IsPresent;
 ushort    Moveable;
 String    Name;//Les_new
 RGBAColor AreaColor;
 RGBAColor OutlineColor;
 ulong	    DisplayStyle;
 ulong	    nFloats;
 float     Floats[nFloats];
 ulong	    ID;
 String    Name2;
}

AltNamedZone

AltNamedZone:
{
 ushort    IsPresent;
 ushort    Moveable;
 String    Name;//Les_new
 RGBAColor AreaColor;
 RGBAColor OutlineColor;
 ulong	    DisplayStyle;
 ulong	    nFloats;
 float     Floats[nFloats];
 ulong	    ID;
 ulong	    Visible
}

RoadNetworkTemplates

 RoadNetworkTemplates
 {
     shortBool               RoadNetworkTemplatesDefined;
     if (!RoadNetworkTemplatesDefined)
     {
         //RoadNetworkTemplates
         ulong               NoOfRoadNetworkTemplates;
         if (NoOfRoadNetworkTemplates > 0)
         {
             RoadNetTemplate     RoadNetTemplates[NoOfRoadNetworkTemplates];
         }
         
         //CrossroadTemplates
         ulong               NoOfCrossroadTemplates;
         if (NoOfCrossroadTemplates > 0)
         {
             CrossroadTemplate   CrossroadTemplates[NoOfCrossroadTemplates];
         }
     }
 }

RoadNetTemplate

 RoadNetTemplate
 {
     String              TemplateName;
     RGBAColor           KeyPartsColour;
     RGBAColor           NormalPartsColour;
     shortBool           FilledLine;
     double              MaxAngle;
     double              MaxBankAngle;
     
     ulong               NoOfStraightParts;
     if (NoOfStraightParts > 0)
         StraightPart        StraightParts[NoOfStraightParts];
     
     ulong               NoOfCurveParts;
     if (NoOfCurveParts > 0)
         CurvePart           CurveParts[NoOfCurveParts];
     
     ulong               NoOfSpecialParts;
     if (NoOfSpecialParts > 0)
         SpecialPart         SpecialParts[NoOfSpecialParts];
     
     ulong               NoOfTerminatorParts;
     if (NoOfTerminatorParts > 0)
         TerminatorPart      TerminatorParts[NoOfTerminatorParts];
 }
StraightPart
 StraightPart
 {
     String              StraightPartName;
     ulong               ObjectTemplateID;
     StraightPartEnum    StraightPartType;
     shortBool           CanChangeBankAngle;
 }
CurvePart
 CurvePart
 {
     String              CurvePartName;
     ulong               ObjectTemplateID;
     CurvePartEnum       CurvePartType;
 }
SpecialPart
 SpecialPart
 {
     String              SpecialPartName;
     ulong               ObjectTemplateID;
     SpecialPartEnum     SpecialPartType;
 }
TerminatorPart
 TerminatorPart
 {
     String              TerminatorPartName;
     ulong               ObjectTemplateID;
 }

CrossroadTemplate

 CrossroadTemplate
 {
     String              TemplateName;
     CrossroadTypeEnum   Shape;
     RGBAColor           Color;
     shortBool           FilledLine;
     ulong               ObjectTemplateID;
     String              Net_A;
     String              Net_B;
     String              Net_C;
     String              Net_D;
 }
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.

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   TerrainSize; // 256 x 256 eg
   float    Heights[TerrainSize];
   float    BlueEdgeTerrainHeights[NoOfBlueFloats]  ; //Always zero values 
   // NoOfBlueFloats = (TerrainSize_Y * TerrainSize_X)/16;
   ulong    Always0;
}

Object

 Object
 {
     ShortBool IsPresent;
     if (IsPresent)
     {
       ShortBool Moveable;              // always 0
       ulong     ObjectID;              // See Below
       TransformMatrix   ColumnFormat;
       double    ObjectRelativeSize;    // decimal percentage
       String    InstanceName;          // "" mostly. "minimalStrelPos" eg for artifical objects
       float     RelativeSurfaceElevation;
       RGBA      OutlineColour; 
       RGBA      ObjectColour;  
       ulong     ModelID;               // See below
     };
 };

  • TransformMatrix

Note that a pew TransformMatrix is the only instance in the entire repertoire of bis file formats where the transform is specified in columns. All other TransformMatrices of BI (notably models) are in Row format. It makes diddly squat difference to the values in the matrix, only the positions of those values are different.

The XYZ positional component is the absolute position. If a relative elevation has been specified in the pew, that value has been added to the component at this storage time.

  • 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 RvmatIndexTable[TableSize.x*y];
       };
   };

TableSize = Elevations.TerrainSize>> SizeType;

RvmatIndexTable

The texture table contains 1-based indexes into the rvmats. This is a traditional bis way-of-doing-things in that the 0th 'rvmat' is, by default 'sea' texture and does not have an associated file, nor, is it referenced in this table.

The organisation of 'cells' differs from it's equivalent wrp. They are the reversed, mirror image of each other. Thus for a pew file with a 'poetic' 4x4 island:

  PEW    
 D 9 5 1
 E A 6 2
 F B 7 3
10 C 8 4

vs WRP

D E F 10
9 A B C
5 6 7 8
1 2 3 4

Unlike a wrp there is no Texture Size (256x256) eg. It is a derived value from the Elevations size (ergo the TerrainSize) (1024x1024 eg) The size of this table, the 'Texture Size' is defined as a ratio via LayerSizeType.

  • 0 same
  • 1 half
  • 2 quarter

Rvmat Conventions

Naming of rvmat files (generally) follows a simple convention largely because the files are auto_generated when importing the satmask. The resolved Texture size (dependent on the pixels and resoltion wanted) are divided into x and y numbered co-ordinates thus

p_(x)00..(x)nn_(y)00..nn_L00..zz

where:

(x) and (y) are the cellgrid position (and not part of the label)

Lzz is the layer

For a mythical single layer island with an 8x8 TEXTURE , files names will range from

p_00_00_L00 to p_07_07_L00



PxxPyy

RoadNetworks

A 'RoadNetwork' essentially is comprised of a 'KeyPart' and 1-4 Directions. A Direction comprsises 0 to 'N' number of 'Parts'. When the Visitor3 user starts placing a 'RoadNetwork' on a map they are 'forced' to place a 'KeyPart'. Each 'RoadNetwork' has at least 1 'Direction' defined. A 'Direction' may have zero 'RoadParts' placed on the map.


 RoadNetworks
 {
   shortBool             NetworkDefined;
   if (NetworkDefined)
   {
       shortBool         Always0x01;
       shortBool         Movable;
       ulong             NetworkID;
       float             Network_XZY[3];
       float             Direction;
       shortBool         KeyPartDefined;         // Should always be 1=Yes 'cause you cant start a road without placing a KeyPart
       float             KeyPart_XZY[3];
       float             KeyPart_Direction;
       ulong             KeyPart_TemplateObjectID;
       KeyPartTypeEnum   KeyPart_Type;
       ushort            KeyPart_FamilyType;
       String            KeyPart_RoadNetworkTemplateName;
       String            KeyPart_ModelName;
       RGBAColor         KeyPart_Color;
       shortBool         DirectionsDefined;     // Should always be 0x0100=yes because every RoadNetwork has at least 1 direction.
       ulong             NoOfDirections;
       ulong             Direction_A_Something; //Always 0x0000 0000
       ulong             Direction_B_Something; //Always 0x0000 0000
       ulong             Direction_C_Something; //Always 0x0000 0000
       ulong             Direction_D_Something; //Always 0x0000 0000
       DirectionHeader   DirectionHeaders[NoOfDirections];
       byte              Unknown[92];
       ulong             NoOfDirections;
       Direction         Directions[NoOfDirections];
   }
 }

DirectionHeader

 DirectionHeader
 {
     String              RoadNetworkTemplateName;
     float               DirectionOffsetXZY[3];
     float               DirectionOffsetDirection; // 180.0 degrees.
 }

Direction

 Direction
 {
     ulong               NoOfParts;
     RoadPart            RoadParts[NoOfParts];
     String              RoadNetworkTemplateName;
     float               DirectionOffsetXZY[3];
     float               DirectionOffsetDirection; // 180.0 degrees.
     RGBAColor           KeyPartColor;
     RGBAColor           NormalPartColor;
     shortBool           FilledLine;
     double              MaxAngle;
     double              MaxBankAngle;
 }
RoadPart
 RoadPart
 {
     shortBool           Defined;
     shortBool           Enabled; // Possibly incorrect.
     float               RoadPartXZY[3];
     float               RoadPartDirection;
     ulong               RoadPart_ObjectTemplateID;
     ushort              PartTypeUIListboxIndex;
     String              ModelName;
     byte                Unknown[102];
 }


KeyPoint

KeyPoint
{
 ShortBool  IsPresent; 
 if (IsPresent)
 {
  ShortBool  Always0; 
  String    ClassName;  //"Noe_Lany"
  RGBA      AreaColor,OutlineColor;
  ulong     DisplayStyle; //0 solid
                          //1..6 hatch-horz,vert,cross,skew right,skew left,skewcross
                          //7 standard
  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"
 }
}

There is always a classname associated with this Keypoint,

  • Forest_Owls
  • Abel_LaTrinite
  • MyPinkElephant

and in most cases a text name that is 'seen' on the map

"La Refuge Des Chassuers"

Viewpoint and Marine types normally don't have names associated with them. There is no "place" in the sea.

Each of these Keypoints have a Locale Type. Some of which are:

  • NameCity
  • NameCityCapital
  • NameVillage
  • VegetationBroadLeaf (Forest)

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                nObjects;
 SelectionObject      SelectionObjects[nObjects]
}

SelectionObject

SelectionObject
{
 ulong ObjectInstanceID;
 byte  Unknown[8];

}

Enums

ObjectTemplateTypeEnum

enum ObjectTemplateTypeEnum { Undefined = 0, Natural = 1, Artificial = 2, Road = 3, Forest = 4, Road2 = 5 }

MarkerTypeEnum

enum MarkerTypeEnum { Rectangular = 0, Elliptical = 1 }

StraightPartEnum

enum StraightPartEnum : ushort { SixBy25, // 6,25m TwelveBy5, // 12,5m TwentyFive // 25m }

CurvePartEnum

enum CurvePartEnum : ushort { Radius25m, Radius50m, Radius75m, Radius100m }

SpecialPartEnum

enum SpecialPartEnum : ushort { SixBy25, // 6,25m TwelveBy5, // 12,5m TwentyFive // 25m }

KeyPartTypeEnum

enum KeyPartTypeEnum { Crossroad, Straight, Special, Terminator }