X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=tools%2Fquake2%2Fq2map%2Fportals.c;h=1c83d75d48dd34f1528fef31dd49ebc110dbe74f;hb=e4287c28bb2dafedc81c66e63951d947cfbeb225;hp=d0c9ea074e977373f6131b43f27a78f7224ce74a;hpb=203343b01a7ad87cb3d136689c9936ff5bc23c01;p=xonotic%2Fnetradiant.git diff --git a/tools/quake2/q2map/portals.c b/tools/quake2/q2map/portals.c index d0c9ea07..1c83d75d 100644 --- a/tools/quake2/q2map/portals.c +++ b/tools/quake2/q2map/portals.c @@ -1,165 +1,175 @@ /* -Copyright (C) 1999-2006 Id Software, Inc. and contributors. -For a list of contributors, see the accompanying CONTRIBUTORS file. + Copyright (C) 1999-2006 Id Software, Inc. and contributors. + For a list of contributors, see the accompanying CONTRIBUTORS file. -This file is part of GtkRadiant. + This file is part of GtkRadiant. -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. + GtkRadiant is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. + GtkRadiant is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ + You should have received a copy of the GNU General Public License + along with GtkRadiant; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ #include "qbsp.h" -int c_active_portals; -int c_peak_portals; -int c_boundary; -int c_boundary_sides; +int c_active_portals; +int c_peak_portals; +int c_boundary; +int c_boundary_sides; /* -=========== -AllocPortal -=========== -*/ -portal_t *AllocPortal (void) -{ - portal_t *p; - - if (numthreads == 1) + =========== + AllocPortal + =========== + */ +portal_t *AllocPortal( void ){ + portal_t *p; + + if ( numthreads == 1 ) { c_active_portals++; - if (c_active_portals > c_peak_portals) + } + if ( c_active_portals > c_peak_portals ) { c_peak_portals = c_active_portals; - - p = malloc (sizeof(portal_t)); - memset (p, 0, sizeof(portal_t)); - + } + + p = malloc( sizeof( portal_t ) ); + memset( p, 0, sizeof( portal_t ) ); + return p; } -void FreePortal (portal_t *p) -{ - if (p->winding) - FreeWinding (p->winding); - if (numthreads == 1) +void FreePortal( portal_t *p ){ + if ( p->winding ) { + FreeWinding( p->winding ); + } + if ( numthreads == 1 ) { c_active_portals--; - free (p); + } + free( p ); } //============================================================== /* -============== -VisibleContents - -Returns the single content bit of the -strongest visible content present -============== -*/ -int VisibleContents (int contents) -{ - int i; - - for (i=1 ; i<=LAST_VISIBLE_CONTENTS ; i<<=1) - if (contents & i ) + ============== + VisibleContents + + Returns the single content bit of the + strongest visible content present + ============== + */ +int VisibleContents( int contents ){ + int i; + + for ( i = 1 ; i <= LAST_VISIBLE_CONTENTS ; i <<= 1 ) + if ( contents & i ) { return i; + } return 0; } /* -=============== -ClusterContents -=============== -*/ -int ClusterContents (node_t *node) -{ - int c1, c2, c; - - if (node->planenum == PLANENUM_LEAF) + =============== + ClusterContents + =============== + */ +int ClusterContents( node_t *node ){ + int c1, c2, c; + + if ( node->planenum == PLANENUM_LEAF ) { return node->contents; + } - c1 = ClusterContents(node->children[0]); - c2 = ClusterContents(node->children[1]); - c = c1|c2; + c1 = ClusterContents( node->children[0] ); + c2 = ClusterContents( node->children[1] ); + c = c1 | c2; // a cluster may include some solid detail areas, but // still be seen into - if ( ! (c1&CONTENTS_SOLID) || ! (c2&CONTENTS_SOLID) ) + if ( !( c1 & CONTENTS_SOLID ) || !( c2 & CONTENTS_SOLID ) ) { c &= ~CONTENTS_SOLID; + } return c; } /* -============= -Portal_VisFlood - -Returns true if the portal is empty or translucent, allowing -the PVS calculation to see through it. -The nodes on either side of the portal may actually be clusters, -not leafs, so all contents should be ored together -============= -*/ -qboolean Portal_VisFlood (portal_t *p) -{ - int c1, c2; - - if (!p->onnode) - return false; // to global outsideleaf - - c1 = ClusterContents(p->nodes[0]); - c2 = ClusterContents(p->nodes[1]); - - if (!VisibleContents (c1^c2)) + ============= + Portal_VisFlood + + Returns true if the portal is empty or translucent, allowing + the PVS calculation to see through it. + The nodes on either side of the portal may actually be clusters, + not leafs, so all contents should be ored together + ============= + */ +qboolean Portal_VisFlood( portal_t *p ){ + int c1, c2; + + if ( !p->onnode ) { + return false; // to global outsideleaf + + } + c1 = ClusterContents( p->nodes[0] ); + c2 = ClusterContents( p->nodes[1] ); + + if ( !VisibleContents( c1 ^ c2 ) ) { return true; + } - if (c1 & (CONTENTS_TRANSLUCENT|CONTENTS_DETAIL)) + if ( c1 & ( CONTENTS_TRANSLUCENT | CONTENTS_DETAIL ) ) { c1 = 0; - if (c2 & (CONTENTS_TRANSLUCENT|CONTENTS_DETAIL)) + } + if ( c2 & ( CONTENTS_TRANSLUCENT | CONTENTS_DETAIL ) ) { c2 = 0; + } - if ( (c1|c2) & CONTENTS_SOLID ) - return false; // can't see through solid + if ( ( c1 | c2 ) & CONTENTS_SOLID ) { + return false; // can't see through solid - if (! (c1 ^ c2)) - return true; // identical on both sides + } + if ( !( c1 ^ c2 ) ) { + return true; // identical on both sides - if (!VisibleContents (c1^c2)) + } + if ( !VisibleContents( c1 ^ c2 ) ) { return true; + } return false; } /* -=============== -Portal_EntityFlood - -The entity flood determines which areas are -"outside" on the map, which are then filled in. -Flowing from side s to side !s -=============== -*/ -qboolean Portal_EntityFlood (portal_t *p, int s) -{ - if (p->nodes[0]->planenum != PLANENUM_LEAF - || p->nodes[1]->planenum != PLANENUM_LEAF) - Error ("Portal_EntityFlood: not a leaf"); - - // can never cross to a solid - if ( (p->nodes[0]->contents & CONTENTS_SOLID) - || (p->nodes[1]->contents & CONTENTS_SOLID) ) + =============== + Portal_EntityFlood + + The entity flood determines which areas are + "outside" on the map, which are then filled in. + Flowing from side s to side !s + =============== + */ +qboolean Portal_EntityFlood( portal_t *p, int s ){ + if ( p->nodes[0]->planenum != PLANENUM_LEAF + || p->nodes[1]->planenum != PLANENUM_LEAF ) { + Error( "Portal_EntityFlood: not a leaf" ); + } + + // can never cross to a solid + if ( ( p->nodes[0]->contents & CONTENTS_SOLID ) + || ( p->nodes[1]->contents & CONTENTS_SOLID ) ) { return false; + } // can flood through everything else return true; @@ -168,22 +178,22 @@ qboolean Portal_EntityFlood (portal_t *p, int s) //============================================================================= -int c_tinyportals; +int c_tinyportals; /* -============= -AddPortalToNodes -============= -*/ -void AddPortalToNodes (portal_t *p, node_t *front, node_t *back) -{ - if (p->nodes[0] || p->nodes[1]) - Error ("AddPortalToNode: allready included"); + ============= + AddPortalToNodes + ============= + */ +void AddPortalToNodes( portal_t *p, node_t *front, node_t *back ){ + if ( p->nodes[0] || p->nodes[1] ) { + Error( "AddPortalToNode: allready included" ); + } p->nodes[0] = front; p->next[0] = front->portals; front->portals = p; - + p->nodes[1] = back; p->next[1] = back->portals; back->portals = p; @@ -191,100 +201,99 @@ void AddPortalToNodes (portal_t *p, node_t *front, node_t *back) /* -============= -RemovePortalFromNode -============= -*/ -void RemovePortalFromNode (portal_t *portal, node_t *l) -{ - portal_t **pp, *t; - + ============= + RemovePortalFromNode + ============= + */ +void RemovePortalFromNode( portal_t *portal, node_t *l ){ + portal_t **pp, *t; + // remove reference to the current portal pp = &l->portals; - while (1) + while ( 1 ) { t = *pp; - if (!t) - Error ("RemovePortalFromNode: portal not in leaf"); + if ( !t ) { + Error( "RemovePortalFromNode: portal not in leaf" ); + } - if ( t == portal ) + if ( t == portal ) { break; + } - if (t->nodes[0] == l) + if ( t->nodes[0] == l ) { pp = &t->next[0]; - else if (t->nodes[1] == l) + } + else if ( t->nodes[1] == l ) { pp = &t->next[1]; - else - Error ("RemovePortalFromNode: portal not bounding leaf"); + } + else{ + Error( "RemovePortalFromNode: portal not bounding leaf" ); + } } - - if (portal->nodes[0] == l) - { + + if ( portal->nodes[0] == l ) { *pp = portal->next[0]; portal->nodes[0] = NULL; } - else if (portal->nodes[1] == l) - { - *pp = portal->next[1]; + else if ( portal->nodes[1] == l ) { + *pp = portal->next[1]; portal->nodes[1] = NULL; } } //============================================================================ -void PrintPortal (portal_t *p) -{ - int i; - winding_t *w; - +void PrintPortal( portal_t *p ){ + int i; + winding_t *w; + w = p->winding; - for (i=0 ; inumpoints ; i++) - Sys_Printf ("(%5.0f,%5.0f,%5.0f)\n",w->p[i][0] - , w->p[i][1], w->p[i][2]); + for ( i = 0 ; i < w->numpoints ; i++ ) + Sys_Printf( "(%5.0f,%5.0f,%5.0f)\n",w->p[i][0] + , w->p[i][1], w->p[i][2] ); } /* -================ -MakeHeadnodePortals - -The created portals will face the global outside_node -================ -*/ -#define SIDESPACE 8 -void MakeHeadnodePortals (tree_t *tree) -{ - vec3_t bounds[2]; - int i, j, n; - portal_t *p, *portals[6]; - plane_t bplanes[6], *pl; + ================ + MakeHeadnodePortals + + The created portals will face the global outside_node + ================ + */ +#define SIDESPACE 8 +void MakeHeadnodePortals( tree_t *tree ){ + vec3_t bounds[2]; + int i, j, n; + portal_t *p, *portals[6]; + plane_t bplanes[6], *pl; node_t *node; node = tree->headnode; // pad with some space so there will never be null volume leafs - for (i=0 ; i<3 ; i++) + for ( i = 0 ; i < 3 ; i++ ) { bounds[0][i] = tree->mins[i] - SIDESPACE; bounds[1][i] = tree->maxs[i] + SIDESPACE; } - + tree->outside_node.planenum = PLANENUM_LEAF; tree->outside_node.brushlist = NULL; tree->outside_node.portals = NULL; tree->outside_node.contents = 0; - for (i=0 ; i<3 ; i++) - for (j=0 ; j<2 ; j++) + for ( i = 0 ; i < 3 ; i++ ) + for ( j = 0 ; j < 2 ; j++ ) { - n = j*3 + i; + n = j * 3 + i; - p = AllocPortal (); + p = AllocPortal(); portals[n] = p; - + pl = &bplanes[n]; - memset (pl, 0, sizeof(*pl)); - if (j) - { + memset( pl, 0, sizeof( *pl ) ); + if ( j ) { pl->normal[i] = -1; pl->dist = -bounds[j][i]; } @@ -294,18 +303,19 @@ void MakeHeadnodePortals (tree_t *tree) pl->dist = bounds[j][i]; } p->plane = *pl; - p->winding = BaseWindingForPlane (pl->normal, pl->dist); - AddPortalToNodes (p, node, &tree->outside_node); + p->winding = BaseWindingForPlane( pl->normal, pl->dist ); + AddPortalToNodes( p, node, &tree->outside_node ); } - + // clip the basewindings by all the other planes - for (i=0 ; i<6 ; i++) + for ( i = 0 ; i < 6 ; i++ ) { - for (j=0 ; j<6 ; j++) + for ( j = 0 ; j < 6 ; j++ ) { - if (j == i) + if ( j == i ) { continue; - ChopWindingInPlace (&portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON); + } + ChopWindingInPlace( &portals[i]->winding, bplanes[j].normal, bplanes[j].dist, ON_EPSILON ); } } } @@ -314,38 +324,36 @@ void MakeHeadnodePortals (tree_t *tree) /* -================ -BaseWindingForNode -================ -*/ -#define BASE_WINDING_EPSILON 0.001 -#define SPLIT_WINDING_EPSILON 0.001 - -winding_t *BaseWindingForNode (node_t *node) -{ - winding_t *w; - node_t *n; - plane_t *plane; - vec3_t normal; - vec_t dist; - - w = BaseWindingForPlane (mapplanes[node->planenum].normal - , mapplanes[node->planenum].dist); + ================ + BaseWindingForNode + ================ + */ +#define BASE_WINDING_EPSILON 0.001 +#define SPLIT_WINDING_EPSILON 0.001 + +winding_t *BaseWindingForNode( node_t *node ){ + winding_t *w; + node_t *n; + plane_t *plane; + vec3_t normal; + vec_t dist; + + w = BaseWindingForPlane( mapplanes[node->planenum].normal + , mapplanes[node->planenum].dist ); // clip by all the parents - for (n=node->parent ; n && w ; ) + for ( n = node->parent ; n && w ; ) { plane = &mapplanes[n->planenum]; - if (n->children[0] == node) - { // take front - ChopWindingInPlace (&w, plane->normal, plane->dist, BASE_WINDING_EPSILON); + if ( n->children[0] == node ) { // take front + ChopWindingInPlace( &w, plane->normal, plane->dist, BASE_WINDING_EPSILON ); } else - { // take back - VectorSubtract (vec3_origin, plane->normal, normal); + { // take back + VectorSubtract( vec3_origin, plane->normal, normal ); dist = -plane->dist; - ChopWindingInPlace (&w, normal, dist, BASE_WINDING_EPSILON); + ChopWindingInPlace( &w, normal, dist, BASE_WINDING_EPSILON ); } node = n; n = n->parent; @@ -356,162 +364,158 @@ winding_t *BaseWindingForNode (node_t *node) //============================================================ -qboolean WindingIsTiny (winding_t *w); +qboolean WindingIsTiny( winding_t *w ); /* -================== -MakeNodePortal - -create the new portal by taking the full plane winding for the cutting plane -and clipping it by all of parents of this node -================== -*/ -void MakeNodePortal (node_t *node) -{ - portal_t *new_portal, *p; - winding_t *w; - vec3_t normal; - float dist; - int side; - - w = BaseWindingForNode (node); + ================== + MakeNodePortal + + create the new portal by taking the full plane winding for the cutting plane + and clipping it by all of parents of this node + ================== + */ +void MakeNodePortal( node_t *node ){ + portal_t *new_portal, *p; + winding_t *w; + vec3_t normal; + float dist; + int side; + + w = BaseWindingForNode( node ); // clip the portal by all the other portals in the node - for (p = node->portals ; p && w; p = p->next[side]) + for ( p = node->portals ; p && w; p = p->next[side] ) { - if (p->nodes[0] == node) - { + if ( p->nodes[0] == node ) { side = 0; - VectorCopy (p->plane.normal, normal); + VectorCopy( p->plane.normal, normal ); dist = p->plane.dist; } - else if (p->nodes[1] == node) - { + else if ( p->nodes[1] == node ) { side = 1; - VectorSubtract (vec3_origin, p->plane.normal, normal); + VectorSubtract( vec3_origin, p->plane.normal, normal ); dist = -p->plane.dist; } - else - Error ("CutNodePortals_r: mislinked portal"); + else{ + Error( "CutNodePortals_r: mislinked portal" ); + } - ChopWindingInPlace (&w, normal, dist, 0.1); + ChopWindingInPlace( &w, normal, dist, 0.1 ); } - if (!w) - { + if ( !w ) { return; } - if (WindingIsTiny (w)) - { + if ( WindingIsTiny( w ) ) { c_tinyportals++; - FreeWinding (w); + FreeWinding( w ); return; } - new_portal = AllocPortal (); + new_portal = AllocPortal(); new_portal->plane = mapplanes[node->planenum]; new_portal->onnode = node; - new_portal->winding = w; - AddPortalToNodes (new_portal, node->children[0], node->children[1]); + new_portal->winding = w; + AddPortalToNodes( new_portal, node->children[0], node->children[1] ); } /* -============== -SplitNodePortals - -Move or split the portals that bound node so that the node's -children have portals instead of node. -============== -*/ -void SplitNodePortals (node_t *node) -{ - portal_t *p, *next_portal, *new_portal; - node_t *f, *b, *other_node; - int side; - plane_t *plane; - winding_t *frontwinding, *backwinding; + ============== + SplitNodePortals + + Move or split the portals that bound node so that the node's + children have portals instead of node. + ============== + */ +void SplitNodePortals( node_t *node ){ + portal_t *p, *next_portal, *new_portal; + node_t *f, *b, *other_node; + int side; + plane_t *plane; + winding_t *frontwinding, *backwinding; plane = &mapplanes[node->planenum]; f = node->children[0]; b = node->children[1]; - for (p = node->portals ; p ; p = next_portal) + for ( p = node->portals ; p ; p = next_portal ) { - if (p->nodes[0] == node) + if ( p->nodes[0] == node ) { side = 0; - else if (p->nodes[1] == node) + } + else if ( p->nodes[1] == node ) { side = 1; - else - Error ("CutNodePortals_r: mislinked portal"); + } + else{ + Error( "CutNodePortals_r: mislinked portal" ); + } next_portal = p->next[side]; other_node = p->nodes[!side]; - RemovePortalFromNode (p, p->nodes[0]); - RemovePortalFromNode (p, p->nodes[1]); + RemovePortalFromNode( p, p->nodes[0] ); + RemovePortalFromNode( p, p->nodes[1] ); // // cut the portal into two portals, one on each side of the cut plane // - ClipWindingEpsilon (p->winding, plane->normal, plane->dist, - SPLIT_WINDING_EPSILON, &frontwinding, &backwinding); + ClipWindingEpsilon( p->winding, plane->normal, plane->dist, + SPLIT_WINDING_EPSILON, &frontwinding, &backwinding ); - if (frontwinding && WindingIsTiny(frontwinding)) - { - FreeWinding (frontwinding); + if ( frontwinding && WindingIsTiny( frontwinding ) ) { + FreeWinding( frontwinding ); frontwinding = NULL; c_tinyportals++; } - if (backwinding && WindingIsTiny(backwinding)) - { - FreeWinding (backwinding); + if ( backwinding && WindingIsTiny( backwinding ) ) { + FreeWinding( backwinding ); backwinding = NULL; c_tinyportals++; } - if (!frontwinding && !backwinding) - { // tiny windings on both sides + if ( !frontwinding && !backwinding ) { // tiny windings on both sides continue; } - if (!frontwinding) - { - FreeWinding (backwinding); - if (side == 0) - AddPortalToNodes (p, b, other_node); - else - AddPortalToNodes (p, other_node, b); + if ( !frontwinding ) { + FreeWinding( backwinding ); + if ( side == 0 ) { + AddPortalToNodes( p, b, other_node ); + } + else{ + AddPortalToNodes( p, other_node, b ); + } continue; } - if (!backwinding) - { - FreeWinding (frontwinding); - if (side == 0) - AddPortalToNodes (p, f, other_node); - else - AddPortalToNodes (p, other_node, f); + if ( !backwinding ) { + FreeWinding( frontwinding ); + if ( side == 0 ) { + AddPortalToNodes( p, f, other_node ); + } + else{ + AddPortalToNodes( p, other_node, f ); + } continue; } - - // the winding is split - new_portal = AllocPortal (); + + // the winding is split + new_portal = AllocPortal(); *new_portal = *p; new_portal->winding = backwinding; - FreeWinding (p->winding); + FreeWinding( p->winding ); p->winding = frontwinding; - if (side == 0) - { - AddPortalToNodes (p, f, other_node); - AddPortalToNodes (new_portal, b, other_node); + if ( side == 0 ) { + AddPortalToNodes( p, f, other_node ); + AddPortalToNodes( new_portal, b, other_node ); } else { - AddPortalToNodes (p, other_node, f); - AddPortalToNodes (new_portal, other_node, b); + AddPortalToNodes( p, other_node, f ); + AddPortalToNodes( new_portal, other_node, b ); } } @@ -520,180 +524,177 @@ void SplitNodePortals (node_t *node) /* -================ -CalcNodeBounds -================ -*/ -void CalcNodeBounds (node_t *node) -{ - portal_t *p; - int s; - int i; + ================ + CalcNodeBounds + ================ + */ +void CalcNodeBounds( node_t *node ){ + portal_t *p; + int s; + int i; // calc mins/maxs for both leafs and nodes - ClearBounds (node->mins, node->maxs); - for (p = node->portals ; p ; p = p->next[s]) + ClearBounds( node->mins, node->maxs ); + for ( p = node->portals ; p ; p = p->next[s] ) { - s = (p->nodes[1] == node); - for (i=0 ; iwinding->numpoints ; i++) - AddPointToBounds (p->winding->p[i], node->mins, node->maxs); + s = ( p->nodes[1] == node ); + for ( i = 0 ; i < p->winding->numpoints ; i++ ) + AddPointToBounds( p->winding->p[i], node->mins, node->maxs ); } } /* -================== -MakeTreePortals_r -================== -*/ -void MakeTreePortals_r (node_t *node) -{ - int i; - - CalcNodeBounds (node); - if (node->mins[0] >= node->maxs[0]) - { - Sys_Printf ("WARNING: node without a volume\n"); + ================== + MakeTreePortals_r + ================== + */ +void MakeTreePortals_r( node_t *node ){ + int i; + + CalcNodeBounds( node ); + if ( node->mins[0] >= node->maxs[0] ) { + Sys_Printf( "WARNING: node without a volume\n" ); } - for (i=0 ; i<3 ; i++) + for ( i = 0 ; i < 3 ; i++ ) { - if (node->mins[i] < -8000 || node->maxs[i] > 8000) - { - Sys_Printf ("WARNING: node with unbounded volume\n"); + if ( node->mins[i] < -8000 || node->maxs[i] > 8000 ) { + Sys_Printf( "WARNING: node with unbounded volume\n" ); break; } } - if (node->planenum == PLANENUM_LEAF) + if ( node->planenum == PLANENUM_LEAF ) { return; + } - MakeNodePortal (node); - SplitNodePortals (node); + MakeNodePortal( node ); + SplitNodePortals( node ); - MakeTreePortals_r (node->children[0]); - MakeTreePortals_r (node->children[1]); + MakeTreePortals_r( node->children[0] ); + MakeTreePortals_r( node->children[1] ); } /* -================== -MakeTreePortals -================== -*/ -void MakeTreePortals (tree_t *tree) -{ - MakeHeadnodePortals (tree); - MakeTreePortals_r (tree->headnode); + ================== + MakeTreePortals + ================== + */ +void MakeTreePortals( tree_t *tree ){ + MakeHeadnodePortals( tree ); + MakeTreePortals_r( tree->headnode ); } /* -========================================================= + ========================================================= -FLOOD ENTITIES + FLOOD ENTITIES -========================================================= -*/ + ========================================================= + */ /* -============= -FloodPortals_r -============= -*/ -void FloodPortals_r (node_t *node, int dist) -{ - portal_t *p; - int s; + ============= + FloodPortals_r + ============= + */ +void FloodPortals_r( node_t *node, int dist ){ + portal_t *p; + int s; node->occupied = dist; - for (p=node->portals ; p ; p = p->next[s]) + for ( p = node->portals ; p ; p = p->next[s] ) { - s = (p->nodes[1] == node); + s = ( p->nodes[1] == node ); - if (p->nodes[!s]->occupied) + if ( p->nodes[!s]->occupied ) { continue; + } - if (!Portal_EntityFlood (p, s)) + if ( !Portal_EntityFlood( p, s ) ) { continue; + } - FloodPortals_r (p->nodes[!s], dist+1); + FloodPortals_r( p->nodes[!s], dist + 1 ); } } /* -============= -PlaceOccupant -============= -*/ -qboolean PlaceOccupant (node_t *headnode, vec3_t origin, entity_t *occupant) -{ - node_t *node; - vec_t d; - plane_t *plane; + ============= + PlaceOccupant + ============= + */ +qboolean PlaceOccupant( node_t *headnode, vec3_t origin, entity_t *occupant ){ + node_t *node; + vec_t d; + plane_t *plane; // find the leaf to start in node = headnode; - while (node->planenum != PLANENUM_LEAF) + while ( node->planenum != PLANENUM_LEAF ) { plane = &mapplanes[node->planenum]; - d = DotProduct (origin, plane->normal) - plane->dist; - if (d >= 0) + d = DotProduct( origin, plane->normal ) - plane->dist; + if ( d >= 0 ) { node = node->children[0]; - else + } + else{ node = node->children[1]; + } } - if (node->contents == CONTENTS_SOLID) + if ( node->contents == CONTENTS_SOLID ) { return false; + } node->occupant = occupant; - FloodPortals_r (node, 1); + FloodPortals_r( node, 1 ); return true; } /* -============= -FloodEntities - -Marks all nodes that can be reached by entites -============= -*/ -qboolean FloodEntities (tree_t *tree) -{ - int i; - vec3_t origin; - char *cl; - qboolean inside; + ============= + FloodEntities + + Marks all nodes that can be reached by entites + ============= + */ +qboolean FloodEntities( tree_t *tree ){ + int i; + vec3_t origin; + char *cl; + qboolean inside; node_t *headnode; headnode = tree->headnode; - Sys_FPrintf( SYS_VRB, "--- FloodEntities ---\n"); + Sys_FPrintf( SYS_VRB, "--- FloodEntities ---\n" ); inside = false; tree->outside_node.occupied = 0; - for (i=1 ; ioutside_node.occupied) - { - Sys_FPrintf( SYS_VRB, "entity reached from outside -- no filling\n"); + else if ( tree->outside_node.occupied ) { + Sys_FPrintf( SYS_VRB, "entity reached from outside -- no filling\n" ); } - return (qboolean)(inside && !tree->outside_node.occupied); + return (qboolean)( inside && !tree->outside_node.occupied ); } /* -========================================================= + ========================================================= -FLOOD AREAS + FLOOD AREAS -========================================================= -*/ + ========================================================= + */ -int c_areas; +int c_areas; /* -============= -FloodAreas_r -============= -*/ -void FloodAreas_r (node_t *node) -{ - portal_t *p; - int s; - bspbrush_t *b; - entity_t *e; - - if (node->contents == CONTENTS_AREAPORTAL) - { + ============= + FloodAreas_r + ============= + */ +void FloodAreas_r( node_t *node ){ + portal_t *p; + int s; + bspbrush_t *b; + entity_t *e; + + if ( node->contents == CONTENTS_AREAPORTAL ) { // this node is part of an area portal b = node->brushlist; e = &entities[b->original->entitynum]; // if the current area has allready touched this // portal, we are done - if (e->portalareas[0] == c_areas || e->portalareas[1] == c_areas) + if ( e->portalareas[0] == c_areas || e->portalareas[1] == c_areas ) { return; + } // note the current area as bounding the portal - if (e->portalareas[1]) - { - Sys_Printf ("WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum); + if ( e->portalareas[1] ) { + Sys_Printf( "WARNING: areaportal entity %i touches > 2 areas\n", b->original->entitynum ); return; } - if (e->portalareas[0]) + if ( e->portalareas[0] ) { e->portalareas[1] = c_areas; - else + } + else{ e->portalareas[0] = c_areas; + } return; } - if (node->area) - return; // allready got it + if ( node->area ) { + return; // allready got it + } node->area = c_areas; - for (p=node->portals ; p ; p = p->next[s]) + for ( p = node->portals ; p ; p = p->next[s] ) { - s = (p->nodes[1] == node); + s = ( p->nodes[1] == node ); #if 0 - if (p->nodes[!s]->occupied) + if ( p->nodes[!s]->occupied ) { continue; + } #endif - if (!Portal_EntityFlood (p, s)) + if ( !Portal_EntityFlood( p, s ) ) { continue; + } - FloodAreas_r (p->nodes[!s]); + FloodAreas_r( p->nodes[!s] ); } } /* -============= -FindAreas_r - -Just decend the tree, and for each node that hasn't had an -area set, flood fill out from there -============= -*/ -void FindAreas_r (node_t *node) -{ - if (node->planenum != PLANENUM_LEAF) - { - FindAreas_r (node->children[0]); - FindAreas_r (node->children[1]); + ============= + FindAreas_r + + Just decend the tree, and for each node that hasn't had an + area set, flood fill out from there + ============= + */ +void FindAreas_r( node_t *node ){ + if ( node->planenum != PLANENUM_LEAF ) { + FindAreas_r( node->children[0] ); + FindAreas_r( node->children[1] ); return; } - if (node->area) - return; // allready got it + if ( node->area ) { + return; // allready got it - if (node->contents & CONTENTS_SOLID) + } + if ( node->contents & CONTENTS_SOLID ) { return; + } - if (!node->occupied) - return; // not reachable by entities + if ( !node->occupied ) { + return; // not reachable by entities + } // area portals are allways only flooded into, never // out of - if (node->contents == CONTENTS_AREAPORTAL) + if ( node->contents == CONTENTS_AREAPORTAL ) { return; + } c_areas++; - FloodAreas_r (node); + FloodAreas_r( node ); } /* -============= -SetAreaPortalAreas_r - -Just decend the tree, and for each node that hasn't had an -area set, flood fill out from there -============= -*/ -void SetAreaPortalAreas_r (node_t *node) -{ - bspbrush_t *b; - entity_t *e; - - if (node->planenum != PLANENUM_LEAF) - { - SetAreaPortalAreas_r (node->children[0]); - SetAreaPortalAreas_r (node->children[1]); + ============= + SetAreaPortalAreas_r + + Just decend the tree, and for each node that hasn't had an + area set, flood fill out from there + ============= + */ +void SetAreaPortalAreas_r( node_t *node ){ + bspbrush_t *b; + entity_t *e; + + if ( node->planenum != PLANENUM_LEAF ) { + SetAreaPortalAreas_r( node->children[0] ); + SetAreaPortalAreas_r( node->children[1] ); return; } - if (node->contents == CONTENTS_AREAPORTAL) - { - if (node->area) - return; // allready set + if ( node->contents == CONTENTS_AREAPORTAL ) { + if ( node->area ) { + return; // allready set + } b = node->brushlist; e = &entities[b->original->entitynum]; node->area = e->portalareas[0]; - if (!e->portalareas[1]) - { - Sys_Printf ("WARNING: areaportal entity %i doesn't touch two areas\n", b->original->entitynum); + if ( !e->portalareas[1] ) { + Sys_Printf( "WARNING: areaportal entity %i doesn't touch two areas\n", b->original->entitynum ); return; } } } /* -============= -EmitAreaPortals - -============= -*/ -void EmitAreaPortals (node_t *headnode) -{ - int i, j; - entity_t *e; - dareaportal_t *dp; - - if (c_areas > MAX_MAP_AREAS) - Error ("MAX_MAP_AREAS"); - numareas = c_areas+1; - numareaportals = 1; // leave 0 as an error - - for (i=1 ; i<=c_areas ; i++) + ============= + EmitAreaPortals + + ============= + */ +void EmitAreaPortals( node_t *headnode ){ + int i, j; + entity_t *e; + dareaportal_t *dp; + + if ( c_areas > MAX_MAP_AREAS ) { + Error( "MAX_MAP_AREAS" ); + } + numareas = c_areas + 1; + numareaportals = 1; // leave 0 as an error + + for ( i = 1 ; i <= c_areas ; i++ ) { dareas[i].firstareaportal = numareaportals; - for (j=0 ; jareaportalnum) + if ( !e->areaportalnum ) { continue; + } dp = &dareaportals[numareaportals]; - if (e->portalareas[0] == i) - { + if ( e->portalareas[0] == i ) { dp->portalnum = e->areaportalnum; dp->otherarea = e->portalareas[1]; numareaportals++; } - else if (e->portalareas[1] == i) - { + else if ( e->portalareas[1] == i ) { dp->portalnum = e->areaportalnum; dp->otherarea = e->portalareas[0]; numareaportals++; @@ -900,134 +901,131 @@ void EmitAreaPortals (node_t *headnode) dareas[i].numareaportals = numareaportals - dareas[i].firstareaportal; } - Sys_FPrintf( SYS_VRB, "%5i numareas\n", numareas); - Sys_FPrintf( SYS_VRB, "%5i numareaportals\n", numareaportals); + Sys_FPrintf( SYS_VRB, "%5i numareas\n", numareas ); + Sys_FPrintf( SYS_VRB, "%5i numareaportals\n", numareaportals ); } /* -============= -FloodAreas - -Mark each leaf with an area, bounded by CONTENTS_AREAPORTAL -============= -*/ -void FloodAreas (tree_t *tree) -{ - Sys_FPrintf( SYS_VRB, "--- FloodAreas ---\n"); - FindAreas_r (tree->headnode); - SetAreaPortalAreas_r (tree->headnode); - Sys_FPrintf( SYS_VRB, "%5i areas\n", c_areas); + ============= + FloodAreas + + Mark each leaf with an area, bounded by CONTENTS_AREAPORTAL + ============= + */ +void FloodAreas( tree_t *tree ){ + Sys_FPrintf( SYS_VRB, "--- FloodAreas ---\n" ); + FindAreas_r( tree->headnode ); + SetAreaPortalAreas_r( tree->headnode ); + Sys_FPrintf( SYS_VRB, "%5i areas\n", c_areas ); } //====================================================== -int c_outside; -int c_inside; -int c_solid; +int c_outside; +int c_inside; +int c_solid; -void FillOutside_r (node_t *node) -{ - if (node->planenum != PLANENUM_LEAF) - { - FillOutside_r (node->children[0]); - FillOutside_r (node->children[1]); +void FillOutside_r( node_t *node ){ + if ( node->planenum != PLANENUM_LEAF ) { + FillOutside_r( node->children[0] ); + FillOutside_r( node->children[1] ); return; } // anything not reachable by an entity // can be filled away - if (!node->occupied) - { - if (node->contents != CONTENTS_SOLID) - { + if ( !node->occupied ) { + if ( node->contents != CONTENTS_SOLID ) { c_outside++; node->contents = CONTENTS_SOLID; } - else + else{ c_solid++; + } } - else + else{ c_inside++; + } } /* -============= -FillOutside - -Fill all nodes that can't be reached by entities -============= -*/ -void FillOutside (node_t *headnode) -{ + ============= + FillOutside + + Fill all nodes that can't be reached by entities + ============= + */ +void FillOutside( node_t *headnode ){ c_outside = 0; c_inside = 0; c_solid = 0; - Sys_FPrintf( SYS_VRB, "--- FillOutside ---\n"); - FillOutside_r (headnode); - Sys_FPrintf( SYS_VRB, "%5i solid leafs\n", c_solid); - Sys_FPrintf( SYS_VRB, "%5i leafs filled\n", c_outside); - Sys_FPrintf( SYS_VRB, "%5i inside leafs\n", c_inside); + Sys_FPrintf( SYS_VRB, "--- FillOutside ---\n" ); + FillOutside_r( headnode ); + Sys_FPrintf( SYS_VRB, "%5i solid leafs\n", c_solid ); + Sys_FPrintf( SYS_VRB, "%5i leafs filled\n", c_outside ); + Sys_FPrintf( SYS_VRB, "%5i inside leafs\n", c_inside ); } //============================================================== /* -============ -FindPortalSide - -Finds a brush side to use for texturing the given portal -============ -*/ -void FindPortalSide (portal_t *p) -{ - int viscontents; - bspbrush_t *bb; - mapbrush_t *brush; - node_t *n; - int i,j; - int planenum; - side_t *side, *bestside; - float dot, bestdot; - plane_t *p1, *p2; + ============ + FindPortalSide + + Finds a brush side to use for texturing the given portal + ============ + */ +void FindPortalSide( portal_t *p ){ + int viscontents; + bspbrush_t *bb; + mapbrush_t *brush; + node_t *n; + int i,j; + int planenum; + side_t *side, *bestside; + float dot, bestdot; + plane_t *p1, *p2; // decide which content change is strongest // solid > lava > water, etc - viscontents = VisibleContents (p->nodes[0]->contents ^ p->nodes[1]->contents); - if (!viscontents) + viscontents = VisibleContents( p->nodes[0]->contents ^ p->nodes[1]->contents ); + if ( !viscontents ) { return; + } planenum = p->onnode->planenum; bestside = NULL; bestdot = 0; - for (j=0 ; j<2 ; j++) + for ( j = 0 ; j < 2 ; j++ ) { n = p->nodes[j]; p1 = &mapplanes[p->onnode->planenum]; - for (bb=n->brushlist ; bb ; bb=bb->next) + for ( bb = n->brushlist ; bb ; bb = bb->next ) { brush = bb->original; - if ( !(brush->contents & viscontents) ) + if ( !( brush->contents & viscontents ) ) { continue; - for (i=0 ; inumsides ; i++) + } + for ( i = 0 ; i < brush->numsides ; i++ ) { side = &brush->original_sides[i]; - if (side->bevel) + if ( side->bevel ) { continue; - if (side->texinfo == TEXINFO_NODE) - continue; // non-visible - if ((side->planenum&~1) == planenum) - { // exact match + } + if ( side->texinfo == TEXINFO_NODE ) { + continue; // non-visible + } + if ( ( side->planenum & ~1 ) == planenum ) { // exact match bestside = &brush->original_sides[i]; goto gotit; } // see how close the match is - p2 = &mapplanes[side->planenum&~1]; - dot = DotProduct (p1->normal, p2->normal); - if (dot > bestdot) - { + p2 = &mapplanes[side->planenum & ~1]; + dot = DotProduct( p1->normal, p2->normal ); + if ( dot > bestdot ) { bestdot = dot; bestside = side; } @@ -1036,8 +1034,9 @@ void FindPortalSide (portal_t *p) } gotit: - if (!bestside) - Sys_FPrintf( SYS_VRB, "WARNING: side not found for portal\n"); + if ( !bestside ) { + Sys_FPrintf( SYS_VRB, "WARNING: side not found for portal\n" ); + } p->sidefound = true; p->side = bestside; @@ -1045,66 +1044,66 @@ gotit: /* -=============== -MarkVisibleSides_r - -=============== -*/ -void MarkVisibleSides_r (node_t *node) -{ - portal_t *p; - int s; - - if (node->planenum != PLANENUM_LEAF) - { - MarkVisibleSides_r (node->children[0]); - MarkVisibleSides_r (node->children[1]); + =============== + MarkVisibleSides_r + + =============== + */ +void MarkVisibleSides_r( node_t *node ){ + portal_t *p; + int s; + + if ( node->planenum != PLANENUM_LEAF ) { + MarkVisibleSides_r( node->children[0] ); + MarkVisibleSides_r( node->children[1] ); return; } // empty leafs are never boundary leafs - if (!node->contents) + if ( !node->contents ) { return; + } // see if there is a visible face - for (p=node->portals ; p ; p = p->next[!s]) + for ( p = node->portals ; p ; p = p->next[!s] ) { - s = (p->nodes[0] == node); - if (!p->onnode) - continue; // edge of world - if (!p->sidefound) - FindPortalSide (p); - if (p->side) + s = ( p->nodes[0] == node ); + if ( !p->onnode ) { + continue; // edge of world + } + if ( !p->sidefound ) { + FindPortalSide( p ); + } + if ( p->side ) { p->side->visible = true; + } } } /* -============= -MarkVisibleSides + ============= + MarkVisibleSides -============= -*/ -void MarkVisibleSides (tree_t *tree, int startbrush, int endbrush) -{ - int i, j; - mapbrush_t *mb; - int numsides; + ============= + */ +void MarkVisibleSides( tree_t *tree, int startbrush, int endbrush ){ + int i, j; + mapbrush_t *mb; + int numsides; - Sys_FPrintf( SYS_VRB, "--- MarkVisibleSides ---\n"); + Sys_FPrintf( SYS_VRB, "--- MarkVisibleSides ---\n" ); // clear all the visible flags - for (i=startbrush ; inumsides; - for (j=0 ; joriginal_sides[j].visible = false; } // set visible flags on the sides that are used by portals - MarkVisibleSides_r (tree->headnode); + MarkVisibleSides_r( tree->headnode ); } -