qbsp: q1: fix so just DETAIL is considered is_empty

This commit is contained in:
Eric Wasylishen 2023-04-17 21:10:28 -06:00
parent ed756bd602
commit cd2926534f
2 changed files with 73 additions and 8 deletions

View File

@ -117,7 +117,7 @@ private:
bool water = false;
bool mist = false; // compiler-internal
// non-visible contents contents
// non-visible contents
bool origin = false;
bool clip = false;
bool illusionary_visblocker = false;
@ -250,12 +250,27 @@ private:
return result;
}
constexpr bool empty() const
constexpr bool all_empty() const
{
// fixme-brushbsp: what should we do with empty, but the detail flag set?
q1_contentflags_bits empty_test;
return (*this) == empty_test;
}
/**
* Contents (excluding non-contents flags) are all unset
*/
constexpr bool contents_empty() const
{
q1_contentflags_bits this_test = *this;
// clear flags
this_test.detail = false;
this_test.mirror_inside = false;
this_test.suppress_clipping_same_type = false;
q1_contentflags_bits empty_test;
return this_test == empty_test;
}
};
inline q1_contentflags_bits contentflags_to_bits(const contentflags_t &contents) const
@ -513,7 +528,7 @@ public:
bool contents_are_empty(const contentflags_t &contents) const override
{
const auto bits = contentflags_to_bits(contents);
return bits.empty();
return bits.contents_empty();
}
bool contents_are_any_solid(const contentflags_t &contents) const override
@ -574,7 +589,7 @@ public:
bool a_translucent = transwater ? (bits_a.water || bits_a.slime || bits_a.lava) : false;
bool b_translucent = transwater ? (bits_b.water || bits_b.slime || bits_b.lava) : false;
if ((bits_a ^ bits_b).visible_contents().empty())
if ((bits_a ^ bits_b).visible_contents().all_empty())
return true;
if (bits_a.detail || a_translucent)
@ -585,10 +600,10 @@ public:
if (bits_a.solid || bits_b.solid)
return false; // can't see through solid
if ((bits_a ^ bits_b).empty())
if ((bits_a ^ bits_b).all_empty())
return true; // identical on both sides
if ((bits_a ^ bits_b).visible_contents().empty())
if ((bits_a ^ bits_b).visible_contents().all_empty())
return true;
return false;
}
@ -671,7 +686,7 @@ public:
inline std::string get_contents_display(const q1_contentflags_bits &bits) const
{
if (bits.empty()) {
if (bits.all_empty()) {
return "EMPTY";
}

View File

@ -76,6 +76,56 @@ TEST_SUITE("common")
}
}
TEST_CASE("cluster_contents")
{
for (auto *bspver : bspversions) {
auto *game = bspver->game;
if (!game)
continue;
SUBCASE(bspver->name)
{
const auto solid = game->create_solid_contents();
const auto solid_detail = game->create_detail_solid_contents(solid);
const auto empty = game->create_empty_contents();
auto solid_solid_cluster = game->cluster_contents(solid_detail, solid_detail);
CAPTURE(solid_solid_cluster.to_string(game));
CHECK(solid_solid_cluster.is_detail_solid(game));
auto solid_empty_cluster = game->cluster_contents(solid_detail, empty);
CAPTURE(solid_empty_cluster.to_string(game));
// it's empty because of the rule that:
// - if all leaves in the cluster are solid, it means you can't see in, and there's no visportal
// - otherwise, you can see in, and it needs a visportal
CHECK(solid_empty_cluster.is_empty(game));
// this is a bit weird...
CHECK(solid_empty_cluster.is_any_detail(game));
}
}
}
TEST_CASE("q1 origin")
{
auto *game = bspver_q1.game;
auto origin = game->face_get_contents("origin", {}, {});
CHECK(origin.is_origin(game));
CHECK(!origin.is_empty(game));
}
TEST_CASE("q2 origin")
{
auto *game = bspver_q2.game;
auto origin = game->face_get_contents("", {}, {Q2_CONTENTS_ORIGIN});
CHECK(origin.is_origin(game));
CHECK(!origin.is_empty(game));
}
TEST_CASE("shared content flag tests")
{
for (auto *bspver : bspversions) {