//
// cut the portal into two portals, one on each side of the cut plane
//
+ /* not strict, we want to always keep one of them even if coplanar */
ClipWindingEpsilon( p->winding, plane->normal, plane->dist,
SPLIT_WINDING_EPSILON, &frontwinding, &backwinding );
CalcNodeBounds( node );
if ( node->mins[0] >= node->maxs[0] ) {
- Sys_Printf( "WARNING: node without a volume\n" );
+ Sys_FPrintf( SYS_WRN, "WARNING: node without a volume\n" );
Sys_Printf( "node has %d tiny portals\n", node->tinyportals );
Sys_Printf( "node reference point %1.2f %1.2f %1.2f\n", node->referencepoint[0],
node->referencepoint[1],
node->skybox = skybox;
}
- if ( node->occupied || node->opaque ) {
+ if ( node->opaque ) {
+ 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;
}
=============
*/
-qboolean FloodEntities( tree_t *tree ){
+int FloodEntities( tree_t *tree ){
int i, s;
vec3_t origin, offset, scale, angles;
- qboolean r, inside, tripped, skybox;
+ qboolean r, inside, skybox, found;
node_t *headnode;
- entity_t *e;
+ entity_t *e, *tripped;
const char *value;
+ int tripcount;
headnode = tree->headnode;
e = &entities[ i ];
/* get origin */
- GetVectorForKey( e, "origin", origin );
- if ( VectorCompare( origin, vec3_origin ) ) {
+ found = GetVectorForKey( e, "origin", origin );
+
+ /* as a special case, allow origin-less entities */
+ if ( !found ) {
+ continue;
+ }
+
+ /* also allow bmodel entities outside, as they could be on a moving path that will go into the map */
+ if ( e->brushes != NULL || e->patches != NULL ) {
continue;
}
if ( r ) {
inside = qtrue;
}
- if ( ( !r || tree->outside_node.occupied ) && !tripped ) {
- xml_Select( "Entity leaked", e->mapEntityNum, 0, qfalse );
- tripped = qtrue;
+ if ( !r ) {
+ Sys_Printf( "Entity %i, Brush %i: Entity in solid\n", e->mapEntityNum, 0 );
}
+ else if ( tree->outside_node.occupied ) {
+ if ( !tripped || tree->outside_node.occupied < tripcount ) {
+ 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 );
if ( !inside ) {
Sys_FPrintf( SYS_VRB, "no entities in open -- no filling\n" );
+ return FLOODENTITIES_EMPTY;
}
- else if ( tree->outside_node.occupied ) {
- 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;
}
/*
// note the current area as bounding the portal
if ( b->portalareas[ 1 ] != -1 ) {
- Sys_Printf( "WARNING: areaportal brush %i touches > 2 areas\n", b->brushNum );
+ Sys_FPrintf( SYS_WRN, "WARNING: areaportal brush %i touches > 2 areas\n", b->brushNum );
return;
}
if ( b->portalareas[ 0 ] != -1 ) {
if ( node->cluster != -1 ) {
if ( node->area == -1 ) {
- Sys_Printf( "WARNING: cluster %d has area set to -1\n", node->cluster );
+ Sys_FPrintf( SYS_WRN, "WARNING: cluster %d has area set to -1\n", node->cluster );
}
}
if ( node->areaportal ) {
// check if the areaportal touches two areas
if ( b->portalareas[0] == -1 || b->portalareas[1] == -1 ) {
- Sys_Printf( "WARNING: areaportal brush %i doesn't touch two areas\n", b->brushNum );
+ Sys_FPrintf( SYS_WRN, "WARNING: areaportal brush %i doesn't touch two areas\n", b->brushNum );
}
}
}