static int NumberNodes_r( node_t *node, int nextNumber ) { if ( node->planenum == PLANENUM_LEAF ) { return nextNumber; } node->nodeNumber = nextNumber; nextNumber++; nextNumber = NumberNodes_r( node->children[0], nextNumber ); nextNumber = NumberNodes_r( node->children[1], nextNumber ); return nextNumber; }
/* ==================== WriteOutputNodes ==================== */ static void WriteOutputNodes( node_t *node ) { int numNodes; // prune unneeded nodes and count PruneNodes_r( node ); numNodes = NumberNodes_r( node, 0 ); // output procFile->WriteFloatString( "nodes { /* numNodes = */ %i\n\n", numNodes ); procFile->WriteFloatString( "/* node format is: ( planeVector ) positiveChild negativeChild */\n" ); procFile->WriteFloatString( "/* a child number of 0 is an opaque, solid area */\n" ); procFile->WriteFloatString( "/* negative child numbers are areas: (-1-child) */\n" ); WriteNode_r( node ); procFile->WriteFloatString( "}\n\n" ); }
/* ============ ProcessModel ============ */ bool ProcessModel( uEntity_t* e, bool floodFill ) { bspface_t* faces; // build a bsp tree using all of the sides // of all of the structural brushes faces = MakeStructuralBspFaceList( e->primitives ); // RB: dump BSP for debugging if( dmapGlobals.glview ) { WriteGLView( faces, "facelist" ); } // RB end e->tree = FaceBSP( faces ); // create portals at every leaf intersection // to allow flood filling MakeTreePortals( e->tree ); // RB: calculate node numbers for split plane analysis NumberNodes_r( e->tree->headnode, 0 ); // classify the leafs as opaque or areaportal FilterBrushesIntoTree( e ); // RB: use mapTri_t by MapPolygonMesh primitives in case we don't use brushes FilterMeshesIntoTree( e ); // RB: dump BSP for debugging //if( dmapGlobals.glview ) //{ //WriteGLView( e->tree, "unclipped", dmapGlobals.entityNum ); //} // RB end // see if the bsp is completely enclosed if( floodFill && !dmapGlobals.noFlood ) { if( FloodEntities( e->tree ) ) { // set the outside leafs to opaque FillOutside( e ); } else { common->Printf( "**********************\n" ); common->Warning( "******* leaked *******" ); common->Printf( "**********************\n" ); LeakFile( e->tree ); // bail out here. If someone really wants to // process a map that leaks, they should use // -noFlood return false; } } // get minimum convex hulls for each visible side // this must be done before creating area portals, // because the visible hull is used as the portal ClipSidesByTree( e ); // determine areas before clipping tris into the // tree, so tris will never cross area boundaries FloodAreas( e ); // RB: dump BSP for debugging if( dmapGlobals.glview ) { WriteGLView( e->tree, "areas", dmapGlobals.entityNum ); } // RB end // we now have a BSP tree with solid and non-solid leafs marked with areas // all primitives will now be clipped into this, throwing away // fragments in the solid areas PutPrimitivesInAreas( e ); // now build shadow volumes for the lights and split // the optimize lists by the light beam trees // so there won't be unneeded overdraw in the static // case Prelight( e ); // optimizing is a superset of fixing tjunctions if( !dmapGlobals.noOptimize ) { OptimizeEntity( e ); } else if( !dmapGlobals.noTJunc ) { FixEntityTjunctions( e ); } // now fix t junctions across areas FixGlobalTjunctions( e ); return true; }