{"name":"PEW File Format","title":"PEW File Format","type":"topic","url":"https://community.bistudio.com/wiki/PEW_File_Format","revid":373448,"updated":"2025-05-08T11:27:12Z","aliases":["POSE v60 File Format"],"markdown":"> **Disclaimer: This page describes internal undocumented structures of Bohemia Interactive software.**\n>\n> This page contains unofficial information.\n>\n> Some usage of this information may constitute a violation of the rights of Bohemia Interactive and is in no way endorsed or recommended by Bohemia Interactive.\n> Bohemia Interactive is not willing to tolerate use of such tools if it contravenes any general licenses granted to end users of this community wiki or BI products.\n\nPEW files are Visitor's project files. Visitor is Bohemia Interactive's tool for creating Islands.\n\nVisitor is a GUI tool interface that interacts with Bulldozer, an in-built 'world' viewer inside any Armed Assault engine.\n\nThe contents of the PEW project file are not directly related to the ultimate output, a WRP file.\nHowever, that data contains all similar elements, such as road networks, elevations, cell matrices, models (P3D files) and textures (RVMAT files).\n\nExporting 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.\nIt 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.\nThis 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.\n\nFurthermore, 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.\nRoadnetworks and other ancilliary data is only processed into a 'binarised' OPRW format wrp, using Bi's binarizer tool.\n\nNote that it is possible to generate 8WVR format without involving bulldozer (or arma) using [*party tools* (dead link)].\n\nWhile there have been several PEW versions, the ones listed here are:\n\n- POSEW59\n- POSEW60\n\nThere are only a few subtle differences to their makeup.\n\n### Legend\n\nSee Generic FileFormat Data Types.\n\n### File Format\n\n> [!NOTE]\n> This file format is principally used with Armed Assault v1.09 and later, with the ArmA Tools Suite final release (v1.14).\n\n```c#\nPOSEW59\nPOSEW60\n{\n    PoseHeader                Header;\n    ulong                    nOFPTextures;            // none in Arma\n    OFPTexture                OFPTextures[nOFPTextures];\n    ulong                    nObjectTemplates;\n    ObjectTemplate            ObjectTemplates[nObjectTemplates];\n    shortBool                NoOfpTerrains;\n    if (!NoOfpTerrains)\n    {\n        ulong                nOFPTerrains;            // none in Arma\n        OFPTerrain            OFPTerrains[nOFPTerrains];\n    }\n    shortBool                NoOFPForests;            // none in Arma\n    if (!NoOFPForests)\n    {\n        ulong                nOFPForests;\n        OFPForest            OFPForests[nOFPForests];\n    }\n    RoadNetworkTemplate        RoadNetworkTemplates[...];\n    Elevation                Elevation[...];\n    ulong                    NoOfObjects;\n    Object                    Objects[NoOfObjects];\n\n    ulong                    NoOfLayers;\n    String                    CurrentLayerName;        // \"Base\"\n    Layer                    Layers[NoOfLayers] ;\n\n    ulong                    nNamedZones;// almost never present on pose60\n    NamedZone                NamedZones[nNamedZones];\n\n    ulong                    nRoadNetworks;\n    if (nRoadNetworks > 0)\n        RoadNetwork            RoadNetworks[nRoadNetworks];\n\n    ulong                    nKeyPoints;\n    KeyPoint                KeyPoints[nKeyPoints];\n    ulong                    NoOfBackgrounds;\n    Background                Backgrounds[NoOfBackgrounds]; // not checked for 59\n    ulong                    TotalSizeOfSelections; // from here, to end of file\n    ulong                    nSelections;\n    Selection                Selections[nSelections];\n}\n```\n\n#### PoseHeader\n\n```c#\nHeader\n{\n    char    Signature[7];        // \"POSEW59\" or \"POSEW60\" note: NOT null terminated\n    ulong    Length;                // of PEW file;\n    ulong    UnknownLong;        // typically 0\n    String    IslandRvMatPath;    // \"SomePboPrefix\\SomeIsland\\data\\0\" see below\n    String    IslandP3dPath;        // \"\" (objects)\n    float    TerrainGridSize;    // 10.0 metres\n    float    SegmentSize;        // 400.0 (==SegmentSize - SegmentOverlap)\n    String    IslandClassname;    // \"\"\n};\n```\n\n##### Texture And Terrain Sizes\n\n- Pew files deal with **terrain**. There is no 'texture' size as such. Therefore the gridsize specified in the header pertains to **terrain** cells.\n- In contrast, the gridsize specified in a WRP pertains to TEXTURE(rvmat) cells.\n\n\"Texture\", 'Material', 'Surface', 'Layer' are synonomous to rvmat files.\nThey are the island's unique surface as generated by importing from a sat mask image. There can be multipler layers of rvmat files.\n\n*Terrain*, are the cell grids of the map and as often as not specified at a different (larger) dimension.\n\nUnlike Wrp files, Textures and Terrain sizes are not declared in a pew directly. At least, not, in the header.\n\nThe Terrain (Map) Size is declared in the elevations structure.\n\nTextureSizeS (plural) are derived, not declared, in each surface 'Layer' of pew. Since, ultimately, each layer must 'fit' onto the map.\nEach layer contains a shift value of how much SMALLER the surface is, relative to the map.\nFor OFP, and OFP converted-to-arma, islands, this is 0 (there is no difference betweem a 256x256 cell Terrain and a 256x256 cell Texture.\n\nFor Arma, it is *generally* x 4 (shift value=2).\n\n###### TerrainGridSize\n\nA wrp file's GridSize is the OPPOSITE of a PewFile's GridSize.\n\nIn a wrp, it defines the size (in meters) of each cell of the TEXTURE (rvmats).\n\nIn a pew, there is no direct TEXTURE dimension since there can be multiple layers, each with different (derived) dimensions.\n\nSo this value, in a pew, is the TERRAIN dimension.\n\n###### IslandRvMatPath\n\nRVMAT file references in the Layers structure are listed as *relative* addresses to the IslandRvMatPath.\nThis is in contradistinction to the general Bis way-of-doing-things where all references are hard references.\n\nTraditionally, an RVMAT(Island) data path is declared as \"Layers\\some.rvmat\".\nIt is expected, therefore, that you do indeed have a \"P:\\SomePboPrefix\\SomeIsland\\...\\Layers\" folder.\nPut another way, the *prefix* of the PBO must be \"SomePboPrefix\\SomeIsland\\...\".\n\nThe SubFolder 'Layers' is hard wired by Visitor. It is generated automatically when importing a satmask image.\nThus, all relative reverences to the rvmats that Visitor produces, are prefaced by 'Layers\\'.\n\nUsing 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).\nThe purpose in doing so is somewhat moot, since, unlike p3d's, rvmat's for an island are unique to an island.\nThe 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.\n\n###### IslandObjectPath\n\nIslandObjectPath uses the same mechanics as above.\nHowever, 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.\nBe that as it may, the mechanism exists and works, identically to IslandRvMatPath.\n\nPEW files are not known to contain anything in IslandObjectPath or IslandClassname.\n\n#### OFPTexture\n\n```c#\nOFPTexture\n{\n    ulong        TextureID;\n    String        TextureFileName;    // \"snih3.paa\"\n    String        TextureName;        // \"snih3\"\n    String        RvmatName;            // \"snih3.rvmat\"\n    byte        UnknownBytes[14];    // (typically 0)\n    RGBAColor    Colour;\n}\n```\n\n#### ObjectTemplate\n\n```c#\nObjectTemplate\n{\n    String        ModelFilename;    // \"SomePrefixRoot\\data\\jablon.p3d\\0\"\n    String        ModelName;        // \"jablon\"\n    ulong        ObjectType;        // 0..5 (so far...)\n                                // 0 Undefined - This type should never be encountered.\n                                // 1 Natural\n                                // 2 Artificial\n                                // 3 Road (RoadFlag will be true)\n                                // 4 Forest\n                                // 5 Road2 (RoadFlag will be false)\n    RGBAColor    OutlineColour;\n    RGBAColor    ObjectColour;\n    double        GeometryBounds[2];                // 50.0\n    ulong        ModelID;                        // uniqueID, used by objects to lookup this model(p3d)\n    XYZTriplet    GeometryAutocenterPos;\n    double        ResolutionBounds[2];            // 50.0\n    XYZTriplet    ResolutionAutoCenterPos;\n    shortBool    Generally0x01;\n    shortBool    RandomScaleFlag;\n    double        RandomScaleMinMax[2];            // 50.0\n    shortBool    RandomRotateFlag;\n    double        RandomRotateMinMax[2];            // 20.0\n    shortBool    RandomOrientationFlag;\n    double        RanmdomOrientationMinMax[2];    // 180.0\n    shortBool    RoadFlag;\n    if (RoadFlag)\n    {\n        TransformMatrix RoadNamedSelections;    // (LB, PB, LE, PE)\n        TransformMatrix XRoadNamedSelections;    // (LD, LH, PD, PH)\n    };\n    ulong        nNamedVectors;                    // Usually 0 (zero)\n    NamedVector    NamedVectors[nNamedVectors];\n    ulong        MarkerType;                        // Rectangular = 0, Elliptical = 1\n}\n```\n\nAs opposed to layers (material RVMAT surfaces), 'objects' are instances of models placed onto the map.\nIrrespective of the number of objects there is only one reference to the model used, which is then referenced as often as needed.\n\nModelFilename, ModelName, and ModelID are unique unduplicated entries.\n\nThe 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.\nThe ObjectID illustrated on maps is, in contrast, the unique InstanceID of each object in the objects structure below.\n'Road2' type cannot be defined with Visitor3 Personal Edition. It's a type specific to VBS2 V3 edition.\n\n##### NamedVector\n\n```c#\nNamedVector\n{\n    String        Name;        // \"pohrada\"\n    LongBool    Unknown;\n    ulong        nTriplets; // generally 2 sometimes 1\n    XYZTriplet    StartEndPos[nTriplets];\n}\n```\n\nAs of v60 a rarely used sub structure with ObjTemplates.\n\n#### OFPTerrain\n\n```c#\nOFPTerrain\n{\n    String        TerrainName;\n    byte        UnknownBytes[11];\n    ulong        nSurfaces;\n    OFPSurface    OFPSurfaces[nSurfaces];\n}\n```\n\n##### OFPSurface\n\n```c#\nOFPSurface\n{\n    String    SurfaceName;\n    float    Surfacefloat[4];\n    byte    UnknownBytes[16];\n}\n```\n\n#### OFPForest\n\n```c#\nOFPForest\n{\n    String        ForestName;\n    RGBAColor    OutlineColour;\n    RGBAColor    ObjectColour;\n    ulong        SquareFillModelID;\n    ulong        SquareModelID;\n    ulong        TriangleModelID;\n    ulong        Unknown1; // (typically 0)\n    ulong        Unknown2; // (typically 0)\n}\n```\n\n#### NamedZone\n\n```c#\nNamedZone\n{\n    ushort        IsPresent;\n    ushort        Moveable;\n    String        Name; // Les_new\n    RGBAColor    AreaColor;\n    RGBAColor    OutlineColor;\n    ulong        DisplayStyle;\n    ulong        nFloats;\n    float        Floats[nFloats];\n    ulong        ID;\n    String        Name2;\n}\n```\n\n#### AltNamedZone\n\n```c#\nAltNamedZone\n{\n    ushort        IsPresent;\n    ushort        Moveable;\n    String        Name; // Les_new\n    RGBAColor    AreaColor;\n    RGBAColor    OutlineColor;\n    ulong        DisplayStyle;\n    ulong        nFloats;\n    float        Floats[nFloats];\n    ulong        ID;\n    ulong        Visible;\n}\n```\n\n#### RoadNetworkTemplates\n\n```c#\nRoadNetworkTemplates\n{\n    shortBool    RoadNetworkTemplatesDefined;\n    if (!RoadNetworkTemplatesDefined)\n    {\n        //RoadNetworkTemplates\n        ulong    NoOfRoadNetworkTemplates;\n        if (NoOfRoadNetworkTemplates > 0)\n        {\n            RoadNetTemplate RoadNetTemplates[NoOfRoadNetworkTemplates];\n        }\n\n        //CrossroadTemplates\n        ulong    NoOfCrossroadTemplates;\n        if (NoOfCrossroadTemplates > 0)\n        {\n            CrossroadTemplate CrossroadTemplates[NoOfCrossroadTemplates];\n        }\n    }\n}\n```\n\n##### RoadNetTemplate\n\n```c#\nRoadNetTemplate\n{\n    String        TemplateName;\n    RGBAColor    KeyPartsColour;\n    RGBAColor    NormalPartsColour;\n    shortBool    FilledLine;\n    double        MaxAngle;\n    double        MaxBankAngle;\n\n    ulong        NoOfStraightParts;\n    if (NoOfStraightParts > 0)\n        StraightPart StraightParts[NoOfStraightParts];\n\n    ulong        NoOfCurveParts;\n    if (NoOfCurveParts > 0)\n        CurvePart CurveParts[NoOfCurveParts];\n\n    ulong        NoOfSpecialParts;\n    if (NoOfSpecialParts > 0)\n        SpecialPart SpecialParts[NoOfSpecialParts];\n\n    ulong        NoOfTerminatorParts;\n    if (NoOfTerminatorParts > 0)\n        TerminatorPart TerminatorParts[NoOfTerminatorParts];\n}\n```\n\n###### StraightPart\n\n```c#\nStraightPart\n{\n    String                StraightPartName;\n    ulong                ObjectTemplateID;\n    StraightPartEnum    StraightPartType;\n    shortBool            CanChangeBankAngle;\n}\n```\n\n###### CurvePart\n\n```c#\nCurvePart\n{\nString            CurvePartName;\nulong            ObjectTemplateID;\nCurvePartEnum    CurvePartType;\n}\n```\n\n###### SpecialPart\n\n```c#\nSpecialPart\n{\n    String                SpecialPartName;\n    ulong                ObjectTemplateID;\n    SpecialPartEnum        SpecialPartType;\n}\n```\n\n###### TerminatorPart\n\n```c#\nTerminatorPart\n{\n    String    TerminatorPartName;\n    ulong    ObjectTemplateID;\n}\n```\n\n##### CrossroadTemplate\n\n```c#\nCrossroadTemplate\n{\n    String                TemplateName;\n    CrossroadTypeEnum    Shape;\n    RGBAColor            Color;\n    shortBool            FilledLine;\n    ulong                ObjectTemplateID;\n    String                Net_A;\n    String                Net_B;\n    String                Net_C;\n    String                Net_D;\n}\n```\n\n**MeterType Values**\n\n| Type | Straights | Curves |\n|---|---|---|\n| 0 | 6 m | 25 m |\n| 1 | 12 m | 50 m |\n| 2 | 25 m | 75 m |\n| 3 |  | 100 m |\n\nBroadly speaking, there are a few basic road types:\n\n- **asfalt**: Bitumen\n- **silnice**: Paved\n- **cesta**: Dirt\n\nEach RoadType describes the general characteristics of the corresponding road, and can have multiple curved, straight, special, and termination P3D models associated with it.\n\nGenerally speaking, there are:\n\n- 3 'straight' models, approximately 6, 12, and 25 meters long respectively.\n- 4 'curved' models, approximately 25, 50, 75, and 100 meters long.\n- 1 'termination' type.\n\nThe termination type is a road like any other but tends to be a fixed 6 meter fade out of the general road texture.\n\nAlthough \"CrossRoads\" could conceivably have any number of intersections, only two types are handled.\n\n- Type 1: A T_Junction (3 intersections)\n- Type 3: A genuine crossroad (4 way intersection)\n\nFor T_Junctions, there is obviously no 4th intersection and this is null filled.\n\nWithout taking too literal an interpretation, there are some major types of road.\n\n- asfaltka: Bitumen (sealed)\n- silnice: Paved\n- cesta: Dirt\n\nThus the names of each intersection reflect the road type of that intersection, sometimes resulting in (up to) four identical names.\n\nThe overall name of the crossroad itself, tries to reflect the nature of it is makeup thus\n\n- `kr_asfaltka_asfaltka_t`: an bitumen T_Junction\n- `kr_silince_x_cesta`: a crossroad of paved and dirt roads.\n\n#### Elevation\n\n```c#\nElevation\n{\n    XYPair    TerrainSize; // 256 x 256 eg\n    float    Heights[TerrainSize];\n    float    BlueEdgeTerrainHeights[NoOfBlueFloats]; // Always zero values\n    // NoOfBlueFloats = (TerrainSize_Y * TerrainSize_X) / 16;\n    ulong    Always0;\n}\n```\n\n#### Object\n\n```c#\nObject\n{\n    ShortBool IsPresent;\n    if (IsPresent)\n    {\n        ShortBool            Moveable;                // always 0\n        ulong                ObjectID;                // See Below\n        TransformMatrix        ColumnFormat;\n\n        double                ObjectRelativeSize;        // decimal percentage\n        String                InstanceName;            // \"\" mostly. \"minimalStrelPos\" eg for artifical objects\n        float                RelativeSurfaceElevation;\n        RGBA                OutlineColour;\n        RGBA                ObjectColour;\n        ulong                ModelID;                // See below\n    };\n};\n```\n\n##### TransformMatrix\n\nNote that a **pew** TransformMatrix is the only instance in the entire repertoire of bis file formats where the transform is specified in columns.\nAll other TransformMatrices of BI (notably models) are in Row format.\nIt makes diddly squat difference to the **values** in the matrix, only the positions of those values are different.\n\nThe 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.\n\n> [!NOTE]\n> See TransformMatrix.\n\n##### ObjectID\n\nEvery object entry has a zero-based, linear sequential ObjectID.\nObjectID is unique for every object and is the value displayed on a map for all models placed on it (including roads, grass, etc.).\nThus, every tree and every road section has its own unique ObjectID.\n\nThe first Object in the PEW file is ObjectID==0, the next 1,2,3,4 etc.\n\nIf an object has been deleted, that entry retains its unique object ID, even though the ObjectID is no longer stored.\nIf an object is not present (IsPresent is false), the ObjectID is calculated based on the last used object ID.\nThe 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.\nThe 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.\n\nWhen you add a new object, it is thus always is added to end of table with a new object ID.\nWhen you remove an object, the object ID remains reserved even though the object no longer exists.\n\nThis 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.\nWith upwards of 100,000 entries per island, this is practically impossible.\n\n##### ModelID\n\nNote that this is the unique ID of the ModelID in the object Template. It is not an index into the template structures.\nUnusual, and slow as a result.\n\n#### Layer\n\n```c#\nLayer\n{\n    ulong        SizeType;            // 0..2 - see below\n    String        Name;                // \"Base\"\n    shortBool    DefaultIndicator;    // 0 ... 1\n\n    if (DefaultIndicator == 0)\n    {\n        ulong    SurfaceTable[TableSize.x*y];\n        ulong    TextureTable[TableSize.x*y];\n        byte    UnknownTable[(TableSize.x*y/4)];\n        ushort    UnknownShort;\n    };\n\n    if (DefaultIndicator == 1)\n    {\n        ulong    NoOfTerrainMaterials;\n        TerrainMaterial[NoOfTerrainMaterials]\n        {\n            ulong    BitFlags;        // 1 = label, 0x40 = rvmatfile,,,,\n            String    MaterialName;    // \"---sea---\", \"Layers\\P_000-000_L00.rvmat\"\n            ulong    TypeID;            // 0..3\n        };\n        ulong    RvmatIndexTable[TableSize.x*y];\n    };\n};\n\nTableSize = Elevations.TerrainSize >> SizeType;\n```\n\n##### RvmatIndexTable\n\nThe texture table contains 1-based indexes into the rvmats.\nThis 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.\n\nThe organisation of 'cells' differs from its equivalent wrp. They are the reversed, mirror image of each other. Thus for a pew file with a 'poetic' 4x4 island:\n\n**PEW vs WRP format**\n\n|  |  |\n|---|---|\n| \\| PEW \\|  \\|  \\|  \\|<br>\\|---\\|---\\|---\\|---\\|<br>\\| C \\| 8 \\| 4 \\| **0** \\|<br>\\| D \\| 9 \\| 5 \\| 1 \\|<br>\\| E \\| A \\| 6 \\| 2 \\|<br>\\| F \\| B \\| 7 \\| 3 \\| | \\| WRP \\|  \\|  \\|  \\|<br>\\|---\\|---\\|---\\|---\\|<br>\\| C \\| D \\| E \\| F \\|<br>\\| 8 \\| 9 \\| A \\| B \\|<br>\\| 4 \\| 5 \\| 6 \\| 7 \\|<br>\\| **0** \\| 1 \\| 2 \\| 3 \\| |\n\nUnlike a wrp there is no Texture Size (256x256) eg. It is a derived value from the Elevations size (ergo the TerrainSize) (1024x1024 eg)\nThe size of this table, the 'Texture Size' is defined as a ratio via LayerSizeType.\n\n- 0 same\n- 1 half\n- 2 quarter\n\n##### Rvmat Conventions\n\nNaming of rvmat files (generally) follows a simple convention largely because the files are auto_generated when importing the satmask.\nThe resolved Texture size (dependent on the pixels and resoltion wanted) are divided into x and y numbered co-ordinates thus\n\np_(x)00..(x)nn_(y)00..nn_L00..zz\n\nwhere:\n\n(x) and (y) are the cellgrid position (and not part of the label)\n\nLzz is the layer\n\nFor a mythical single layer island with an 8x8 TEXTURE , files names will range from\n\np_00_00_L00 to p_07_07_L00\n\nPxxPyy\n\n#### RoadNetworks\n\nA 'RoadNetwork' essentially is comprised of a 'KeyPart' and 1-4 Directions. A Direction comprsises 0 to 'N' number of 'Parts'.\nWhen 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.\n\n```c#\nRoadNetworks\n{\n    shortBool                NetworkDefined;\n    if (NetworkDefined)\n    {\n        shortBool            Always0x01;\n        shortBool            Movable;\n        ulong                NetworkID;\n        float                Network_XZY[3];\n        float                Direction;\n        shortBool            KeyPartDefined;        // Should always be 1=Yes 'cause you cant start a road without placing a KeyPart\n        float                KeyPart_XZY[3];\n        float                KeyPart_Direction;\n        ulong                KeyPart_TemplateObjectID;\n        KeyPartTypeEnum        KeyPart_Type;\n        ushort                KeyPart_FamilyType;\n        String                KeyPart_RoadNetworkTemplateName;\n        String                KeyPart_ModelName;\n        RGBAColor            KeyPart_Color;\n        shortBool            DirectionsDefined;    // Should always be 0x0100=yes because every RoadNetwork has at least 1 direction.\n        ulong                NoOfDirections;\n        ulong                Direction_A_Something; //Always 0x0000 0000\n        ulong                Direction_B_Something; //Always 0x0000 0000\n        ulong                Direction_C_Something; //Always 0x0000 0000\n        ulong                Direction_D_Something; //Always 0x0000 0000\n        DirectionHeader        DirectionHeaders[NoOfDirections];\n        byte                Unknown[92];\n        ulong                NoOfDirections;\n        Direction            Directions[NoOfDirections];\n    }\n}\n```\n\n##### DirectionHeader\n\n```c#\nDirectionHeader\n{\n    String    RoadNetworkTemplateName;\n    float    DirectionOffsetXZY[3];\n    float    DirectionOffsetDirection; // 180.0 degrees.\n}\n```\n\n##### Direction\n\n```c#\nDirection\n{\n    ulong        NoOfParts;\n    RoadPart    RoadParts[NoOfParts];\n    String        RoadNetworkTemplateName;\n    float        DirectionOffsetXZY[3];\n    float        DirectionOffsetDirection; // 180.0 degrees.\n    RGBAColor    KeyPartColor;\n    RGBAColor    NormalPartColor;\n    shortBool    FilledLine;\n    double        MaxAngle;\n    double        MaxBankAngle;\n}\n```\n\n###### RoadPart\n\n```c#\nRoadPart\n{\n    shortBool    Defined;\n    shortBool    Enabled; // Possibly incorrect.\n    float        RoadPartXZY[3];\n    float        RoadPartDirection;\n    ulong        RoadPart_ObjectTemplateID;\n    ushort        PartTypeUIListboxIndex;\n    String        ModelName;\n    byte        Unknown[102];\n}\n```\n\n#### KeyPoint\n\n```c#\nKeyPoint\n{\n    ShortBool IsPresent;\n    if (IsPresent)\n    {\n        ShortBool    Always0;\n        String        ClassName;    // \"Noe_Lany\"\n        RGBA        AreaColor,OutlineColor;\n        ulong        DisplayStyle;    // 0 solid\n                                    // 1..6 hatch-horz,vert,cross,skew right,skew left,skewcross\n                                    // 7 standard\n        ShortBool    Visible;\n        float        Offset[2];    // map relative\n        float        Size[2];    // 250 x 250.0 eg (width and height)\n        ulong        ID;            // 0,1,2,3,4,5,6....\n        BisString    TownName;     // \"Lipany\", \"Hill\"\n        BisString    LocaleType;    // \"NameCity\" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf, Hill, Marine, ViewPoint\n        BisString    ClassText;    // \"canOcclude=1; BumbleButt='FlowControl2\"; ++=)#4555Semi\"\n    }\n}\n```\n\nThere is **always** a classname associated with this Keypoint,\n\n- Forest_Owls\n- Abel_LaTrinite\n- MyPinkElephant\n\nand in most cases a text name that is 'seen' on the map\n\n```\n\"Le Refuge Des Chasseurs\"\n```\n\nViewpoint and Marine types normally don't have names associated with them. There is no \"place\" in the sea.\n\nEach of these Keypoints have a Locale **Type**. Some of which are:\n\n- NameCity\n- NameCityCapital\n- NameVillage\n- VegetationBroadLeaf (Forest)\n\n> [!NOTE]\n> See Location.\n\n#### Background\n\n```c#\nBackground // this structure has not been seen\n{\n    String        BackgroundFilename;    // \"sat_lco.bmp\"\n    String        BackgroundName;        // \"overlay1\"\n    float        OffsetXY[2];\n    float        SizeXY[2];\n    ulong        Transparency;\n    shortBool    Visible;            // or ulong?\n}\n```\n\n#### Selection\n\n```c#\nSelection\n{\n    ushort                strlen;\n    char[]                SelectionName[strlen]; // NOT null terminated\n    ulong                nObjects;\n    SelectionObject        SelectionObjects[nObjects]\n}\n```\n\n##### SelectionObject\n\n```c#\nSelectionObject\n{\n    ulong    ObjectInstanceID;\n    byte    Unknown[8];\n}\n```\n\n### Enums\n\n#### ObjectTemplateTypeEnum\n\n```c#\nenum ObjectTemplateTypeEnum\n{\n    Undefined = 0,\n    Natural = 1,\n    Artificial = 2,\n    Road = 3,\n    Forest = 4,\n    Road2 = 5\n}\n```\n\n#### MarkerTypeEnum\n\n```c#\nenum MarkerTypeEnum\n{\n    Rectangular = 0,\n    Elliptical = 1\n}\n```\n\n#### StraightPartEnum\n\n```c#\nenum StraightPartEnum : ushort\n{\n    SixBy25,    // 6,25m\n    TwelveBy5,    // 12,5m\n    TwentyFive    // 25m\n}\n```\n\n#### CurvePartEnum\n\n```c#\nenum CurvePartEnum : ushort\n{\n    Radius25m,\n    Radius50m,\n    Radius75m,\n    Radius100m\n}\n```\n\n#### SpecialPartEnum\n\n```c#\nenum SpecialPartEnum : ushort\n{\n    SixBy25,    // 6,25m\n    TwelveBy5,    // 12,5m\n    TwentyFive    // 25m\n}\n```\n\n#### KeyPartTypeEnum\n\n```c#\nenum KeyPartTypeEnum\n{\n    Crossroad,\n    Straight,\n    Special,\n    Terminator\n}\n```","sections":[{"heading":null,"level":1,"markdown":"> **Disclaimer: This page describes internal undocumented structures of Bohemia Interactive software.**\n>\n> This page contains unofficial information.\n>\n> Some usage of this information may constitute a violation of the rights of Bohemia Interactive and is in no way endorsed or recommended by Bohemia Interactive.\n> Bohemia Interactive is not willing to tolerate use of such tools if it contravenes any general licenses granted to end users of this community wiki or BI products.\n\nPEW files are Visitor's project files. Visitor is Bohemia Interactive's tool for creating Islands.\n\nVisitor is a GUI tool interface that interacts with Bulldozer, an in-built 'world' viewer inside any Armed Assault engine.\n\nThe contents of the PEW project file are not directly related to the ultimate output, a WRP file.\nHowever, that data contains all similar elements, such as road networks, elevations, cell matrices, models (P3D files) and textures (RVMAT files).\n\nExporting 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.\nIt 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.\nThis 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.\n\nFurthermore, 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.\nRoadnetworks and other ancilliary data is only processed into a 'binarised' OPRW format wrp, using Bi's binarizer tool.\n\nNote that it is possible to generate 8WVR format without involving bulldozer (or arma) using [*party tools* (dead link)].\n\nWhile there have been several PEW versions, the ones listed here are:\n\n- POSEW59\n- POSEW60\n\nThere are only a few subtle differences to their makeup."},{"heading":"Legend","level":3,"markdown":"See Generic FileFormat Data Types."},{"heading":"File Format","level":3,"markdown":"> [!NOTE]\n> This file format is principally used with Armed Assault v1.09 and later, with the ArmA Tools Suite final release (v1.14).\n\n```c#\nPOSEW59\nPOSEW60\n{\n    PoseHeader                Header;\n    ulong                    nOFPTextures;            // none in Arma\n    OFPTexture                OFPTextures[nOFPTextures];\n    ulong                    nObjectTemplates;\n    ObjectTemplate            ObjectTemplates[nObjectTemplates];\n    shortBool                NoOfpTerrains;\n    if (!NoOfpTerrains)\n    {\n        ulong                nOFPTerrains;            // none in Arma\n        OFPTerrain            OFPTerrains[nOFPTerrains];\n    }\n    shortBool                NoOFPForests;            // none in Arma\n    if (!NoOFPForests)\n    {\n        ulong                nOFPForests;\n        OFPForest            OFPForests[nOFPForests];\n    }\n    RoadNetworkTemplate        RoadNetworkTemplates[...];\n    Elevation                Elevation[...];\n    ulong                    NoOfObjects;\n    Object                    Objects[NoOfObjects];\n\n    ulong                    NoOfLayers;\n    String                    CurrentLayerName;        // \"Base\"\n    Layer                    Layers[NoOfLayers] ;\n\n    ulong                    nNamedZones;// almost never present on pose60\n    NamedZone                NamedZones[nNamedZones];\n\n    ulong                    nRoadNetworks;\n    if (nRoadNetworks > 0)\n        RoadNetwork            RoadNetworks[nRoadNetworks];\n\n    ulong                    nKeyPoints;\n    KeyPoint                KeyPoints[nKeyPoints];\n    ulong                    NoOfBackgrounds;\n    Background                Backgrounds[NoOfBackgrounds]; // not checked for 59\n    ulong                    TotalSizeOfSelections; // from here, to end of file\n    ulong                    nSelections;\n    Selection                Selections[nSelections];\n}\n```"},{"heading":"PoseHeader","level":4,"markdown":"```c#\nHeader\n{\n    char    Signature[7];        // \"POSEW59\" or \"POSEW60\" note: NOT null terminated\n    ulong    Length;                // of PEW file;\n    ulong    UnknownLong;        // typically 0\n    String    IslandRvMatPath;    // \"SomePboPrefix\\SomeIsland\\data\\0\" see below\n    String    IslandP3dPath;        // \"\" (objects)\n    float    TerrainGridSize;    // 10.0 metres\n    float    SegmentSize;        // 400.0 (==SegmentSize - SegmentOverlap)\n    String    IslandClassname;    // \"\"\n};\n```"},{"heading":"Texture And Terrain Sizes","level":5,"markdown":"- Pew files deal with **terrain**. There is no 'texture' size as such. Therefore the gridsize specified in the header pertains to **terrain** cells.\n- In contrast, the gridsize specified in a WRP pertains to TEXTURE(rvmat) cells.\n\n\"Texture\", 'Material', 'Surface', 'Layer' are synonomous to rvmat files.\nThey are the island's unique surface as generated by importing from a sat mask image. There can be multipler layers of rvmat files.\n\n*Terrain*, are the cell grids of the map and as often as not specified at a different (larger) dimension.\n\nUnlike Wrp files, Textures and Terrain sizes are not declared in a pew directly. At least, not, in the header.\n\nThe Terrain (Map) Size is declared in the elevations structure.\n\nTextureSizeS (plural) are derived, not declared, in each surface 'Layer' of pew. Since, ultimately, each layer must 'fit' onto the map.\nEach layer contains a shift value of how much SMALLER the surface is, relative to the map.\nFor OFP, and OFP converted-to-arma, islands, this is 0 (there is no difference betweem a 256x256 cell Terrain and a 256x256 cell Texture.\n\nFor Arma, it is *generally* x 4 (shift value=2)."},{"heading":"TerrainGridSize","level":6,"markdown":"A wrp file's GridSize is the OPPOSITE of a PewFile's GridSize.\n\nIn a wrp, it defines the size (in meters) of each cell of the TEXTURE (rvmats).\n\nIn a pew, there is no direct TEXTURE dimension since there can be multiple layers, each with different (derived) dimensions.\n\nSo this value, in a pew, is the TERRAIN dimension."},{"heading":"IslandRvMatPath","level":6,"markdown":"RVMAT file references in the Layers structure are listed as *relative* addresses to the IslandRvMatPath.\nThis is in contradistinction to the general Bis way-of-doing-things where all references are hard references.\n\nTraditionally, an RVMAT(Island) data path is declared as \"Layers\\some.rvmat\".\nIt is expected, therefore, that you do indeed have a \"P:\\SomePboPrefix\\SomeIsland\\...\\Layers\" folder.\nPut another way, the *prefix* of the PBO must be \"SomePboPrefix\\SomeIsland\\...\".\n\nThe SubFolder 'Layers' is hard wired by Visitor. It is generated automatically when importing a satmask image.\nThus, all relative reverences to the rvmats that Visitor produces, are prefaced by 'Layers\\'.\n\nUsing 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).\nThe purpose in doing so is somewhat moot, since, unlike p3d's, rvmat's for an island are unique to an island.\nThe 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."},{"heading":"IslandObjectPath","level":6,"markdown":"IslandObjectPath uses the same mechanics as above.\nHowever, 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.\nBe that as it may, the mechanism exists and works, identically to IslandRvMatPath.\n\nPEW files are not known to contain anything in IslandObjectPath or IslandClassname."},{"heading":"OFPTexture","level":4,"markdown":"```c#\nOFPTexture\n{\n    ulong        TextureID;\n    String        TextureFileName;    // \"snih3.paa\"\n    String        TextureName;        // \"snih3\"\n    String        RvmatName;            // \"snih3.rvmat\"\n    byte        UnknownBytes[14];    // (typically 0)\n    RGBAColor    Colour;\n}\n```"},{"heading":"ObjectTemplate","level":4,"markdown":"```c#\nObjectTemplate\n{\n    String        ModelFilename;    // \"SomePrefixRoot\\data\\jablon.p3d\\0\"\n    String        ModelName;        // \"jablon\"\n    ulong        ObjectType;        // 0..5 (so far...)\n                                // 0 Undefined - This type should never be encountered.\n                                // 1 Natural\n                                // 2 Artificial\n                                // 3 Road (RoadFlag will be true)\n                                // 4 Forest\n                                // 5 Road2 (RoadFlag will be false)\n    RGBAColor    OutlineColour;\n    RGBAColor    ObjectColour;\n    double        GeometryBounds[2];                // 50.0\n    ulong        ModelID;                        // uniqueID, used by objects to lookup this model(p3d)\n    XYZTriplet    GeometryAutocenterPos;\n    double        ResolutionBounds[2];            // 50.0\n    XYZTriplet    ResolutionAutoCenterPos;\n    shortBool    Generally0x01;\n    shortBool    RandomScaleFlag;\n    double        RandomScaleMinMax[2];            // 50.0\n    shortBool    RandomRotateFlag;\n    double        RandomRotateMinMax[2];            // 20.0\n    shortBool    RandomOrientationFlag;\n    double        RanmdomOrientationMinMax[2];    // 180.0\n    shortBool    RoadFlag;\n    if (RoadFlag)\n    {\n        TransformMatrix RoadNamedSelections;    // (LB, PB, LE, PE)\n        TransformMatrix XRoadNamedSelections;    // (LD, LH, PD, PH)\n    };\n    ulong        nNamedVectors;                    // Usually 0 (zero)\n    NamedVector    NamedVectors[nNamedVectors];\n    ulong        MarkerType;                        // Rectangular = 0, Elliptical = 1\n}\n```\n\nAs opposed to layers (material RVMAT surfaces), 'objects' are instances of models placed onto the map.\nIrrespective of the number of objects there is only one reference to the model used, which is then referenced as often as needed.\n\nModelFilename, ModelName, and ModelID are unique unduplicated entries.\n\nThe 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.\nThe ObjectID illustrated on maps is, in contrast, the unique InstanceID of each object in the objects structure below.\n'Road2' type cannot be defined with Visitor3 Personal Edition. It's a type specific to VBS2 V3 edition."},{"heading":"NamedVector","level":5,"markdown":"```c#\nNamedVector\n{\n    String        Name;        // \"pohrada\"\n    LongBool    Unknown;\n    ulong        nTriplets; // generally 2 sometimes 1\n    XYZTriplet    StartEndPos[nTriplets];\n}\n```\n\nAs of v60 a rarely used sub structure with ObjTemplates."},{"heading":"OFPTerrain","level":4,"markdown":"```c#\nOFPTerrain\n{\n    String        TerrainName;\n    byte        UnknownBytes[11];\n    ulong        nSurfaces;\n    OFPSurface    OFPSurfaces[nSurfaces];\n}\n```"},{"heading":"OFPSurface","level":5,"markdown":"```c#\nOFPSurface\n{\n    String    SurfaceName;\n    float    Surfacefloat[4];\n    byte    UnknownBytes[16];\n}\n```"},{"heading":"OFPForest","level":4,"markdown":"```c#\nOFPForest\n{\n    String        ForestName;\n    RGBAColor    OutlineColour;\n    RGBAColor    ObjectColour;\n    ulong        SquareFillModelID;\n    ulong        SquareModelID;\n    ulong        TriangleModelID;\n    ulong        Unknown1; // (typically 0)\n    ulong        Unknown2; // (typically 0)\n}\n```"},{"heading":"NamedZone","level":4,"markdown":"```c#\nNamedZone\n{\n    ushort        IsPresent;\n    ushort        Moveable;\n    String        Name; // Les_new\n    RGBAColor    AreaColor;\n    RGBAColor    OutlineColor;\n    ulong        DisplayStyle;\n    ulong        nFloats;\n    float        Floats[nFloats];\n    ulong        ID;\n    String        Name2;\n}\n```"},{"heading":"AltNamedZone","level":4,"markdown":"```c#\nAltNamedZone\n{\n    ushort        IsPresent;\n    ushort        Moveable;\n    String        Name; // Les_new\n    RGBAColor    AreaColor;\n    RGBAColor    OutlineColor;\n    ulong        DisplayStyle;\n    ulong        nFloats;\n    float        Floats[nFloats];\n    ulong        ID;\n    ulong        Visible;\n}\n```"},{"heading":"RoadNetworkTemplates","level":4,"markdown":"```c#\nRoadNetworkTemplates\n{\n    shortBool    RoadNetworkTemplatesDefined;\n    if (!RoadNetworkTemplatesDefined)\n    {\n        //RoadNetworkTemplates\n        ulong    NoOfRoadNetworkTemplates;\n        if (NoOfRoadNetworkTemplates > 0)\n        {\n            RoadNetTemplate RoadNetTemplates[NoOfRoadNetworkTemplates];\n        }\n\n        //CrossroadTemplates\n        ulong    NoOfCrossroadTemplates;\n        if (NoOfCrossroadTemplates > 0)\n        {\n            CrossroadTemplate CrossroadTemplates[NoOfCrossroadTemplates];\n        }\n    }\n}\n```"},{"heading":"RoadNetTemplate","level":5,"markdown":"```c#\nRoadNetTemplate\n{\n    String        TemplateName;\n    RGBAColor    KeyPartsColour;\n    RGBAColor    NormalPartsColour;\n    shortBool    FilledLine;\n    double        MaxAngle;\n    double        MaxBankAngle;\n\n    ulong        NoOfStraightParts;\n    if (NoOfStraightParts > 0)\n        StraightPart StraightParts[NoOfStraightParts];\n\n    ulong        NoOfCurveParts;\n    if (NoOfCurveParts > 0)\n        CurvePart CurveParts[NoOfCurveParts];\n\n    ulong        NoOfSpecialParts;\n    if (NoOfSpecialParts > 0)\n        SpecialPart SpecialParts[NoOfSpecialParts];\n\n    ulong        NoOfTerminatorParts;\n    if (NoOfTerminatorParts > 0)\n        TerminatorPart TerminatorParts[NoOfTerminatorParts];\n}\n```"},{"heading":"StraightPart","level":6,"markdown":"```c#\nStraightPart\n{\n    String                StraightPartName;\n    ulong                ObjectTemplateID;\n    StraightPartEnum    StraightPartType;\n    shortBool            CanChangeBankAngle;\n}\n```"},{"heading":"CurvePart","level":6,"markdown":"```c#\nCurvePart\n{\nString            CurvePartName;\nulong            ObjectTemplateID;\nCurvePartEnum    CurvePartType;\n}\n```"},{"heading":"SpecialPart","level":6,"markdown":"```c#\nSpecialPart\n{\n    String                SpecialPartName;\n    ulong                ObjectTemplateID;\n    SpecialPartEnum        SpecialPartType;\n}\n```"},{"heading":"TerminatorPart","level":6,"markdown":"```c#\nTerminatorPart\n{\n    String    TerminatorPartName;\n    ulong    ObjectTemplateID;\n}\n```"},{"heading":"CrossroadTemplate","level":5,"markdown":"```c#\nCrossroadTemplate\n{\n    String                TemplateName;\n    CrossroadTypeEnum    Shape;\n    RGBAColor            Color;\n    shortBool            FilledLine;\n    ulong                ObjectTemplateID;\n    String                Net_A;\n    String                Net_B;\n    String                Net_C;\n    String                Net_D;\n}\n```\n\n**MeterType Values**\n\n| Type | Straights | Curves |\n|---|---|---|\n| 0 | 6 m | 25 m |\n| 1 | 12 m | 50 m |\n| 2 | 25 m | 75 m |\n| 3 |  | 100 m |\n\nBroadly speaking, there are a few basic road types:\n\n- **asfalt**: Bitumen\n- **silnice**: Paved\n- **cesta**: Dirt\n\nEach RoadType describes the general characteristics of the corresponding road, and can have multiple curved, straight, special, and termination P3D models associated with it.\n\nGenerally speaking, there are:\n\n- 3 'straight' models, approximately 6, 12, and 25 meters long respectively.\n- 4 'curved' models, approximately 25, 50, 75, and 100 meters long.\n- 1 'termination' type.\n\nThe termination type is a road like any other but tends to be a fixed 6 meter fade out of the general road texture.\n\nAlthough \"CrossRoads\" could conceivably have any number of intersections, only two types are handled.\n\n- Type 1: A T_Junction (3 intersections)\n- Type 3: A genuine crossroad (4 way intersection)\n\nFor T_Junctions, there is obviously no 4th intersection and this is null filled.\n\nWithout taking too literal an interpretation, there are some major types of road.\n\n- asfaltka: Bitumen (sealed)\n- silnice: Paved\n- cesta: Dirt\n\nThus the names of each intersection reflect the road type of that intersection, sometimes resulting in (up to) four identical names.\n\nThe overall name of the crossroad itself, tries to reflect the nature of it is makeup thus\n\n- `kr_asfaltka_asfaltka_t`: an bitumen T_Junction\n- `kr_silince_x_cesta`: a crossroad of paved and dirt roads."},{"heading":"Elevation","level":4,"markdown":"```c#\nElevation\n{\n    XYPair    TerrainSize; // 256 x 256 eg\n    float    Heights[TerrainSize];\n    float    BlueEdgeTerrainHeights[NoOfBlueFloats]; // Always zero values\n    // NoOfBlueFloats = (TerrainSize_Y * TerrainSize_X) / 16;\n    ulong    Always0;\n}\n```"},{"heading":"Object","level":4,"markdown":"```c#\nObject\n{\n    ShortBool IsPresent;\n    if (IsPresent)\n    {\n        ShortBool            Moveable;                // always 0\n        ulong                ObjectID;                // See Below\n        TransformMatrix        ColumnFormat;\n\n        double                ObjectRelativeSize;        // decimal percentage\n        String                InstanceName;            // \"\" mostly. \"minimalStrelPos\" eg for artifical objects\n        float                RelativeSurfaceElevation;\n        RGBA                OutlineColour;\n        RGBA                ObjectColour;\n        ulong                ModelID;                // See below\n    };\n};\n```"},{"heading":"TransformMatrix","level":5,"markdown":"Note that a **pew** TransformMatrix is the only instance in the entire repertoire of bis file formats where the transform is specified in columns.\nAll other TransformMatrices of BI (notably models) are in Row format.\nIt makes diddly squat difference to the **values** in the matrix, only the positions of those values are different.\n\nThe 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.\n\n> [!NOTE]\n> See TransformMatrix."},{"heading":"ObjectID","level":5,"markdown":"Every object entry has a zero-based, linear sequential ObjectID.\nObjectID is unique for every object and is the value displayed on a map for all models placed on it (including roads, grass, etc.).\nThus, every tree and every road section has its own unique ObjectID.\n\nThe first Object in the PEW file is ObjectID==0, the next 1,2,3,4 etc.\n\nIf an object has been deleted, that entry retains its unique object ID, even though the ObjectID is no longer stored.\nIf an object is not present (IsPresent is false), the ObjectID is calculated based on the last used object ID.\nThe 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.\nThe 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.\n\nWhen you add a new object, it is thus always is added to end of table with a new object ID.\nWhen you remove an object, the object ID remains reserved even though the object no longer exists.\n\nThis 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.\nWith upwards of 100,000 entries per island, this is practically impossible."},{"heading":"ModelID","level":5,"markdown":"Note that this is the unique ID of the ModelID in the object Template. It is not an index into the template structures.\nUnusual, and slow as a result."},{"heading":"Layer","level":4,"markdown":"```c#\nLayer\n{\n    ulong        SizeType;            // 0..2 - see below\n    String        Name;                // \"Base\"\n    shortBool    DefaultIndicator;    // 0 ... 1\n\n    if (DefaultIndicator == 0)\n    {\n        ulong    SurfaceTable[TableSize.x*y];\n        ulong    TextureTable[TableSize.x*y];\n        byte    UnknownTable[(TableSize.x*y/4)];\n        ushort    UnknownShort;\n    };\n\n    if (DefaultIndicator == 1)\n    {\n        ulong    NoOfTerrainMaterials;\n        TerrainMaterial[NoOfTerrainMaterials]\n        {\n            ulong    BitFlags;        // 1 = label, 0x40 = rvmatfile,,,,\n            String    MaterialName;    // \"---sea---\", \"Layers\\P_000-000_L00.rvmat\"\n            ulong    TypeID;            // 0..3\n        };\n        ulong    RvmatIndexTable[TableSize.x*y];\n    };\n};\n\nTableSize = Elevations.TerrainSize >> SizeType;\n```"},{"heading":"RvmatIndexTable","level":5,"markdown":"The texture table contains 1-based indexes into the rvmats.\nThis 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.\n\nThe organisation of 'cells' differs from its equivalent wrp. They are the reversed, mirror image of each other. Thus for a pew file with a 'poetic' 4x4 island:\n\n**PEW vs WRP format**\n\n|  |  |\n|---|---|\n| \\| PEW \\|  \\|  \\|  \\|<br>\\|---\\|---\\|---\\|---\\|<br>\\| C \\| 8 \\| 4 \\| **0** \\|<br>\\| D \\| 9 \\| 5 \\| 1 \\|<br>\\| E \\| A \\| 6 \\| 2 \\|<br>\\| F \\| B \\| 7 \\| 3 \\| | \\| WRP \\|  \\|  \\|  \\|<br>\\|---\\|---\\|---\\|---\\|<br>\\| C \\| D \\| E \\| F \\|<br>\\| 8 \\| 9 \\| A \\| B \\|<br>\\| 4 \\| 5 \\| 6 \\| 7 \\|<br>\\| **0** \\| 1 \\| 2 \\| 3 \\| |\n\nUnlike a wrp there is no Texture Size (256x256) eg. It is a derived value from the Elevations size (ergo the TerrainSize) (1024x1024 eg)\nThe size of this table, the 'Texture Size' is defined as a ratio via LayerSizeType.\n\n- 0 same\n- 1 half\n- 2 quarter"},{"heading":"Rvmat Conventions","level":5,"markdown":"Naming of rvmat files (generally) follows a simple convention largely because the files are auto_generated when importing the satmask.\nThe resolved Texture size (dependent on the pixels and resoltion wanted) are divided into x and y numbered co-ordinates thus\n\np_(x)00..(x)nn_(y)00..nn_L00..zz\n\nwhere:\n\n(x) and (y) are the cellgrid position (and not part of the label)\n\nLzz is the layer\n\nFor a mythical single layer island with an 8x8 TEXTURE , files names will range from\n\np_00_00_L00 to p_07_07_L00\n\nPxxPyy"},{"heading":"RoadNetworks","level":4,"markdown":"A 'RoadNetwork' essentially is comprised of a 'KeyPart' and 1-4 Directions. A Direction comprsises 0 to 'N' number of 'Parts'.\nWhen 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.\n\n```c#\nRoadNetworks\n{\n    shortBool                NetworkDefined;\n    if (NetworkDefined)\n    {\n        shortBool            Always0x01;\n        shortBool            Movable;\n        ulong                NetworkID;\n        float                Network_XZY[3];\n        float                Direction;\n        shortBool            KeyPartDefined;        // Should always be 1=Yes 'cause you cant start a road without placing a KeyPart\n        float                KeyPart_XZY[3];\n        float                KeyPart_Direction;\n        ulong                KeyPart_TemplateObjectID;\n        KeyPartTypeEnum        KeyPart_Type;\n        ushort                KeyPart_FamilyType;\n        String                KeyPart_RoadNetworkTemplateName;\n        String                KeyPart_ModelName;\n        RGBAColor            KeyPart_Color;\n        shortBool            DirectionsDefined;    // Should always be 0x0100=yes because every RoadNetwork has at least 1 direction.\n        ulong                NoOfDirections;\n        ulong                Direction_A_Something; //Always 0x0000 0000\n        ulong                Direction_B_Something; //Always 0x0000 0000\n        ulong                Direction_C_Something; //Always 0x0000 0000\n        ulong                Direction_D_Something; //Always 0x0000 0000\n        DirectionHeader        DirectionHeaders[NoOfDirections];\n        byte                Unknown[92];\n        ulong                NoOfDirections;\n        Direction            Directions[NoOfDirections];\n    }\n}\n```"},{"heading":"DirectionHeader","level":5,"markdown":"```c#\nDirectionHeader\n{\n    String    RoadNetworkTemplateName;\n    float    DirectionOffsetXZY[3];\n    float    DirectionOffsetDirection; // 180.0 degrees.\n}\n```"},{"heading":"Direction","level":5,"markdown":"```c#\nDirection\n{\n    ulong        NoOfParts;\n    RoadPart    RoadParts[NoOfParts];\n    String        RoadNetworkTemplateName;\n    float        DirectionOffsetXZY[3];\n    float        DirectionOffsetDirection; // 180.0 degrees.\n    RGBAColor    KeyPartColor;\n    RGBAColor    NormalPartColor;\n    shortBool    FilledLine;\n    double        MaxAngle;\n    double        MaxBankAngle;\n}\n```"},{"heading":"RoadPart","level":6,"markdown":"```c#\nRoadPart\n{\n    shortBool    Defined;\n    shortBool    Enabled; // Possibly incorrect.\n    float        RoadPartXZY[3];\n    float        RoadPartDirection;\n    ulong        RoadPart_ObjectTemplateID;\n    ushort        PartTypeUIListboxIndex;\n    String        ModelName;\n    byte        Unknown[102];\n}\n```"},{"heading":"KeyPoint","level":4,"markdown":"```c#\nKeyPoint\n{\n    ShortBool IsPresent;\n    if (IsPresent)\n    {\n        ShortBool    Always0;\n        String        ClassName;    // \"Noe_Lany\"\n        RGBA        AreaColor,OutlineColor;\n        ulong        DisplayStyle;    // 0 solid\n                                    // 1..6 hatch-horz,vert,cross,skew right,skew left,skewcross\n                                    // 7 standard\n        ShortBool    Visible;\n        float        Offset[2];    // map relative\n        float        Size[2];    // 250 x 250.0 eg (width and height)\n        ulong        ID;            // 0,1,2,3,4,5,6....\n        BisString    TownName;     // \"Lipany\", \"Hill\"\n        BisString    LocaleType;    // \"NameCity\" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf, Hill, Marine, ViewPoint\n        BisString    ClassText;    // \"canOcclude=1; BumbleButt='FlowControl2\"; ++=)#4555Semi\"\n    }\n}\n```\n\nThere is **always** a classname associated with this Keypoint,\n\n- Forest_Owls\n- Abel_LaTrinite\n- MyPinkElephant\n\nand in most cases a text name that is 'seen' on the map\n\n```\n\"Le Refuge Des Chasseurs\"\n```\n\nViewpoint and Marine types normally don't have names associated with them. There is no \"place\" in the sea.\n\nEach of these Keypoints have a Locale **Type**. Some of which are:\n\n- NameCity\n- NameCityCapital\n- NameVillage\n- VegetationBroadLeaf (Forest)\n\n> [!NOTE]\n> See Location."},{"heading":"Background","level":4,"markdown":"```c#\nBackground // this structure has not been seen\n{\n    String        BackgroundFilename;    // \"sat_lco.bmp\"\n    String        BackgroundName;        // \"overlay1\"\n    float        OffsetXY[2];\n    float        SizeXY[2];\n    ulong        Transparency;\n    shortBool    Visible;            // or ulong?\n}\n```"},{"heading":"Selection","level":4,"markdown":"```c#\nSelection\n{\n    ushort                strlen;\n    char[]                SelectionName[strlen]; // NOT null terminated\n    ulong                nObjects;\n    SelectionObject        SelectionObjects[nObjects]\n}\n```"},{"heading":"SelectionObject","level":5,"markdown":"```c#\nSelectionObject\n{\n    ulong    ObjectInstanceID;\n    byte    Unknown[8];\n}\n```"},{"heading":"Enums","level":3,"markdown":""},{"heading":"ObjectTemplateTypeEnum","level":4,"markdown":"```c#\nenum ObjectTemplateTypeEnum\n{\n    Undefined = 0,\n    Natural = 1,\n    Artificial = 2,\n    Road = 3,\n    Forest = 4,\n    Road2 = 5\n}\n```"},{"heading":"MarkerTypeEnum","level":4,"markdown":"```c#\nenum MarkerTypeEnum\n{\n    Rectangular = 0,\n    Elliptical = 1\n}\n```"},{"heading":"StraightPartEnum","level":4,"markdown":"```c#\nenum StraightPartEnum : ushort\n{\n    SixBy25,    // 6,25m\n    TwelveBy5,    // 12,5m\n    TwentyFive    // 25m\n}\n```"},{"heading":"CurvePartEnum","level":4,"markdown":"```c#\nenum CurvePartEnum : ushort\n{\n    Radius25m,\n    Radius50m,\n    Radius75m,\n    Radius100m\n}\n```"},{"heading":"SpecialPartEnum","level":4,"markdown":"```c#\nenum SpecialPartEnum : ushort\n{\n    SixBy25,    // 6,25m\n    TwelveBy5,    // 12,5m\n    TwentyFive    // 25m\n}\n```"},{"heading":"KeyPartTypeEnum","level":4,"markdown":"```c#\nenum KeyPartTypeEnum\n{\n    Crossroad,\n    Straight,\n    Special,\n    Terminator\n}\n```"}],"categories":["Real Virtuality File Formats"],"groups":["Tools and File Formats"]}