summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-02-27 00:19:30 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-02-27 10:50:00 +0100
commit741fb2b226acf840ec1a9ddfdef3dcaf452ee66e (patch)
tree586b46d7587f19b318af3d2d4b03a899b15659b2
parentb16d1613e5c4de120b20f539f3b7792ab7304ccc (diff)
factor out common code in flood fill
-rw-r--r--src/chunk-region.cpp57
1 files changed, 28 insertions, 29 deletions
diff --git a/src/chunk-region.cpp b/src/chunk-region.cpp
index 22c97eed..a6968866 100644
--- a/src/chunk-region.cpp
+++ b/src/chunk-region.cpp
@@ -66,7 +66,7 @@ struct node_s
struct tmp_s
{
- Array<node_s> stack;
+ Array<node_s> stack{NoInit, 0};
std::bitset<visited_bits> visited;
static uint32_t get_index(Vector2i pos);
@@ -145,43 +145,42 @@ auto chunk::make_pass_region(const pred& f, bool debug) -> pass_region
auto& tmp = get_tmp();
const auto nbs = _world->neighbors(_coord);
- constexpr Vector2i fours[4] = {
- {-1, 0}, {1, 0},
- {0, -1}, {0, 1},
- };
-
//if (Vector2i pos{0, 0}; check_pos(*c, nbs, pos, fours[1])) tmp.append(pos, 1); // top
- for (int i = 0; i < div_count.x(); i++)
+ enum : uint8_t { L, R, U, D };
+
+ const auto do_pixel = [&]<int Dir, bool Edge>(const Vector2i pos0)
{
- constexpr auto get_positions = [](int i) {
- constexpr auto last = div_count - Vector2i{1};
- return std::array<Vector2i, 4> {{
- {0, i}, // left
- {last.x(), i}, // right
- {i, 0}, // top
- {i, last.y()}, // bottom
- }};
- };
-
- auto positions = get_positions(i);
- for (auto i = 0u; i < 4; i++)
- if (check_pos(*this, nbs, positions[i], fours[i], f))
- tmp.append(ret.bits, positions[i]);
+ constexpr Vector2i fours[4] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1}, };
+ constexpr auto dir = fours[Dir];
+ const auto pos = pos0 + dir;
+ if constexpr(!Edge && (Dir == L || Dir == R))
+ if ((uint32_t)pos.x() >= div_count.x()) [[unlikely]]
+ return;
+ if constexpr(!Edge && (Dir == U || Dir == D))
+ if ((uint32_t)pos.y() >= div_count.y()) [[unlikely]]
+ return;
+ if (tmp.check_visited(ret.bits, pos, Dir) && check_pos(*this, nbs, pos, dir, f))
+ tmp.append(ret.bits, pos);
+ };
+
+ for (int i = 0; i < div_count.y(); i++)
+ {
+ do_pixel.operator()<L, true>(Vector2i(div_count.x(), i));
+ do_pixel.operator()<R, true>(Vector2i(-1, i));
+ do_pixel.operator()<U, true>(Vector2i(i, div_count.y()));
+ do_pixel.operator()<D, true>(Vector2i(i, -1));
}
while (!tmp.stack.isEmpty())
{
auto p = tmp.stack.back().pos;
arrayRemoveSuffix(tmp.stack);
- for (int i = 0; i < 4; i++)
- {
- Vector2i from = fours[i], pos{p + from};
- if ((uint32_t)pos.x() >= div_count.x() || (uint32_t)pos.y() >= div_count.y()) [[unlikely]]
- continue;
- if (tmp.check_visited(ret.bits, pos, i) && check_pos(*this, nbs, pos, from, f))
- tmp.append(ret.bits, pos);
- }
+
+ do_pixel.operator()<L, false>(p);
+ do_pixel.operator()<R, false>(p);
+ do_pixel.operator()<U, false>(p);
+ do_pixel.operator()<D, false>(p);
}
if (debug) [[unlikely]]