diff options
-rw-r--r-- | editor/tests/hole-test.cpp | 62 | ||||
-rw-r--r-- | src/RTree-search.hpp | 12 | ||||
-rw-r--r-- | src/hole-cut.cpp | 81 | ||||
-rw-r--r-- | src/hole.hpp | 16 | ||||
-rw-r--r-- | src/object.cpp | 1 | ||||
-rw-r--r-- | src/rect-intersects.hpp | 14 | ||||
-rw-r--r-- | src/search.cpp | 1 | ||||
-rw-r--r-- | test/hole.cpp | 4 |
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) |