group together # of clipped faces, to reduce console spam of Q1 maps

always allow midplane split for hulls
This commit is contained in:
Jonathan 2022-08-12 21:38:41 -04:00
parent e7647f5ca7
commit 6d66e6d5cf
6 changed files with 34 additions and 23 deletions

View File

@ -93,5 +93,5 @@ struct bspbrush_t
bspbrush_t clone() const; bspbrush_t clone() const;
}; };
std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush, const contentflags_t &contents, const int hullnum); std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush, const contentflags_t &contents, const int hullnum, std::optional<std::reference_wrapper<size_t>> num_clipped);
bool CreateBrushWindings(bspbrush_t *brush); bool CreateBrushWindings(bspbrush_t *brush);

View File

@ -345,7 +345,7 @@ qvec3d FixRotateOrigin(mapentity_t *entity);
constexpr int HULL_COLLISION = -1; constexpr int HULL_COLLISION = -1;
/* Create BSP brushes from map brushes */ /* Create BSP brushes from map brushes */
void Brush_LoadEntity(mapentity_t *entity, const int hullnum, bspbrush_t::container &brushes); void Brush_LoadEntity(mapentity_t *entity, const int hullnum, bspbrush_t::container &brushes, size_t &num_clipped);
std::list<face_t *> CSGFace( std::list<face_t *> CSGFace(
face_t *srcface, const mapentity_t *srcentity, const bspbrush_t *srcbrush, const node_t *srcnode); face_t *srcface, const mapentity_t *srcentity, const bspbrush_t *srcbrush, const node_t *srcnode);

View File

@ -103,9 +103,10 @@ CheckFace
Note: this will not catch 0 area polygons Note: this will not catch 0 area polygons
================= =================
*/ */
static void CheckFace(side_t *face, const mapface_t &sourceface) static void CheckFace(side_t *face, const mapface_t &sourceface, std::optional<std::reference_wrapper<size_t>> num_clipped)
{ {
if (face->w.size() < 3) { if (face->w.size() < 3) {
if (qbsp_options.verbose.value()) {
if (face->w.size() == 2) { if (face->w.size() == 2) {
logging::print( logging::print(
"WARNING: {}: partially clipped into degenerate polygon @ ({}) - ({})\n", sourceface.line, face->w[0], face->w[1]); "WARNING: {}: partially clipped into degenerate polygon @ ({}) - ({})\n", sourceface.line, face->w[0], face->w[1]);
@ -114,6 +115,11 @@ static void CheckFace(side_t *face, const mapface_t &sourceface)
} else { } else {
logging::print("WARNING: {}: completely clipped away\n", sourceface.line); logging::print("WARNING: {}: completely clipped away\n", sourceface.line);
} }
}
if (num_clipped) {
(*num_clipped)++;
}
face->w.clear(); face->w.clear();
return; return;
@ -151,7 +157,7 @@ static void CheckFace(side_t *face, const mapface_t &sourceface)
for (size_t j = i + 1; j < face->w.size(); j++) for (size_t j = i + 1; j < face->w.size(); j++)
face->w[j - 1] = face->w[j]; face->w[j - 1] = face->w[j];
face->w.resize(face->w.size() - 1); face->w.resize(face->w.size() - 1);
CheckFace(face, sourceface); CheckFace(face, sourceface, num_clipped);
break; break;
} }
@ -298,7 +304,7 @@ Converts a mapbrush to a bsp brush
=============== ===============
*/ */
std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush, const contentflags_t &contents, std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush, const contentflags_t &contents,
const int hullnum) const int hullnum, std::optional<std::reference_wrapper<size_t>> num_clipped)
{ {
// create the brush // create the brush
bspbrush_t brush{}; bspbrush_t brush{};
@ -352,7 +358,7 @@ std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush
} }
for (auto &face : brush.sides) { for (auto &face : brush.sides) {
CheckFace(&face, *face.source); CheckFace(&face, *face.source, num_clipped);
} }
// Rotatable objects must have a bounding box big enough to // Rotatable objects must have a bounding box big enough to
@ -393,7 +399,7 @@ std::optional<bspbrush_t> LoadBrush(const mapentity_t *src, mapbrush_t *mapbrush
//============================================================================= //=============================================================================
static void Brush_LoadEntity(mapentity_t *dst, mapentity_t *src, const int hullnum, content_stats_base_t &stats, bspbrush_t::container &brushes, logging::percent_clock &clock) static void Brush_LoadEntity(mapentity_t *dst, mapentity_t *src, const int hullnum, content_stats_base_t &stats, bspbrush_t::container &brushes, logging::percent_clock &clock, size_t &num_clipped)
{ {
// _omitbrushes 1 just discards all brushes in the entity. // _omitbrushes 1 just discards all brushes in the entity.
// could be useful for geometry guides, selective compilation, etc. // could be useful for geometry guides, selective compilation, etc.
@ -494,7 +500,7 @@ static void Brush_LoadEntity(mapentity_t *dst, mapentity_t *src, const int hulln
*/ */
if (hullnum != HULL_COLLISION && contents.is_clip(qbsp_options.target_game)) { if (hullnum != HULL_COLLISION && contents.is_clip(qbsp_options.target_game)) {
if (hullnum == 0) { if (hullnum == 0) {
if (auto brush = LoadBrush(src, &mapbrush, contents, hullnum)) { if (auto brush = LoadBrush(src, &mapbrush, contents, hullnum, num_clipped)) {
dst->bounds += brush->bounds; dst->bounds += brush->bounds;
} }
continue; continue;
@ -541,7 +547,7 @@ static void Brush_LoadEntity(mapentity_t *dst, mapentity_t *src, const int hulln
contents.set_clips_same_type(clipsametype); contents.set_clips_same_type(clipsametype);
contents.illusionary_visblocker = func_illusionary_visblocker; contents.illusionary_visblocker = func_illusionary_visblocker;
auto brush = LoadBrush(src, &mapbrush, contents, hullnum); auto brush = LoadBrush(src, &mapbrush, contents, hullnum, num_clipped);
if (!brush) { if (!brush) {
continue; continue;
@ -562,7 +568,7 @@ hullnum HULL_COLLISION should contain ALL brushes. (used by BSPX_CreateBrushList
hullnum 0 does not contain clip brushes. hullnum 0 does not contain clip brushes.
============ ============
*/ */
void Brush_LoadEntity(mapentity_t *entity, const int hullnum, bspbrush_t::container &brushes) void Brush_LoadEntity(mapentity_t *entity, const int hullnum, bspbrush_t::container &brushes, size_t &num_clipped)
{ {
logging::funcheader(); logging::funcheader();
@ -570,7 +576,7 @@ void Brush_LoadEntity(mapentity_t *entity, const int hullnum, bspbrush_t::contai
logging::percent_clock clock(0); logging::percent_clock clock(0);
clock.displayElapsed = (entity == map.world_entity()); clock.displayElapsed = (entity == map.world_entity());
Brush_LoadEntity(entity, entity, hullnum, *stats, brushes, clock); Brush_LoadEntity(entity, entity, hullnum, *stats, brushes, clock, num_clipped);
/* /*
* If this is the world entity, find all func_group and func_detail * If this is the world entity, find all func_group and func_detail
@ -590,7 +596,7 @@ void Brush_LoadEntity(mapentity_t *entity, const int hullnum, bspbrush_t::contai
ProcessAreaPortal(source); ProcessAreaPortal(source);
if (IsWorldBrushEntity(source) || IsNonRemoveWorldBrushEntity(source)) { if (IsWorldBrushEntity(source) || IsNonRemoveWorldBrushEntity(source)) {
Brush_LoadEntity(entity, source, hullnum, *stats, brushes, clock); Brush_LoadEntity(entity, source, hullnum, *stats, brushes, clock, num_clipped);
} }
} }
} }

View File

@ -2860,7 +2860,7 @@ static void TestExpandBrushes(mapentity_t *src)
for (auto &mapbrush : src->mapbrushes) { for (auto &mapbrush : src->mapbrushes) {
auto hull1brush = LoadBrush(src, &mapbrush, {CONTENTS_SOLID}, auto hull1brush = LoadBrush(src, &mapbrush, {CONTENTS_SOLID},
qbsp_options.target_game->id == GAME_QUAKE_II ? HULL_COLLISION : 1); qbsp_options.target_game->id == GAME_QUAKE_II ? HULL_COLLISION : 1, std::nullopt);
if (hull1brush) { if (hull1brush) {
hull1brushes.emplace_back(bspbrush_t::make_ptr(std::move(*hull1brush))); hull1brushes.emplace_back(bspbrush_t::make_ptr(std::move(*hull1brush)));

View File

@ -451,7 +451,12 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
/* /*
* Convert the map brushes (planes) into BSP brushes (polygons) * Convert the map brushes (planes) into BSP brushes (polygons)
*/ */
Brush_LoadEntity(entity, hullnum, brushes); size_t num_clipped = 0;
Brush_LoadEntity(entity, hullnum, brushes, num_clipped);
if (num_clipped && !qbsp_options.verbose.value()) {
logging::print("WARNING: {} faces were clipped away. This is normal for expanded hulls; use -verbose if you need more info.\n", num_clipped);
}
size_t num_sides = 0; size_t num_sides = 0;
for (size_t i = 0; i < brushes.size(); ++i) { for (size_t i = 0; i < brushes.size(); ++i) {
@ -481,7 +486,7 @@ static void ProcessEntity(mapentity_t *entity, const int hullnum)
if (FillOutside(entity, tree.get(), hullnum, brushes)) { if (FillOutside(entity, tree.get(), hullnum, brushes)) {
// make a really good tree // make a really good tree
tree.reset(); tree.reset();
tree = BrushBSP(entity, brushes, false); tree = BrushBSP(entity, brushes, std::nullopt);
// fill again so PruneNodes works // fill again so PruneNodes works
MakeTreePortals(tree.get()); MakeTreePortals(tree.get());

View File

@ -398,7 +398,7 @@ TEST_CASE("duplicatePlanes", "[qbsp]")
REQUIRE(1 == worldspawn.mapbrushes.size()); REQUIRE(1 == worldspawn.mapbrushes.size());
CHECK(6 == worldspawn.mapbrushes.front().faces.size()); CHECK(6 == worldspawn.mapbrushes.front().faces.size());
auto brush = LoadBrush(&worldspawn, &worldspawn.mapbrushes.front(), {CONTENTS_SOLID}, 0); auto brush = LoadBrush(&worldspawn, &worldspawn.mapbrushes.front(), {CONTENTS_SOLID}, 0, std::nullopt);
CHECK(6 == brush->sides.size()); CHECK(6 == brush->sides.size());
} }