summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--editor/tests/hole-test.cpp62
-rw-r--r--src/RTree-search.hpp12
-rw-r--r--src/hole-cut.cpp81
-rw-r--r--src/hole.hpp16
-rw-r--r--src/object.cpp1
-rw-r--r--src/rect-intersects.hpp14
-rw-r--r--src/search.cpp1
-rw-r--r--test/hole.cpp4
8 files changed, 96 insertions, 95 deletions
diff --git a/editor/tests/hole-test.cpp b/editor/tests/hole-test.cpp
index 61b0c931..2e7533b9 100644
--- a/editor/tests/hole-test.cpp
+++ b/editor/tests/hole-test.cpp
@@ -37,34 +37,13 @@ struct hole_test final : base_test
State st;
};
-bool hole_test::handle_key(app& a, const key_event& e, bool is_down)
-{
- return false;
-}
-
-bool hole_test::handle_mouse_click(app& a, const mouse_button_event& e, bool is_down)
-{
- return false;
-}
-
-bool hole_test::handle_mouse_move(app& a, const mouse_move_event& e)
-{
- return false;
-}
+bool hole_test::handle_key(app&, const key_event&, bool) { return false; }
+bool hole_test::handle_mouse_click(app&, const mouse_button_event&, bool) { return false; }
+bool hole_test::handle_mouse_move(app&, const mouse_move_event&) { return false; }
+void hole_test::draw_overlay(app& a) {}
-void hole_test::draw_overlay(app& a)
-{
-}
-
-constexpr ImVec2 to_imvec2(Vector2 val)
-{
- return {val.x(), val.y()};
-}
-
-auto to_color(Color4 val)
-{
- return ImGui::ColorConvertFloat4ToU32({ val.r(), val.g(), val.b(), val.a() });
-}
+constexpr ImVec2 to_imvec2(Vector2 val) { return {val.x(), val.y()}; }
+uint32_t to_color(Color4 val) { return ImGui::ColorConvertFloat4ToU32({ val.r(), val.g(), val.b(), val.a() }); }
constexpr auto colors = std::array{
0x488f31_rgbf, // rect 1
@@ -79,6 +58,8 @@ constexpr auto colors = std::array{
void hole_test::draw_ui(app& a, float)
{
+ using crr = cut_rectangle_result<Int>;
+ using bbox = typename crr::bbox;
const auto& m = a.main();
const auto width = Math::min(ImGui::GetWindowSize().x, 400.f);
const auto window_size = ImVec2{width, width};
@@ -92,13 +73,10 @@ void hole_test::draw_ui(app& a, float)
constexpr auto igwf = 0;//ImGuiWindowFlags_NoDecoration;
constexpr auto imdf = ImDrawFlags_None;
char buf[32];
-
ImGui::NewLine();
- //ImGui::LabelText("##test-area", "Test area");
- //ImGui::NewLine();
-
- auto count = -1u;
+ bbox rect{{}, Vector2ub{tile_size_xy}};
+ const auto res = crr::cut(rect, {st.pos, st.size});
ImGui::SetNextWindowSize({width, width});
if (auto b1 = imgui::begin_child("Test area"_s, window_size, igcf, igwf))
@@ -116,10 +94,6 @@ void hole_test::draw_ui(app& a, float)
draw.AddRectFilled(to_imvec2(center + (Vector2(st.pos) - Vector2(st.size)/2)*mult),
to_imvec2(center + (Vector2(st.pos) + Vector2(st.size)/2)*mult), red); // hole
- cut_rectangle_result::bbox rect{{}, Vector2ub{tile_size_xy}};
- cut_rectangle_result res = cut_rectangle(rect, {st.pos, st.size});
- count = res.size;
-
for (auto i = 0u; i < res.size; i++)
{
auto r = res.array[i];
@@ -135,13 +109,9 @@ void hole_test::draw_ui(app& a, float)
draw.AddRect(to_imvec2(center + (Vector2(st.pos) - Vector2(st.size)*.5f)*mult),
to_imvec2(center + (Vector2(st.pos) + Vector2(st.size)*.5f)* mult), red, 0, 0, 1); // hole
}
- if (count == -1u)
- {
- cut_rectangle_result::bbox rect{{}, Vector2ub{tile_size_xy}};
- cut_rectangle_result res = cut_rectangle(rect, {st.pos, st.size});
- count = res.size;
- }
+ constexpr auto rmin = Int{-tile_size_xy/2}, rmax = Int{(tile_size_xy+1)/2};
+ const bool found = res.size != 1 || res.array[0].min != Vector2i{rmin} || res.array[0].max != Vector2i{rmax};
const auto label_width = ImGui::CalcTextSize("MMMMMM").x;
ImGui::NewLine();
@@ -161,13 +131,17 @@ void hole_test::draw_ui(app& a, float)
}
{
label_left("count", buf, label_width);
- ImGui::Text("%zu", size_t{count});
+ ImGui::Text("%zu", size_t{res.size});
+ }
+ {
+ label_left("found", buf, label_width);
+ ImGui::Text("%s", found ? "true" : "false");
}
ImGui::Unindent(style.FramePadding.x);
}
-void hole_test::update_pre(app& a, const Ns& dt)
+void hole_test::update_pre(app&, const Ns&)
{
}
diff --git a/src/RTree-search.hpp b/src/RTree-search.hpp
index 47c53592..4b824cd6 100644
--- a/src/RTree-search.hpp
+++ b/src/RTree-search.hpp
@@ -1,18 +1,6 @@
#pragma once
#include "compat/assert.hpp"
#include "RTree.h"
-#include <Magnum/Magnum.h>
-#include <Magnum/Math/Vector2.h>
-
-namespace floormat {
-
-constexpr inline bool rect_intersects(Vector2 min1, Vector2 max1, Vector2 min2, Vector2 max2)
-{
- return min1.x() < max2.x() && max1.x() > min2.x() &&
- min1.y() < max2.y() && max1.y() > min2.y();
-}
-
-} // namespace floormat
RTREE_TEMPLATE
template<typename F>
diff --git a/src/hole-cut.cpp b/src/hole-cut.cpp
index 8110510a..51d1a8af 100644
--- a/src/hole-cut.cpp
+++ b/src/hole-cut.cpp
@@ -8,12 +8,16 @@
#pragma GCC diagnostic ignored "-Wswitch-default"
//#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#endif
+#ifdef __clang__
+#pragma clang diagnostic ignored "-Wbitwise-instead-of-logical"
+#endif
namespace floormat {
namespace {
-using bbox = cut_rectangle_result::bbox;
-using rect = cut_rectangle_result::rect;
+template<typename T> using crr = cut_rectangle_result<T>;
+template<typename T> using bbox = typename cut_rectangle_result<T>::bbox;
+template<typename T> using rect = typename cut_rectangle_result<T>::rect;
enum shift : uint8_t { __ = 0, x0 = 1 << 0, x1 = 1 << 1, y0 = 1 << 2, y1 = 1 << 3, };
enum class location : uint8_t { R0, R1, H0, H1, };
@@ -32,6 +36,8 @@ struct element
std::array<coords, 8> array;
};
+template<typename T> using Vec2ʹ = VectorTypeFor<2, T>;
+
constexpr element make_element(uint8_t s)
{
// ReSharper disable CppIdenticalOperandsInBinaryExpression
@@ -114,12 +120,13 @@ constexpr element make_element(uint8_t s)
}
// NOLINTEND(*-simplify)
// ReSharper restore CppIdenticalOperandsInBinaryExpression
- std::unreachable();
+ fm_assert(false);
}
constexpr auto elements = map(make_element, iota_array<uint8_t, 16>);
-constexpr auto get_value_from_coord(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, coords c)
+template<typename T>
+constexpr auto get_value_from_coord(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2ʹ<T> h0, Vec2ʹ<T> h1, coords c)
{
const auto xs = std::array{ r0.x(), r1.x(), h0.x(), h1.x(), };
const auto ys = std::array{ r0.y(), r1.y(), h0.y(), h1.y(), };
@@ -127,37 +134,29 @@ constexpr auto get_value_from_coord(Vector2i r0, Vector2i r1, Vector2i h0, Vecto
const auto x1 = xs[(uint8_t)c.x1];
const auto y0 = ys[(uint8_t)c.y0];
const auto y1 = ys[(uint8_t)c.y1];
- return rect{ Vector2i{x0, y0}, Vector2i{x1, y1} };
+ return rect<T>{ {x0, y0}, {x1, y1} };
}
+template<typename T>
[[nodiscard]]
-constexpr bool
-check_empty(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1, Vector2ub input_bb, Vector2ub hole_bb)
+constexpr bool check_empty(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2ʹ<T> h0, Vec2ʹ<T> h1)
{
- bool iempty = Vector2ui{input_bb}.product() == 0;
- bool hempty = Vector2ui{hole_bb}.product() == 0;
+ bool iempty = r0.x() == r1.x() | r0.y() == r1.y();
+ bool hempty = h0.x() == h1.x() | h0.y() == h1.y();
bool empty_before_x = h1.x() <= r0.x();
bool empty_after_x = h0.x() >= r1.x();
bool empty_before_y = h1.y() <= r0.y();
bool empty_after_y = h0.y() >= r1.y();
-
return iempty | hempty | empty_before_x | empty_after_x | empty_before_y | empty_after_y;
}
-constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole)
+template<typename T>
+constexpr cut_rectangle_result<T> cut_rectangle(Vec2ʹ<T> r0, Vec2ʹ<T> r1, Vec2ʹ<T> h0, Vec2ʹ<T> h1)
{
- auto ihalf = Vector2i{input.bbox_size/2};
- auto r0 = input.position - ihalf;
- auto r1 = input.position + Vector2i{input.bbox_size} - ihalf;
-
- auto hhalf = Vector2i{hole.bbox_size/2};
- auto h0 = hole.position - hhalf;
- auto h1 = hole.position + Vector2i{hole.bbox_size} - hhalf;
-
- if (check_empty(r0, r1, h0, h1, input.bbox_size, hole.bbox_size))
+ if (check_empty<T>(r0, r1, h0, h1))
return {
.size = 1,
- .array = {{ rect { r0, r1 }, }},
+ .array = {{ { r0, r1 }, }},
};
const bool sx = h0.x() <= r0.x();
@@ -169,23 +168,45 @@ constexpr cut_rectangle_result cut_rectangleʹ(bbox input, bbox hole)
CORRADE_ASSUME(val < 16);
const auto elt = elements[val];
const auto sz = elt.size;
- cut_rectangle_result res = {
+ cut_rectangle_result<T> res = {
.size = sz,
.array = {},
};
- CORRADE_ASSUME(sz <= 8);
-
- for (auto i = 0u; i < sz; i++)
- res.array[i] = get_value_from_coord(r0, r1, h0, h1, elt.array[i]);
+ for (auto i = 0u; i < 8; i++)
+ res.array[i] = get_value_from_coord<T>(r0, r1, h0, h1, elt.array[i]);
return res;
}
-} // namespace
-
-cut_rectangle_result cut_rectangle(bbox input, bbox hole)
+template<typename T>
+constexpr cut_rectangle_result<T> cut_rectangle(bbox<T> input, bbox<T> hole)
{
- return cut_rectangleʹ(input, hole);
+ using Vec2 = Vec2ʹ<T>;
+
+ auto ihalf = Vec2{input.bbox_size/2};
+ auto r0 = input.position - ihalf;
+ auto r1 = input.position + Vec2{input.bbox_size} - ihalf;
+
+ auto hhalf = Vec2{hole.bbox_size/2};
+ auto h0 = hole.position - hhalf;
+ auto h1 = hole.position + Vec2{hole.bbox_size} - hhalf;
+
+ return cut_rectangle<T>(r0, r1, h0, h1);
}
+
+} // namespace
+
+template struct cut_rectangle_result<Int>;
+template struct cut_rectangle_result<float>;
+
+template<typename T> crr<T> cut_rectangle_result<T>::cut(bbox input, bbox hole) { return cut_rectangle<T>(input, hole); }
+template<typename T> crr<T> cut_rectangle_result<T>::cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1) { return cut_rectangle<T>(r0, r1, h0, h1); }
+
+template cut_rectangle_result<Int> cut_rectangle_result<Int>::cut(bbox input, bbox hole);
+template cut_rectangle_result<float> cut_rectangle_result<float>::cut(bbox input, bbox hole);
+
+template cut_rectangle_result<Int> cut_rectangle_result<Int>::cut(Vector2i r0, Vector2i r1, Vector2i h0, Vector2i h1);
+template cut_rectangle_result<float> cut_rectangle_result<float>::cut(Vector2 r0, Vector2 r1, Vector2 h0, Vector2 h1);
+
} // namespace floormat
diff --git a/src/hole.hpp b/src/hole.hpp
index 6ec1c666..384a5044 100644
--- a/src/hole.hpp
+++ b/src/hole.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "object.hpp"
#include <array>
+#include <Magnum/DimensionTraits.h>
namespace floormat {
@@ -54,17 +55,18 @@ private:
void mark_chunk_modified();
};
-struct cut_rectangle_result
+template<typename T>
+struct cut_rectangle_result // todo rename
{
- struct bbox { Vector2i position; Vector2ub bbox_size; };
- struct rect { Vector2i min, max; };
+ using Vec2 = VectorTypeFor<2, T>;
+ struct bbox { Vec2 position; Vector2ub bbox_size; };
+ struct rect { Vec2 min, max; };
+
+ static cut_rectangle_result cut(bbox input, bbox hole);
+ static cut_rectangle_result cut(Vec2 r0, Vec2 r1, Vec2 h0, Vec2 h1);
uint8_t size = 0;
std::array<rect, 8> array;
-
- operator ArrayView<const bbox>() const;
};
-cut_rectangle_result cut_rectangle(cut_rectangle_result::bbox input, cut_rectangle_result::bbox hole);
-
} // namespace floormat
diff --git a/src/object.cpp b/src/object.cpp
index 72906320..a3df2ef9 100644
--- a/src/object.cpp
+++ b/src/object.cpp
@@ -4,6 +4,7 @@
#include "rotation.inl"
#include "anim-atlas.hpp"
#include "src/RTree-search.hpp"
+#include "rect-intersects.hpp"
#include "src/timer.hpp"
#include "compat/debug.hpp"
#include "compat/exception.hpp"
diff --git a/src/rect-intersects.hpp b/src/rect-intersects.hpp
new file mode 100644
index 00000000..25d838d6
--- /dev/null
+++ b/src/rect-intersects.hpp
@@ -0,0 +1,14 @@
+#pragma once
+#include <mg/Vector.h>
+
+namespace floormat {
+
+template<typename T>
+requires (std::is_same_v<Int, T> || std::is_same_v<float, T>)
+constexpr bool rect_intersects(Math::Vector<2, T> min1, Math::Vector<2, T> max1, Math::Vector<2, T> min2, Math::Vector<2, T> max2)
+{
+ return min1.data()[0] < max2.data()[0] && max1.data()[0] > min2.data()[0] &&
+ min1.data()[1] < max2.data()[1] && max1.data()[1] > min2.data()[1];
+}
+
+} // namespace floormat
diff --git a/src/search.cpp b/src/search.cpp
index 68ec0cce..220e3869 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -6,6 +6,7 @@
#include "world.hpp"
#include "pass-mode.hpp"
#include "RTree-search.hpp"
+#include "rect-intersects.hpp"
#include "compat/array-size.hpp"
#include "compat/function2.hpp"
#include <bit>
diff --git a/test/hole.cpp b/test/hole.cpp
index 50e9b8f0..fdcfdfec 100644
--- a/test/hole.cpp
+++ b/test/hole.cpp
@@ -4,13 +4,13 @@
namespace floormat {
namespace {
-using bbox = cut_rectangle_result::bbox;
+using bbox = cut_rectangle_result<Int>::bbox;
auto cut(bbox rect, bbox hole, Vector2i offset)
{
auto rectʹ = bbox { rect.position + offset, rect.bbox_size };
auto holeʹ = bbox { hole.position + offset, hole.bbox_size };
- return cut_rectangle(rectʹ, holeʹ).size;
+ return cut_rectangle_result<Int>::cut(rectʹ, holeʹ).size;
}
void test1(Vector2i offset)