group together # of clipped faces, to reduce console spam of Q1 maps
always allow midplane split for hulls
This commit is contained in:
parent
e7647f5ca7
commit
6d66e6d5cf
|
|
@ -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);
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -103,16 +103,22 @@ 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 (face->w.size() == 2) {
|
if (qbsp_options.verbose.value()) {
|
||||||
logging::print(
|
if (face->w.size() == 2) {
|
||||||
"WARNING: {}: partially clipped into degenerate polygon @ ({}) - ({})\n", sourceface.line, face->w[0], face->w[1]);
|
logging::print(
|
||||||
} else if (face->w.size() == 1) {
|
"WARNING: {}: partially clipped into degenerate polygon @ ({}) - ({})\n", sourceface.line, face->w[0], face->w[1]);
|
||||||
logging::print("WARNING: {}: partially clipped into degenerate polygon @ ({})\n", sourceface.line, face->w[0]);
|
} else if (face->w.size() == 1) {
|
||||||
} else {
|
logging::print("WARNING: {}: partially clipped into degenerate polygon @ ({})\n", sourceface.line, face->w[0]);
|
||||||
logging::print("WARNING: {}: completely clipped away\n", sourceface.line);
|
} else {
|
||||||
|
logging::print("WARNING: {}: completely clipped away\n", sourceface.line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_clipped) {
|
||||||
|
(*num_clipped)++;
|
||||||
}
|
}
|
||||||
|
|
||||||
face->w.clear();
|
face->w.clear();
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)));
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue