PEW File Format: Difference between revisions
m (→Introduction) |
(→File Format: cleanup) |
||
Line 68: | Line 68: | ||
== File Format == | == File Format == | ||
::*This file format is principally used with Armed Assault v1.09 and later plus the ArmA Tools Suite Final release (v1.14). | ::*This file format is principally used with Armed Assault v1.09 and later plus the ArmA Tools Suite Final release (v1.14). | ||
Line 83: | Line 79: | ||
RoadNets RoadNets[...]; | RoadNets RoadNets[...]; | ||
Terrain Terrain[...]; | Terrain Terrain[...]; | ||
ulong NoOfObjects; | ulong NoOfObjects; | ||
Object Objects[NoOfObjects]; | Object Objects[NoOfObjects]; | ||
Line 99: | Line 94: | ||
UnknownStruct2 UnknownStructs[Count]; | UnknownStruct2 UnknownStructs[Count]; | ||
} | } | ||
ulong nBlocks; | ulong nBlocks; | ||
RoadBlock RoadBlocks[nBlocks]; | |||
if (POSEW60) | if (POSEW60) | ||
{ | { | ||
Line 112: | Line 109: | ||
} | } | ||
ulong Count; | ulong Count; | ||
Locale Locales[Count]; | |||
ulong Always0; | ulong Always0; | ||
ulong Always4; | ulong Always4; | ||
ulong Always0; | ulong Always0; | ||
} | } | ||
===PoseHeader=== | ===PoseHeader=== | ||
Header | Header | ||
{ | { | ||
char | char Signature[7]; "POSEW59" or "POSEW60" note: NOT null terminated | ||
ulong UnknownLong0; | ulong UnknownLong0; | ||
ulong UnknownLong1; // typically 0 | ulong UnknownLong1; // typically 0 | ||
String | String IslandDataPath;//"SomePboPrefix\SomeIsland\data\0" | ||
String UnknownString2;//"" | String UnknownString2;//"" | ||
float GridSize; //50.0 | float GridSize; //50.0 | ||
Line 138: | Line 135: | ||
ObjectType | ObjectType | ||
{ | { | ||
String ModelFilename; //"SomePrefixRoot\data\ | String ModelFilename; //"SomePrefixRoot\data\jablon.p3d\0" | ||
String | String ModelName; //"jablon" | ||
ulong | ulong ObjectType; // 0..5 | ||
RGBAColor OutlineColour; | RGBAColor OutlineColour; | ||
RGBAColor ObjectColour; | RGBAColor ObjectColour; | ||
switch ( | switch (ObjectType) | ||
{ | { | ||
case | case ObjectTypeEnum.Natural // 1 | ||
case | case ObjectTypeEnum.Artificial // 2 | ||
case | case ObjectTypeEnum.ArtificialAndDefinedInRoad // 5 | ||
{ | { | ||
byte[118] | byte[118] VariousInfo; | ||
} | } | ||
case | case ObjectTypeEnum.Road // 3 | ||
{ | { | ||
byte[214] | byte[214] VariousInfo; | ||
} | } | ||
} | } | ||
ulong | ulong nOfArtificialObjects; | ||
ArtificialObject ArtificialObjects[nOfArtificialObjects]; | |||
// ulong | // ulong MarkerType; //See MarkerTypeEnum | ||
LongBool | LongBool LongBool; // 0 or 1 | ||
} | } | ||
</nowiki></code> | </nowiki></code> | ||
Line 172: | Line 169: | ||
ArtificialSubObject | ArtificialSubObject | ||
{ | { | ||
String Name; | String Name; //"pohrada" | ||
LongBool LongBool; | LongBool LongBool; | ||
ulong Always02; | ulong Always02; | ||
Line 196: | Line 193: | ||
{ | { | ||
String FamilyName; // "cesta","silnice",etc | String FamilyName; // "cesta","silnice",etc | ||
RGBA KeyPartsColour; | RGBA KeyPartsColour; | ||
RGBA NormalPartsColour; | RGBA NormalPartsColour; | ||
shortBool FilledLine; // 0 or 1 | shortBool FilledLine; // 0 or 1 | ||
double MaxAngle; // 25.0 degrees | double MaxAngle; // 25.0 degrees | ||
Line 211: | Line 208: | ||
} | } | ||
} | } | ||
=====RoadList===== | =====RoadList===== | ||
Line 281: | Line 277: | ||
float TerrainGridHeights[TerrainGridSize]; | float TerrainGridHeights[TerrainGridSize]; | ||
float BlueEdgeTerrainHeights[NoOfBlueFloats] ; //Always zero values // NoOfBlueFloats = (TerrainGrid_Y * TerrainGrid_X)/16; | float BlueEdgeTerrainHeights[NoOfBlueFloats] ; //Always zero values // NoOfBlueFloats = (TerrainGrid_Y * TerrainGrid_X)/16; | ||
ulong Always0; | |||
} | } | ||
Line 300: | Line 297: | ||
RGBA OutlineColour; | RGBA OutlineColour; | ||
RGBA ObjectColour; | RGBA ObjectColour; | ||
ulong | ulong ObjectID; | ||
}; | }; | ||
}; | }; | ||
Line 321: | Line 318: | ||
TerrainMaterial | TerrainMaterial | ||
{ | { | ||
ulong | ulong BitFlags; // 1 = label, 0x40 = rvmatfile,,,, | ||
String MaterialName; // "---sea---","Layers\P_000-000_L00.rvmat" | String MaterialName; // "---sea---","Layers\P_000-000_L00.rvmat" | ||
ulong TypeID; // 0,1,2 | ulong TypeID; // 0,1,2 | ||
} | } | ||
===Background=== | ===Background=== | ||
Background | Background // this structure has not been seen | ||
{ | { | ||
String BackgroundFilename; | String BackgroundFilename; | ||
Line 338: | Line 335: | ||
ulong Visible; | ulong Visible; | ||
} | } | ||
===RoadBlock=== | ===RoadBlock=== | ||
RoadBlock | RoadBlock | ||
Line 352: | Line 349: | ||
**C6 6F C6 42 0E 01 00 00 4B 00 00 00 00 00 00 00 | **C6 6F C6 42 0E 01 00 00 4B 00 00 00 00 00 00 00 | ||
*/ | */ | ||
ushort Type; | ushort Type; // 0,1,2,3 | ||
String RoadFamilyName; //"hlavni silnice" | String RoadFamilyName; //"hlavni silnice" | ||
String RoadModelName; //"kr_silnice_cesta_t" | String RoadModelName; //"kr_silnice_cesta_t" | ||
RGBA color; | RGBA color; | ||
ShortBool Always1; | ShortBool Always1; | ||
ulong Count; | ulong Count; | ||
FamilyList FamilyLists[Count]; | FamilyList FamilyLists[Count]; | ||
ulong Unknown[27]; | ulong Unknown[27]; | ||
Line 369: | Line 366: | ||
**09 00 00 00 0B 80 00 00 04 00 00 00 | **09 00 00 00 0B 80 00 00 04 00 00 00 | ||
*/ | */ | ||
ulong Count; | ulong Count; | ||
ModelList ModelLists[Count]; | |||
} | } | ||
} | } | ||
Line 388: | Line 385: | ||
This struct is principally used for Xroads and Tjunctions. It typically lists the order of all RoadFamilyName's required | This struct is principally used for Xroads and Tjunctions. It typically lists the order of all RoadFamilyName's required | ||
==== | ====ModelList==== | ||
ModelList | |||
{ | { | ||
ulong | ulong Count; //15 eg | ||
BlockModel BlockModel[Count]; | |||
String | String FamilyName; //"silnice hlavni silnic\0" | ||
ulong | ulong Unknown[4]; //Typically 00 00 C8 C0 00 00 C8 C0 00 00 00 00 0E 01 00 00 | ||
RGBA | RGBA color[2]; | ||
ShortBool Always01; //01 | |||
ShortBool Always01; //01 | ulong buf2[4]; // Typically 00 00 00 00 00 00 39 40 00 00 00 00 00 00 24 40 | ||
ulong | |||
} | } | ||
===== | =====BlockModel===== | ||
BlockModel | |||
{ | { | ||
ulong unknown[6]; | ulong unknown[6]; | ||
Line 411: | Line 407: | ||
*/ | */ | ||
ushort Type; //0,1,2,3 | ushort Type; //0,1,2,3 | ||
String | String ModelName; //"silnice10 100\0" | ||
ulong unknown[25]; | ulong unknown[25]; | ||
/*typical data | /*typical data | ||
Line 459: | Line 455: | ||
Locale | Locale | ||
{ | { | ||
LongBool | LongBool Always1; | ||
String ClassName; | String ClassName; //"Noe_Lany" | ||
RGBA Colour[3]; | RGBA Colour[3]; | ||
ShortBool ShortInd; | ShortBool ShortInd; | ||
float Offset[2];// map relative | float Offset[2]; // map relative | ||
float Size[2]; // 250 x 250.0 eg | float Size[2]; // 250 x 250.0 eg | ||
ulong ID; | ulong ID; // 0,1,2,3,4,5,6.... | ||
BisString TownName; //"Lipany", "Hill" | BisString TownName; //"Lipany", "Hill" | ||
BisString LocaleType; | BisString LocaleType; //"NameCity" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf,Hill,Marine,ViewPoint | ||
BisString NoName; | BisString NoName; // always null | ||
} | } | ||
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. | |||
== Enums == | == Enums == |
Revision as of 03:29, 15 February 2009
Introduction
Pew are Visitor's project files. Visitor is BI's tool for creating Islands.
Visitor is a Gui tool interface that interacts with Bulldozer, an inbuilt 'world' viewer inside any Armed Assault engine.
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
Little endian byte order, lsb first for numeric values, text is stored in Big endian byte order.
Type | Description |
---|---|
byte | 8 bit (1 byte) |
short | 16 bit signed short (2 bytes) |
int | 32 bit signed integer (4 bytes) |
float | 32 bit signed single precision floating point value (4 bytes) |
double | 64 bit signed single precision floating point value (8 bytes) |
asciiz | Null terminated (0x00) variable length ascii string |
ascii | fixed length ascii string(UTF-8) |
XYPair
XYPair { ulong x,y; // normally associated with cell sizes }
RGBAColor
RGBAColor { byte r,g,b,a; // // 0xFF:FF:FF:FF means 'default' }
- RGBA colors correspond to Microsoft's D3DCOLORVALUE
- They normally come in pairs innside the pew structures
String
String { ulong Length; Asciiz Characters;// null terminated regardless.
Length always =strlen(Characters)+1;
This is a pre-calculated convenience to reduce load times (and skip over the variable length block).
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 nObjectTypes; ObjectType ObjectTypes[nObjectTypes]; RoadNets RoadNets[...]; Terrain Terrain[...]; ulong NoOfObjects; Object Objects[NoOfObjects]; ulong NoOfLayers; Layer Layers[[NoOfLayers] ; ulong RoadNetIndices[TerrainGridSizeXY]; if (POSEW60) { ulong NoOfBackgrounds; Background Backgrounds[NoOfBackgrounds] ;// probably } else // pose59 { ulong Count; UnknownStruct2 UnknownStructs[Count]; } ulong nBlocks; RoadBlock RoadBlocks[nBlocks]; if (POSEW60) { ulong Count; UnknownStruct2 UnknownStructs[Count]; } else // pose59 { ulong NoOfBackgrounds; Background Backgrounds[NoOfBackgrounds] ;// probably } ulong Count; Locale Locales[Count]; ulong Always0; ulong Always4; ulong Always0; }
PoseHeader
Header { char Signature[7]; "POSEW59" or "POSEW60" note: NOT null terminated ulong UnknownLong0; ulong UnknownLong1; // typically 0 String IslandDataPath;//"SomePboPrefix\SomeIsland\data\0" String UnknownString2;//"" float GridSize; //50.0 float UnknownFloat3; //400.0 String UnknownString3;//"" ulong UnknownLong2; // typically 0 };
ObjectType
ObjectType
{
String ModelFilename; //"SomePrefixRoot\data\jablon.p3d\0"
String ModelName; //"jablon"
ulong ObjectType; // 0..5
RGBAColor OutlineColour;
RGBAColor ObjectColour;
switch (ObjectType)
{
case ObjectTypeEnum.Natural // 1
case ObjectTypeEnum.Artificial // 2
case ObjectTypeEnum.ArtificialAndDefinedInRoad // 5
{
byte[118] VariousInfo;
}
case ObjectTypeEnum.Road // 3
{
byte[214] VariousInfo;
}
}
ulong nOfArtificialObjects;
ArtificialObject ArtificialObjects[nOfArtificialObjects];
// ulong MarkerType; //See MarkerTypeEnum
LongBool LongBool; // 0 or 1
}
- NB: While the 'VariousInfo' byte array is decernable at this time it essentially defines various floats, integers, transforms etc. that denote the 'default' and/or 'seed' values for a given ObjectType.
// ObjectTypeID is also present at offset 16 in the VariousInfo's
ArtificialSubObject
ArtificialSubObject { String Name; //"pohrada" LongBool LongBool; ulong Always02; XYZTriplet StartEndPos[2]; }
RoadNet
RoadNet { shortBool Always1; shortBool Always1; 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 Type //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.
Terrain
Terrain { XYPair TerrainGridSize; // 256 x 256 eg float TerrainGridHeights[TerrainGridSize]; float BlueEdgeTerrainHeights[NoOfBlueFloats] ; //Always zero values // NoOfBlueFloats = (TerrainGrid_Y * TerrainGrid_X)/16; ulong Always0; }
Object
Object
{
ShortBool IsPresent;
if (IsPresent)
{
ShortBool Always0;
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 ObjectID;
};
};
Layer
Layer { String Name1; //"Base" ulong SizeType; //0 String Name2; //"Base" ushort DefaultIndicator; // 1 ulong NoOfTerrainMaterials; TerrainMaterial TerrainMaterials[NoOfTerrainMaterials]; } }
TerrainMaterial
TerrainMaterial { ulong BitFlags; // 1 = label, 0x40 = rvmatfile,,,, String MaterialName; // "---sea---","Layers\P_000-000_L00.rvmat" ulong TypeID; // 0,1,2 }
Background
Background // this structure has not been seen { String BackgroundFilename; String BackgroundName; float OffsetX; float OffsetY; float SizeX; float SizeY; ulong Transparency; ulong Visible; }
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 unknown[6]; /* typical data **01 00 01 00 00 86 2D 46 **00 98 23 46 65 6C C5 42 **0E 01 00 00 4D 00 00 00 */ 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 }
UnknownStruct2
UnknownStruct2 { ShortBool IsPresent; if IsPresent { ShortBool Always0; BisString Name1; //"Les_new" ulong Colour[3]; ulong nFloats; float Floats[nFloats]; /* 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 Always1; } else { BisString Name2; //Les_new Name2==Name1 } } };
Locale
Locale { LongBool Always1; String ClassName; //"Noe_Lany" RGBA Colour[3]; ShortBool ShortInd; float Offset[2]; // map relative float Size[2]; // 250 x 250.0 eg ulong ID; // 0,1,2,3,4,5,6.... BisString TownName; //"Lipany", "Hill" BisString LocaleType; //"NameCity" NameCityCapital, NameVillage, NameLocal, VegetationBroadLeaf,Hill,Marine,ViewPoint BisString NoName; // always null }
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.
Enums
ObjectClassEnum
enum ObjectClassEnum
{
Natural = 1,
Artificial = 2,
ArtificialAndDefinedInRoad = 5,
Road = 3
}
MarkerTypeEnum
enum MarkerTypeEnum
{
Rectangular = 0,
Elliptical = 1
}