====== PEW File Format ====== ====== Introduction ====== PEW are Visitor's project files. Visitor is BIS tool for creating terrains. Visitor is a GUI tool that interacts with Bulldozer, an inbuilt 'world' viewer inside any Armed Assault engine. The contents of the project file, pew, are not directly related to the ultimate output, a wrp file. However, that data, of course, contains all similar elements, such as road networks, elevations, cell matrices, models and textures. Exporting a pew file into wrp format, involves the use of Bulldozer, since it is Bulldozer that decides how it wants that data presented, rather than anything visitor might like to decide. It is Bulldozer that determines the format and version of the resulting wrp file (in 8WVR format), and consequently, that, is a reflection of the Arma Engine itself. While there have been several pew versions, the one's 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 plus the ArmA Tools Suite Final release (v1.14). POSEW59 POSEW60 { PoseHeader Header; ulong nOFPTextures // none in Arma; OFPTexture OFPTextures[[nOFPTextures]]; ulong nObjectTemplates; ObjectTemplate ObjectTemplates[[nObjectTemplates]]; shortBool NoOfpTerrains; if (!NoOfpTerrains) { ulong nOFPTerrains; // none in Arma; OFPTerrain OFPTerrains[[nOFPTerrains]]; } shortBool NoOFPForests; // none in Arma; if (!NoOFPForests) { ulong nOFPForests; OFPForest OFPForests[[nOFPForests]]; } RoadNets RoadNets[[...]]; Elevation Elevation[[...]]; ulong NoOfObjects; Object Objects[[NoOfObjects]]; ulong NoOfLayers; String LayerName; //"Base" Layer Layers[[NoOfLayers]] ; if (POSEW60) { ulong Unknown; } else // pose59 { ulong nNamedZones; NamedZone NamedZones[[nNamedZones]]; } ulong nRoadBlocks; RoadBlock RoadBlocks[[nRoadBlocks]]; if (POSEW60) { ulong nNamedZones; NamedZone NamedZones[[nNamedZones]]; } else // pose59 { ulong Unknown; } ulong nKeyPoints; KeyPoint KeyPoints[[nKeyPoints]]; ulong NoOfBackgrounds; Background Backgrounds[[NoOfBackgrounds]] ;// not checked for 59 ulong TotalSizeOfSelections; // from here, to end of file ulong nSelections; Selection Selections[[nSelections]]; } ====== PoseHeader ====== Header { char Signature[[7]]; // "POSEW59" or "POSEW60" note: NOT null terminated ulong Length; // of PEW file; ulong UnknownLong; // typically 0 String IslandDataPath; //"SomePboPrefix\SomeIsland\data\0" // Folderlocation of the rvmat material list String IslandObjectPath; //"" float GridSize; //50.0 float SegmentSize; //400.0 (==SegmentSize - SegmentOverlap) String IslandClassname; //"" }; ====== OFPTexture ====== OFPTexture { ulong TextureID; String TextureFileName; // "snih3.paa" String TextureName; // "snih3" String RvmatName; // "snih3.rvmat" byte UnknownBytes[[14]]; // (typically 0) RGBAColor Colour; } ====== ObjectTemplate ====== ObjectTemplate { String ModelFilename; //"SomePrefixRoot\data\jablon.p3d\0" String ModelName; //"jablon" ulong ObjectType; // 0..5 // 0 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; 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 } ====== NamedVector ====== NamedVector { String Name; //"pohrada" LongBool Unknown; ulong nTriplets; // always 2 XYZTriplet StartEndPos[[nTriplets]]; } ====== OFPTerrain ====== OFPTerrain { String TerrainName; byte UnknownBytes[[11]]; ulong nSurfaces; OFPSurface OFPSurfaces[[nSurfaces]]; } ====== OFPSurface ====== OFPSurface { String SurfaceName; float Surfacefloat[[4]]; byte UnknownBytes[[16]]; } ====== OFPForest ====== OFPForest { String ForestName; RGBAColor OutlineColour; RGBAColor ObjectColour; ulong SquareFillModelID; ulong SquareModelID; ulong TriangleModelID; ulong Unknown1; // (typically 0) ulong Unknown2; // (typically 0) } ====== RoadNet ====== shortBool NoRoads; if (!NoRoads) { ulong nTypes; RoadType RoadTypes[[nTypes]]; ulong nXRoads; XRoad XRoads[[nXRoads]]; } ====== RoadType ====== RoadType { String FamilyName; // "cesta","silnice",etc RGBA KeyPartsColour; RGBA NormalPartsColour; shortBool FilledLine; // 0 or 1 double MaxAngle; // 25.0 degrees double MaxBankAngle; // 5.0 degrees ulong nStraights; RoadList Straights[[nStraights]]; ulong nCurves; RoadList Curves[[nCurves]]; ulong nSpecials; RoadList Specials[[nSpecials]]; ulong nTerminators; RoadList Terminators[[nTerminators]]; } } ====== RoadList ====== RoadList { String ModelName; // "cesta25" ulong ObjectID; // in the model list ushort MeterType; // 0,1,2,3 not present for Terminators shortBool CanChangeAngle; // not present for Terminators or Curves } MeterType :Type Straights Curves :0 6 25 meters :1 12 50 :2 25 75 :3 100 Broadly speaking, there are a few basic road types *asfalt bitumen. *silnice Paved *cesta dirt Each RoadType describes the general characteristics of a Dirt Road as opposed to (say) an Asphalt one. Each of these RoadTypes (such as asphalt) can have multiple curved, straight, special, and termination p3d models associated with them. Generally speaking, there are *3 'straight' models, approximately 6,12, and 25 meters long respectively. *4 'curved' models, 25,50,75 and 100 meters long. *1 'terminaton type. The termination type is a road like any other but tends to be a fixed 6 meter fade out of the general road texture. ====== XRoad ====== XRoad { String Name; //kr_asfaltka_asfaltka_t. ushort Shape; //1 or 3 RGBA color; //FF FF FF FF shortBool CanChangeBankAngle; ulong ObjectID; String Intersections[[4]]; //"asfaltka","silnice","cesta",Type=3 "silnice" else "" } Although CrossRoads could, conceivably, have any number of intersections, only two types are handled. *Type 1: A T_Junction (3 intersections) *Type 3: A Genuine crossroad (4 way intersection) For T_Junctions, there is, obviously, no 4th intersection and this is null filled. Without taking too literal an interpretation, there are some major types of road. *asfaltka:bitumen (sealed) *silnice: Paved *cesta: Dirt Thus the names of each intersection reflect the road type of that intersection, sometimes resulting in (up to) four identical names. The overall name of the crossroad itself, tries to reflect the nature of it's makeup thus kr_asfaltka_asfaltka_t: an bitumen T_Junction kr_silince_x_cesta: a crossroad of paved and dirt roads. ====== Elevation ====== Elevation { XYPair GridSize; // 256 x 256 eg float Heights[[GridSize]]; float BlueEdgeTerrainHeights[[NoOfBlueFloats]] ; //Always zero values // NoOfBlueFloats = (GridSize_Y * GridSize_X)/16; ulong Always0; } ====== Object ====== Object { ShortBool IsPresent; if (IsPresent) { ShortBool Moveable; // always 0 ulong InstanceId; float TransformColumn[[3]][[4]]; // described here to solidly illustrate to reader // this is a standard DirectX Transform matrix // but in COLUMN format; double ObjectRelativeSize; // decimal percentage String InstanceName; // "minimalStrelPos" float RelativeSurfaceElevation; RGBA OutlineColour; RGBA ObjectColour; ulong ObjectTemplateID; }; }; ====== Layer ====== Layer { ulong SizeType; //0..2 //see below String Name; //"Base" shortBool DefaultIndicator; // 0 ... 1 if (DefaultIndicator == 0) { ulong SurfaceTable[[TableSize.x*y]]; ulong TextureTable[[TableSize.x*y]]; byte UnknownTable[[(TableSize.x*y/4)]]; ushort UnknownShort; }; if (DefaultIndicator == 1) { ulong NoOfTerrainMaterials; TerrainMaterial[[NoOfTerrainMaterials]] { ulong BitFlags; // 1 = label, 0x40 = rvmatfile,,,, String MaterialName; // "---sea---","Layers\P_000-000_L00.rvmat" ulong TypeID; // 0..3 }; ulong RvmatTable[[TableSize.x*y]]; }; }; TableSize = Terrain.GridSize>> SizeType; ====== RoadBlock ====== RoadBlock { ShortBool IsPresent; if IsPresent { ShortBool Always1; ulong Unknown[[12]]; /* typical data **00 00 00 00 00 00 00 F0 2C 46 00 98 23 46 C6 6F C6 42 0E 01 00 00 01 00 00 F0 2C 46 00 98 23 46 C6 6F C6 42 0E 01 00 00 4B 00 00 00 00 00 00 00 */ ushort Type; // 0,1,2,3 String RoadFamilyName; //"hlavni silnice" String RoadModelName; //"kr_silnice_cesta_t" RGBA color; ShortBool Always1; ulong Count; FamilyList FamilyLists[[Count]]; ulong Unknown[[27]]; /* typical data **FA D4 30 BF 94 58 08 3D 00 00 C8 C0 00 00 60 C0 **00 00 00 00 00 00 48 C1 00 00 60 40 00 00 00 00 **00 00 48 C1 00 00 60 C0 00 00 00 00 00 00 00 00 **00 00 60 40 00 00 00 00 00 00 00 00 00 00 C8 C0 **00 00 00 00 00 00 30 C0 00 00 C8 C0 00 00 00 00 **00 00 1C C1 04 01 00 00 00 00 00 00 00 00 00 00 **09 00 00 00 0B 80 00 00 04 00 00 00 */ ulong Count; ModelList ModelLists[[Count]]; } } Type *0 Road Ending with FamilyName and it's ModelName_konec *1 TJunction ModelName Only *2 Road similar to type 0 *3 Xroad with ModelName Only ====== FamilyList ====== FamilyList { ulong Unknown[[4]];// Typically 00 00 C8 C0 00 00 C8 C0 00 00 00 00 0E 01 00 00 String Name; // "silnice hlavni silnic\0" } This struct is principally used for Xroads and Tjunctions. It typically lists the order of all RoadFamilyName's required ====== ModelList ====== ModelList { ulong Count; //15 eg BlockModel BlockModel[[Count]]; String FamilyName; //"silnice hlavni silnic\0" ulong Unknown[[4]]; //Typically 00 00 C8 C0 00 00 C8 C0 00 00 00 00 0E 01 00 00 RGBA color[[2]]; ShortBool Always01; //01 ulong buf2[[4]]; // Typically 00 00 00 00 00 00 39 40 00 00 00 00 00 00 24 40 } ====== BlockModel ====== BlockModel { ulong ModelFlag; // 0x000001 ... 0x00010001 XYZTriplet Position; // Model coordinates float ModelDirection; ulong ObjectID; ushort Type; //0,1,2,3 String ModelName; //"silnice10 100\0" ulong unknown[[25]]; /*typical data **00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 **C4 76 C2 3F 0E EB 8A C1 00 00 00 00 BE 00 00 00 **CC ED 26 BE CA 0F 12 40 56 30 28 3F 00 00 00 00 **18 CA 04 C1 48 8B 3D C0 00 00 00 00 2D 3D 91 C1 **06 01 C0 40 00 00 00 00 EE 98 84 C1 99 99 91 C0 **00 00 00 00 64 4A 5F 35 99 99 91 40 00 00 00 00 **64 4A 5F B5 01 00 */ ShortBool ok; // 0 or 1 } ====== NamedZone ====== NamedZone { ShortBool IsPresent; if IsPresent { ShortBool Movable; // Always0; BisString Name1; //"Les_new" ulong AreaColor,OutlineColor; ulong DisplayStyle; ulong nPoints; PointsRectangle { float TopLeft.xy; float BottomRight.xy; }[[nPoints/4]]; /* Typical Data **00 00 61 45 00 78 1B 46 00 20 64 45 00 20 19 46 **00 20 64 45 00 78 1B 46 00 40 67 45 00 58 18 46 **00 40 67 45 00 78 1B 46 00 60 6A 45 00 58 18 46 **00 60 6A 45 00 78 1B 46 00 80 6D 45 00 90 17 46 **00 80 6D 45 00 B0 1A 46 00 A0 70 45 00 C8 16 46 **00 A0 70 45 00 E8 19 46 00 C0 73 45 00 00 16 46 */ ulong ID; // 0,1,2,3,4.... if POSEW60 { LongBool Visible; // always } else { BisString Name2; //Les_new Name2==Name1 } } }; ====== KeyPoint ====== KeyPoint { LongBool Always1; String ClassName; //"Noe_Lany" RGBA AreaColor,OutlineColor; ulong DisplayStyle; ShortBool Visible; float Offset[[2]]; // map relative float Size[[2]]; // 250 x 250.0 eg (widht and height) ulong ID; // 0,1,2,3,4,5,6.... BisString TownName; //"Lipany", "Hill" BisString LocaleType; //"NameCity" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf,Hill,Marine,ViewPoint BisString ClassText; // "canOcclude=1; BumbleButt='FlowControl2"; ++=)#4555Semi" } Each of these locales have a LocaleType. Some of which are: *NameCity *NameCityCapital *NameVillage *VegetationBroadLeaf (Forest) There is always a classname associated with this locale, *Forest_Owls *Abel_LaTrinite and in most cases a text name "La Refuge Des Chassuers" (Type Viewpoints and Marine eg) do not have names associated with them. There is no "place" in the sea. ====== Background ====== Background // this structure has not been seen { String BackgroundFilename;//"sat_lco.bmp" String BackgroundName; //"overlay1" float OffsetXY[[2]]; float SizeXY[[2]]; ulong Transparency; shortBool Visible; // or ulong? } ====== Selection ====== Selection { ushort strlen; char[[]] SelectionName[[strlen]]; // NOT null terminated ulong nSubSelections; SubSelection SubSelections[[nSubSelections]] } ====== SubSelection ====== SubSelection { ulong ObjectId; byte Type; byte Unknown[[7]]; } ====== Enums ====== ====== ObjectClassEnum ====== enum ObjectClassEnum { Natural = 1, Artificial = 2, Road = 3, Forest = 4, ArtificialAndDefinedInRoad = 5 } ====== MarkerTypeEnum ====== enum MarkerTypeEnum { Rectangular = 0, Elliptical = 1 } As of v60 a rarely used sub structure with ObjTemplates.