2020-04-23 00:56:21 +08:00
//========= Copyright 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 "datamap.h"
# include "mathlib/bumpvects.h"
# include "mathlib/compressed_light_cube.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
2022-11-30 20:58:19 +08:00
# define BSPVERSION 21
2020-04-23 00:56:21 +08:00
// This needs to match the value in gl_lightmap.h
// Need to dynamically allocate the weights and light values in radial_t to make this variable.
# define MAX_BRUSH_LIGHTMAP_DIM_WITHOUT_BORDER 32
// This is one more than what vbsp cuts for to allow for rounding errors
# define MAX_BRUSH_LIGHTMAP_DIM_INCLUDING_BORDER 35
// We can have larger lightmaps on displacements
# define MAX_DISP_LIGHTMAP_DIM_WITHOUT_BORDER 125
# define MAX_DISP_LIGHTMAP_DIM_INCLUDING_BORDER 128
// 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 8192
# define MAX_MAP_TEXINFO 12288
# define MAX_MAP_TEXDATA 2048
2022-12-03 02:45:33 +08:00
# define MAX_MAP_DISPINFO 4096
2020-04-23 00:56:21 +08:00
# 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 256
# 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 512
# 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_UNUSED0 = 22 ,
LUMP_UNUSED1 = 23 ,
LUMP_UNUSED2 = 24 ,
LUMP_UNUSED3 = 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_PHYSCOLLIDESURFACE = 49 , // deprecated. We no longer use win32-specific havok compression on terrain
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
} ;
// 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 ,
2022-11-30 20:58:19 +08:00
LUMP_WORLDLIGHTS_VERSION = 1
2020-04-23 00:56:21 +08:00
} ;
# define HEADER_LUMPS 64
# include "zip_uncompressed.h"
struct lump_t
{
DECLARE_BYTESWAP_DATADESC ( ) ;
int fileofs , filelen ;
int version ; // default to zero
// this field was char fourCC[4] previously, but was unused, favoring the LUMP IDs above instead. It has been
// repurposed for compression. 0 implies the lump is not compressed.
int uncompressedSize ; // default to zero
} ;
struct dheader_t
{
DECLARE_BYTESWAP_DATADESC ( ) ;
int ident ;
int version ;
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
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 ;
// 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 ;
} ;
// 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 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_TAG_REMOVE (1<<5)
class CDispTri
{
public :
DECLARE_BYTESWAP_DATADESC ( ) ;
unsigned short m_uiTags ; // Displacement triangle tags.
} ;
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 } ;
2022-02-23 19:50:30 +08:00
unsigned int m_AllowedVerts [ ALLOWEDVERTS_SIZE ] ; // This is built based on the layout and sizes of our neighbors
2020-04-23 00:56:21 +08:00
// 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 ;
} ;
// NOTE: Only 7-bits stored!!!
# 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
# if defined( _X360 )
# pragma bitfield_order( push, lsb_to_msb )
# endif
2021-10-23 19:41:59 +08:00
# ifdef WIN32
2020-04-23 00:56:21 +08:00
# pragma warning( disable:4201 ) // C4201: nonstandard extension used: nameless struct/union
2021-10-23 19:41:59 +08:00
# endif
2020-04-23 00:56:21 +08:00
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 )
# 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)
short bevel ; // is the side a bevel plane? (BSPVERSION 7)
} ;
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.
2022-11-30 20:58:19 +08:00
# define DWL_FLAGS_CASTENTITYSHADOWS 0x0002 // This says that the light will cast shadows from entities
2020-04-23 00:56:21 +08:00
2022-11-30 20:58:19 +08:00
// 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
} ;
2020-04-23 00:56:21 +08:00
struct dworldlight_t
{
DECLARE_BYTESWAP_DATADESC ( ) ;
Vector origin ;
Vector intensity ;
Vector normal ; // for surfaces and spotlights
2022-11-30 20:58:19 +08:00
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)
2020-04-23 00:56:21 +08:00
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 )
{
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 )
{
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 ;
} ;
# 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 )
{
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 )
{
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