From dfb8d7c9fc9f41bb35b78c5b3f4445a8971c87a8 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Wed, 15 Jun 2022 21:37:19 -0600 Subject: [PATCH] qbsp: refactoring portal code towards qbsp3 --- include/qbsp/portals.hh | 3 ++- qbsp/portals.cc | 45 +++++++++++++++++++++++++++-------------- qbsp/qbsp.cc | 14 ++++++++----- 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/include/qbsp/portals.hh b/include/qbsp/portals.hh index 69b999e4..e2928bbc 100644 --- a/include/qbsp/portals.hh +++ b/include/qbsp/portals.hh @@ -41,5 +41,6 @@ struct tree_t }; contentflags_t ClusterContents(const node_t *node); -void PortalizeEntity(const mapentity_t *entity, tree_t *tree, const int hullnum); +void MakeTreePortals(tree_t *tree); void FreeAllPortals(node_t *node); +void WritePortalFile(tree_t *tree); diff --git a/qbsp/portals.cc b/qbsp/portals.cc index 48968002..9604299f 100644 --- a/qbsp/portals.cc +++ b/qbsp/portals.cc @@ -338,7 +338,7 @@ MakeHeadnodePortals The created portals will face the global outside_node ================ */ -static void MakeHeadnodePortals(const mapentity_t *entity, tree_t *tree) +static void MakeHeadnodePortals(tree_t *tree) { int i, j, n; portal_t *p, *portals[6]; @@ -346,7 +346,7 @@ static void MakeHeadnodePortals(const mapentity_t *entity, tree_t *tree) side_t side; // pad with some space so there will never be null volume leafs - aabb3d bounds = entity->bounds.grow(SIDESPACE); + aabb3d bounds = tree->bounds.grow(SIDESPACE); tree->outside_node.planenum = PLANENUM_LEAF; tree->outside_node.contents = options.target_game->create_solid_contents(); @@ -614,7 +614,25 @@ PortalizeWorld Builds the exact polyhedrons for the nodes and leafs ================== */ -void PortalizeEntity(const mapentity_t *entity, tree_t *tree, const int hullnum) +void MakeTreePortals(tree_t *tree) +{ + portal_state_t state{}; + + state.iNodesDone = 0; + + FreeAllPortals(tree->headnode); + + AssertNoPortals(tree->headnode); + MakeHeadnodePortals(tree); + CutNodePortals_r(tree->headnode, &state); +} + +/* +================== +WritePortalFile +================== +*/ +void WritePortalFile(tree_t *tree) { logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__); @@ -622,21 +640,18 @@ void PortalizeEntity(const mapentity_t *entity, tree_t *tree, const int hullnum) state.iNodesDone = 0; + FreeAllPortals(tree->headnode); + AssertNoPortals(tree->headnode); - MakeHeadnodePortals(entity, tree); + MakeHeadnodePortals(tree); CutNodePortals_r(tree->headnode, &state); - logging::percent(splitnodes, splitnodes, entity == map.world_entity()); + /* save portal file for vis tracing */ + WritePortalfile(tree->headnode, &state); - // fixme-brushbsp: extract this out like q2 tools - if (hullnum <= 0 && entity == map.world_entity()) { - /* save portal file for vis tracing */ - WritePortalfile(tree->headnode, &state); - - logging::print(logging::flag::STAT, " {:8} vis leafs\n", state.num_visleafs); - logging::print(logging::flag::STAT, " {:8} vis clusters\n", state.num_visclusters); - logging::print(logging::flag::STAT, " {:8} vis portals\n", state.num_visportals); - } + logging::print(logging::flag::STAT, " {:8} vis leafs\n", state.num_visleafs); + logging::print(logging::flag::STAT, " {:8} vis clusters\n", state.num_visclusters); + logging::print(logging::flag::STAT, " {:8} vis portals\n", state.num_visportals); } /* @@ -663,5 +678,5 @@ void FreeAllPortals(node_t *node) RemovePortalFromNode(p, p->nodes[1]); delete p; } - node->portals = NULL; + node->portals = nullptr; } diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 5db2c3e8..4eb35ad5 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -825,7 +825,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) tree = BrushBSP(entity, true); if (entity == map.world_entity() && !options.nofill.value()) { // assume non-world bmodels are simple - PortalizeEntity(entity, tree, hullnum); + MakeTreePortals(tree); if (FillOutside(entity, tree, hullnum)) { // fixme-brushbsp: re-add // FreeNodes(nodes); @@ -834,7 +834,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) tree = BrushBSP(entity, false); // fill again so PruneNodes works - PortalizeEntity(entity, tree, hullnum); + MakeTreePortals(tree); FillOutside(entity, tree, hullnum); PruneNodes(tree->headnode); DetailToSolid(tree->headnode); @@ -862,7 +862,7 @@ 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 - PortalizeEntity(entity, tree, hullnum); + MakeTreePortals(tree); if (entity == map.world_entity()) { // flood fills from the void. @@ -877,7 +877,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) tree = BrushBSP(entity, false); // make the real portals for vis tracing - PortalizeEntity(entity, tree, hullnum); + MakeTreePortals(tree); // fill again so PruneNodes works FillOutside(entity, tree, hullnum); @@ -899,10 +899,14 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) PruneNodes(tree->headnode); - PortalizeEntity(entity, tree, hullnum); + MakeTreePortals(tree); MakeVisibleFaces(entity, tree->headnode); + if (hullnum <= 0 && entity == map.world_entity() && !map.leakfile) { + WritePortalFile(tree); + } + // merge polygons MergeAll(tree->headnode);