another experimental change: better handle leaky maps
authorRudolf Polzer <divverent@xonotic.org>
Tue, 14 Feb 2012 10:35:59 +0000 (11:35 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Tue, 14 Feb 2012 10:35:59 +0000 (11:35 +0100)
tools/quake3/q3map2/bsp.c
tools/quake3/q3map2/portals.c
tools/quake3/q3map2/q3map2.h

index 4f4c717..a0ddafa 100644 (file)
@@ -266,6 +266,7 @@ void ProcessWorldModel( void )
        xmlNodePtr      polyline, leaknode;
        char            level[ 2 ], shader[ 1024 ];
        const char      *value;
        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" );
        
        /* 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 */
        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;
                leaked = qfalse;
-               
-               /* ydnar: flood again for skybox */
-               if( skyboxPresent )
-                       FloodEntities( tree );
        }
        else
        {
        }
        else
        {
+               leaked = qtrue;
+
                Sys_FPrintf( SYS_NOXML, "**********************\n" );
                Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" );
                Sys_FPrintf( SYS_NOXML, "**********************\n" );
                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 );
                }
                        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 );
                /* 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 */
        }
        
        /* save out information for visibility processing */
index e16c12c..944b6d8 100644 (file)
@@ -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;
 {
        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, "%9d flooded leafs\n", c_floodedleafs );
        
        if( !inside )
+       {
                Sys_FPrintf( SYS_VRB, "no entities in open -- no filling\n" );
                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;
 }
 
 /*
 }
 
 /*
index 89dbe3c..abde6c8 100644 (file)
@@ -1599,7 +1599,10 @@ void                                             SplitNodePortals( node_t *node );
 
 qboolean                                       PortalPassable( portal_t *p );
 
 
 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 );
 void                                           FillOutside( node_t *headnode);
 void                                           FloodAreas( tree_t *tree);
 face_t                                         *VisibleFaces( entity_t *e, tree_t *tree );