/* ============= FloodAreas_r ============= */ void FloodAreas_r( node_t *node ) { uPortal_t *p; int s; if( node->area != -1 ) { return; // allready got it } if( node->opaque ) { return; } c_areaFloods++; node->area = c_areas; for( p = node->portals ; p ; p = p->next[s] ) { node_t *other; s = ( p->nodes[1] == node ); other = p->nodes[!s]; if( !Portal_Passable( p ) ) { continue; } // can't flood through an area portal if( FindSideForPortal( p ) ) { continue; } FloodAreas_r( other ); } }
static void DrawTree_r(node_t * node) { int s; portal_t *p, *nextp; winding_t *w; if(node->planenum != PLANENUM_LEAF) { DrawTree_r(node->children[0]); DrawTree_r(node->children[1]); return; } // draw all the portals for(p = node->portals; p; p = p->next[s]) { w = p->winding; s = (p->nodes[1] == node); if(w) // && p->nodes[0] == node) { if(Portal_Passable(p)) continue; DrawPortal(p, node->areaportal); } } }
/* ================= 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(Portal_Passable(p)) 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"); } } } }
/* ================= 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 (!Portal_Passable(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); if (p->hint) fprintf (pf, "1 "); else fprintf (pf, "0 "); 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) { 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(Portal_Passable(p)) num_visportals++; else num_solidfaces++; p = p->next[0]; } else { if(!Portal_Passable(p)) num_solidfaces++; p = p->next[1]; } } }