outside.cc: prototype marking visible brush sides

This commit is contained in:
Eric Wasylishen 2022-04-09 21:46:01 -06:00
parent b1ba7064ea
commit 39d1930446
3 changed files with 67 additions and 10 deletions

View File

@ -21,5 +21,5 @@
#pragma once
bool FillOutside(node_t *node, const int hullnum);
bool FillOutside(mapentity_t *entity, node_t *node, const int hullnum);
std::vector<node_t *> FindOccupiedClusters(node_t *headnode);

View File

@ -321,6 +321,23 @@ std::vector<node_t *> FindOccupiedClusters(node_t *headnode)
return result;
}
//=============================================================================
static void AssertBrushSidesInvisible(node_t *node)
{
if (node->planenum != PLANENUM_LEAF) {
AssertBrushSidesInvisible(node->children[0]);
AssertBrushSidesInvisible(node->children[1]);
return;
}
for (auto *brush : node->original_brushes) {
for (const auto &face : brush->faces) {
Q_assert(!face.visible);
}
}
}
/*
==================
MarkVisibleBrushSides
@ -336,13 +353,32 @@ static void MarkVisibleBrushSides(node_t *node)
return;
}
// visit the leaf
if (node->opaque()) {
return;
}
// fixme-brushbsp: do a flood fill from all empty leafs.
// when we reach a portal to solid, look for a brush side with the same
// planenum. mark it as 'visible'.
// visit the non-opaque leaf: check all portals to neighbouring leafs.
int side;
for (portal_t *portal = node->portals; portal; portal = portal->next[!side]) {
side = (portal->nodes[0] == node);
node_t *neighbour_leaf = portal->nodes[side];
for (auto *brush : neighbour_leaf->original_brushes) {
for (auto &side : brush->faces) {
if (side.planenum == portal->planenum) {
// we've found a brush side in an original brush in the neighbouring
// leaf, on a portal to this (non-opaque) leaf, so mark it as visible.
side.visible = true;
}
}
}
}
}
//=============================================================================
static void OutLeafsToSolid_r(node_t *node, int *outleafs_count)
{
if (node->planenum != PLANENUM_LEAF) {
@ -393,11 +429,15 @@ Now all leafs marked "empty" are actually empty, not void.
This will handle partially-void, partially-in-bounds sides (they'll be marked visible).
(doing it the opposite way, defaulting brushes to "visible" and flood-filling
from the void wouldn't work, because brush sides that cross into the map would
get incorrectly marked as "invisible").
fixme-brushbsp: we'll want to do this for detail as well, which means building another set of
portals for everything (not just structural).
===========
*/
bool FillOutside(node_t *node, const int hullnum)
bool FillOutside(mapentity_t *entity, node_t *node, const int hullnum)
{
logging::print(logging::flag::PROGRESS, "---- {} ----\n", __func__);
@ -461,12 +501,29 @@ bool FillOutside(node_t *node, const int hullnum)
return false;
}
// change the leaf contents
const int outleafs = OutLeafsToSolid(node);
// See missing_face_simple.map for a test case with a brush that straddles between void and non-void
MarkVisibleBrushSides(node);
AssertBrushSidesInvisible(node);
MarkVisibleBrushSides(node);
// Count brush sides
int visible_brush_sides = 0;
int invisible_brush_sides = 0;
for (const auto &brush : entity->brushes) {
for (auto &side : brush.faces) {
if (side.visible) {
++visible_brush_sides;
} else {
++invisible_brush_sides;
}
}
}
logging::print(logging::flag::STAT, " {:8} outleafs\n", outleafs);
logging::print(logging::flag::STAT, " {:8} visible brush sides\n", visible_brush_sides);
logging::print(logging::flag::STAT, " {:8} invisible brush sides\n", invisible_brush_sides);
return true;
}

View File

@ -645,7 +645,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
if (entity == pWorldEnt() && !options.nofill.value()) {
// assume non-world bmodels are simple
PortalizeWorld(entity, nodes, hullnum);
if (FillOutside(nodes, hullnum)) {
if (FillOutside(entity, nodes, hullnum)) {
// fixme-brushbsp: re-add
// FreeNodes(nodes);
@ -685,7 +685,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
// marks brush sides which are *only* touching void;
// we can skip using them as BSP splitters on the "really good tree"
// (effectively expanding those brush sides outwards).
if (!options.nofill.value() && FillOutside(nodes, hullnum)) {
if (!options.nofill.value() && FillOutside(entity, nodes, hullnum)) {
// fixme-brushbsp: re-add
//FreeNodes(nodes);