|
|
//========= Copyright (c) 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose: Defines and structures for the BSP file format.
//
// $NoKeywords: $
//=============================================================================//
#ifndef BSPFILE_H
#define BSPFILE_H
#pragma once
#ifndef MATHLIB_H
#include "mathlib/mathlib.h"
#endif
#include "mathlib/vector4d.h"
#include "datamap.h"
#include "mathlib/bumpvects.h"
#include "mathlib/compressed_light_cube.h"
#include "datalinker_interface.h"
// little-endian "VBSP"
#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'V')
// MINBSPVERSION is the minimum acceptable version. The engine will load MINBSPVERSION through BSPVERSION
#define MINBSPVERSION 19
#define BSPVERSION 21
// This is one more than what vbsp cuts for to allow for rounding errors
#define MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER 35
// Need to dynamically allocate the weights and light values in radial_t to make this variable.
#define MAX_BRUSH_LIGHTMAP_DIM_WITHOUT_BORDER ( MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER - 3 )
// We can have larger lightmaps on displacements
#define MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER 128
#define MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER ( MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER - 3 )
// This is the actual max.. (change if you change the brush lightmap dim or disp lightmap dim
#define MAX_LIGHTMAP_DIM_WITHOUT_BORDER MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER
#define MAX_LIGHTMAP_DIM_INCLUDING_BORDER MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER
#define MAX_LIGHTSTYLES 64
// upper design bounds
#define MIN_MAP_DISP_POWER 2 // Minimum and maximum power a displacement can be.
#define MAX_MAP_DISP_POWER 4
// Max # of neighboring displacement touching a displacement's corner.
#define MAX_DISP_CORNER_NEIGHBORS 4
#define NUM_DISP_POWER_VERTS(power) ( ((1 << (power)) + 1) * ((1 << (power)) + 1) )
#define NUM_DISP_POWER_TRIS(power) ( (1 << (power)) * (1 << (power)) * 2 )
#if !defined( BSP_USE_LESS_MEMORY )
// Common limits
// leaffaces, leafbrushes, planes, and verts are still bounded by
// 16 bit short limits
#define MAX_MAP_MODELS 1024
#define MAX_MAP_BRUSHES 8192
#define MAX_MAP_ENTITIES 20480 // bumped from 16384
#define MAX_MAP_TEXINFO 12288
#define MAX_MAP_TEXDATA 2048
#define MAX_MAP_DISPINFO 32768
#define MAX_MAP_DISP_VERTS ( MAX_MAP_DISPINFO * ((1<<MAX_MAP_DISP_POWER)+1) * ((1<<MAX_MAP_DISP_POWER)+1) )
#define MAX_MAP_DISP_TRIS ( (1 << MAX_MAP_DISP_POWER) * (1 << MAX_MAP_DISP_POWER) * 2 )
#define MAX_DISPVERTS NUM_DISP_POWER_VERTS( MAX_MAP_DISP_POWER )
#define MAX_DISPTRIS NUM_DISP_POWER_TRIS( MAX_MAP_DISP_POWER )
#define MAX_MAP_AREAS 1024
#define MAX_MAP_AREA_BYTES (MAX_MAP_AREAS/8)
#define MAX_MAP_AREAPORTALS 1024
// Planes come in pairs, thus an even number.
#define MAX_MAP_PLANES 65536
#define MAX_MAP_NODES 65536
#define MAX_MAP_BRUSHSIDES 65536
#define MAX_MAP_LEAFS 65536
#define MAX_MAP_VERTS 65536
#define MAX_MAP_VERTNORMALS 256000
#define MAX_MAP_VERTNORMALINDICES 256000
#define MAX_MAP_FACES 65536
#define MAX_MAP_LEAFFACES 65536
#define MAX_MAP_LEAFBRUSHES 65536
#define MAX_MAP_PORTALS 65536
#define MAX_MAP_CLUSTERS 65536
#define MAX_MAP_LEAFWATERDATA 32768
#define MAX_MAP_PORTALVERTS 128000
#define MAX_MAP_EDGES 256000
#define MAX_MAP_SURFEDGES 512000
#define MAX_MAP_LIGHTING 0x1000000
#define MAX_MAP_VISIBILITY 0x1000000 // increased BSPVERSION 7
#define MAX_MAP_TEXTURES 1024
#define MAX_MAP_WORLDLIGHTS 8192
#define MAX_MAP_CUBEMAPSAMPLES 1024
#define MAX_MAP_OVERLAYS 1024
#define MAX_MAP_WATEROVERLAYS 16384
#define MAX_MAP_TEXDATA_STRING_DATA 256000
#define MAX_MAP_TEXDATA_STRING_TABLE 65536
// this is stuff for trilist/tristrips, etc.
#define MAX_MAP_PRIMITIVES 32768
#define MAX_MAP_PRIMVERTS 65536
#define MAX_MAP_PRIMINDICES 65536
#else
// Xbox 360 - Force static arrays to be very small
#define MAX_MAP_MODELS 2
#define MAX_MAP_BRUSHES 2
#define MAX_MAP_ENTITIES 2
#define MAX_MAP_TEXINFO 2
#define MAX_MAP_TEXDATA 2
#define MAX_MAP_DISPINFO 2
#define MAX_MAP_DISP_VERTS ( MAX_MAP_DISPINFO * ((1<<MAX_MAP_DISP_POWER)+1) * ((1<<MAX_MAP_DISP_POWER)+1) )
#define MAX_MAP_DISP_TRIS ( (1 << MAX_MAP_DISP_POWER) * (1 << MAX_MAP_DISP_POWER) * 2 )
#define MAX_DISPVERTS NUM_DISP_POWER_VERTS( MAX_MAP_DISP_POWER )
#define MAX_DISPTRIS NUM_DISP_POWER_TRIS( MAX_MAP_DISP_POWER )
#define MAX_MAP_AREAS 2
#define MAX_MAP_AREA_BYTES 2
#define MAX_MAP_AREAPORTALS 2
#define MAX_MAP_PLANES 2
#define MAX_MAP_NODES 2
#define MAX_MAP_BRUSHSIDES 2
#define MAX_MAP_LEAFS 2
#define MAX_MAP_VERTS 2
#define MAX_MAP_VERTNORMALS 2
#define MAX_MAP_VERTNORMALINDICES 2
#define MAX_MAP_FACES 2
#define MAX_MAP_LEAFFACES 2
#define MAX_MAP_LEAFBRUSHES 2
#define MAX_MAP_PORTALS 2
#define MAX_MAP_CLUSTERS 2
#define MAX_MAP_LEAFWATERDATA 2
#define MAX_MAP_PORTALVERTS 2
#define MAX_MAP_EDGES 2
#define MAX_MAP_SURFEDGES 2
#define MAX_MAP_LIGHTING 2
#define MAX_MAP_VISIBILITY 2
#define MAX_MAP_TEXTURES 2
#define MAX_MAP_WORLDLIGHTS 2
#define MAX_MAP_CUBEMAPSAMPLES 2
#define MAX_MAP_OVERLAYS 2
#define MAX_MAP_WATEROVERLAYS 2
#define MAX_MAP_TEXDATA_STRING_DATA 2
#define MAX_MAP_TEXDATA_STRING_TABLE 2
#define MAX_MAP_PRIMITIVES 2
#define MAX_MAP_PRIMVERTS 2
#define MAX_MAP_PRIMINDICES 2
#endif // BSP_USE_LESS_MEMORY
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
// ------------------------------------------------------------------------------------------------ //
// Displacement neighbor rules
// ------------------------------------------------------------------------------------------------ //
//
// Each displacement is considered to be in its own space:
//
// NEIGHBOREDGE_TOP
//
// 1 --- 2
// | |
// NEIGHBOREDGE_LEFT | | NEIGHBOREDGE_RIGHT
// | |
// 0 --- 3
//
// NEIGHBOREDGE_BOTTOM
//
//
// Edge edge of a displacement can have up to two neighbors. If it only has one neighbor
// and the neighbor fills the edge, then SubNeighbor 0 uses CORNER_TO_CORNER (and SubNeighbor 1
// is undefined).
//
// CORNER_TO_MIDPOINT means that it spans [bottom edge,midpoint] or [left edge,midpoint] depending
// on which edge you're on.
//
// MIDPOINT_TO_CORNER means that it spans [midpoint,top edge] or [midpoint,right edge] depending
// on which edge you're on.
//
// Here's an illustration (where C2M=CORNER_TO_MIDPOINT and M2C=MIDPOINT_TO_CORNER
//
//
// C2M M2C
//
// 1 --------------> x --------------> 2
//
// ^ ^
// | |
// | |
// M2C | | M2C
// | |
// | |
//
// x x x
//
// ^ ^
// | |
// | |
// C2M | | C2M
// | |
// | |
//
// 0 --------------> x --------------> 3
//
// C2M M2C
//
//
// The CHILDNODE_ defines can be used to refer to a node's child nodes (this is for when you're
// recursing into the node tree inside a displacement):
//
// ---------
// | | |
// | 1 | 0 |
// | | |
// |---x---|
// | | |
// | 2 | 3 |
// | | |
// ---------
//
// ------------------------------------------------------------------------------------------------ //
// These can be used to index g_ChildNodeIndexMul.
enum { CHILDNODE_UPPER_RIGHT=0, CHILDNODE_UPPER_LEFT=1, CHILDNODE_LOWER_LEFT=2, CHILDNODE_LOWER_RIGHT=3 };
// Corner indices. Used to index m_CornerNeighbors.
enum { CORNER_LOWER_LEFT=0, CORNER_UPPER_LEFT=1, CORNER_UPPER_RIGHT=2, CORNER_LOWER_RIGHT=3 };
// These edge indices must match the edge indices of the CCoreDispSurface.
enum { NEIGHBOREDGE_LEFT=0, NEIGHBOREDGE_TOP=1, NEIGHBOREDGE_RIGHT=2, NEIGHBOREDGE_BOTTOM=3 };
// These denote where one dispinfo fits on another.
// Note: tables are generated based on these indices so make sure to update
// them if these indices are changed.
typedef enum { CORNER_TO_CORNER=0, CORNER_TO_MIDPOINT=1, MIDPOINT_TO_CORNER=2 } NeighborSpan;
// These define relative orientations of displacement neighbors.
typedef enum { ORIENTATION_CCW_0=0, ORIENTATION_CCW_90=1, ORIENTATION_CCW_180=2, ORIENTATION_CCW_270=3 } NeighborOrientation;
//=============================================================================
enum { LUMP_ENTITIES = 0, // *
LUMP_PLANES = 1, // *
LUMP_TEXDATA = 2, // *
LUMP_VERTEXES = 3, // *
LUMP_VISIBILITY = 4, // *
LUMP_NODES = 5, // *
LUMP_TEXINFO = 6, // *
LUMP_FACES = 7, // *
LUMP_LIGHTING = 8, // *
LUMP_OCCLUSION = 9, LUMP_LEAFS = 10, // *
LUMP_FACEIDS = 11, LUMP_EDGES = 12, // *
LUMP_SURFEDGES = 13, // *
LUMP_MODELS = 14, // *
LUMP_WORLDLIGHTS = 15, //
LUMP_LEAFFACES = 16, // *
LUMP_LEAFBRUSHES = 17, // *
LUMP_BRUSHES = 18, // *
LUMP_BRUSHSIDES = 19, // *
LUMP_AREAS = 20, // *
LUMP_AREAPORTALS = 21, // *
LUMP_FACEBRUSHES = 22, // * Index of the brush each face came from
LUMP_FACEBRUSHLIST = 23, // *
LUMP_UNUSED1 = 24, // *
LUMP_UNUSED2 = 25, // *
LUMP_DISPINFO = 26, LUMP_ORIGINALFACES = 27, LUMP_PHYSDISP = 28, LUMP_PHYSCOLLIDE = 29, LUMP_VERTNORMALS = 30, LUMP_VERTNORMALINDICES = 31, LUMP_DISP_LIGHTMAP_ALPHAS = 32, LUMP_DISP_VERTS = 33, // CDispVerts
LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS = 34, // For each displacement
// For each lightmap sample
// byte for index
// if 255, then index = next byte + 255
// 3 bytes for barycentric coordinates
// The game lump is a method of adding game-specific lumps
// FIXME: Eventually, all lumps could use the game lump system
LUMP_GAME_LUMP = 35, LUMP_LEAFWATERDATA = 36, LUMP_PRIMITIVES = 37, LUMP_PRIMVERTS = 38, LUMP_PRIMINDICES = 39, // A pak file can be embedded in a .bsp now, and the file system will search the pak
// file first for any referenced names, before deferring to the game directory
// file system/pak files and finally the base directory file system/pak files.
LUMP_PAKFILE = 40, LUMP_CLIPPORTALVERTS = 41, // A map can have a number of cubemap entities in it which cause cubemap renders
// to be taken after running vrad.
LUMP_CUBEMAPS = 42, LUMP_TEXDATA_STRING_DATA = 43, LUMP_TEXDATA_STRING_TABLE = 44, LUMP_OVERLAYS = 45, LUMP_LEAFMINDISTTOWATER = 46, LUMP_FACE_MACRO_TEXTURE_INFO = 47, LUMP_DISP_TRIS = 48, LUMP_PROP_BLOB = 49, // static prop triangle & string data
LUMP_WATEROVERLAYS = 50, LUMP_LEAF_AMBIENT_INDEX_HDR = 51, // index of LUMP_LEAF_AMBIENT_LIGHTING_HDR
LUMP_LEAF_AMBIENT_INDEX = 52, // index of LUMP_LEAF_AMBIENT_LIGHTING
// optional lumps for HDR
LUMP_LIGHTING_HDR = 53, LUMP_WORLDLIGHTS_HDR = 54, LUMP_LEAF_AMBIENT_LIGHTING_HDR = 55, // NOTE: this data overrides part of the data stored in LUMP_LEAFS.
LUMP_LEAF_AMBIENT_LIGHTING = 56, // NOTE: this data overrides part of the data stored in LUMP_LEAFS.
LUMP_XZIPPAKFILE = 57, // deprecated. xbox 1: xzip version of pak file
LUMP_FACES_HDR = 58, // HDR maps may have different face data.
LUMP_MAP_FLAGS = 59, // extended level-wide flags. not present in all levels
LUMP_OVERLAY_FADES = 60, // Fade distances for overlays
LUMP_OVERLAY_SYSTEM_LEVELS = 61, // System level settings (min/max CPU & GPU to render this overlay)
LUMP_PHYSLEVEL = 62, LUMP_DISP_MULTIBLEND = 63, // Displacement multiblend info
};
// Lumps that have versions are listed here
enum { LUMP_LIGHTING_VERSION = 1, LUMP_FACES_VERSION = 1, LUMP_OCCLUSION_VERSION = 2, LUMP_LEAFS_VERSION = 1, LUMP_LEAF_AMBIENT_LIGHTING_VERSION = 1, LUMP_WORLDLIGHTS_VERSION = 1 };
#define HEADER_LUMPS 64
#include "zip_uncompressed.h"
struct lump_t { DECLARE_BYTESWAP_DATADESC(); int fileofs, filelen; int version; // default to zero
char fourCC[4]; // default to ( char )0, ( char )0, ( char )0, ( char )0
};
struct BSPHeader_t { DECLARE_BYTESWAP_DATADESC(); int ident; int m_nVersion; lump_t lumps[HEADER_LUMPS]; int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6)
};
// level feature flags
#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_NONHDR 0x00000001 // was processed by vrad with -staticproplighting, no hdr data
#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_HDR 0x00000002 // was processed by vrad with -staticproplighting, in hdr
#define LVLFLAGS_LIGHTMAP_ALPHA 0x00000004 // indicates that lightmap alpha data is interleved in the lighting lump
#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_3 0x00000008 // was processed by vrad with -staticproplighting3
#define LVLFLAGS_LIGHTMAP_ALPHA_3 0x00000010 // indicates that 3 sets of lightmap alpha data are interleved in the lighting lump
#define LVLFLAGS_BAKED_STATIC_PROP_LIGHTING_3_NO_SUN 0x00000020// indicates that vertexlitgeneric static prop lighting does not contain direct sunlight in lighting vertex stream
#define LVLFLAGS_LIGHTSTYLES_WITH_CSM 0x00000040 // indicates that lightstyles now compatible with CSMs
struct dflagslump_t { DECLARE_BYTESWAP_DATADESC(); uint32 m_LevelFlags; // LVLFLAGS_xxx
};
struct lumpfileheader_t { int lumpOffset; int lumpID; int lumpVersion; int lumpLength; int mapRevision; // the map's revision (iteration, version) number (added BSPVERSION 6)
};
struct dgamelumpheader_t { DECLARE_BYTESWAP_DATADESC(); int lumpCount;
// dgamelump_t follow this
};
// This is expected to be a four-CC code ('lump')
typedef int GameLumpId_t;
// 360 only: game lump is compressed, filelen reflects original size
// use next entry fileofs to determine actual disk lump compressed size
// compression stage ensures a terminal null dictionary entry
#define GAMELUMPFLAG_COMPRESSED 0x0001
struct dgamelump_t { DECLARE_BYTESWAP_DATADESC(); GameLumpId_t id; unsigned short flags; unsigned short version; int fileofs; int filelen; };
extern int g_MapRevision;
struct dmodel_t { DECLARE_BYTESWAP_DATADESC(); Vector mins, maxs; Vector origin; // for sounds or lights
int headnode; int firstface, numfaces; // submodels just draw faces without walking the bsp tree
};
struct dphysmodel_t { DECLARE_BYTESWAP_DATADESC() int modelIndex; int dataSize; int keydataSize; int solidCount; };
struct dphyslevelpolytope_t { DECLARE_BYTESWAP_DATADESC() };
struct DiskPhysics2Polytope_t { DECLARE_BYTESWAP_DATADESC(); int32 offsetPolytope; // this is the offset to the serialized data of this polytope
int32 offsetInertia; };
struct DiskPhysics2LevelMesh_t { DECLARE_BYTESWAP_DATADESC(); DataLinker::Offset_t<void> polymesh; // this is polysoup in data version 0xC0000002, and polytope in 0xC0000001
int32 flags;
enum { FLAG_RESERVED = 1, FLAG_FORCE_POLYSOUP = 1 << 1, FLAG_FORCE_POLYTOPE = 1 << 2 }; };
struct dphyslevelV0_t { DECLARE_BYTESWAP_DATADESC() enum {DATA_VERSION_WITH_DISPLACEMENT = 0xC0000001}; enum {DATA_VERSION = 0xC0000002}; int32 toolVersion; // increment this for backward-compatible data changes (changes that the old code can read without problems)
int32 dataVersion; // change this for backward-incompatible changes
int32 sizeofDiskPhysics2LevelMesh; int32 buildTime; DataLinker::OffsetAndSize_t<DiskPhysics2LevelMesh_t> levelMeshes; DataLinker::Offset_t<void> polysoup; DataLinker::Offset_t<void> mopp; DataLinker::Offset_t<void> displacementMesh; DataLinker::Offset_t<void> staticProps; // serialized polysoup
DataLinker::OffsetAndSize_t<DiskPhysics2LevelMesh_t> levelWaterMeshes; DataLinker::OffsetAndSize_t< DiskPhysics2LevelMesh_t > levelCModels; // the entities that belong to bsp, implementing features from old physics
DataLinker::OffsetAndSize_t< DataLinker::Offset_t<char> > levelStaticModels; int32 nReserved2[8]; };
// contains the binary blob for each displacement surface's virtual hull
struct dphysdisp_t { DECLARE_BYTESWAP_DATADESC() unsigned short numDisplacements; //unsigned short dataSize[numDisplacements];
};
struct dprophull_t { DECLARE_BYTESWAP_DATADESC(); int m_nVertCount; int m_nVertStart; int m_nSurfaceProp; unsigned int m_nContents; };
struct dprophulltris_t { DECLARE_BYTESWAP_DATADESC(); int m_nIndexStart; int m_nIndexCount; };
struct dpropcollision_t { DECLARE_BYTESWAP_DATADESC(); int m_nHullCount; int m_nHullStart; };
struct dvertex_t { DECLARE_BYTESWAP_DATADESC(); Vector point; };
// planes (x&~1) and (x&~1)+1 are always opposites
struct dplane_t { DECLARE_BYTESWAP_DATADESC(); Vector normal; float dist; int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
};
#ifndef BSPFLAGS_H
#include "bspflags.h"
#endif
struct dnode_t { DECLARE_BYTESWAP_DATADESC(); int planenum; int children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for frustom culling
short maxs[3]; unsigned short firstface; unsigned short numfaces; // counting both sides
short area; // If all leaves below this node are in the same area, then
// this is the area index. If not, this is -1.
};
typedef struct texinfo_s { DECLARE_BYTESWAP_DATADESC(); float textureVecsTexelsPerWorldUnits[2][4]; // [s/t][xyz offset]
float lightmapVecsLuxelsPerWorldUnits[2][4]; // [s/t][xyz offset] - length is in units of texels/area
int flags; // miptex flags + overrides
int texdata; // Pointer to texture name, size, etc.
} texinfo_t;
#define TEXTURE_NAME_LENGTH 128 // changed from 64 BSPVERSION 8
struct dtexdata_t { DECLARE_BYTESWAP_DATADESC(); Vector reflectivity; int nameStringTableID; // index into g_StringTable for the texture name
int width, height; // source image
int view_width, view_height; //
};
//-----------------------------------------------------------------------------
// Occluders are simply polygons
//-----------------------------------------------------------------------------
// Flags field of doccluderdata_t
enum { OCCLUDER_FLAGS_INACTIVE = 0x1, };
struct doccluderdata_t { DECLARE_BYTESWAP_DATADESC(); int flags; int firstpoly; // index into doccluderpolys
int polycount; Vector mins; Vector maxs; int area; };
struct doccluderdataV1_t { int flags; int firstpoly; // index into doccluderpolys
int polycount; Vector mins; Vector maxs; };
struct doccluderpolydata_t { DECLARE_BYTESWAP_DATADESC(); int firstvertexindex; // index into doccludervertindices
int vertexcount; int planenum; };
// NOTE: see the section above titled "displacement neighbor rules".
struct CDispSubNeighbor { public: DECLARE_BYTESWAP_DATADESC(); unsigned short GetNeighborIndex() const { return m_iNeighbor; } NeighborSpan GetSpan() const { return (NeighborSpan)m_Span; } NeighborSpan GetNeighborSpan() const { return (NeighborSpan)m_NeighborSpan; } NeighborOrientation GetNeighborOrientation() const { return (NeighborOrientation)m_NeighborOrientation; }
bool IsValid() const { return m_iNeighbor != 0xFFFF; } void SetInvalid() { m_iNeighbor = 0xFFFF; }
public: unsigned short m_iNeighbor; // This indexes into ddispinfos.
// 0xFFFF if there is no neighbor here.
unsigned char m_NeighborOrientation; // (CCW) rotation of the neighbor wrt this displacement.
// These use the NeighborSpan type.
unsigned char m_Span; // Where the neighbor fits onto this side of our displacement.
unsigned char m_NeighborSpan; // Where we fit onto our neighbor.
};
// NOTE: see the section above titled "displacement neighbor rules".
class CDispNeighbor { public: DECLARE_BYTESWAP_DATADESC(); void SetInvalid() { m_SubNeighbors[0].SetInvalid(); m_SubNeighbors[1].SetInvalid(); } // Returns false if there isn't anything touching this edge.
bool IsValid() { return m_SubNeighbors[0].IsValid() || m_SubNeighbors[1].IsValid(); }
public: // Note: if there is a neighbor that fills the whole side (CORNER_TO_CORNER),
// then it will always be in CDispNeighbor::m_Neighbors[0]
CDispSubNeighbor m_SubNeighbors[2]; };
class CDispCornerNeighbors { public: DECLARE_BYTESWAP_DATADESC(); void SetInvalid() { m_nNeighbors = 0; }
public: unsigned short m_Neighbors[MAX_DISP_CORNER_NEIGHBORS]; // indices of neighbors.
unsigned char m_nNeighbors; };
class CDispVert { public: DECLARE_BYTESWAP_DATADESC(); Vector m_vVector; // Vector field defining displacement volume.
float m_flDist; // Displacement distances.
float m_flAlpha; // "per vertex" alpha values.
};
#define DISPTRI_TAG_SURFACE (1<<0)
#define DISPTRI_TAG_WALKABLE (1<<1)
#define DISPTRI_TAG_BUILDABLE (1<<2)
#define DISPTRI_FLAG_SURFPROP1 (1<<3)
#define DISPTRI_FLAG_SURFPROP2 (1<<4)
#define DISPTRI_FLAG_SURFPROP3 (1<<5)
#define DISPTRI_FLAG_SURFPROP4 (1<<6)
class CDispTri { public: DECLARE_BYTESWAP_DATADESC(); unsigned short m_uiTags; // Displacement triangle tags.
};
#define MAX_MULTIBLEND_CHANNELS 4
class CDispMultiBlend { public: DECLARE_BYTESWAP_DATADESC();
Vector4D m_vMultiBlend; Vector4D m_vAlphaBlend; Vector m_vMultiBlendColors[ MAX_MULTIBLEND_CHANNELS ]; };
#define DISP_MULTIBLEND_PROP_THRESHOLD 2.0f
#define DISP_INFO_FLAG_HAS_MULTIBLEND 0x40000000
#define DISP_INFO_FLAG_MAGIC 0x80000000
class ddispinfo_t { public: DECLARE_BYTESWAP_DATADESC(); int NumVerts() const { return NUM_DISP_POWER_VERTS(power); } int NumTris() const { return NUM_DISP_POWER_TRIS(power); }
public: Vector startPosition; // start position used for orientation -- (added BSPVERSION 6)
int m_iDispVertStart; // Index into LUMP_DISP_VERTS.
int m_iDispTriStart; // Index into LUMP_DISP_TRIS.
int power; // power - indicates size of map (2^power + 1)
int minTess; // minimum tesselation allowed
float smoothingAngle; // lighting smoothing angle
int contents; // surface contents
unsigned short m_iMapFace; // Which map face this displacement comes from.
int m_iLightmapAlphaStart; // Index into ddisplightmapalpha.
// The count is m_pParent->lightmapTextureSizeInLuxels[0]*m_pParent->lightmapTextureSizeInLuxels[1].
int m_iLightmapSamplePositionStart; // Index into LUMP_DISP_LIGHTMAP_SAMPLE_POSITIONS.
CDispNeighbor m_EdgeNeighbors[4]; // Indexed by NEIGHBOREDGE_ defines.
CDispCornerNeighbors m_CornerNeighbors[4]; // Indexed by CORNER_ defines.
enum unnamed { ALLOWEDVERTS_SIZE = PAD_NUMBER( MAX_DISPVERTS, 32 ) / 32 }; unsigned int m_AllowedVerts[ALLOWEDVERTS_SIZE]; // This is built based on the layout and sizes of our neighbors
// and tells us which vertices are allowed to be active.
};
// note that edge 0 is never used, because negative edge nums are used for
// counterclockwise use of the edge in a face
struct dedge_t { DECLARE_BYTESWAP_DATADESC(); unsigned short v[2]; // vertex numbers
};
#define MAXLIGHTMAPS 4
enum dprimitive_type { PRIM_TRILIST=0, PRIM_TRISTRIP=1, };
struct dprimitive_t { DECLARE_BYTESWAP_DATADESC(); unsigned char type; unsigned short firstIndex; unsigned short indexCount; unsigned short firstVert; unsigned short vertCount; };
struct dprimvert_t { DECLARE_BYTESWAP_DATADESC(); Vector pos; };
struct dface_t { DECLARE_BYTESWAP_DATADESC(); unsigned short planenum; byte side; // faces opposite to the node's plane direction
byte onNode; // 1 of on node, 0 if in leaf
int firstedge; // we must support > 64k edges
short numedges; short texinfo; // This is a union under the assumption that a fog volume boundary (ie. water surface)
// isn't a displacement map.
// FIXME: These should be made a union with a flags or type field for which one it is
// if we can add more to this.
// union
// {
short dispinfo; // This is only for surfaces that are the boundaries of fog volumes
// (ie. water surfaces)
// All of the rest of the surfaces can look at their leaf to find out
// what fog volume they are in.
short surfaceFogVolumeID; // };
// lighting info
byte styles[MAXLIGHTMAPS]; int lightofs; // start of [numstyles*surfsize] samples
float area;
// TODO: make these unsigned chars?
int m_LightmapTextureMinsInLuxels[2]; int m_LightmapTextureSizeInLuxels[2];
int origFace; // reference the original face this face was derived from
public:
unsigned short GetNumPrims() const; void SetNumPrims( unsigned short nPrims ); bool AreDynamicShadowsEnabled(); void SetDynamicShadowsEnabled( bool bEnabled );
// non-polygon primitives (strips and lists)
private: unsigned short m_NumPrims; // Top bit, if set, disables shadows on this surface (this is why there are accessors).
public: unsigned short firstPrimID; unsigned int smoothingGroups; };
inline unsigned short dface_t::GetNumPrims() const { return m_NumPrims & 0x7FFF; }
inline void dface_t::SetNumPrims( unsigned short nPrims ) { Assert( (nPrims & 0x8000) == 0 ); m_NumPrims &= ~0x7FFF; m_NumPrims |= (nPrims & 0x7FFF); }
inline bool dface_t::AreDynamicShadowsEnabled() { return (m_NumPrims & 0x8000) == 0; }
inline void dface_t::SetDynamicShadowsEnabled( bool bEnabled ) { if ( bEnabled ) m_NumPrims &= ~0x8000; else m_NumPrims |= 0x8000; }
struct dfaceid_t { DECLARE_BYTESWAP_DATADESC(); unsigned short hammerfaceid; };
struct dfacebrushlist_t { DECLARE_BYTESWAP_DATADESC(); unsigned short m_nFaceBrushCount; // number of brushes that contributed a side to this face
unsigned short m_nFaceBrushStart; // first brush. NOTE: if m_nFaceBrushCount is 1, this is a brush index!
};
// NOTE: Only 7-bits stored on disk!!!
#define LEAF_FLAGS_SKY 0x01 // This leaf has 3D sky in its PVS
#define LEAF_FLAGS_RADIAL 0x02 // This leaf culled away some portals due to radial vis
#define LEAF_FLAGS_SKY2D 0x04 // This leaf has 2D sky in its PVS
#define LEAF_FLAGS_CONTAINS_DETAILOBJECTS 0x08 // this leaf has at least one detail object in it (set by loader).
#if defined( _X360 )
#pragma bitfield_order( push, lsb_to_msb )
#elif defined( _PS3 )
#pragma ms_struct on
#pragma reverse_bitfields on
#endif
#pragma warning( disable:4201 ) // C4201: nonstandard extension used: nameless struct/union
struct dleaf_version_0_t { DECLARE_BYTESWAP_DATADESC(); int contents; // OR of all brushes (not needed?)
short cluster;
BEGIN_BITFIELD( bf ); short area:9; short flags:7; // Per leaf flags.
END_BITFIELD();
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstleafface; unsigned short numleaffaces;
unsigned short firstleafbrush; unsigned short numleafbrushes; short leafWaterDataID; // -1 for not in water
// Precaculated light info for entities.
CompressedLightCube m_AmbientLighting; };
// version 1
struct dleaf_t { DECLARE_BYTESWAP_DATADESC(); int contents; // OR of all brushes (not needed?)
short cluster;
BEGIN_BITFIELD( bf ); short area:9; short flags:7; // Per leaf flags.
END_BITFIELD();
short mins[3]; // for frustum culling
short maxs[3];
unsigned short firstleafface; unsigned short numleaffaces;
unsigned short firstleafbrush; unsigned short numleafbrushes; short leafWaterDataID; // -1 for not in water
// NOTE: removed this for version 1 and moved into separate lump "LUMP_LEAF_AMBIENT_LIGHTING" or "LUMP_LEAF_AMBIENT_LIGHTING_HDR"
// Precaculated light info for entities.
// CompressedLightCube m_AmbientLighting;
}; #pragma warning( default:4201 ) // C4201: nonstandard extension used: nameless struct/union
#if defined( _X360 )
#pragma bitfield_order( pop )
#elif defined( _PS3 )
#pragma ms_struct off
#pragma reverse_bitfields off
#endif
// each leaf contains N samples of the ambient lighting
// each sample contains a cube of ambient light projected on to each axis
// and a sampling position encoded as a 0.8 fraction (mins=0,maxs=255) of the leaf's bounding box
struct dleafambientlighting_t { DECLARE_BYTESWAP_DATADESC(); CompressedLightCube cube; byte x; // fixed point fraction of leaf bounds
byte y; // fixed point fraction of leaf bounds
byte z; // fixed point fraction of leaf bounds
byte pad; // unused
};
struct dleafambientindex_t { DECLARE_BYTESWAP_DATADESC();
unsigned short ambientSampleCount; unsigned short firstAmbientSample; };
struct dbrushside_t { DECLARE_BYTESWAP_DATADESC(); unsigned short planenum; // facing out of the leaf
short texinfo; short dispinfo; // displacement info (BSPVERSION 7)
byte bevel; // is the side a bevel plane? (BSPVERSION 7)
byte thin; // is a thin side?
};
struct dbrush_t { DECLARE_BYTESWAP_DATADESC(); int firstside; int numsides; int contents; };
#define ANGLE_UP -1
#define ANGLE_DOWN -2
// the visibility lump consists of a header with a count, then
// byte offsets for the PVS and PHS of each cluster, then the raw
// compressed bit vectors
#define DVIS_PVS 0
#define DVIS_PAS 1
struct dvis_t { int numclusters; int bitofs[8][2]; // bitofs[numclusters][2]
};
// each area has a list of portals that lead into other areas
// when portals are closed, other areas may not be visible or
// hearable even if the vis info says that it should be
struct dareaportal_t { DECLARE_BYTESWAP_DATADESC(); unsigned short m_PortalKey; // Entities have a key called portalnumber (and in vbsp a variable
// called areaportalnum) which is used
// to bind them to the area portals by comparing with this value.
unsigned short otherarea; // The area this portal looks into.
unsigned short m_FirstClipPortalVert; // Portal geometry.
unsigned short m_nClipPortalVerts;
int planenum; };
struct darea_t { DECLARE_BYTESWAP_DATADESC(); int numareaportals; int firstareaportal; };
struct dleafwaterdata_t { DECLARE_BYTESWAP_DATADESC(); float surfaceZ; float minZ; short surfaceTexInfoID; };
class CFaceMacroTextureInfo { public: DECLARE_BYTESWAP_DATADESC(); // This looks up into g_TexDataStringTable, which looks up into g_TexDataStringData.
// 0xFFFF if the face has no macro texture.
unsigned short m_MacroTextureNameID; };
// lights that were used to illuminate the world
enum emittype_t { emit_surface, // 90 degree spotlight
emit_point, // simple point light source
emit_spotlight, // spotlight with penumbra
emit_skylight, // directional light with no falloff (surface must trace to SKY texture)
emit_quakelight, // linear falloff, non-lambertian
emit_skyambient, // spherical light source with no falloff (surface must trace to SKY texture)
};
// Flags for dworldlight_t::flags
#define DWL_FLAGS_INAMBIENTCUBE 0x0001 // This says that the light was put into the per-leaf ambient cubes.
#define DWL_FLAGS_CASTENTITYSHADOWS 0x0002 // This says that the light will cast shadows from entities
// Old version of the worldlight struct, used for backward compatibility loading.
struct dworldlight_version0_t { DECLARE_BYTESWAP_DATADESC(); Vector origin; Vector intensity; Vector normal; // for surfaces and spotlights
int cluster; emittype_t type; int style; float stopdot; // start of penumbra for emit_spotlight
float stopdot2; // end of penumbra for emit_spotlight
float exponent; //
float radius; // cutoff distance
// falloff for emit_spotlight + emit_point:
// 1 / (constant_attn + linear_attn * dist + quadratic_attn * dist^2)
float constant_attn; float linear_attn; float quadratic_attn; int flags; // Uses a combination of the DWL_FLAGS_ defines.
int texinfo; //
int owner; // entity that this light it relative to
};
struct dworldlight_t { DECLARE_BYTESWAP_DATADESC(); Vector origin; Vector intensity; Vector normal; // for surfaces and spotlights
Vector shadow_cast_offset; // gets added to the light origin when this light is used as a shadow caster (only if DWL_FLAGS_CASTENTITYSHADOWS flag is set)
int cluster; emittype_t type; int style; float stopdot; // start of penumbra for emit_spotlight
float stopdot2; // end of penumbra for emit_spotlight
float exponent; //
float radius; // cutoff distance
// falloff for emit_spotlight + emit_point:
// 1 / (constant_attn + linear_attn * dist + quadratic_attn * dist^2)
float constant_attn; float linear_attn; float quadratic_attn; int flags; // Uses a combination of the DWL_FLAGS_ defines.
int texinfo; //
int owner; // entity that this light it relative to
};
struct dcubemapsample_t { DECLARE_BYTESWAP_DATADESC(); int origin[3]; // position of light snapped to the nearest integer
// the filename for the vtf file is derived from the position
unsigned char size; // 0 - default
// otherwise, 1<<(size-1)
};
#define OVERLAY_BSP_FACE_COUNT 64
#define OVERLAY_NUM_RENDER_ORDERS (1<<OVERLAY_RENDER_ORDER_NUM_BITS)
#define OVERLAY_RENDER_ORDER_NUM_BITS 2
#define OVERLAY_RENDER_ORDER_MASK 0xC000 // top 2 bits set
struct doverlay_t { DECLARE_BYTESWAP_DATADESC(); int nId; short nTexInfo;
// Accessors..
void SetFaceCount( unsigned short count ); unsigned short GetFaceCount() const;
void SetRenderOrder( unsigned short order ); unsigned short GetRenderOrder() const;
private: unsigned short m_nFaceCountAndRenderOrder;
public: int aFaces[OVERLAY_BSP_FACE_COUNT]; float flU[2]; float flV[2]; Vector vecUVPoints[4]; Vector vecOrigin; Vector vecBasisNormal; };
inline void doverlay_t::SetFaceCount( unsigned short count ) { Assert( (count & OVERLAY_RENDER_ORDER_MASK) == 0 ); m_nFaceCountAndRenderOrder &= OVERLAY_RENDER_ORDER_MASK; m_nFaceCountAndRenderOrder |= (count & ~OVERLAY_RENDER_ORDER_MASK); }
inline unsigned short doverlay_t::GetFaceCount() const { return m_nFaceCountAndRenderOrder & ~OVERLAY_RENDER_ORDER_MASK; }
inline void doverlay_t::SetRenderOrder( unsigned short order ) { Assert( order < OVERLAY_NUM_RENDER_ORDERS ); m_nFaceCountAndRenderOrder &= ~OVERLAY_RENDER_ORDER_MASK; m_nFaceCountAndRenderOrder |= (order << (16 - OVERLAY_RENDER_ORDER_NUM_BITS)); // leave 2 bits for render order.
}
inline unsigned short doverlay_t::GetRenderOrder() const { return (m_nFaceCountAndRenderOrder >> (16 - OVERLAY_RENDER_ORDER_NUM_BITS)); }
struct doverlayfade_t { DECLARE_BYTESWAP_DATADESC();
float flFadeDistMinSq; float flFadeDistMaxSq; };
struct doverlaysystemlevel_t { DECLARE_BYTESWAP_DATADESC();
unsigned char nMinCPULevel; unsigned char nMaxCPULevel; unsigned char nMinGPULevel; unsigned char nMaxGPULevel; };
#define WATEROVERLAY_BSP_FACE_COUNT 256
#define WATEROVERLAY_RENDER_ORDER_NUM_BITS 2
#define WATEROVERLAY_NUM_RENDER_ORDERS (1<<WATEROVERLAY_RENDER_ORDER_NUM_BITS)
#define WATEROVERLAY_RENDER_ORDER_MASK 0xC000 // top 2 bits set
struct dwateroverlay_t { DECLARE_BYTESWAP_DATADESC(); int nId; short nTexInfo;
// Accessors..
void SetFaceCount( unsigned short count ); unsigned short GetFaceCount() const; void SetRenderOrder( unsigned short order ); unsigned short GetRenderOrder() const;
private:
unsigned short m_nFaceCountAndRenderOrder;
public:
int aFaces[WATEROVERLAY_BSP_FACE_COUNT]; float flU[2]; float flV[2]; Vector vecUVPoints[4]; Vector vecOrigin; Vector vecBasisNormal; };
inline void dwateroverlay_t::SetFaceCount( unsigned short count ) { Assert( (count & WATEROVERLAY_RENDER_ORDER_MASK) == 0 ); m_nFaceCountAndRenderOrder &= WATEROVERLAY_RENDER_ORDER_MASK; m_nFaceCountAndRenderOrder |= (count & ~WATEROVERLAY_RENDER_ORDER_MASK); }
inline unsigned short dwateroverlay_t::GetFaceCount() const { return m_nFaceCountAndRenderOrder & ~WATEROVERLAY_RENDER_ORDER_MASK; }
inline void dwateroverlay_t::SetRenderOrder( unsigned short order ) { Assert( order < WATEROVERLAY_NUM_RENDER_ORDERS ); m_nFaceCountAndRenderOrder &= ~WATEROVERLAY_RENDER_ORDER_MASK; m_nFaceCountAndRenderOrder |= ( order << ( 16 - WATEROVERLAY_RENDER_ORDER_NUM_BITS ) ); // leave 2 bits for render order.
}
inline unsigned short dwateroverlay_t::GetRenderOrder() const { return ( m_nFaceCountAndRenderOrder >> ( 16 - WATEROVERLAY_RENDER_ORDER_NUM_BITS ) ); }
#ifndef _DEF_BYTE_
#define _DEF_BYTE_
typedef unsigned char byte; typedef unsigned short word; #endif
#define ANGLE_UP -1
#define ANGLE_DOWN -2
//===============
struct epair_t { epair_t *next; char *key; char *value; };
// finalized page of surface's lightmaps
#define MAX_LIGHTMAPPAGE_WIDTH 256
#define MAX_LIGHTMAPPAGE_HEIGHT 128
typedef struct nameForDatadesc_dlightmappage_t // unnamed structs collide in the datadesc macros
{ DECLARE_BYTESWAP_DATADESC(); byte data[MAX_LIGHTMAPPAGE_WIDTH*MAX_LIGHTMAPPAGE_HEIGHT]; byte palette[256*4]; } dlightmappage_t;
typedef struct nameForDatadesc_dlightmappageinfo_t // unnamed structs collide in the datadesc macros
{ DECLARE_BYTESWAP_DATADESC(); byte page; // lightmap page [0..?]
byte offset[2]; // offset into page (s,t)
byte pad; // unused
ColorRGBExp32 avgColor; // average used for runtime lighting calcs
} dlightmappageinfo_t;
#endif // BSPFILE_H
|