doom3-bfg/neo/tools/compilers/dmap/dmap.h
2014-08-02 15:09:25 +02:00

512 lines
14 KiB
C

/*
===========================================================================
Doom 3 GPL Source Code
Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
Doom 3 Source Code is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Doom 3 Source Code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
===========================================================================
*/
#include "../../../renderer/tr_local.h"
typedef struct primitive_s
{
struct primitive_s* next;
// only one of these will be non-NULL
struct bspbrush_s* brush;
struct mapTri_s* tris;
} primitive_t;
typedef struct
{
struct optimizeGroup_s* groups;
// we might want to add other fields later
} uArea_t;
typedef struct
{
idMapEntity* mapEntity; // points into mapFile_t data
idVec3 origin;
primitive_t* primitives;
struct tree_s* tree;
int numAreas;
uArea_t* areas;
} uEntity_t;
// chains of mapTri_t are the general unit of processing
typedef struct mapTri_s
{
struct mapTri_s* next;
const idMaterial* material;
void* mergeGroup; // we want to avoid merging triangles
// from different fixed groups, like guiSurfs and mirrors
int planeNum; // not set universally, just in some areas
idDrawVert v[3];
const struct hashVert_s* hashVert[3];
struct optVertex_s* optVert[3];
} mapTri_t;
typedef struct
{
int width, height;
idDrawVert* verts;
} mesh_t;
#define MAX_PATCH_SIZE 32
#define PLANENUM_LEAF -1
typedef struct parseMesh_s
{
struct parseMesh_s* next;
mesh_t mesh;
const idMaterial* material;
} parseMesh_t;
typedef struct bspface_s
{
struct bspface_s* next;
int planenum;
bool portal; // all portals will be selected before
// any non-portals
bool checked; // used by SelectSplitPlaneNum()
idWinding* w;
} bspface_t;
typedef struct
{
idVec4 v[2]; // the offset value will always be in the 0.0 to 1.0 range
} textureVectors_t;
typedef struct side_s
{
int planenum;
const idMaterial* material;
textureVectors_t texVec;
idWinding* winding; // only clipped to the other sides of the brush
idWinding* visibleHull; // also clipped to the solid parts of the world
} side_t;
typedef struct bspbrush_s
{
struct bspbrush_s* next;
struct bspbrush_s* original; // chopped up brushes will reference the originals
int entitynum; // editor numbering for messages
int brushnum; // editor numbering for messages
const idMaterial* contentShader; // one face's shader will determine the volume attributes
int contents;
bool opaque;
int outputNumber; // set when the brush is written to the file list
idBounds bounds;
int numsides;
side_t sides[6]; // variably sized
} uBrush_t;
typedef struct drawSurfRef_s
{
struct drawSurfRef_s* nextRef;
int outputNumber;
} drawSurfRef_t;
typedef struct node_s
{
// both leafs and nodes
int planenum; // -1 = leaf node
struct node_s* parent;
idBounds bounds; // valid after portalization
// nodes only
side_t* side; // the side that created the node
struct node_s* children[2];
int nodeNumber; // set after pruning
// leafs only
bool opaque; // view can never be inside
uBrush_t* brushlist; // fragments of all brushes in this leaf
// needed for FindSideForPortal
int area; // determined by flood filling up to areaportals
int occupied; // 1 or greater can reach entity
uEntity_t* occupant; // for leak file testing
struct uPortal_s* portals; // also on nodes during construction
} node_t;
typedef struct uPortal_s
{
idPlane plane;
node_t* onnode; // NULL = outside box
node_t* nodes[2]; // [0] = front side of plane
struct uPortal_s* next[2];
idWinding* winding;
} uPortal_t;
// a tree_t is created by FaceBSP()
typedef struct tree_s
{
node_t* headnode;
node_t outside_node;
idBounds bounds;
} tree_t;
#define MAX_QPATH 256 // max length of a game pathname
typedef struct
{
idRenderLightLocal def;
char name[MAX_QPATH]; // for naming the shadow volume surface and interactions
srfTriangles_t* shadowTris;
idPlane frustumPlanes[6]; // RB: should be calculated after R_DeriveLightData()
} mapLight_t;
#define MAX_GROUP_LIGHTS 16
typedef struct optimizeGroup_s
{
struct optimizeGroup_s* nextGroup;
idBounds bounds; // set in CarveGroupsByLight
// all of these must match to add a triangle to the triList
bool smoothed; // curves will never merge with brushes
int planeNum;
int areaNum;
const idMaterial* material;
int numGroupLights;
mapLight_t* groupLights[MAX_GROUP_LIGHTS]; // lights effecting this list
void* mergeGroup; // if this differs (guiSurfs, mirrors, etc), the
// groups will not be combined into model surfaces
// after optimization
textureVectors_t texVec;
bool surfaceEmited;
mapTri_t* triList;
mapTri_t* regeneratedTris; // after each island optimization
idVec3 axis[2]; // orthogonal to the plane, so optimization can be 2D
} optimizeGroup_t;
// all primitives from the map are added to optimzeGroups, creating new ones as needed
// each optimizeGroup is then split into the map areas, creating groups in each area
// each optimizeGroup is then divided by each light, creating more groups
// the final list of groups is then tjunction fixed against all groups, then optimized internally
// multiple optimizeGroups will be merged together into .proc surfaces, but no further optimization
// is done on them
//=============================================================================
// dmap.cpp
typedef enum
{
SO_NONE, // 0
SO_MERGE_SURFACES, // 1
SO_CULL_OCCLUDED, // 2
SO_CLIP_OCCLUDERS, // 3
SO_CLIP_SILS, // 4
SO_SIL_OPTIMIZE // 5
} shadowOptLevel_t;
typedef struct
{
// mapFileBase will contain the qpath without any extension: "maps/test_box"
char mapFileBase[1024];
idMapFile* dmapFile;
idPlaneSet mapPlanes;
int num_entities;
uEntity_t* uEntities;
int entityNum;
idList<mapLight_t*> mapLights;
bool verbose;
bool glview;
bool noOptimize;
bool verboseentities;
bool noCurves;
bool fullCarve;
bool noModelBrushes;
bool noTJunc;
bool nomerge;
bool noFlood;
bool noClipSides; // don't cut sides by solid leafs, use the entire thing
bool noLightCarve; // extra triangle subdivision by light frustums
shadowOptLevel_t shadowOptLevel;
bool noShadow; // don't create optimized shadow volumes
idBounds drawBounds;
bool drawflag;
int totalShadowTriangles;
int totalShadowVerts;
} dmapGlobals_t;
extern dmapGlobals_t dmapGlobals;
int FindFloatPlane( const idPlane& plane, bool* fixedDegeneracies = NULL );
//=============================================================================
// brush.cpp
#ifndef CLIP_EPSILON
#define CLIP_EPSILON 0.1f
#endif
#define PSIDE_FRONT 1
#define PSIDE_BACK 2
#define PSIDE_BOTH (PSIDE_FRONT|PSIDE_BACK)
#define PSIDE_FACING 4
int CountBrushList( uBrush_t* brushes );
uBrush_t* AllocBrush( int numsides );
void FreeBrush( uBrush_t* brushes );
void FreeBrushList( uBrush_t* brushes );
uBrush_t* CopyBrush( uBrush_t* brush );
void DrawBrushList( uBrush_t* brush );
void PrintBrush( uBrush_t* brush );
bool BoundBrush( uBrush_t* brush );
bool CreateBrushWindings( uBrush_t* brush );
uBrush_t* BrushFromBounds( const idBounds& bounds );
float BrushVolume( uBrush_t* brush );
void WriteBspBrushMap( const char* name, uBrush_t* list );
void FilterBrushesIntoTree( uEntity_t* e );
void SplitBrush( uBrush_t* brush, int planenum, uBrush_t** front, uBrush_t** back );
node_t* AllocNode();
//=============================================================================
// map.cpp
bool LoadDMapFile( const char* filename );
void FreeOptimizeGroupList( optimizeGroup_t* groups );
void FreeDMapFile();
//=============================================================================
// draw.cpp -- draw debug views either directly, or through glserv.exe
void Draw_ClearWindow();
void DrawWinding( const idWinding* w );
void DrawAuxWinding( const idWinding* w );
void DrawLine( idVec3 v1, idVec3 v2, int color );
void GLS_BeginScene();
void GLS_Winding( const idWinding* w, int code );
void GLS_Triangle( const mapTri_t* tri, int code );
void GLS_EndScene();
//=============================================================================
// portals.cpp
#define MAX_INTER_AREA_PORTALS 1024
typedef struct
{
int area0, area1;
side_t* side;
} interAreaPortal_t;
extern interAreaPortal_t interAreaPortals[MAX_INTER_AREA_PORTALS];
extern int numInterAreaPortals;
bool FloodEntities( tree_t* tree );
void FillOutside( uEntity_t* e );
void FloodAreas( uEntity_t* e );
void MakeTreePortals( tree_t* tree );
void FreePortal( uPortal_t* p );
//=============================================================================
// glfile.cpp -- write a debug file to be viewd with glview.exe
void OutputWinding( idWinding* w, idFile* glview );
void WriteGLView( tree_t* tree, char* source );
//=============================================================================
// leakfile.cpp
void LeakFile( tree_t* tree );
//=============================================================================
// facebsp.cpp
tree_t* AllocTree();
void FreeTree( tree_t* tree );
void FreeTree_r( node_t* node );
void FreeTreePortals_r( node_t* node );
bspface_t* MakeStructuralBspFaceList( primitive_t* list );
bspface_t* MakeVisibleBspFaceList( primitive_t* list );
tree_t* FaceBSP( bspface_t* list );
node_t* NodeForPoint( node_t* node, const idVec3& origin );
//=============================================================================
// surface.cpp
mapTri_t* CullTrisInOpaqueLeafs( mapTri_t* triList, tree_t* tree );
void ClipSidesByTree( uEntity_t* e );
void SplitTrisToSurfaces( mapTri_t* triList, tree_t* tree );
void PutPrimitivesInAreas( uEntity_t* e );
void Prelight( uEntity_t* e );
//=============================================================================
// tritjunction.cpp
struct hashVert_s* GetHashVert( idVec3& v );
void HashTriangles( optimizeGroup_t* groupList );
void FreeTJunctionHash();
int CountGroupListTris( const optimizeGroup_t* groupList );
void FixEntityTjunctions( uEntity_t* e );
void FixAreaGroupsTjunctions( optimizeGroup_t* groupList );
void FixGlobalTjunctions( uEntity_t* e );
//=============================================================================
// optimize.cpp -- triangle mesh reoptimization
// the shadow volume optimizer call internal optimizer routines, normal triangles
// will just be done by OptimizeEntity()
typedef struct optVertex_s
{
idDrawVert v;
idVec3 pv; // projected against planar axis, third value is 0
struct optEdge_s* edges;
struct optVertex_s* islandLink;
bool addedToIsland;
bool emited; // when regenerating triangles
} optVertex_t;
typedef struct optEdge_s
{
optVertex_t* v1, *v2;
struct optEdge_s* islandLink;
bool addedToIsland;
bool created; // not one of the original edges
bool combined; // combined from two or more colinear edges
struct optTri_s* frontTri, *backTri;
struct optEdge_s* v1link, *v2link;
} optEdge_t;
typedef struct optTri_s
{
struct optTri_s* next;
idVec3 midpoint;
optVertex_t* v[3];
bool filled;
} optTri_t;
typedef struct
{
optimizeGroup_t* group;
optVertex_t* verts;
optEdge_t* edges;
optTri_t* tris;
} optIsland_t;
void OptimizeEntity( uEntity_t* e );
void OptimizeGroupList( optimizeGroup_t* groupList );
//=============================================================================
// tritools.cpp
mapTri_t* AllocTri();
void FreeTri( mapTri_t* tri );
int CountTriList( const mapTri_t* list );
mapTri_t* MergeTriLists( mapTri_t* a, mapTri_t* b );
mapTri_t* CopyTriList( const mapTri_t* a );
void FreeTriList( mapTri_t* a );
mapTri_t* CopyMapTri( const mapTri_t* tri );
float MapTriArea( const mapTri_t* tri );
mapTri_t* RemoveBadTris( const mapTri_t* tri );
void BoundTriList( const mapTri_t* list, idBounds& b );
void DrawTri( const mapTri_t* tri );
void FlipTriList( mapTri_t* tris );
void TriVertsFromOriginal( mapTri_t* tri, const mapTri_t* original );
void PlaneForTri( const mapTri_t* tri, idPlane& plane );
idWinding* WindingForTri( const mapTri_t* tri );
mapTri_t* WindingToTriList( const idWinding* w, const mapTri_t* originalTri );
void ClipTriList( const mapTri_t* list, const idPlane& plane, float epsilon, mapTri_t** front, mapTri_t** back );
//=============================================================================
// output.cpp
srfTriangles_t* ShareMapTriVerts( const mapTri_t* tris );
void WriteOutputFile();
//=============================================================================
// shadowopt.cpp
srfTriangles_t* CreateLightShadow( optimizeGroup_t* shadowerGroups, const mapLight_t* light );
void FreeBeamTree( struct beamTree_s* beamTree );
void CarveTriByBeamTree( const struct beamTree_s* beamTree, const mapTri_t* tri, mapTri_t** lit, mapTri_t** unLit );