//========= Copyright 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
#if !defined( VBSP_H )
#define VBSP_H
#include "cmdlib.h"
#include "vector.h"
#include "scriplib.h"
#include "polylib.h"
#include "threads.h"
#include "bsplib.h"
#include "qfiles.h"
#include "materialpatch.h"
class CUtlBuffer;
#define MAX_BRUSH_SIDES 128
#define CLIP_EPSILON 0.1
#define TEXINFO_NODE -1 // side is allready on a node
// this will output glview files for the given brushmodel. Brushmodel 1 is the world, 2 is the first brush entity, etc.
#define DEBUG_BRUSHMODEL 0
struct portal_t;
struct node_t;
struct plane_t : public dplane_t
{
plane_t *hash_chain;
plane_t() { normal.Init(); }
};
struct brush_texture_t
{
Vector UAxis;
Vector VAxis;
vec_t shift[2];
vec_t rotate;
vec_t textureWorldUnitsPerTexel[2];
vec_t lightmapWorldUnitsPerLuxel;
char name[TEXTURE_NAME_LENGTH];
int flags;
brush_texture_t() : UAxis(0,0,0), VAxis(0,0,0) {}
};
struct mapdispinfo_t;
struct side_t
{
int planenum;
int texinfo;
mapdispinfo_t *pMapDisp;
winding_t *winding;
side_t *original; // bspbrush_t sides will reference the mapbrush_t sides
int contents; // from miptex
int surf; // from miptex
qboolean visible; // choose visble planes first
qboolean tested; // this plane allready checked as a split
qboolean bevel; // don't ever use for bsp splitting
side_t *next;
int origIndex;
int id; // This is the unique id generated by worldcraft for this side.
unsigned int smoothingGroups;
CUtlVector<int> aOverlayIds; // List of overlays that reside on this side.
CUtlVector<int> aWaterOverlayIds; // List of water overlays that reside on this side.
bool m_bDynamicShadowsEnabled; // Goes into dface_t::SetDynamicShadowsEnabled().
};
struct mapbrush_t
{
int entitynum;
int brushnum;
int id; // The unique ID of this brush in the editor, used for reporting errors.
int contents;
Vector mins, maxs;
int numsides;
side_t *original_sides;
};
#define PLANENUM_LEAF -1
#define MAXEDGES 32
struct face_t
{
int id;
face_t *next; // on node
// the chain of faces off of a node can be merged or split,
// but each face_t along the way will remain in the chain
// until the entire tree is freed
face_t *merged; // if set, this face isn't valid anymore
face_t *split[2]; // if set, this face isn't valid anymore
portal_t *portal;
int texinfo;
int 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.
node_t *fogVolumeLeaf;
int planenum;
int contents; // faces in different contents can't merge
int outputnumber;
winding_t *w;
int numpoints;
qboolean badstartvert; // tjunctions cannot be fixed without a midpoint vertex
int vertexnums[MAXEDGES];
side_t *originalface; // save the "side" this face came from
int firstPrimID;
int numPrims;
unsigned int smoothingGroups;
};
void EmitFace( face_t *f, qboolean onNode );
struct mapdispinfo_t
{
face_t face;
int entitynum;
int power;
int minTess;
float smoothingAngle;
Vector uAxis;
Vector vAxis;
Vector startPosition;
float alphaValues[MAX_DISPVERTS];
float maxDispDist;
float dispDists[MAX_DISPVERTS];
Vector vectorDisps[MAX_DISPVERTS];
Vector vectorOffsets[MAX_DISPVERTS];
int contents;
int brushSideID;
unsigned short triTags[MAX_DISPTRIS];
int flags;
};
extern int nummapdispinfo;
extern mapdispinfo_t mapdispinfo[MAX_MAP_DISPINFO];
extern float g_defaultLuxelSize;
extern float g_luxelScale;
extern float g_minLuxelScale;
extern bool g_BumpAll;
extern int g_nDXLevel;
int GetDispInfoEntityNum( mapdispinfo_t *pDisp );
void ComputeBoundsNoSkybox( );
struct bspbrush_t
{
int id;
bspbrush_t *next;
Vector mins, maxs;
int side, testside; // side of node during construction
mapbrush_t *original;
int numsides;
side_t sides[6]; // variably sized
};
#define MAX_NODE_BRUSHES 8
struct leafface_t
{
face_t *pFace;
leafface_t *pNext;
};
struct node_t
{
int id;
// both leafs and nodes
int planenum; // -1 = leaf node
node_t *parent;
Vector mins, maxs; // valid after portalization
bspbrush_t *volume; // one for each leaf/node
// nodes only
side_t *side; // the side that created the node
node_t *children[2];
face_t *faces; // these are the cutup ones that live in the plane of "side".
// leafs only
bspbrush_t *brushlist; // fragments of all brushes in this leaf
leafface_t *leaffacelist;
int contents; // OR of all brush contents
int occupied; // 1 or greater can reach entity
entity_t *occupant; // for leak file testing
int cluster; // for portalfile writing
int area; // for areaportals
portal_t *portals; // also on nodes during construction
int diskId; // dnodes or dleafs index after this has been emitted
};
struct portal_t
{
int id;
plane_t plane;
node_t *onnode; // NULL = outside box
node_t *nodes[2]; // [0] = front side of plane
portal_t *next[2];
winding_t *winding;
qboolean sidefound; // false if ->side hasn't been checked
side_t *side; // NULL = non-visible
face_t *face[2]; // output face in bsp file
};
struct tree_t
{
node_t *headnode;
node_t outside_node;
Vector mins, maxs;
bool leaked;
};
extern int entity_num;
extern plane_t mapplanes[MAX_MAP_PLANES];
extern int nummapplanes;
extern int nummapbrushes;
extern mapbrush_t mapbrushes[MAX_MAP_BRUSHES];
extern Vector map_mins, map_maxs;
extern int nummapbrushsides;
extern side_t brushsides[MAX_MAP_BRUSHSIDES];
extern int g_nMapFileVersion;
extern qboolean noprune;
extern qboolean nodetail;
extern qboolean fulldetail;
extern qboolean nomerge;
extern qboolean nomergewater;
extern qboolean nosubdiv;
extern qboolean nowater;
extern qboolean noweld;
extern qboolean noshare;
extern qboolean notjunc;
extern qboolean nocsg;
extern qboolean noopt;
extern qboolean dumpcollide;
extern qboolean nodetailcuts;
extern qboolean g_DumpStaticProps;
extern vec_t microvolume;
extern bool g_snapAxialPlanes;
extern bool g_NodrawTriggers;
extern bool g_DisableWaterLighting;
extern bool g_bAllowDetailCracks;
extern bool g_bNoVirtualMesh;
extern char outbase[32];
extern char source[1024];
extern char mapbase[ 64 ];
void LoadMapFile(const char *filename);
int FindFloatPlane (Vector& normal, vec_t dist);
int GetVertexnum( Vector& v );
//=============================================================================
// textures.c
struct textureref_t
{
char name[TEXTURE_NAME_LENGTH];
int flags;
float lightmapWorldUnitsPerLuxel;
int contents;
};
extern textureref_t textureref[MAX_MAP_TEXTURES];
int FindMiptex (const char *name);
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, const Vector& origin);
int GetSurfaceProperties2( MaterialSystemMaterial_t matID, const char *pMatName );
extern int g_SurfaceProperties[MAX_MAP_TEXDATA];
void LoadSurfaceProperties( void );
int PointLeafnum ( dmodel_t* pModel, const Vector& p );
//=============================================================================
void FindGCD (int *v);
mapbrush_t *Brush_LoadEntity (entity_t *ent);
int PlaneTypeForNormal (Vector& normal);
qboolean MakeBrushPlanes (mapbrush_t *b);
int FindIntPlane (int *inormal, int *iorigin);
void CreateBrush (int brushnum);
//=============================================================================
// detail objects
//=============================================================================
void LoadEmitDetailObjectDictionary( char const* pGameDir );
void EmitDetailObjects();
//=============================================================================
// static props
//=============================================================================
void EmitStaticProps();
bool LoadStudioModel( char const* pFileName, char const* pEntityType, CUtlBuffer& buf );
//=============================================================================
//=============================================================================
// procedurally created .vmt files
//=============================================================================
void EmitStaticProps();
// draw.c
extern Vector draw_mins, draw_maxs;
extern bool g_bLightIfMissing;
void Draw_ClearWindow (void);
void DrawWinding (winding_t *w);
void GLS_BeginScene (void);
void GLS_Winding (winding_t *w, int code);
void GLS_EndScene (void);
//=============================================================================
// csg
enum detailscreen_e
{
FULL_DETAIL = 0,
ONLY_DETAIL = 1,
NO_DETAIL = 2,
};
#define TRANSPARENT_CONTENTS (CONTENTS_GRATE|CONTENTS_WINDOW)
#include "csg.h"
//=============================================================================
// brushbsp
void WriteBrushList (char *name, bspbrush_t *brush, qboolean onlyvis);
bspbrush_t *CopyBrush (bspbrush_t *brush);
void SplitBrush (bspbrush_t *brush, int planenum,
bspbrush_t **front, bspbrush_t **back);
tree_t *AllocTree (void);
node_t *AllocNode (void);
bspbrush_t *AllocBrush (int numsides);
int CountBrushList (bspbrush_t *brushes);
void FreeBrush (bspbrush_t *brushes);
vec_t BrushVolume (bspbrush_t *brush);
node_t *NodeForPoint (node_t *node, Vector& origin);
void BoundBrush (bspbrush_t *brush);
void FreeBrushList (bspbrush_t *brushes);
tree_t *BrushBSP (bspbrush_t *brushlist, Vector& mins, Vector& maxs);
#define PSIDE_FRONT 1
#define PSIDE_BACK 2
#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK)
#define PSIDE_FACING 4
int BrushBspBoxOnPlaneSide (const Vector& mins, const Vector& maxs, dplane_t *plane);
extern qboolean WindingIsTiny (winding_t *w);
//=============================================================================
// portals.c
int VisibleContents (int contents);
void MakeHeadnodePortals (tree_t *tree);
void MakeNodePortal (node_t *node);
void SplitNodePortals (node_t *node);
qboolean Portal_VisFlood (portal_t *p);
qboolean FloodEntities (tree_t *tree);
void FillOutside (node_t *headnode);
void FloodAreas (tree_t *tree);
void MarkVisibleSides (tree_t *tree, int start, int end, int detailScreen);
void MarkVisibleSides (tree_t *tree, mapbrush_t **ppBrushes, int nCount );
void FreePortal (portal_t *p);
void EmitAreaPortals (node_t *headnode);
void MakeTreePortals (tree_t *tree);
//=============================================================================
// glfile.c
void OutputWinding (winding_t *w, FileHandle_t glview);
void WriteGLView (tree_t *tree, char *source);
void WriteGLViewFaces (tree_t *tree, const char *source);
//=============================================================================
// leakfile.c
void LeakFile (tree_t *tree);
void AreaportalLeakFile( tree_t *tree, portal_t *pStartPortal, portal_t *pEndPortal, node_t *pStart );
//=============================================================================
// prtfile.c
void WritePortalFile (tree_t *tree);
//=============================================================================
// writebsp.c
void SetModelNumbers (void);
void SetLightStyles (void);
void BeginBSPFile (void);
void WriteBSP (node_t *headnode, face_t *pLeafFaceList);
void EndBSPFile (void);
void BeginModel (void);
void EndModel (void);
extern int firstmodeledge;
extern int firstmodelface;
//=============================================================================
// faces.c
void MakeFaces (node_t *headnode);
void MakeDetailFaces (node_t *headnode);
face_t *FixTjuncs( node_t *headnode, face_t *pLeafFaceList );
face_t *AllocFace (void);
void FreeFace (face_t *f);
void FreeFaceList( face_t *pFaces );
void MergeFaceList(face_t **pFaceList);
void SubdivideFaceList(face_t **pFaceList);
extern face_t *edgefaces[MAX_MAP_EDGES][2];
//=============================================================================
// tree.c
void FreeTree (tree_t *tree);
void FreeTree_r (node_t *node);
void PrintTree_r (node_t *node, int depth);
void FreeTreePortals_r (node_t *node);
void PruneNodes_r (node_t *node);
void PruneNodes (node_t *node);
// Returns true if the entity is a func_occluder
bool IsFuncOccluder( int entity_num );
//=============================================================================
// ivp.cpp
class CPhysCollide;
void EmitPhysCollision();
void DumpCollideToGlView( CPhysCollide *pCollide, const char *pFilename );
void EmitWaterVolumesForBSP( dmodel_t *pModel, node_t *headnode );
//=============================================================================
// find + find or create the texdata
int FindTexData( const char *pName );
int FindOrCreateTexData( const char *pName );
// Add a clone of an existing texdata with a new name
int AddCloneTexData( dtexdata_t *pExistingTexData, char const *cloneTexDataName );
int FindOrCreateTexInfo( const texinfo_t &searchTexInfo );
int FindAliasedTexData( const char *pName, dtexdata_t *sourceTexture );
int FindTexInfo( const texinfo_t &searchTexInfo );
//=============================================================================
// normals.c
void SaveVertexNormals( void );
//=============================================================================
// cubemap.cpp
void Cubemap_InsertSample( const Vector& origin, int size );
void Cubemap_CreateDefaultCubemaps( void );
void Cubemap_SaveBrushSides( const char *pSideListStr );
void Cubemap_FixupBrushSidesMaterials( void );
void Cubemap_AttachDefaultCubemapToSpecularSides( void );
// Collapse down unused texinfos + texdatas (cubemaps will make them unused)
void Cubemap_ClearUnusedTexInfos( void );
// Add skipped cubemaps that are referenced by the engine
void Cubemap_AddUnreferencedCubemaps( void );
//=============================================================================
// overlay.cpp
#define OVERLAY_MAP_STRLEN 256
struct mapoverlay_t
{
int nId;
unsigned short m_nRenderOrder;
char szMaterialName[OVERLAY_MAP_STRLEN];
float flU[2];
float flV[2];
Vector vecUVPoints[4];
Vector vecOrigin;
Vector vecBasis[3];
CUtlVector<int> aSideList;
CUtlVector<int> aFaceList;
};
extern CUtlVector<mapoverlay_t> g_aMapOverlays;
extern CUtlVector<mapoverlay_t> g_aMapWaterOverlays;
void Overlay_GetFromEntity( entity_t *pMapEnt );
void Overlay_UpdateSideLists( void );
void Overlay_AddFaceToLists( int iFace, side_t *pSide );
void Overlay_EmitOverlayFaces( void );
void OverlayTransition_UpdateSideLists( void );
void OverlayTransition_AddFaceToLists( int iFace, side_t *pSide );
void OverlayTransition_EmitOverlayFaces( void );
//=============================================================================
void RemoveAreaPortalBrushes_R( node_t *node );
dtexdata_t *GetTexData( int index );
#endif