|
发表于 2006-9-5 03:14:00
|
显示全部楼层
Re:改造hl2_src过程中的小郁闷
你可以参考一下:
http://www.geocities.com/cofrdrbob/bspformat.html
文中对HL2的BSP文件结构有详细的介绍。
另外,你可以下载一份HL2的最新SDK,并研究一下public/gamebspfile.h文件,其中对新版BSP文件的Game Lump有详细的定义。
原文部分摘录:
Game Lump
The Game lump (35) seems to be intended to be used for map data that is specific to a particular game using the Source engine, so that the file format can be extended without altering the previously defined format. It starts with a game lump header:
struct dgamelumpheader_t
{
int lumpCount; // number of game lumps
dgamelump_t gamelump[lumpCount];
};
where the gamelump directory array is defined by:
struct dgamelump_t
{
int id; // gamelump ID
unsigned short flags; // flags
unsigned short version; // gamelump version
int fileofs; // offset to this gamelump
int filelen; // length
};
The gamelump is identified by the 4-byte id member, which defines what data is stored in it, and the byte position of the data (from the start of the file) and its length is given in fileofs and filelen.
Of interest is the gamelump which is used to store prop_static entities, which uses the gamelump ID of 'sprp' ASCII (1936749168 decimal). Unlike most other entities, prop_statics are not stored in the entity lump. The gamelump formats used in HL2 are defined in the public/gamebspfile.h header file.
The first element of the prop_static game lump is the dictionary; this is an integer count followed by the list of model (prop) names used in the map:
struct StaticPropDictLump_t
{
int dictEntries;
char name[dictEntries]; // model name
};
Each name entry is 128 characters long, null-padded to this length.
Following the dictionary is the leaf array:
struct StaticPropLeafLump_t
{
int leafEntries;
unsigned short leaf[leafEntries];
};
Presumably, this array is used to index into the leaf lump to locate the leaves that each prop static is located in. Note that a prop static may span several leaves.
Next, an integer giving the number of StaticPropLump_t entries, followed by that many structures themselves:
struct StaticPropLump_t
{
Vector Origin; // origin
QAngle Angles; // orientation (pitch roll yaw)
unsigned short PropType; // index into model name dictionary
unsigned short FirstLeaf; // index into leaf array
unsigned short LeafCount;
unsigned char Solid; // solidity type
unsigned char Flags;
int Skin; // model skin numbers
float FadeMinDist;
float FadeMaxDist;
Vector LightingOrigin; // for lighting
float ForcedFadeScale; // only present in version 5 gamelump
};
The coordinates of the prop are given by the Origin member; its orientation (pitch, roll, yaw) is given by the Angles entry, which is a 3-float vector. The PropType element is an index into the dictionary of prop model names, given above. The other elements correspond to the location of the prop in the BSP structure of the map, its lighting, and other entity properties as set in Hammer. The last element (ForcedFadeScale) is only present in the prop_static structure if the gamelump is specified as version 5 (dgamelump_t.version above); both version 4 and version 5 static prop gamelumps are used in official HL2 maps.
Other gamelumps used in HL2 BSP files are the detail prop gamelump (ID is 'dprp'), and the detail prop lighting lump (ID: 'dplt'). These are used for the prop_detail entities (grass tufts, etc.) automatically emitted by certain textures when placed on displacement surfaces. In version 20 BSP files there is also another gamelump (ID: 'dplh') which is probably related to HDR lighting of detail props.
There does not seem to be a specified limit on the size of the game lump.
Dispinfo, DispVerts and DispTris Lumps
Displacement surfaces are the most complex parts of a BSP file, and I will cover only part of their format here. Their data is split over a number of different data lumps in the file, but the fundamental reference to them is through the dispinfo lump (26). Dispinfos are referenced from the face, original face, and brushside arrays.
struct ddispinfo_t
{
Vector startPosition; // start position used for orientation
int DispVertStart; // Index into LUMP_DISP_VERTS.
int DispTriStart; // Index into LUMP_DISP_TRIS.
int power; // power - indicates size of surface (2^power + 1)
int minTess; // minimum tesselation allowed
float smoothingAngle; // lighting smoothing angle
int contents; // surface contents
unsigned short MapFace; // Which map face this displacement comes from.
int LightmapAlphaStart; // Index into ddisplightmapalpha.
int LightmapSamplePositionStart; // Index into LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS.
CDispNeighbor EdgeNeighbors[4]; // Indexed by NEIGHBOREDGE_ defines.
CDispCornerNeighbors CornerNeighbors[4]; // Indexed by CORNER_ defines.
unsigned long AllowedVerts[ALLOWEDVERTS_SIZE]; // active verticies
};
The structure is 176 bytes long. The startPosition element is the coordinates of the first corner of the displacement. DispVertStart and DispTriStart are indices into the DispVerts and DispTris lumps. The power entry gives the number of subdivisions in the displacement surface - allowed values are 2, 3 and 4, and these correspond to 4, 8 and 16 subdivisions on each side of the displacement surface. The structure also references any neighbouring displacements on the sides or the corners of this displacement through the EdgeNeighbors and CornerNeighbors members. There are complex rules governing the order that these neighbour displacements are given; see the comments in bspfile.h for more. The MapFace value is an index into the face array and is face that was turned into a displacement surface. This face is used to set the texture and overall physical location and boundaries of the displacement.
The DispVerts lump (33) contains the vertex data of the displacements. It is given by:
struct dDispVert
{
Vector vec; // Vector field defining displacement volume.
float dist; // Displacement distances.
float alpha; // "per vertex" alpha values.
};
where vec is the normalized vector of the offset of each displacement vertex from its original (flat) position; dist is the distance the offset has taken place; and alpha is the alpha-blending of the texture at that vertex.
A displacement of power p references (2^p+1)^2 dispverts in the array, starting from the DispVertStart index.
The DispTris lump (48) contains "triangle tags" or flags related to the properties of a particular triangle in the displacement mesh:
struct dDispTri
{
unsigned short Tags; // Displacement triangle tags.
};
where the flags are:
DISPTRI_TAG_SURFACE 1
DISPTRI_TAG_WALKABLE 2
DISPTRI_TAG_BUILDABLE 4
DISPTRI_FLAG_SURFPROP1 8
DISPTRI_FLAG_SURFPROP2 16
There are 2x(2^p)^2 DispTri entries for a displacement of power p. They are presumably used to indicate properties for each triangle of the displacement such as whether the surface is walkable at that point (not too steep to climb).
There are a limit of 2048 Dispinfos per map, and the limits of DispVerts and DispTris are such that all 2048 displacements could be of power 4 (maximally subdivided).
Other displacement-related data are the DispLightmapAlphas (32) and DispLightmapSamplePos (34) lumps, which seem to relate to lighting of each displacement surface.
|
|