123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351 |
- #include "bsp5.h"
- // WriteClipNodes_r
- // WriteClipNodes
- // WriteDrawLeaf
- // WriteFace
- // WriteDrawNodes_r
- // FreeDrawNodes_r
- // WriteDrawNodes
- // BeginBSPFile
- // FinishBSPFile
- #include <map>
- typedef std::map<int,int> PlaneMap;
- static PlaneMap gPlaneMap;
- static int gNumMappedPlanes;
- static dplane_t gMappedPlanes[MAX_MAP_PLANES];
- extern bool g_noopt;
- // =====================================================================================
- // WritePlane
- // hook for plane optimization
- // =====================================================================================
- static int WritePlane(int planenum)
- {
- planenum = planenum & (~1);
- if(g_noopt)
- {
- return planenum;
- }
- PlaneMap::iterator item = gPlaneMap.find(planenum);
- if(item != gPlaneMap.end())
- {
- return item->second;
- }
- //add plane to BSP
- hlassume(gNumMappedPlanes < MAX_MAP_PLANES, assume_MAX_MAP_PLANES);
- gMappedPlanes[gNumMappedPlanes] = g_dplanes[planenum];
- gPlaneMap.insert(PlaneMap::value_type(planenum,gNumMappedPlanes));
- return gNumMappedPlanes++;
- }
- // =====================================================================================
- // WriteClipNodes_r
- // =====================================================================================
- static int WriteClipNodes_r(node_t* node)
- {
- int i, c;
- dclipnode_t* cn;
- int num;
- if (node->planenum == -1)
- {
- num = node->contents;
- free(node->markfaces);
- free(node);
- return num;
- }
- hlassume(g_numclipnodes < MAX_MAP_CLIPNODES, assume_MAX_MAP_CLIPNODES);
- // emit a clipnode
- c = g_numclipnodes;
- cn = &g_dclipnodes[g_numclipnodes];
- g_numclipnodes++;
- if (node->planenum & 1)
- {
- Error("WriteClipNodes_r: odd planenum");
- }
-
- #ifdef ZHLT_PLANETYPE_FIX //debug
- {
- dplane_t *plane = &g_dplanes[node->planenum];
- if (plane->normal[(plane->type)%3] < 0)
- if (plane->type < 3)
- Warning ("WriteClipNodes_r: negative plane");
- else
- Developer (DEVELOPER_LEVEL_MESSAGE, "Warning: WriteClipNodes_r: negative plane\n");
- }
- #endif
-
- cn->planenum = WritePlane(node->planenum);
- for (i = 0; i < 2; i++)
- {
- cn->children[i] = WriteClipNodes_r(node->children[i]);
- }
- free(node);
- return c;
- }
- // =====================================================================================
- // WriteClipNodes
- // Called after the clipping hull is completed. Generates a disk format
- // representation and frees the original memory.
- // =====================================================================================
- void WriteClipNodes(node_t* nodes)
- {
- WriteClipNodes_r(nodes);
- }
- // =====================================================================================
- // WriteDrawLeaf
- // =====================================================================================
- static void WriteDrawLeaf(const node_t* const node)
- {
- face_t** fp;
- face_t* f;
- dleaf_t* leaf_p;
- // emit a leaf
- leaf_p = &g_dleafs[g_numleafs];
- g_numleafs++;
- leaf_p->contents = node->contents;
- //
- // write bounding box info
- //
- VectorCopy(node->mins, leaf_p->mins);
- VectorCopy(node->maxs, leaf_p->maxs);
- leaf_p->visofs = -1; // no vis info yet
- //
- // write the marksurfaces
- //
- leaf_p->firstmarksurface = g_nummarksurfaces;
- hlassume(node->markfaces != NULL, assume_EmptySolid);
- for (fp = node->markfaces; *fp; fp++)
- {
- // emit a marksurface
- f = *fp;
- do
- {
- g_dmarksurfaces[g_nummarksurfaces] = f->outputnumber;
- hlassume(g_nummarksurfaces < MAX_MAP_MARKSURFACES, assume_MAX_MAP_MARKSURFACES);
- g_nummarksurfaces++;
- f = f->original; // grab tjunction split faces
- }
- while (f);
- }
- free(node->markfaces);
- leaf_p->nummarksurfaces = g_nummarksurfaces - leaf_p->firstmarksurface;
- }
- // =====================================================================================
- // WriteFace
- // =====================================================================================
- static void WriteFace(face_t* f)
- {
- dface_t* df;
- int i;
- int e;
- if ( CheckFaceForHint(f)
- || CheckFaceForSkip(f)
- #ifdef ZHLT_NULLTEX
- || CheckFaceForNull(f) // AJM
- #endif
- // =====================================================================================
- //Cpt_Andrew - Env_Sky Check
- // =====================================================================================
- || CheckFaceForEnv_Sky(f)
- // =====================================================================================
- )
- {
- return;
- }
- f->outputnumber = g_numfaces;
- df = &g_dfaces[g_numfaces];
- hlassume(g_numfaces < MAX_MAP_FACES, assume_MAX_MAP_FACES);
- g_numfaces++;
- df->planenum = WritePlane(f->planenum);
- df->side = f->planenum & 1;
- df->firstedge = g_numsurfedges;
- df->numedges = f->numpoints;
- df->texinfo = f->texturenum;
- for (i = 0; i < f->numpoints; i++)
- {
- e = GetEdge(f->pts[i], f->pts[(i + 1) % f->numpoints], f);
- hlassume(g_numsurfedges < MAX_MAP_SURFEDGES, assume_MAX_MAP_SURFEDGES);
- g_dsurfedges[g_numsurfedges] = e;
- g_numsurfedges++;
- }
- }
- // =====================================================================================
- // WriteDrawNodes_r
- // =====================================================================================
- static void WriteDrawNodes_r(const node_t* const node)
- {
- dnode_t* n;
- int i;
- face_t* f;
- // emit a node
- hlassume(g_numnodes < MAX_MAP_NODES, assume_MAX_MAP_NODES);
- n = &g_dnodes[g_numnodes];
- g_numnodes++;
- VectorCopy(node->mins, n->mins);
- VectorCopy(node->maxs, n->maxs);
- if (node->planenum & 1)
- {
- Error("WriteDrawNodes_r: odd planenum");
- }
- n->planenum = WritePlane(node->planenum);
- n->firstface = g_numfaces;
- for (f = node->faces; f; f = f->next)
- {
- WriteFace(f);
- }
- n->numfaces = g_numfaces - n->firstface;
- //
- // recursively output the other nodes
- //
- for (i = 0; i < 2; i++)
- {
- if (node->children[i]->planenum == -1)
- {
- if (node->children[i]->contents == CONTENTS_SOLID)
- {
- n->children[i] = -1;
- }
- else
- {
- n->children[i] = -(g_numleafs + 1);
- WriteDrawLeaf(node->children[i]);
- }
- }
- else
- {
- n->children[i] = g_numnodes;
- WriteDrawNodes_r(node->children[i]);
- }
- }
- }
- // =====================================================================================
- // FreeDrawNodes_r
- // =====================================================================================
- static void FreeDrawNodes_r(node_t* node)
- {
- int i;
- face_t* f;
- face_t* next;
- for (i = 0; i < 2; i++)
- {
- if (node->children[i]->planenum != -1)
- {
- FreeDrawNodes_r(node->children[i]);
- }
- }
- //
- // free the faces on the node
- //
- for (f = node->faces; f; f = next)
- {
- next = f->next;
- FreeFace(f);
- }
- free(node);
- }
- // =====================================================================================
- // WriteDrawNodes
- // Called after a drawing hull is completed
- // Frees all nodes and faces
- // =====================================================================================
- void WriteDrawNodes(node_t* headnode)
- {
- if (headnode->contents < 0)
- {
- WriteDrawLeaf(headnode);
- }
- else
- {
- WriteDrawNodes_r(headnode);
- FreeDrawNodes_r(headnode);
- }
- }
- // =====================================================================================
- // BeginBSPFile
- // =====================================================================================
- void BeginBSPFile()
- {
- // these values may actually be initialized
- // if the file existed when loaded, so clear them explicitly
- gNumMappedPlanes = 0;
- gPlaneMap.clear();
- g_nummodels = 0;
- g_numfaces = 0;
- g_numnodes = 0;
- g_numclipnodes = 0;
- g_numvertexes = 0;
- g_nummarksurfaces = 0;
- g_numsurfedges = 0;
- // edge 0 is not used, because 0 can't be negated
- g_numedges = 1;
- // leaf 0 is common solid with no faces
- g_numleafs = 1;
- g_dleafs[0].contents = CONTENTS_SOLID;
- }
- // =====================================================================================
- // FinishBSPFile
- // =====================================================================================
- void FinishBSPFile()
- {
- Verbose("--- FinishBSPFile ---\n");
- if(!g_noopt)
- {
- for(int counter = 0; counter < gNumMappedPlanes; counter++)
- {
- g_dplanes[counter] = gMappedPlanes[counter];
- }
- g_numplanes = gNumMappedPlanes;
- }
- if (g_chart)
- {
- PrintBSPFileSizes();
- }
- WriteBSPFile(g_bspfilename);
- }
|