using facelist_t = std::forward_list<face_t>

This commit is contained in:
Garux 2021-08-01 22:50:35 +03:00
parent c3041cc2f8
commit e8996d0857
4 changed files with 107 additions and 190 deletions

View File

@ -285,7 +285,7 @@ static void FixBrushSides( entity_t *e ){
void ProcessWorldModel( void ){ void ProcessWorldModel( void ){
entity_t *e; entity_t *e;
tree_t *tree; tree_t *tree;
face_t *faces; facelist_t faces;
xmlNodePtr polyline, leaknode; xmlNodePtr polyline, leaknode;
char level[ 2 ]; char level[ 2 ];
const char *value; const char *value;

View File

@ -725,7 +725,7 @@ void PseudoCompileBSP( bool need_tree ){
int models; int models;
char modelValue[16]; char modelValue[16];
entity_t *entity; entity_t *entity;
face_t *faces; facelist_t faces;
tree_t *tree; tree_t *tree;
node_t *node; node_t *node;
brush_t *brush; brush_t *brush;

View File

@ -36,47 +36,13 @@
int c_faceLeafs; 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() SelectSplitPlaneNum()
finds the best split plane for this node finds the best split plane for this node
*/ */
static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum, int *compileFlags ){ static void SelectSplitPlaneNum( node_t *node, const facelist_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;
//int frontC,backC,splitsC,facingC; //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 */ /* 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 */ /* 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 ) { if ( blockSize[ i ] <= 0 ) {
continue; 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 ) { if ( node->minmax.maxs[ i ] > dist ) {
planenum = FindFloatPlane( g_vector3_axes[i], dist, 0, NULL ); *splitPlaneNum = FindFloatPlane( g_vector3_axes[i], dist, 0, NULL );
*splitPlaneNum = planenum;
return; return;
} }
} }
/* pick one of the face planes */ /* pick one of the face planes */
bestValue = -99999; int bestValue = -99999;
bestSplit = list; const face_t *bestSplit = nullptr;
// div0: this check causes detail/structural mixes // div0: this check causes detail/structural mixes
//for( split = list; split; split = split->next ) //for( face_t& split : list )
// split->checked = false; // split.checked = false;
for ( split = list; split; split = split->next ) for ( const face_t& split : list )
{ {
//if ( split->checked ) //if ( split->checked )
// continue; // continue;
const plane_t& plane = mapplanes[ split->planenum ]; const plane_t& plane = mapplanes[ split.planenum ];
splits = 0; int splits = 0;
facing = 0; int facing = 0;
front = 0; int front = 0;
back = 0; int back = 0;
for ( check = list ; check ; check = check->next ) { for ( const face_t& check : list ) {
if ( check->planenum == split->planenum ) { if ( check.planenum == split.planenum ) {
facing++; facing++;
//check->checked = true; // won't need to test this plane again //check->checked = true; // won't need to test this plane again
continue; continue;
} }
const EPlaneSide side = WindingOnPlaneSide( *check->w, plane.plane ); const EPlaneSide side = WindingOnPlaneSide( check.w, plane.plane );
if ( side == eSideCross ) { if ( side == eSideCross ) {
splits++; splits++;
} }
@ -138,11 +103,12 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
} }
} }
int value;
if ( bspAlternateSplitWeights ) { if ( bspAlternateSplitWeights ) {
// from 27 // from 27
//Bigger is better //Bigger is better
sizeBias = WindingArea( *split->w ); const float sizeBias = WindingArea( split.w );
//Base score = 20000 perfectly balanced //Base score = 20000 perfectly balanced
value = 20000 - ( abs( front - back ) ); 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 ) { if ( value > bestValue ) {
bestValue = value; bestValue = value;
bestSplit = split; bestSplit = &split;
//frontC=front; //frontC=front;
//backC=back; //backC=back;
//splitsC=splits; //splitsC=splits;
@ -184,8 +150,8 @@ static void SelectSplitPlaneNum( node_t *node, face_t *list, int *splitPlaneNum,
#if 0 #if 0
if ( bestSplit->compileFlags & C_DETAIL ) { if ( bestSplit->compileFlags & C_DETAIL ) {
for ( split = list; split; split = split->next ) for ( const face_t& split : list )
if ( !( split->compileFlags & C_DETAIL ) ) { if ( !( split.compileFlags & C_DETAIL ) ) {
Sys_FPrintf( SYS_ERR, "DON'T DO SUCH SPLITS (1)\n" ); 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() BuildFaceTree_r()
recursively builds the bsp, splitting on face planes recursively builds the bsp, splitting on face planes
*/ */
void BuildFaceTree_r( node_t *node, face_t *list ){ void BuildFaceTree_r( node_t *node, facelist_t& list ){
face_t *split; facelist_t childLists[2];
face_t *next;
face_t *newFace;
face_t *childLists[2];
winding_t *frontWinding, *backWinding;
int i;
int splitPlaneNum, compileFlags; int splitPlaneNum, compileFlags;
#if 0 #if 0
bool isstruct = false; bool isstruct = false;
#endif #endif
/* count faces left */
i = CountFaceList( list );
/* select the best split plane */ /* select the best split plane */
SelectSplitPlaneNum( node, list, &splitPlaneNum, &compileFlags ); SelectSplitPlaneNum( node, list, &splitPlaneNum, &compileFlags );
@ -255,72 +196,68 @@ void BuildFaceTree_r( node_t *node, face_t *list ){
node->compileFlags = compileFlags; node->compileFlags = compileFlags;
node->has_structural_children = !( compileFlags & C_DETAIL ) && !node->opaque; node->has_structural_children = !( compileFlags & C_DETAIL ) && !node->opaque;
const plane_t& plane = mapplanes[ splitPlaneNum ]; const plane_t& plane = mapplanes[ splitPlaneNum ];
childLists[0] = NULL;
childLists[1] = NULL;
for ( split = list; split; split = next ) while ( !list.empty() )
{ {
/* set next */ const face_t& split = list.front();
next = split->next;
/* don't split by identical plane */ /* don't split by identical plane */
if ( split->planenum == node->planenum ) { if ( split.planenum == node->planenum ) {
FreeBspFace( split ); list.pop_front();
continue; continue;
} }
#if 0 #if 0
if ( !( split->compileFlags & C_DETAIL ) ) { if ( !( split.compileFlags & C_DETAIL ) ) {
isstruct = true; isstruct = true;
} }
#endif #endif
/* determine which side the face falls on */ /* 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 */ /* switch on side */
if ( side == eSideCross ) { 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 */ frontWinding, backWinding ); /* strict; if no winding is left, we have a "virtually identical" plane and don't want to split by it */
if ( frontWinding ) { if ( frontWinding ) {
newFace = AllocBspFace(); face_t& newFace = childLists[0].emplace_front();
newFace->w = frontWinding; newFace.w.swap( *frontWinding );
newFace->next = childLists[0]; FreeWinding( frontWinding );
newFace->planenum = split->planenum; newFace.planenum = split.planenum;
newFace->priority = split->priority; newFace.priority = split.priority;
newFace->compileFlags = split->compileFlags; newFace.compileFlags = split.compileFlags;
childLists[0] = newFace;
} }
if ( backWinding ) { if ( backWinding ) {
newFace = AllocBspFace(); face_t& newFace = childLists[1].emplace_front();
newFace->w = backWinding; newFace.w.swap( *backWinding );
newFace->next = childLists[1]; FreeWinding( backWinding );
newFace->planenum = split->planenum; newFace.planenum = split.planenum;
newFace->priority = split->priority; newFace.priority = split.priority;
newFace->compileFlags = split->compileFlags; newFace.compileFlags = split.compileFlags;
childLists[1] = newFace;
} }
FreeBspFace( split ); list.pop_front();
} }
else if ( side == eSideFront ) { else if ( side == eSideFront ) {
split->next = childLists[0]; childLists[0].splice_after( childLists[0].cbefore_begin(), list, list.cbefore_begin() );
childLists[0] = split;
} }
else if ( side == eSideBack ) { else if ( side == eSideBack ) {
split->next = childLists[1]; childLists[1].splice_after( childLists[1].cbefore_begin(), list, list.cbefore_begin() );
childLists[1] = split; }
else{ // eSideOn
list.pop_front();
} }
} }
// recursively process children // recursively process children
for ( i = 0 ; i < 2 ; i++ ) { for ( int i = 0; i < 2; i++ ) {
node->children[i] = AllocNode(); node->children[i] = AllocNode();
node->children[i]->parent = node; node->children[i]->parent = node;
node->children[i]->minmax = node->minmax; node->children[i]->minmax = node->minmax;
} }
for ( i = 0 ; i < 3 ; i++ ) { for ( int i = 0; i < 3; i++ ) {
if ( plane.normal()[i] == 1 ) { if ( plane.normal()[i] == 1 ) {
node->children[0]->minmax.mins[i] = plane.dist(); node->children[0]->minmax.mins[i] = plane.dist();
node->children[1]->minmax.maxs[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 #endif
for ( i = 0 ; i < 2 ; i++ ) { for ( int i = 0; i < 2; i++ ) {
BuildFaceTree_r( node->children[i], childLists[i] ); BuildFaceTree_r( node->children[i], childLists[i] );
node->has_structural_children |= node->children[i]->has_structural_children; 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 List will be freed before returning
================ ================
*/ */
tree_t *FaceBSP( face_t *list ) { tree_t *FaceBSP( facelist_t& list ) {
Sys_FPrintf( SYS_VRB, "--- FaceBSP ---\n" ); Sys_FPrintf( SYS_VRB, "--- FaceBSP ---\n" );
tree_t *tree = AllocTree(); tree_t *tree = AllocTree();
int count = 0; 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++; count++;
} }
Sys_FPrintf( SYS_VRB, "%9d faces\n", count ); Sys_FPrintf( SYS_VRB, "%9d faces\n", count );
@ -398,62 +335,52 @@ tree_t *FaceBSP( face_t *list ) {
get structural brush faces get structural brush faces
*/ */
face_t *MakeStructuralBSPFaceList( brush_t *list ){ facelist_t MakeStructuralBSPFaceList( const brush_t *list ){
brush_t *b; facelist_t flist;
int i;
side_t *s;
winding_t *w;
face_t *f, *flist;
for ( const brush_t *b = list; b != NULL; b = b->next )
flist = NULL;
for ( b = list; b != NULL; b = b->next )
{ {
if ( !deepBSP && b->detail ) { if ( !deepBSP && b->detail ) {
continue; continue;
} }
for ( i = 0; i < b->numsides; i++ ) for ( int i = 0; i < b->numsides; i++ )
{ {
/* get side and winding */ /* get side and winding */
s = &b->sides[ i ]; const side_t& s = b->sides[ i ];
w = s->winding; const winding_t *w = s.winding;
if ( w == NULL ) { if ( w == NULL ) {
continue; continue;
} }
/* ydnar: skip certain faces */ /* ydnar: skip certain faces */
if ( s->compileFlags & C_SKIP ) { if ( s.compileFlags & C_SKIP ) {
continue; continue;
} }
/* allocate a face */ /* allocate a face */
f = AllocBspFace(); face_t& f = flist.emplace_front();
f->w = CopyWinding( w ); f.w = *w;
f->planenum = s->planenum & ~1; f.planenum = s.planenum & ~1;
f->compileFlags = s->compileFlags; /* ydnar */ f.compileFlags = s.compileFlags; /* ydnar */
if ( b->detail ) { if ( b->detail ) {
f->compileFlags |= C_DETAIL; f.compileFlags |= C_DETAIL;
} }
/* ydnar: set priority */ /* ydnar: set priority */
f->priority = 0; f.priority = 0;
if ( f->compileFlags & C_HINT ) { if ( f.compileFlags & C_HINT ) {
f->priority += HINT_PRIORITY; f.priority += HINT_PRIORITY;
} }
if ( f->compileFlags & C_ANTIPORTAL ) { if ( f.compileFlags & C_ANTIPORTAL ) {
f->priority += ANTIPORTAL_PRIORITY; f.priority += ANTIPORTAL_PRIORITY;
} }
if ( f->compileFlags & C_AREAPORTAL ) { if ( f.compileFlags & C_AREAPORTAL ) {
f->priority += AREAPORTAL_PRIORITY; f.priority += AREAPORTAL_PRIORITY;
} }
if ( f->compileFlags & C_DETAIL ) { if ( f.compileFlags & C_DETAIL ) {
f->priority += DETAIL_PRIORITY; 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 get visible brush faces
*/ */
face_t *MakeVisibleBSPFaceList( brush_t *list ){ facelist_t MakeVisibleBSPFaceList( const brush_t *list ){
brush_t *b; facelist_t flist;
int i;
side_t *s;
winding_t *w;
face_t *f, *flist;
for ( const brush_t *b = list; b != NULL; b = b->next )
flist = NULL;
for ( b = list; b != NULL; b = b->next )
{ {
if ( !deepBSP && b->detail ) { if ( !deepBSP && b->detail ) {
continue; continue;
} }
for ( i = 0; i < b->numsides; i++ ) for ( int i = 0; i < b->numsides; i++ )
{ {
/* get side and winding */ /* get side and winding */
s = &b->sides[ i ]; const side_t& s = b->sides[ i ];
w = s->visibleHull; const winding_t *w = s.visibleHull;
if ( w == NULL ) { if ( w == NULL ) {
continue; continue;
} }
/* ydnar: skip certain faces */ /* ydnar: skip certain faces */
if ( s->compileFlags & C_SKIP ) { if ( s.compileFlags & C_SKIP ) {
continue; continue;
} }
/* allocate a face */ /* allocate a face */
f = AllocBspFace(); face_t& f = flist.emplace_front();
f->w = CopyWinding( w ); f.w = *w;
f->planenum = s->planenum & ~1; f.planenum = s.planenum & ~1;
f->compileFlags = s->compileFlags; /* ydnar */ f.compileFlags = s.compileFlags; /* ydnar */
if ( b->detail ) { if ( b->detail ) {
f->compileFlags |= C_DETAIL; f.compileFlags |= C_DETAIL;
} }
/* ydnar: set priority */ /* ydnar: set priority */
f->priority = 0; f.priority = 0;
if ( f->compileFlags & C_HINT ) { if ( f.compileFlags & C_HINT ) {
f->priority += HINT_PRIORITY; f.priority += HINT_PRIORITY;
} }
if ( f->compileFlags & C_ANTIPORTAL ) { if ( f.compileFlags & C_ANTIPORTAL ) {
f->priority += ANTIPORTAL_PRIORITY; f.priority += ANTIPORTAL_PRIORITY;
} }
if ( f->compileFlags & C_AREAPORTAL ) { if ( f.compileFlags & C_AREAPORTAL ) {
f->priority += AREAPORTAL_PRIORITY; f.priority += AREAPORTAL_PRIORITY;
} }
if ( f->compileFlags & C_DETAIL ) { if ( f.compileFlags & C_DETAIL ) {
f->priority += DETAIL_PRIORITY; f.priority += DETAIL_PRIORITY;
} }
/* get next face */
f->next = flist;
flist = f;
} }
} }

View File

@ -85,6 +85,7 @@
#include "stream/stringstream.h" #include "stream/stringstream.h"
#include "bitflags.h" #include "bitflags.h"
#include <list> #include <list>
#include <forward_list>
#include "qmath.h" #include "qmath.h"
#include <stddef.h> #include <stddef.h>
@ -699,13 +700,13 @@ struct shaderInfo_t
struct face_t struct face_t
{ {
face_t *next;
int planenum; int planenum;
int priority; int priority;
//bool checked; //bool checked;
int compileFlags; int compileFlags;
winding_t *w; winding_t w;
}; };
using facelist_t = std::forward_list<face_t>;
struct plane_t struct plane_t
@ -1620,7 +1621,6 @@ enum class EFloodEntities
EFloodEntities FloodEntities( tree_t *tree ); EFloodEntities FloodEntities( tree_t *tree );
void FillOutside( node_t *headnode ); void FillOutside( node_t *headnode );
void FloodAreas( tree_t *tree ); void FloodAreas( tree_t *tree );
face_t *VisibleFaces( entity_t *e, tree_t *tree );
void FreePortal( portal_t *p ); void FreePortal( portal_t *p );
void MakeTreePortals( tree_t *tree ); void MakeTreePortals( tree_t *tree );
@ -1677,9 +1677,9 @@ void CreateMapFogs( void );
/* facebsp.c */ /* facebsp.c */
face_t *MakeStructuralBSPFaceList( brush_t *list ); facelist_t MakeStructuralBSPFaceList( const brush_t *list );
face_t *MakeVisibleBSPFaceList( brush_t *list ); facelist_t MakeVisibleBSPFaceList( const brush_t *list );
tree_t *FaceBSP( face_t *list ); tree_t *FaceBSP( facelist_t& list );
/* model.c */ /* model.c */