Merge remote-tracking branch 'origin/divVerent/leak-fix'
This commit is contained in:
commit
e8f94f12dd
|
|
@ -266,6 +266,7 @@ void ProcessWorldModel( void )
|
||||||
xmlNodePtr polyline, leaknode;
|
xmlNodePtr polyline, leaknode;
|
||||||
char level[ 2 ], shader[ 1024 ];
|
char level[ 2 ], shader[ 1024 ];
|
||||||
const char *value;
|
const char *value;
|
||||||
|
int leakStatus;
|
||||||
|
|
||||||
/* sets integer blockSize from worldspawn "_blocksize" key if it exists */
|
/* sets integer blockSize from worldspawn "_blocksize" key if it exists */
|
||||||
value = ValueForKey( &entities[ 0 ], "_blocksize" );
|
value = ValueForKey( &entities[ 0 ], "_blocksize" );
|
||||||
|
|
@ -314,28 +315,19 @@ void ProcessWorldModel( void )
|
||||||
FilterStructuralBrushesIntoTree( e, tree );
|
FilterStructuralBrushesIntoTree( e, tree );
|
||||||
|
|
||||||
/* see if the bsp is completely enclosed */
|
/* see if the bsp is completely enclosed */
|
||||||
if( FloodEntities( tree ) || ignoreLeaks )
|
leakStatus = FloodEntities(tree);
|
||||||
|
if (ignoreLeaks)
|
||||||
|
if(leakStatus == FLOODENTITIES_LEAKED)
|
||||||
|
leakStatus = FLOODENTITIES_GOOD;
|
||||||
|
|
||||||
|
if ( leakStatus == FLOODENTITIES_GOOD )
|
||||||
{
|
{
|
||||||
/* 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 */
|
|
||||||
faces = MakeVisibleBSPFaceList( entities[ 0 ].brushes );
|
|
||||||
FreeTree( tree );
|
|
||||||
tree = FaceBSP( faces );
|
|
||||||
MakeTreePortals( tree );
|
|
||||||
FilterStructuralBrushesIntoTree( e, tree );
|
|
||||||
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, "**********************\n" );
|
||||||
Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" );
|
Sys_FPrintf( SYS_NOXML, "******* leaked *******\n" );
|
||||||
Sys_FPrintf( SYS_NOXML, "**********************\n" );
|
Sys_FPrintf( SYS_NOXML, "**********************\n" );
|
||||||
|
|
@ -352,10 +344,26 @@ void ProcessWorldModel( void )
|
||||||
Sys_Printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n");
|
Sys_Printf ("--- MAP LEAKED, ABORTING LEAKTEST ---\n");
|
||||||
exit( 0 );
|
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 */
|
/* chop the sides to the convex hull of their visible fragments, giving us the smallest polygons */
|
||||||
ClipSidesIntoTree( e, tree );
|
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 */
|
||||||
|
|
|
||||||
|
|
@ -586,9 +586,26 @@ void FloodPortals_r( node_t *node, int dist, qboolean skybox )
|
||||||
if( skybox )
|
if( skybox )
|
||||||
node->skybox = skybox;
|
node->skybox = skybox;
|
||||||
|
|
||||||
if( node->occupied || node->opaque )
|
if( node->opaque)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if( node->occupied )
|
||||||
|
{
|
||||||
|
if( node->occupied > dist )
|
||||||
|
{
|
||||||
|
/* reduce distance! */
|
||||||
|
/* for better leak line */
|
||||||
|
/* note: node->occupied will also be true for all further nodes, then */
|
||||||
|
node->occupied = dist;
|
||||||
|
for( p = node->portals; p; p = p->next[ s ] )
|
||||||
|
{
|
||||||
|
s = (p->nodes[ 1 ] == node);
|
||||||
|
FloodPortals_r( p->nodes[ !s ], dist + 1, skybox );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
c_floodedleafs++;
|
c_floodedleafs++;
|
||||||
node->occupied = dist;
|
node->occupied = dist;
|
||||||
|
|
||||||
|
|
@ -644,14 +661,15 @@ Marks all nodes that can be reached by entites
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
|
|
||||||
qboolean FloodEntities( tree_t *tree )
|
int FloodEntities( tree_t *tree )
|
||||||
{
|
{
|
||||||
int i, s;
|
int i, s;
|
||||||
vec3_t origin, offset, scale, angles;
|
vec3_t origin, offset, scale, angles;
|
||||||
qboolean r, inside, tripped, skybox;
|
qboolean r, inside, skybox;
|
||||||
node_t *headnode;
|
node_t *headnode;
|
||||||
entity_t *e;
|
entity_t *e, *tripped;
|
||||||
const char *value;
|
const char *value;
|
||||||
|
int tripcount;
|
||||||
|
|
||||||
|
|
||||||
headnode = tree->headnode;
|
headnode = tree->headnode;
|
||||||
|
|
@ -729,21 +747,33 @@ qboolean FloodEntities( tree_t *tree )
|
||||||
{
|
{
|
||||||
Sys_Printf( "Entity %i, Brush %i: Entity in solid\n", e->mapEntityNum, 0);
|
Sys_Printf( "Entity %i, Brush %i: Entity in solid\n", e->mapEntityNum, 0);
|
||||||
}
|
}
|
||||||
else if( tree->outside_node.occupied && !tripped )
|
else if( tree->outside_node.occupied )
|
||||||
{
|
{
|
||||||
xml_Select( "Entity leaked", e->mapEntityNum, 0, qfalse );
|
if(!tripped || tree->outside_node.occupied < tripcount)
|
||||||
tripped = qtrue;
|
{
|
||||||
|
tripped = e;
|
||||||
|
tripcount = tree->outside_node.occupied;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(tripped)
|
||||||
|
xml_Select( "Entity leaked", e->mapEntityNum, 0, qfalse );
|
||||||
|
|
||||||
Sys_FPrintf( SYS_VRB, "%9d flooded leafs\n", c_floodedleafs );
|
Sys_FPrintf( SYS_VRB, "%9d flooded leafs\n", c_floodedleafs );
|
||||||
|
|
||||||
if( !inside )
|
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 )
|
return FLOODENTITIES_EMPTY;
|
||||||
Sys_FPrintf( SYS_VRB, "entity reached from outside -- no filling\n" );
|
}
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1598,7 +1598,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 FillOutside( node_t *headnode);
|
||||||
void FloodAreas( tree_t *tree);
|
void FloodAreas( tree_t *tree);
|
||||||
face_t *VisibleFaces( entity_t *e, tree_t *tree );
|
face_t *VisibleFaces( entity_t *e, tree_t *tree );
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user