From: Rudolf Polzer Date: Tue, 14 Feb 2012 10:35:59 +0000 (+0100) Subject: another experimental change: better handle leaky maps X-Git-Tag: xonotic-v0.6.0~10^2~2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=bca4840507fc1d66a34d7c253b146a08d49e02c0;p=xonotic%2Fnetradiant.git another experimental change: better handle leaky maps --- diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index 4f4c7172..a0ddafa4 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -266,6 +266,7 @@ void ProcessWorldModel( void ) xmlNodePtr polyline, leaknode; char level[ 2 ], shader[ 1024 ]; const char *value; + int leakStatus; /* sets integer blockSize from worldspawn "_blocksize" key if it exists */ value = ValueForKey( &entities[ 0 ], "_blocksize" ); @@ -314,28 +315,19 @@ void ProcessWorldModel( void ) FilterStructuralBrushesIntoTree( e, tree ); /* see if the bsp is completely enclosed */ - if( FloodEntities( tree ) || ignoreLeaks ) - { - /* rebuild a better bsp tree using only the sides that are visible from the inside */ - FillOutside( tree->headnode ); + leakStatus = FloodEntities(tree); + if (ignoreLeaks) + if(leakStatus == FLOODENTITIES_LEAKED) + leakStatus = FLOODENTITIES_GOOD; - /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */ - ClipSidesIntoTree( e, tree ); - - /* build a visible face tree */ - faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes ); - FreeTree( tree ); - tree = FaceBSP( faces ); - MakeTreePortals( tree ); - FilterStructuralBrushesIntoTree( e, tree ); + if ( leakStatus == FLOODENTITIES_GOOD ) + { leaked = qfalse; - - /* ydnar: flood again for skybox */ - if( skyboxPresent ) - FloodEntities( tree ); } else { + leaked = qtrue; + Sys_FPrintf( SYS_NOXML, "**********************\n" ); Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" ); Sys_FPrintf( SYS_NOXML, "**********************\n" ); @@ -352,10 +344,26 @@ void ProcessWorldModel( void ) Sys_Printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n"); exit( 0 ); } - leaked = qtrue; - + } + + if(leakStatus != FLOODENTITIES_EMPTY) /* if no entities exist, this would accidentally the whole map, and that IS bad */ + { + /* rebuild a better bsp tree using only the sides that are visible from the inside */ + FillOutside( tree->headnode ); + /* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */ ClipSidesIntoTree( e, tree ); + + /* build a visible face tree (same thing as the initial bsp tree but after reducing the faces) */ + faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes ); + FreeTree( tree ); + tree = FaceBSP( faces ); + MakeTreePortals( tree ); + FilterStructuralBrushesIntoTree( e, tree ); + + /* ydnar: flood again for skybox */ + if( skyboxPresent ) + FloodEntities( tree ); } /* save out information for visibility processing */ diff --git a/tools/quake3/q3map2/portals.c b/tools/quake3/q3map2/portals.c index e16c12c7..944b6d82 100644 --- a/tools/quake3/q3map2/portals.c +++ b/tools/quake3/q3map2/portals.c @@ -644,7 +644,7 @@ Marks all nodes that can be reached by entites ============= */ -qboolean FloodEntities( tree_t *tree ) +int FloodEntities( tree_t *tree ) { int i, s; vec3_t origin, offset, scale, angles; @@ -739,11 +739,17 @@ qboolean FloodEntities( tree_t *tree ) Sys_FPrintf( SYS_VRB, "%9d flooded leafs\n", c_floodedleafs ); if( !inside ) + { Sys_FPrintf( SYS_VRB, "no entities in open -- no filling\n" ); - else if( tree->outside_node.occupied ) - Sys_FPrintf( SYS_VRB, "entity reached from outside -- no filling\n" ); + return FLOODENTITIES_EMPTY; + } + if( tree->outside_node.occupied ) + { + Sys_FPrintf( SYS_VRB, "entity reached from outside -- leak detected\n" ); + return FLOODENTITIES_LEAKED; + } - return (qboolean) (inside && !tree->outside_node.occupied); + return FLOODENTITIES_GOOD; } /* diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 89dbe3c9..abde6c85 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1599,7 +1599,10 @@ void SplitNodePortals( node_t *node ); qboolean PortalPassable( portal_t *p ); -qboolean FloodEntities( tree_t *tree ); +#define FLOODENTITIES_LEAKED 1 +#define FLOODENTITIES_GOOD 0 +#define FLOODENTITIES_EMPTY -1 +int FloodEntities( tree_t *tree ); void FillOutside( node_t *headnode); void FloodAreas( tree_t *tree); face_t *VisibleFaces( entity_t *e, tree_t *tree );