//----------------------------------------------------------------------------- // Purpose: Build faces for the detail brushes and merge them into the BSP // Input : *worldtree - // brush_start - // brush_end - //----------------------------------------------------------------------------- face_t *MergeDetailTree( tree_t *worldtree, int brush_start, int brush_end ) { int start; bspbrush_t *detailbrushes = NULL; tree_t *detailtree = NULL; face_t *pFaces = NULL; face_t *pLeafFaceList = NULL; // Grab the list of detail brushes detailbrushes = MakeBspBrushList (brush_start, brush_end, map_mins, map_maxs, ONLY_DETAIL ); if (detailbrushes) { start = Plat_FloatTime(); Msg("Chop Details..."); // if there are detail brushes, chop them against each other if (!nocsg) detailbrushes = ChopBrushes (detailbrushes); Msg("done (%d)\n", (int)(Plat_FloatTime() - start) ); // Now mark the visible sides so we can eliminate all detail brush sides // that are covered by other detail brush sides // NOTE: This still leaves detail brush sides that are covered by the world. (these are removed in the merge operation) Msg("Find Visible Detail Sides..."); pFaces = ComputeVisibleBrushSides( detailbrushes ); TryMergeFaceList( &pFaces ); SubdivideFaceList( &pFaces ); Msg("done (%d)\n", (int)(Plat_FloatTime() - start) ); start = Plat_FloatTime(); Msg("Merging details..."); // Merge the detail solids and faces into the world tree // Merge all of the faces into the world tree pLeafFaceList = FilterFacesIntoTree( worldtree, pFaces ); FilterBrushesIntoTree( worldtree, detailbrushes ); FreeFaceList( pFaces ); FreeBrushList(detailbrushes); Msg("done (%d)\n", (int)(Plat_FloatTime() - start) ); } return pLeafFaceList; }
/* ============ 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 ); e->tree = FaceBSP( faces ); // create portals at every leaf intersection // to allow flood filling MakeTreePortals( e->tree ); // classify the leafs as opaque or areaportal FilterBrushesIntoTree( e ); // 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 ); // 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; }