diff --git a/tools/quake3/q3map2/bsp.cpp b/tools/quake3/q3map2/bsp.cpp index 494b6de6..481d4153 100644 --- a/tools/quake3/q3map2/bsp.cpp +++ b/tools/quake3/q3map2/bsp.cpp @@ -285,7 +285,7 @@ static void FixBrushSides( entity_t *e ){ void ProcessWorldModel( void ){ entity_t *e; tree_t *tree; - face_t *faces; + facelist_t faces; xmlNodePtr polyline, leaknode; char level[ 2 ]; const char *value; diff --git a/tools/quake3/q3map2/convert_bsp.cpp b/tools/quake3/q3map2/convert_bsp.cpp index b1283834..1ca17067 100644 --- a/tools/quake3/q3map2/convert_bsp.cpp +++ b/tools/quake3/q3map2/convert_bsp.cpp @@ -725,7 +725,7 @@ void PseudoCompileBSP( bool need_tree ){ int models; char modelValue[16]; entity_t *entity; - face_t *faces; + facelist_t faces; tree_t *tree; node_t *node; brush_t *brush; diff --git a/tools/quake3/q3map2/facebsp.cpp b/tools/quake3/q3map2/facebsp.cpp index 12473551..008f813a 100644 --- a/tools/quake3/q3map2/facebsp.cpp +++ b/tools/quake3/q3map2/facebsp.cpp @@ -36,47 +36,13 @@ int c_faceLeafs; -/* - ================ - AllocBspFace - ================ - */ -face_t *AllocBspFace( void ) { - return safe_calloc( sizeof( face_t ) ); -} - - - -/* - ================ - FreeBspFace - ================ - */ -void FreeBspFace( face_t *f ) { - if ( f->w ) { - FreeWinding( f->w ); - } - free( f ); -} - - /* SelectSplitPlaneNum() finds the best split plane for this node */ -static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, int *compileFlags ){ - face_t *split; - face_t *check; - face_t *bestSplit; - int splits, facing, front, back; - int value, bestValue; - int i; - float dist; - int planenum; - float sizeBias; - +static void SelectSplitPlaneNum( node_t *node, const facelist_t& list, int *splitPlaneNum, int *compileFlags ){ //int frontC,backC,splitsC,facingC; @@ -88,45 +54,44 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, /* ydnar 2002-09-21: changed blocksize to be a vector, so mappers can specify a 3 element value */ /* if it is crossing a block boundary, force a split */ - for ( i = 0; i < 3; i++ ) + for ( int i = 0; i < 3; i++ ) { if ( blockSize[ i ] <= 0 ) { continue; } - dist = blockSize[ i ] * ( floor( node->minmax.mins[ i ] / blockSize[ i ] ) + 1 ); + const float dist = blockSize[ i ] * ( floor( node->minmax.mins[ i ] / blockSize[ i ] ) + 1 ); if ( node->minmax.maxs[ i ] > dist ) { - planenum = FindFloatPlane( g_vector3_axes[i], dist, 0, NULL ); - *splitPlaneNum = planenum; + *splitPlaneNum = FindFloatPlane( g_vector3_axes[i], dist, 0, NULL ); return; } } /* pick one of the face planes */ - bestValue = -99999; - bestSplit = list; + int bestValue = -99999; + const face_t *bestSplit = nullptr; // div0: this check causes detail/structural mixes - //for( split = list; split; split = split->next ) - // split->checked = false; + //for( face_t& split : list ) + // split.checked = false; - for ( split = list; split; split = split->next ) + for ( const face_t& split : list ) { //if ( split->checked ) // continue; - const plane_t& plane = mapplanes[ split->planenum ]; - splits = 0; - facing = 0; - front = 0; - back = 0; - for ( check = list ; check ; check = check->next ) { - if ( check->planenum == split->planenum ) { + const plane_t& plane = mapplanes[ split.planenum ]; + int splits = 0; + int facing = 0; + int front = 0; + int back = 0; + for ( const face_t& check : list ) { + if ( check.planenum == split.planenum ) { facing++; //check->checked = true; // won't need to test this plane again continue; } - const EPlaneSide side = WindingOnPlaneSide( *check->w, plane.plane ); + const EPlaneSide side = WindingOnPlaneSide( check.w, plane.plane ); if ( side == eSideCross ) { splits++; } @@ -138,11 +103,12 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, } } + int value; if ( bspAlternateSplitWeights ) { // from 27 //Bigger is better - sizeBias = WindingArea( *split->w ); + const float sizeBias = WindingArea( split.w ); //Base score = 20000 perfectly balanced value = 20000 - ( abs( front - back ) ); @@ -159,11 +125,11 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, } } - value += split->priority; // prioritize hints higher + value += split.priority; // prioritize hints higher if ( value > bestValue ) { bestValue = value; - bestSplit = split; + bestSplit = &split; //frontC=front; //backC=back; //splitsC=splits; @@ -184,8 +150,8 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, #if 0 if ( bestSplit->compileFlags & C_DETAIL ) { - for ( split = list; split; split = split->next ) - if ( !( split->compileFlags & C_DETAIL ) ) { + for ( const face_t& split : list ) + if ( !( split.compileFlags & C_DETAIL ) ) { Sys_FPrintf( SYS_ERR, "DON'T DO SUCH SPLITS (1)\n" ); } } @@ -201,44 +167,19 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, -/* - CountFaceList() - counts bsp faces in the linked list - */ - -int CountFaceList( face_t *list ){ - int c; - - - c = 0; - for ( ; list != NULL; list = list->next ) - c++; - return c; -} - - - /* BuildFaceTree_r() recursively builds the bsp, splitting on face planes */ -void BuildFaceTree_r( node_t *node, face_t *list ){ - face_t *split; - face_t *next; - face_t *newFace; - face_t *childLists[2]; - winding_t *frontWinding, *backWinding; - int i; +void BuildFaceTree_r( node_t *node, facelist_t& list ){ + facelist_t childLists[2]; int splitPlaneNum, compileFlags; #if 0 bool isstruct = false; #endif - /* count faces left */ - i = CountFaceList( list ); - /* select the best split plane */ SelectSplitPlaneNum( node, list, &splitPlaneNum, &compileFlags ); @@ -255,72 +196,68 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ node->compileFlags = compileFlags; node->has_structural_children = !( compileFlags & C_DETAIL ) && !node->opaque; const plane_t& plane = mapplanes[ splitPlaneNum ]; - childLists[0] = NULL; - childLists[1] = NULL; - for ( split = list; split; split = next ) + while ( !list.empty() ) { - /* set next */ - next = split->next; - + const face_t& split = list.front(); /* don't split by identical plane */ - if ( split->planenum == node->planenum ) { - FreeBspFace( split ); + if ( split.planenum == node->planenum ) { + list.pop_front(); continue; } #if 0 - if ( !( split->compileFlags & C_DETAIL ) ) { + if ( !( split.compileFlags & C_DETAIL ) ) { isstruct = true; } #endif /* determine which side the face falls on */ - const EPlaneSide side = WindingOnPlaneSide( *split->w, plane.plane ); + const EPlaneSide side = WindingOnPlaneSide( split.w, plane.plane ); /* switch on side */ if ( side == eSideCross ) { - ClipWindingEpsilonStrict( *split->w, plane.plane, CLIP_EPSILON * 2, + winding_t *frontWinding, *backWinding; + ClipWindingEpsilonStrict( split.w, plane.plane, CLIP_EPSILON * 2, frontWinding, backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */ if ( frontWinding ) { - newFace = AllocBspFace(); - newFace->w = frontWinding; - newFace->next = childLists[0]; - newFace->planenum = split->planenum; - newFace->priority = split->priority; - newFace->compileFlags = split->compileFlags; - childLists[0] = newFace; + face_t& newFace = childLists[0].emplace_front(); + newFace.w.swap( *frontWinding ); + FreeWinding( frontWinding ); + newFace.planenum = split.planenum; + newFace.priority = split.priority; + newFace.compileFlags = split.compileFlags; } if ( backWinding ) { - newFace = AllocBspFace(); - newFace->w = backWinding; - newFace->next = childLists[1]; - newFace->planenum = split->planenum; - newFace->priority = split->priority; - newFace->compileFlags = split->compileFlags; - childLists[1] = newFace; + face_t& newFace = childLists[1].emplace_front(); + newFace.w.swap( *backWinding ); + FreeWinding( backWinding ); + newFace.planenum = split.planenum; + newFace.priority = split.priority; + newFace.compileFlags = split.compileFlags; } - FreeBspFace( split ); + list.pop_front(); } else if ( side == eSideFront ) { - split->next = childLists[0]; - childLists[0] = split; + childLists[0].splice_after( childLists[0].cbefore_begin(), list, list.cbefore_begin() ); } else if ( side == eSideBack ) { - split->next = childLists[1]; - childLists[1] = split; + childLists[1].splice_after( childLists[1].cbefore_begin(), list, list.cbefore_begin() ); + } + else{ // eSideOn + list.pop_front(); } } // recursively process children - for ( i = 0 ; i < 2 ; i++ ) { + for ( int i = 0; i < 2; i++ ) { node->children[i] = AllocNode(); node->children[i]->parent = node; node->children[i]->minmax = node->minmax; } - for ( i = 0 ; i < 3 ; i++ ) { + for ( int i = 0; i < 3; i++ ) { if ( plane.normal()[i] == 1 ) { node->children[0]->minmax.mins[i] = plane.dist(); node->children[1]->minmax.maxs[i] = plane.dist(); @@ -339,7 +276,7 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ } #endif - for ( i = 0 ; i < 2 ; i++ ) { + for ( int i = 0; i < 2; i++ ) { BuildFaceTree_r( node->children[i], childLists[i] ); node->has_structural_children |= node->children[i]->has_structural_children; } @@ -362,15 +299,15 @@ void BuildFaceTree_r( node_t *node, face_t *list ){ List will be freed before returning ================ */ -tree_t *FaceBSP( face_t *list ) { +tree_t *FaceBSP( facelist_t& list ) { Sys_FPrintf( SYS_VRB, "--- FaceBSP ---\n" ); tree_t *tree = AllocTree(); int count = 0; - for ( const face_t *face = list; face != NULL; face = face->next ) + for ( const face_t& face : list ) { - WindingExtendBounds( *face->w, tree->minmax ); + WindingExtendBounds( face.w, tree->minmax ); count++; } Sys_FPrintf( SYS_VRB, "%9d faces\n", count ); @@ -398,62 +335,52 @@ tree_t *FaceBSP( face_t *list ) { get structural brush faces */ -face_t *MakeStructuralBSPFaceList( brush_t *list ){ - brush_t *b; - int i; - side_t *s; - winding_t *w; - face_t *f, *flist; +facelist_t MakeStructuralBSPFaceList( const brush_t *list ){ + facelist_t flist; - - flist = NULL; - for ( b = list; b != NULL; b = b->next ) + for ( const brush_t *b = list; b != NULL; b = b->next ) { if ( !deepBSP && b->detail ) { continue; } - for ( i = 0; i < b->numsides; i++ ) + for ( int i = 0; i < b->numsides; i++ ) { /* get side and winding */ - s = &b->sides[ i ]; - w = s->winding; + const side_t& s = b->sides[ i ]; + const winding_t *w = s.winding; if ( w == NULL ) { continue; } /* ydnar: skip certain faces */ - if ( s->compileFlags & C_SKIP ) { + if ( s.compileFlags & C_SKIP ) { continue; } /* allocate a face */ - f = AllocBspFace(); - f->w = CopyWinding( w ); - f->planenum = s->planenum & ~1; - f->compileFlags = s->compileFlags; /* ydnar */ + face_t& f = flist.emplace_front(); + f.w = *w; + f.planenum = s.planenum & ~1; + f.compileFlags = s.compileFlags; /* ydnar */ if ( b->detail ) { - f->compileFlags |= C_DETAIL; + f.compileFlags |= C_DETAIL; } /* ydnar: set priority */ - f->priority = 0; - if ( f->compileFlags & C_HINT ) { - f->priority += HINT_PRIORITY; + f.priority = 0; + if ( f.compileFlags & C_HINT ) { + f.priority += HINT_PRIORITY; } - if ( f->compileFlags & C_ANTIPORTAL ) { - f->priority += ANTIPORTAL_PRIORITY; + if ( f.compileFlags & C_ANTIPORTAL ) { + f.priority += ANTIPORTAL_PRIORITY; } - if ( f->compileFlags & C_AREAPORTAL ) { - f->priority += AREAPORTAL_PRIORITY; + if ( f.compileFlags & C_AREAPORTAL ) { + f.priority += AREAPORTAL_PRIORITY; } - if ( f->compileFlags & C_DETAIL ) { - f->priority += DETAIL_PRIORITY; + if ( f.compileFlags & C_DETAIL ) { + f.priority += DETAIL_PRIORITY; } - - /* get next face */ - f->next = flist; - flist = f; } } @@ -467,62 +394,52 @@ face_t *MakeStructuralBSPFaceList( brush_t *list ){ get visible brush faces */ -face_t *MakeVisibleBSPFaceList( brush_t *list ){ - brush_t *b; - int i; - side_t *s; - winding_t *w; - face_t *f, *flist; +facelist_t MakeVisibleBSPFaceList( const brush_t *list ){ + facelist_t flist; - - flist = NULL; - for ( b = list; b != NULL; b = b->next ) + for ( const brush_t *b = list; b != NULL; b = b->next ) { if ( !deepBSP && b->detail ) { continue; } - for ( i = 0; i < b->numsides; i++ ) + for ( int i = 0; i < b->numsides; i++ ) { /* get side and winding */ - s = &b->sides[ i ]; - w = s->visibleHull; + const side_t& s = b->sides[ i ]; + const winding_t *w = s.visibleHull; if ( w == NULL ) { continue; } /* ydnar: skip certain faces */ - if ( s->compileFlags & C_SKIP ) { + if ( s.compileFlags & C_SKIP ) { continue; } /* allocate a face */ - f = AllocBspFace(); - f->w = CopyWinding( w ); - f->planenum = s->planenum & ~1; - f->compileFlags = s->compileFlags; /* ydnar */ + face_t& f = flist.emplace_front(); + f.w = *w; + f.planenum = s.planenum & ~1; + f.compileFlags = s.compileFlags; /* ydnar */ if ( b->detail ) { - f->compileFlags |= C_DETAIL; + f.compileFlags |= C_DETAIL; } /* ydnar: set priority */ - f->priority = 0; - if ( f->compileFlags & C_HINT ) { - f->priority += HINT_PRIORITY; + f.priority = 0; + if ( f.compileFlags & C_HINT ) { + f.priority += HINT_PRIORITY; } - if ( f->compileFlags & C_ANTIPORTAL ) { - f->priority += ANTIPORTAL_PRIORITY; + if ( f.compileFlags & C_ANTIPORTAL ) { + f.priority += ANTIPORTAL_PRIORITY; } - if ( f->compileFlags & C_AREAPORTAL ) { - f->priority += AREAPORTAL_PRIORITY; + if ( f.compileFlags & C_AREAPORTAL ) { + f.priority += AREAPORTAL_PRIORITY; } - if ( f->compileFlags & C_DETAIL ) { - f->priority += DETAIL_PRIORITY; + if ( f.compileFlags & C_DETAIL ) { + f.priority += DETAIL_PRIORITY; } - - /* get next face */ - f->next = flist; - flist = f; } } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 41833330..d8339d48 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -85,6 +85,7 @@ #include "stream/stringstream.h" #include "bitflags.h" #include +#include #include "qmath.h" #include @@ -699,13 +700,13 @@ struct shaderInfo_t struct face_t { - face_t *next; int planenum; int priority; //bool checked; int compileFlags; - winding_t *w; + winding_t w; }; +using facelist_t = std::forward_list; struct plane_t @@ -1620,7 +1621,6 @@ enum class EFloodEntities EFloodEntities FloodEntities( tree_t *tree ); void FillOutside( node_t *headnode ); void FloodAreas( tree_t *tree ); -face_t *VisibleFaces( entity_t *e, tree_t *tree ); void FreePortal( portal_t *p ); void MakeTreePortals( tree_t *tree ); @@ -1677,9 +1677,9 @@ void CreateMapFogs( void ); /* facebsp.c */ -face_t *MakeStructuralBSPFaceList( brush_t *list ); -face_t *MakeVisibleBSPFaceList( brush_t *list ); -tree_t *FaceBSP( face_t *list ); +facelist_t MakeStructuralBSPFaceList( const brush_t *list ); +facelist_t MakeVisibleBSPFaceList( const brush_t *list ); +tree_t *FaceBSP( facelist_t& list ); /* model.c */