From 70ea7525873a9adca2c4225d29d40ab24f419c87 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Sun, 20 Feb 2022 23:49:15 -0700 Subject: [PATCH] qbsp: restore MergeAll --- include/qbsp/merge.hh | 2 +- include/qbsp/surfaces.hh | 3 +- qbsp/merge.cc | 39 +++++++++++----- qbsp/qbsp.cc | 6 +++ qbsp/surfaces.cc | 39 +++++++++++++--- testmaps/qbsp_merge.map | 96 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 testmaps/qbsp_merge.map diff --git a/include/qbsp/merge.hh b/include/qbsp/merge.hh index 26f78cc2..132d4585 100644 --- a/include/qbsp/merge.hh +++ b/include/qbsp/merge.hh @@ -24,4 +24,4 @@ #include void MergeFaceToList(face_t *face, std::list &list); -void MergeAll(std::vector &surfhead); +void MergeAll(node_t *headnode); diff --git a/include/qbsp/surfaces.hh b/include/qbsp/surfaces.hh index 56ab0b0c..662969a3 100644 --- a/include/qbsp/surfaces.hh +++ b/include/qbsp/surfaces.hh @@ -25,4 +25,5 @@ std::vector GatherNodeFaces(node_t *headnode); void FreeNodes(node_t* node); -void MakeVisibleFaces(mapentity_t *entity, node_t *headnode); \ No newline at end of file +void MakeVisibleFaces(mapentity_t *entity, node_t *headnode); +void MakeMarkFaces(mapentity_t* entity, node_t* headnode); \ No newline at end of file diff --git a/qbsp/merge.cc b/qbsp/merge.cc index e10663ac..e38917b8 100644 --- a/qbsp/merge.cc +++ b/qbsp/merge.cc @@ -167,7 +167,9 @@ void MergeFaceToList(face_t *face, std::list &list) if (newf) { delete face; + delete *it; list.erase(it); + // restart, now trying to merge `newf` into the list face = newf; it = list.begin(); } else { @@ -180,37 +182,52 @@ void MergeFaceToList(face_t *face, std::list &list) /* =============== -MergePlaneFaces +MergeFaceList =============== */ -inline void MergePlaneFaces(surface_t &plane) +inline std::list MergeFaceList(std::list input) { - std::list merged; + std::list result; - for (auto &f : plane.faces) { - MergeFaceToList(f, merged); + for (face_t * face : input) { + MergeFaceToList(face, result); } - plane.faces = std::move(merged); + return result; } #include +static void CollectNodes_R(node_t *node, std::vector &allnodes) +{ + allnodes.push_back(node); + + if (node->planenum == PLANENUM_LEAF) { + return; + } + + CollectNodes_R(node->children[0], allnodes); + CollectNodes_R(node->children[1], allnodes); +} + /* ============ MergeAll ============ */ -void MergeAll(std::vector &surfhead) +void MergeAll(node_t *headnode) { std::atomic mergefaces = 0, premergefaces = 0; LogPrint(LOG_PROGRESS, "---- {} ----\n", __func__); - tbb::parallel_for_each(surfhead, [&](surface_t &surf) { - premergefaces += surf.faces.size(); - MergePlaneFaces(surf); - mergefaces += surf.faces.size(); + std::vector allnodes; + CollectNodes_R(headnode, allnodes); + + tbb::parallel_for_each(allnodes, [&](node_t *node) { + premergefaces += node->facelist.size(); + node->facelist = MergeFaceList(node->facelist); + mergefaces += node->facelist.size(); }); LogPrint(LOG_STAT, " {:8} mergefaces (from {}; {:.0}% merged)\n", mergefaces, premergefaces, (static_cast(mergefaces) / premergefaces) * 100.); diff --git a/qbsp/qbsp.cc b/qbsp/qbsp.cc index 184a76ba..a022cda3 100644 --- a/qbsp/qbsp.cc +++ b/qbsp/qbsp.cc @@ -570,6 +570,12 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum) MakeVisibleFaces(entity, nodes); + // fixme-brushbsp: only here for testing, was inside FillOutside if() + MergeAll(nodes); + + // needs to come after any face creation + MakeMarkFaces(entity, nodes); + // build all the portals in the bsp tree // some portals are solid polygons, and some are paths to other leafs if (entity == pWorldEnt()) { diff --git a/qbsp/surfaces.cc b/qbsp/surfaces.cc index db7a143d..c8150682 100644 --- a/qbsp/surfaces.cc +++ b/qbsp/surfaces.cc @@ -516,6 +516,16 @@ int MakeFaceEdges(mapentity_t *entity, node_t *headnode) static int c_nodefaces; +/* +================ +AddMarksurfaces_r + +Adds the given face to the markfaces lists of all descendant leafs of `node`. + +fixme-brushbsp: do this accurately, not exhaustively +fixme-brushbsp: all leafs in a cluster can share the same marksurfaces, right? +================ +*/ static void AddMarksurfaces_r(face_t *face, node_t *node) { if (node->planenum == PLANENUM_LEAF) { @@ -527,6 +537,30 @@ static void AddMarksurfaces_r(face_t *face, node_t *node) AddMarksurfaces_r(face, node->children[1]); } +/* +================ +MakeMarkFaces + +Populates the `markfaces` vectors of all leafs +================ +*/ +void MakeMarkFaces(mapentity_t* entity, node_t* node) +{ + if (node->planenum == PLANENUM_LEAF) { + return; + } + + // for the faces on this splitting node.. + for (face_t *face : node->facelist) { + // add this face to all descendant leafs (temporary hack) + AddMarksurfaces_r(face, node); + } + + // process child nodes recursively + MakeMarkFaces(entity, node->children[0]); + MakeMarkFaces(entity, node->children[1]); +} + static void AddFaceToTree_r(mapentity_t* entity, face_t *face, brush_t *srcbrush, node_t* node) { if (node->planenum == PLANENUM_LEAF) { @@ -555,11 +589,6 @@ static void AddFaceToTree_r(mapentity_t* entity, face_t *face, brush_t *srcbrush for (face_t *part: parts) { node->facelist.push_back(part); - - // Now that the final face has been added - // fixme-brushbsp: do this as a postprocessing step - // fixme-brushbsp: all leafs in a cluster can share the same marksurfaces, right? - AddMarksurfaces_r(part, node); } } diff --git a/testmaps/qbsp_merge.map b/testmaps/qbsp_merge.map new file mode 100644 index 00000000..34febacc --- /dev/null +++ b/testmaps/qbsp_merge.map @@ -0,0 +1,96 @@ +// Game: Quake +// Format: Valve +// entity 0 +{ +"mapversion" "220" +"classname" "worldspawn" +"wad" "deprecated/free_wad.wad;deprecated/fence.wad;deprecated/origin.wad;deprecated/hintskip.wad" +"_wateralpha" "0.5" +"_tb_def" "builtin:Quake.fgd" +// brush 0 +{ +( 176 16 96 ) ( 160 80 96 ) ( 160 80 224 ) orangestuff8 [ 0.24253562503633297 -0.9701425001453319 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 208 16 96 ) ( 176 64 96 ) ( 176 64 224 ) orangestuff8 [ 0.5547001962252291 -0.8320502943378437 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 96 80 ) ( 224 96 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 160 48 96 ) ( 112 16 96 ) ( 112 16 224 ) orangestuff8 [ 0.8320502943378437 0.5547001962252291 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 96 96 ) ( 224 0 80 ) ( 224 0 96 ) orangestuff8 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 1 +{ +( 208 16 96 ) ( 176 64 96 ) ( 176 64 224 ) orangestuff8 [ 0.5547001962252291 -0.8320502943378437 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 160 48 96 ) ( 112 16 224 ) ( 112 16 96 ) orangestuff8 [ -0.8320502943378437 -0.5547001962252291 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 0 96 ) ( 48 0 80 ) ( 48 0 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 224 0 80 ) ( 224 0 96 ) orangestuff8 [ 0 -1 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 2 +{ +( 208 16 96 ) ( 176 64 96 ) ( 176 64 224 ) orangestuff8 [ 0.5547001962252291 -0.8320502943378437 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 96 80 ) ( 224 96 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 176 16 96 ) ( 160 80 224 ) ( 160 80 96 ) orangestuff8 [ -0.24253562503633297 0.9701425001453319 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 3 +{ +( 176 16 96 ) ( 160 80 96 ) ( 160 80 224 ) orangestuff8 [ 0.24253562503633297 -0.9701425001453319 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 160 48 96 ) ( 112 16 96 ) ( 112 16 224 ) orangestuff8 [ 0.8320502943378437 0.5547001962252291 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 208 16 96 ) ( 176 64 224 ) ( 176 64 96 ) orangestuff8 [ -0.5547001962252291 0.8320502943378437 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 4 +{ +( 176 16 96 ) ( 160 80 96 ) ( 160 80 224 ) orangestuff8 [ 0.24253562503633297 -0.9701425001453319 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 160 48 96 ) ( 112 16 224 ) ( 112 16 96 ) orangestuff8 [ -0.8320502943378437 -0.5547001962252291 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 0 96 ) ( 48 0 80 ) ( 48 0 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 208 16 96 ) ( 176 64 224 ) ( 176 64 96 ) orangestuff8 [ -0.5547001962252291 0.8320502943378437 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 5 +{ +( 128 16 96 ) ( 112 48 96 ) ( 112 48 224 ) orangestuff8 [ 0.447213595499958 -0.894427190999916 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 96 80 ) ( 224 96 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 160 48 96 ) ( 112 16 96 ) ( 112 16 224 ) orangestuff8 [ 0.8320502943378437 0.5547001962252291 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 208 16 96 ) ( 176 64 224 ) ( 176 64 96 ) orangestuff8 [ -0.5547001962252291 0.8320502943378437 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 176 16 96 ) ( 160 80 224 ) ( 160 80 96 ) orangestuff8 [ -0.24253562503633297 0.9701425001453319 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 6 +{ +( 48 0 96 ) ( 48 96 80 ) ( 48 96 96 ) orangestuff8 [ 0 1 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 224 0 96 ) ( 48 0 80 ) ( 48 0 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 96 80 ) ( 224 96 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 160 48 96 ) ( 112 16 96 ) ( 112 16 224 ) orangestuff8 [ 0.8320502943378437 0.5547001962252291 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 128 16 96 ) ( 112 48 224 ) ( 112 48 96 ) orangestuff8 [ -0.447213595499958 0.894427190999916 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 7 +{ +( 128 16 96 ) ( 112 48 96 ) ( 112 48 224 ) orangestuff8 [ 0.447213595499958 -0.894427190999916 0 0 ] [ 0 0 -1 0 ] 0 2 2 +( 160 48 96 ) ( 112 16 224 ) ( 112 16 96 ) orangestuff8 [ -0.8320502943378437 -0.5547001962252291 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 0 96 ) ( 48 0 80 ) ( 48 0 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 176 16 96 ) ( 160 80 224 ) ( 160 80 96 ) orangestuff8 [ -0.24253562503633297 0.9701425001453319 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +// brush 8 +{ +( 160 48 96 ) ( 112 16 224 ) ( 112 16 96 ) orangestuff8 [ -0.8320502943378437 -0.5547001962252291 0 -32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 0 96 ) ( 48 0 80 ) ( 48 0 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 0 -1 0 ] 180 2 2 +( 224 96 80 ) ( 48 0 80 ) ( 224 0 80 ) orangestuff8 [ 1 0 0 -32 ] [ 0 -1 0 0 ] 180 2 2 +( 224 96 96 ) ( 48 0 96 ) ( 48 96 96 ) orangestuff8 [ -1 0 0 32 ] [ 0 -1 0 0 ] 180 2 2 +( 128 16 96 ) ( 112 48 224 ) ( 112 48 96 ) orangestuff8 [ -0.447213595499958 0.894427190999916 0 0 ] [ 0 0 -1 0 ] 0 2 2 +} +} +// entity 1 +{ +"classname" "info_player_start" +"origin" "72 32 120" +}