void CountVisportals_r(node_t *node) { int s; portal_t *p; winding_t *w; // decision node if (node->planenum != PLANENUM_LEAF) { CountVisportals_r (node->children[0]); CountVisportals_r (node->children[1]); return; } if (node->opaque) { return; } for (p = node->portals ; p ; p=p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if (w && p->nodes[0] == node) { if (!PortalPassable(p)) continue; if(p->nodes[0]->cluster == p->nodes[1]->cluster) continue; ++num_visportals; } } }
void CountSolidFaces_r (node_t *node) { int s; portal_t *p; winding_t *w; // decision node if (node->planenum != PLANENUM_LEAF) { CountSolidFaces_r (node->children[0]); CountSolidFaces_r (node->children[1]); return; } if (node->opaque) { return; } for (p = node->portals ; p ; p=p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if (w) { if (PortalPassable(p)) continue; if(p->nodes[0]->cluster == p->nodes[1]->cluster) continue; // write out to the file ++num_solidfaces; } } }
/* ================= WriteFaceFile_r ================= */ void WriteFaceFile_r (node_t *node) { int i, s; portal_t *p; winding_t *w; // decision node if (node->planenum != PLANENUM_LEAF) { WriteFaceFile_r (node->children[0]); WriteFaceFile_r (node->children[1]); return; } if (node->opaque) { return; } for (p = node->portals ; p ; p=p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if (w) { if (PortalPassable(p)) continue; if(p->nodes[0]->cluster == p->nodes[1]->cluster) continue; // write out to the file if (p->nodes[0] == node) { fprintf (pf,"%i %i ",w->numpoints, p->nodes[0]->cluster); for (i=0 ; i<w->numpoints ; i++) { fprintf (pf,"("); WriteFloat (pf, w->p[i][0]); WriteFloat (pf, w->p[i][1]); WriteFloat (pf, w->p[i][2]); fprintf (pf,") "); } fprintf (pf,"\n"); } else { fprintf (pf,"%i %i ",w->numpoints, p->nodes[1]->cluster); for (i = w->numpoints-1; i >= 0; i--) { fprintf (pf,"("); WriteFloat (pf, w->p[i][0]); WriteFloat (pf, w->p[i][1]); WriteFloat (pf, w->p[i][2]); fprintf (pf,") "); } fprintf (pf,"\n"); } } } }
void FloodAreas_r( node_t *node ) { int s; portal_t *p; brush_t *b; if( node->areaportal ) { if( node->area == -1 ) node->area = c_areas; /* this node is part of an area portal brush */ b = node->brushlist->original; /* if the current area has already touched this portal, we are done */ if( b->portalareas[ 0 ] == c_areas || b->portalareas[ 1 ] == c_areas ) return; // 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 ); return; } if( b->portalareas[ 0 ] != -1 ) b->portalareas[ 1 ] = c_areas; else b->portalareas[ 0 ] = c_areas; return; } if( node->area != -1 ) return; if( node->cluster == -1 ) return; node->area = c_areas; /* ydnar: skybox nodes set the skybox area */ if( node->skybox ) skyboxArea = c_areas; for( p = node->portals; p; p = p->next[ s ] ) { s = (p->nodes[1] == node); /* ydnar: allow areaportal portals to block area flow */ if( p->compileFlags & C_AREAPORTAL ) continue; if( !PortalPassable( p ) ) continue; FloodAreas_r( p->nodes[ !s ] ); } }
/* ================ NumberLeafs_r ================ */ void NumberLeafs_r( node_t *node ){ portal_t *p; if ( node->planenum != PLANENUM_LEAF ) { // decision node node->cluster = -99; NumberLeafs_r( node->children[0] ); NumberLeafs_r( node->children[1] ); return; } node->area = -1; if ( node->opaque ) { // solid block, viewpoint never inside node->cluster = -1; return; } node->cluster = num_visclusters; num_visclusters++; // count the portals for ( p = node->portals ; p ; ) { if ( p->nodes[0] == node ) { // only write out from first leaf if ( PortalPassable( p ) ) { num_visportals++; } else{ num_solidfaces++; } p = p->next[0]; } else { if ( !PortalPassable( p ) ) { num_solidfaces++; } p = p->next[1]; } } }
/* ================= WritePortalFile_r ================= */ void WritePortalFile_r (node_t *node) { int i, s; portal_t *p; winding_t *w; vec3_t normal; vec_t dist; // decision node if (node->planenum != PLANENUM_LEAF) { WritePortalFile_r (node->children[0]); WritePortalFile_r (node->children[1]); return; } if (node->opaque) { return; } for (p = node->portals ; p ; p=p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if (w && p->nodes[0] == node) { if (!PortalPassable(p)) continue; // write out to the file // sometimes planes get turned around when they are very near // the changeover point between different axis. interpret the // plane the same way vis will, and flip the side orders if needed // FIXME: is this still relevent? WindingPlane (w, normal, &dist); if ( DotProduct (p->plane.normal, normal) < 0.99 ) { // backwards... fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[1]->cluster, p->nodes[0]->cluster); } else fprintf (pf,"%i %i %i ",w->numpoints, p->nodes[0]->cluster, p->nodes[1]->cluster); /* ydnar: added this change to make antiportals work */ if( p->compileFlags & C_HINT ) fprintf( pf, "1 " ); else fprintf( pf, "0 " ); /* write the winding */ for (i=0 ; i<w->numpoints ; i++) { fprintf (pf,"("); WriteFloat (pf, w->p[i][0]); WriteFloat (pf, w->p[i][1]); WriteFloat (pf, w->p[i][2]); fprintf (pf,") "); } fprintf (pf,"\n"); } } }
/* ================ NumberLeafs_r ================ */ void NumberLeafs_r (node_t *node, int c) { #if 0 portal_t *p; #endif if ( node->planenum != PLANENUM_LEAF ) { // decision node node->cluster = -99; if(node->has_structural_children) { #if 0 if(c >= 0) Sys_FPrintf (SYS_ERR,"THIS CANNOT HAPPEN\n"); #endif NumberLeafs_r (node->children[0], c); NumberLeafs_r (node->children[1], c); } else { if(c < 0) c = num_visclusters++; NumberLeafs_r (node->children[0], c); NumberLeafs_r (node->children[1], c); } return; } node->area = -1; if ( node->opaque ) { // solid block, viewpoint never inside node->cluster = -1; return; } if(c < 0) c = num_visclusters++; node->cluster = c; #if 0 // count the portals for (p = node->portals ; p ; ) { if (p->nodes[0] == node) // only write out from first leaf { if (PortalPassable(p)) num_visportals++; else num_solidfaces++; p = p->next[0]; } else { if (!PortalPassable(p)) num_solidfaces++; p = p->next[1]; } } #endif }