diff --git a/include/qbsp/outside.hh b/include/qbsp/outside.hh index f8879172..030d546e 100644 --- a/include/qbsp/outside.hh +++ b/include/qbsp/outside.hh @@ -22,4 +22,6 @@ #pragma once bool FillOutside(mapentity_t *entity, node_t *node, const int hullnum); -std::vector FindOccupiedClusters(node_t *headnode); \ No newline at end of file +std::vector FindOccupiedClusters(node_t *headnode); + +void FillBrushEntity(mapentity_t *entity, node_t *node, const int hullnum); diff --git a/include/qbsp/portals.hh b/include/qbsp/portals.hh index e2c7cf39..16e7d4b8 100644 --- a/include/qbsp/portals.hh +++ b/include/qbsp/portals.hh @@ -35,5 +35,5 @@ struct portal_t extern node_t outside_node; // portals outside the world face this contentflags_t ClusterContents(const node_t *node); -void PortalizeWorld(const mapentity_t *entity, node_t *headnode, const int hullnum); +void PortalizeEntity(const mapentity_t *entity, node_t *headnode, const int hullnum); void FreeAllPortals(node_t *node); diff --git a/qbsp/outside.cc b/qbsp/outside.cc index abcca899..750c552d 100644 --- a/qbsp/outside.cc +++ b/qbsp/outside.cc @@ -585,3 +585,15 @@ bool FillOutside(mapentity_t *entity, node_t *node, const int hullnum) logging::print(logging::flag::STAT, " {:8} outleafs\n", outleafs); return true; } + +void FillBrushEntity(mapentity_t* entity, node_t* node, const int hullnum) +{ + logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__); + + // Clear the outside filling state on all nodes + ClearOccupied_r(node); + + MarkBrushSidesInvisible(entity); + + MarkVisibleBrushSides_R(node); +} diff --git a/qbsp/portals.cc b/qbsp/portals.cc index d1e403bd..5bfdfd43 100644 --- a/qbsp/portals.cc +++ b/qbsp/portals.cc @@ -617,7 +617,7 @@ PortalizeWorld Builds the exact polyhedrons for the nodes and leafs ================== */ -void PortalizeWorld(const mapentity_t *entity, node_t *headnode, const int hullnum) +void PortalizeEntity(const mapentity_t *entity, node_t *headnode, const int hullnum) { logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__); @@ -630,7 +630,7 @@ void PortalizeWorld(const mapentity_t *entity, node_t *headnode, const int hulln logging::percent(splitnodes, splitnodes, entity == map.world_entity()); - if (hullnum <= 0) { + if (hullnum <= 0 && entity == map.world_entity()) { /* save portal file for vis tracing */ WritePortalfile(headnode, &state); diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index b76ef9b7..6b458da0 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -699,7 +699,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) nodes = SolidBSP(entity, true); if (entity == map.world_entity() && !options.nofill.value()) { // assume non-world bmodels are simple - PortalizeWorld(entity, nodes, hullnum); + PortalizeEntity(entity, nodes, hullnum); if (FillOutside(entity, nodes, hullnum)) { // fixme-brushbsp: re-add // FreeNodes(nodes); @@ -732,10 +732,9 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) // build all the portals in the bsp tree // some portals are solid polygons, and some are paths to other leafs - if (entity == map.world_entity()) { - // assume non-world bmodels are simple - PortalizeWorld(entity, nodes, hullnum); + PortalizeEntity(entity, nodes, hullnum); + if (entity == map.world_entity()) { // flood fills from the void. // marks brush sides which are *only* touching void; // we can skip using them as BSP splitters on the "really good tree" @@ -748,7 +747,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) nodes = SolidBSP(entity, false); // make the real portals for vis tracing - PortalizeWorld(entity, nodes, hullnum); + PortalizeEntity(entity, nodes, hullnum); } // Area portals @@ -756,6 +755,11 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) FloodAreas(entity, nodes); EmitAreaPortals(nodes); } + } else { + FillBrushEntity(entity, nodes, hullnum); + + // rebuild BSP now that we've marked invisible brush sides + nodes = SolidBSP(entity, false); } PruneNodes(nodes);