* discard excess portals in the void (great optimization for maps with void areas in between of playable areas and non rectangular maps)
(excess portals there are effect of _blocksize) * optimize FloodPortals() (also fix stack depth crash in debug mode due to recursive calls) * fix xml_Select() of leaked entity (was selecting last map entity always) * xml_Select() leaked entity exactly in the beginning of leak line
This commit is contained in:
parent
e729f7b898
commit
5fd7b340df
|
|
@ -378,10 +378,9 @@ void ProcessWorldModel( void ){
|
||||||
exit( 0 );
|
exit( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ydnar: flood again for skybox */
|
/* flood again to discard portals in the void (also required for _skybox) */
|
||||||
if ( skyboxPresent ) {
|
FloodEntities( tree );
|
||||||
FloodEntities( tree );
|
FillOutside( tree->headnode );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* save out information for visibility processing */
|
/* save out information for visibility processing */
|
||||||
|
|
|
||||||
|
|
@ -117,5 +117,7 @@ xmlNodePtr LeakFile( tree_t *tree ){
|
||||||
|
|
||||||
fclose( linefile );
|
fclose( linefile );
|
||||||
|
|
||||||
|
xml_Select( "Entity leaked", node->occupant->mapEntityNum, 0, false );
|
||||||
|
|
||||||
return xml_node;
|
return xml_node;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -547,47 +547,35 @@ void MakeTreePortals( tree_t *tree ){
|
||||||
|
|
||||||
int c_floodedleafs;
|
int c_floodedleafs;
|
||||||
|
|
||||||
/*
|
void FloodPortals( node_t *node, bool skybox ){
|
||||||
=============
|
int dist = 1;
|
||||||
FloodPortals_r
|
std::vector<node_t*> nodes{ node };
|
||||||
=============
|
while( !nodes.empty() ){
|
||||||
*/
|
std::vector<node_t*> nodes2;
|
||||||
|
for( node_t *n : nodes ){
|
||||||
|
if ( skybox ) {
|
||||||
|
n->skybox = skybox;
|
||||||
|
}
|
||||||
|
|
||||||
void FloodPortals_r( node_t *node, int dist, bool skybox ){
|
if ( n->opaque || ( n->occupied && n->occupied <= dist ) ) { // also reprocess occupied nodes for shorter leak line
|
||||||
int s;
|
continue;
|
||||||
portal_t *p;
|
}
|
||||||
|
|
||||||
|
if( !n->occupied ){
|
||||||
|
++c_floodedleafs;
|
||||||
|
}
|
||||||
|
|
||||||
if ( skybox ) {
|
n->occupied = dist;
|
||||||
node->skybox = skybox;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( node->opaque ) {
|
int s;
|
||||||
return;
|
for ( portal_t *p = n->portals; p; p = p->next[ s ] )
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
s = ( p->nodes[ 1 ] == n );
|
||||||
FloodPortals_r( p->nodes[ !s ], dist + 1, skybox );
|
nodes2.push_back( p->nodes[ !s ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
nodes.swap( nodes2 );
|
||||||
}
|
++dist;
|
||||||
|
|
||||||
c_floodedleafs++;
|
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -599,7 +587,7 @@ void FloodPortals_r( node_t *node, int dist, bool skybox ){
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool PlaceOccupant( node_t *headnode, vec3_t origin, entity_t *occupant, bool skybox ){
|
bool PlaceOccupant( node_t *headnode, vec3_t origin, const entity_t *occupant, bool skybox ){
|
||||||
vec_t d;
|
vec_t d;
|
||||||
node_t *node;
|
node_t *node;
|
||||||
plane_t *plane;
|
plane_t *plane;
|
||||||
|
|
@ -625,7 +613,7 @@ bool PlaceOccupant( node_t *headnode, vec3_t origin, entity_t *occupant, bool sk
|
||||||
node->occupant = occupant;
|
node->occupant = occupant;
|
||||||
node->skybox = skybox;
|
node->skybox = skybox;
|
||||||
|
|
||||||
FloodPortals_r( node, 1, skybox );
|
FloodPortals( node, skybox );
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -641,9 +629,7 @@ bool PlaceOccupant( node_t *headnode, vec3_t origin, entity_t *occupant, bool sk
|
||||||
int FloodEntities( tree_t *tree ){
|
int FloodEntities( tree_t *tree ){
|
||||||
bool r, inside, skybox;
|
bool r, inside, skybox;
|
||||||
node_t *headnode;
|
node_t *headnode;
|
||||||
entity_t *e, *tripped;
|
|
||||||
const char *value;
|
const char *value;
|
||||||
int tripcount = INT_MIN;
|
|
||||||
|
|
||||||
|
|
||||||
headnode = tree->headnode;
|
headnode = tree->headnode;
|
||||||
|
|
@ -651,31 +637,29 @@ int FloodEntities( tree_t *tree ){
|
||||||
inside = false;
|
inside = false;
|
||||||
tree->outside_node.occupied = 0;
|
tree->outside_node.occupied = 0;
|
||||||
|
|
||||||
tripped = NULL;
|
|
||||||
c_floodedleafs = 0;
|
c_floodedleafs = 0;
|
||||||
for ( std::size_t i = 1; i < entities.size(); ++i )
|
for ( std::size_t i = 1; i < entities.size(); ++i )
|
||||||
{
|
{
|
||||||
/* get entity */
|
/* get entity */
|
||||||
e = &entities[ i ];
|
const entity_t& e = entities[ i ];
|
||||||
|
|
||||||
/* get origin */
|
/* get origin */
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
e->vectorForKey( "origin", origin );
|
e.vectorForKey( "origin", origin );
|
||||||
#if 0 //allow maps with only point entity@( 0, 0, 0 ); assuming that entities, containing no primitives are point ones
|
#if 0 // 0 = allow maps with only point entity@( 0, 0, 0 ); assuming that entities, containing no primitives are point ones
|
||||||
/* as a special case, allow origin-less entities */
|
/* as a special case, allow origin-less entities */
|
||||||
if ( VectorCompare( origin, vec3_origin ) ) {
|
if ( VectorCompare( origin, vec3_origin ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* also allow bmodel entities outside, as they could be on a moving path that will go into the map */
|
/* 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 || e->classname_is( "_decal" ) ) { //_decal primitive is freed at this point
|
if ( e.brushes != NULL || e.patches != NULL || e.classname_is( "_decal" ) ) { //_decal primitive is freed at this point
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle skybox entities */
|
/* handle skybox entities */
|
||||||
if ( e->classname_is( "_skybox" ) ) {
|
if ( e.classname_is( "_skybox" ) ) {
|
||||||
skybox = true;
|
skybox = true;
|
||||||
skyboxPresent = true;
|
|
||||||
|
|
||||||
/* invert origin */
|
/* invert origin */
|
||||||
vec3_t offset;
|
vec3_t offset;
|
||||||
|
|
@ -683,15 +667,15 @@ int FloodEntities( tree_t *tree ){
|
||||||
|
|
||||||
/* get scale */
|
/* get scale */
|
||||||
vec3_t scale = { 64.0f, 64.0f, 64.0f };
|
vec3_t scale = { 64.0f, 64.0f, 64.0f };
|
||||||
if( !e->read_keyvalue( scale, "_scale" ) )
|
if( !e.read_keyvalue( scale, "_scale" ) )
|
||||||
if( e->read_keyvalue( scale[0], "_scale" ) )
|
if( e.read_keyvalue( scale[0], "_scale" ) )
|
||||||
scale[1] = scale[2] = scale[0];
|
scale[1] = scale[2] = scale[0];
|
||||||
|
|
||||||
/* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */
|
/* get "angle" (yaw) or "angles" (pitch yaw roll), store as (roll pitch yaw) */
|
||||||
vec3_t angles = { 0.f, 0.f, 0.f };
|
vec3_t angles = { 0.f, 0.f, 0.f };
|
||||||
if ( !e->read_keyvalue( value, "angles" ) ||
|
if ( !e.read_keyvalue( value, "angles" ) ||
|
||||||
3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) )
|
3 != sscanf( value, "%f %f %f", &angles[ 1 ], &angles[ 2 ], &angles[ 0 ] ) )
|
||||||
e->read_keyvalue( angles[ 2 ], "angle" );
|
e.read_keyvalue( angles[ 2 ], "angle" );
|
||||||
|
|
||||||
/* set transform matrix (thanks spog) */
|
/* set transform matrix (thanks spog) */
|
||||||
m4x4_identity( skyboxTransform );
|
m4x4_identity( skyboxTransform );
|
||||||
|
|
@ -709,23 +693,13 @@ int FloodEntities( tree_t *tree ){
|
||||||
//% origin[ 2 ] += 4096;
|
//% origin[ 2 ] += 4096;
|
||||||
|
|
||||||
/* find leaf */
|
/* find leaf */
|
||||||
r = PlaceOccupant( headnode, origin, e, skybox );
|
r = PlaceOccupant( headnode, origin, &e, skybox );
|
||||||
if ( r ) {
|
if ( r ) {
|
||||||
inside = true;
|
inside = true;
|
||||||
}
|
}
|
||||||
if ( !r ) {
|
else {
|
||||||
Sys_FPrintf( SYS_WRN, "Entity %i (%s): Entity in solid\n", e->mapEntityNum, e->classname() );
|
Sys_FPrintf( SYS_WRN, "Entity %i (%s): Entity in solid\n", e.mapEntityNum, e.classname() );
|
||||||
}
|
}
|
||||||
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, false );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Sys_FPrintf( SYS_VRB, "%9d flooded leafs\n", c_floodedleafs );
|
Sys_FPrintf( SYS_VRB, "%9d flooded leafs\n", c_floodedleafs );
|
||||||
|
|
|
||||||
|
|
@ -1115,7 +1115,7 @@ struct node_t
|
||||||
drawSurfRef_t *drawSurfReferences;
|
drawSurfRef_t *drawSurfReferences;
|
||||||
|
|
||||||
int occupied; /* 1 or greater can reach entity */
|
int occupied; /* 1 or greater can reach entity */
|
||||||
entity_t *occupant; /* for leak file testing */
|
const entity_t *occupant; /* for leak file testing */
|
||||||
|
|
||||||
struct portal_t *portals; /* also on nodes during construction */
|
struct portal_t *portals; /* also on nodes during construction */
|
||||||
|
|
||||||
|
|
@ -2132,7 +2132,6 @@ Q_EXTERN byte debugColors[ 12 ][ 3 ]
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Q_EXTERN bool skyboxPresent Q_ASSIGN( false );
|
|
||||||
Q_EXTERN int skyboxArea Q_ASSIGN( -1 );
|
Q_EXTERN int skyboxArea Q_ASSIGN( -1 );
|
||||||
Q_EXTERN m4x4_t skyboxTransform;
|
Q_EXTERN m4x4_t skyboxTransform;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user