From 8d5978dcc2f3e7b8a304e4754fd79872d40f3a94 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sat, 18 Jun 2022 13:42:41 -0600 Subject: [PATCH] qbsp: switch to qbsp3 implementation for MakeTreePortals Quick update to outside filling to remove cluster handling, because now we perform filling with all leaf portals --- qbsp/outside.cc | 84 ++++++++++++++----------------------------------- qbsp/portals.cc | 8 +++-- 2 files changed, 30 insertions(+), 62 deletions(-) diff --git a/qbsp/outside.cc b/qbsp/outside.cc index 2fa3f30c..8a5ff364 100644 --- a/qbsp/outside.cc +++ b/qbsp/outside.cc @@ -34,27 +34,9 @@ #include #include -static bool AllSolid(const node_t* node) { - if (node->planenum != PLANENUM_LEAF) { - return AllSolid(node->children[0]) && AllSolid(node->children[1]); - } - - return node->contents.is_solid(options.target_game); -} - -static bool ClusterSealsMap(const node_t *node) +static bool LeafSealsMap(const node_t *node) { - Q_assert(node->planenum == PLANENUM_LEAF || node->detail_separator); - - // detail separators can seal if all leafs have been turned to solid by outside filling - if (node->detail_separator && AllSolid(node)) { - return true; - } - - // normally detail doesn't seal - if (node->detail_separator) { - return false; - } + Q_assert(node->planenum == PLANENUM_LEAF); return options.target_game->contents_seals_map(node->contents); } @@ -70,9 +52,9 @@ This avoids spurious leaks if a point entity is on the outside of the map (exactly on a brush faces) - happens in base1.map. =========== */ -static node_t *PointInCluster(node_t *node, const qvec3d &point) +static node_t *PointInLeaf(node_t *node, const qvec3d &point) { - if (node->planenum == PLANENUM_LEAF || node->detail_separator) { + if (node->planenum == PLANENUM_LEAF) { return node; } @@ -81,18 +63,18 @@ static node_t *PointInCluster(node_t *node, const qvec3d &point) if (dist > 0) { // point is on the front of the node plane - return PointInCluster(node->children[0], point); + return PointInLeaf(node->children[0], point); } else if (dist < 0) { // point is on the back of the node plane - return PointInCluster(node->children[1], point); + return PointInLeaf(node->children[1], point); } else { // point is exactly on the node plane - node_t *front = PointInCluster(node->children[0], point); - node_t *back = PointInCluster(node->children[1], point); + node_t *front = PointInLeaf(node->children[0], point); + node_t *back = PointInLeaf(node->children[1], point); // prefer the opaque one - if (ClusterSealsMap(front)) { + if (LeafSealsMap(front)) { return front; } return back; @@ -101,7 +83,7 @@ static node_t *PointInCluster(node_t *node, const qvec3d &point) static void ClearOccupied_r(node_t *node) { - // we need to clear this on leaf nodes and detail separators (clusters).. just clear it on everything + // we need to clear this on leaf nodes.. just clear it on everything node->outside_distance = -1; node->occupied = 0; node->occupant = nullptr; @@ -120,16 +102,9 @@ static bool OutsideFill_Passable(const portal_t *p) } auto leafOpaque = [](const node_t *l) { - Q_assert(l->planenum == PLANENUM_LEAF || l->detail_separator); + Q_assert(l->planenum == PLANENUM_LEAF); - // fixme-brushbsp: confirm, why was this not needed before? - // detail separators are treated as non-opaque because detail doesn't block vis - // fixme-brushbsp: should probably move to node_t::opaque() - if (l->detail_separator) { - return false; - } - - return ClusterSealsMap(l); + return LeafSealsMap(l); }; if (leafOpaque(p->nodes[0]) || leafOpaque(p->nodes[1])) @@ -180,8 +155,8 @@ static void FloodFillClustersFromVoid(tree_t *tree) Q_assert(fillnode != &tree->outside_node); - // this must be true because the map is made from closed brushes, beyion which is void - Q_assert(!ClusterSealsMap(fillnode)); + // this must be true because the map is made from closed brushes, beyond which is void + Q_assert(!LeafSealsMap(fillnode)); queue.emplace_back(fillnode, 0); } @@ -340,9 +315,9 @@ static void MarkOccupiedClusters(node_t *headnode) #endif /* find the leaf it's in. Skip opqaue leafs */ - node_t *cluster = PointInCluster(headnode, entity->origin); + node_t *cluster = PointInLeaf(headnode, entity->origin); - if (ClusterSealsMap(cluster)) { + if (LeafSealsMap(cluster)) { continue; } @@ -357,7 +332,6 @@ static void MarkOccupiedClusters(node_t *headnode) static void FindOccupiedClusters_R(node_t *node, std::vector& result) { - // node could be a leaf or detail separator node if (node->occupant) { result.push_back(node); } @@ -418,23 +392,19 @@ Set f->touchesOccupiedLeaf=true on faces that are touching occupied leafs */ static void MarkVisibleBrushSides_R(node_t *node) { - // descent to clusters - if (!(node->planenum == PLANENUM_LEAF || node->detail_separator)) { + // descent to leafs + if (!(node->planenum == PLANENUM_LEAF)) { MarkVisibleBrushSides_R(node->children[0]); MarkVisibleBrushSides_R(node->children[1]); return; } - if (ClusterSealsMap(node)) { + if (LeafSealsMap(node)) { // this cluster is opaque return; } - if (node->detail_separator) { - // this is a detail cluster, so mark all descendant brushes (all sides) as visible - MarkAllBrushSidesVisible_R(node); - } - + Q_assert(!node->detail_separator); // we also want to mark brush sides in the neighbouring cluster // as visible @@ -458,11 +428,8 @@ static void MarkVisibleBrushSides_R(node_t *node) } } } else { - // other case: neighbour is a detail separator, so it has detail at a finer granularity - // than the portal. Need to mark all brush sides as potentially visible. - Q_assert(neighbour_leaf->detail_separator); - MarkAllBrushSidesVisible_R(neighbour_leaf); - } + Q_assert(false); + } } } @@ -537,11 +504,8 @@ static void BFSFloodFillFromOccupiedLeafs(const std::vector &occupied_ if (node->occupied == 0) { // we haven't visited this node yet - if (node->detail_separator) { - SetOccupied_R(node, dist); - } else { - node->occupied = dist; - } + Q_assert(!node->detail_separator); + node->occupied = dist; // push neighbouring nodes onto the back of the queue int side; diff --git a/qbsp/portals.cc b/qbsp/portals.cc index 5724d06a..ed0460ee 100644 --- a/qbsp/portals.cc +++ b/qbsp/portals.cc @@ -457,8 +457,12 @@ void MakeTreePortals_r(node_t *node, portalstats_t &stats) MakeTreePortals ================== */ -void MakeTreePortals_new(tree_t *tree) +void MakeTreePortals(tree_t *tree) { + FreeTreePortals_r(tree->headnode); + + AssertNoPortals(tree->headnode); + portalstats_t stats{}; MakeHeadnodePortals(tree); @@ -602,7 +606,7 @@ PortalizeWorld Builds the exact polyhedrons for the nodes and leafs ================== */ -void MakeTreePortals(tree_t *tree) +void MakeTreePortals_old(tree_t *tree) { FreeTreePortals_r(tree->headnode);