diff options
Diffstat (limited to 'editor/tests/path.cpp')
-rw-r--r-- | editor/tests/path.cpp | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/editor/tests/path.cpp b/editor/tests/path.cpp index 3b015e27..f6ebc1cb 100644 --- a/editor/tests/path.cpp +++ b/editor/tests/path.cpp @@ -3,49 +3,48 @@ #include "floormat/main.hpp" #include "src/path-search.hpp" #include "src/critter.hpp" +#include "shaders/shader.hpp" +#include "../imgui-raii.hpp" +#include "src/camera-offset.hpp" namespace floormat::tests { -bool path_test::handle_key(app& a, const key_event& e) +bool path_test::handle_key(app& a, const key_event& e, bool is_down) { + (void)a; (void)e; (void)is_down; return false; } -bool path_test::handle_mouse_click(app& a, const mouse_button_event& e) +bool path_test::handle_mouse_click(app& a, const mouse_button_event& e, bool is_down) { + if (is_down) + return false; + switch (e.button) { case mouse_button_left: { auto& M = a.main(); auto& w = M.world(); - auto& astar = M.astar(); auto C = a.ensure_player_character(w); if (auto pt = a.cursor_state().point()) { constexpr auto chunk_size = iTILE_SIZE2 * TILE_MAX_DIM; auto pt0 = C->position(); - auto vec = (pt->coord() - pt0.coord()) * iTILE_SIZE2 * 2 + chunk_size * 3; + auto vec = (pt->coord() - pt0.coord()) * iTILE_SIZE2 + chunk_size * 1; auto dist = (uint32_t)vec.length(); - auto res = astar.Dijkstra(w, *pt, pt0, C->id, dist, C->bbox_size, 1); - if (res) - { - active = true; - from = pt0; - path = res.path(); - } - else - { - active = false; - from = {}; - path = {}; - } + + has_pending = true; + pending = { .from = pt0, .to = *pt, .own_id = C->id, + .max_dist = dist, .own_size = C->bbox_size, }; } return true; } case mouse_button_right: - if (active) + if (has_pending | has_result) { - *this = {}; + has_pending = has_result = false; + pending = {}; + result = {}; return true; } return false; @@ -56,22 +55,66 @@ bool path_test::handle_mouse_click(app& a, const mouse_button_event& e) bool path_test::handle_mouse_move(app& a, const mouse_move_event& e) { + (void)a; (void)e; return false; } void path_test::draw_overlay(app& a) { + if (!has_result) + return; + + const auto win_size = a.main().window_size(); + const auto line_color = ImGui::ColorConvertFloat4ToU32({0, 0, 1, 1}); + const auto dot_color = ImGui::ColorConvertFloat4ToU32({1, 0, 0, 1}); + constexpr float line_thickness = 3, dot_radius = 5; + auto& shader = a.main().shader(); + ImDrawList& draw = *ImGui::GetForegroundDrawList(); + constexpr auto get_screen_pos = [](tile_shader& shader, point pt, Vector2i win_size) { + auto c3 = pt.chunk3(); + auto c2 = pt.chunk(); + with_shifted_camera_offset co{shader, c3, c2, c2 }; + auto world_pos = TILE_SIZE20 * Vector3(pt.local()) + Vector3(Vector2(pt.offset()), 0); + return Vector2(shader.camera_offset()) + Vector2(win_size)*.5f + shader.project(world_pos); + }; + + auto last = get_screen_pos(shader, result.from, win_size); + draw.AddCircleFilled({last.x(), last.y()}, dot_radius, dot_color); + + for (auto pt : result.path) + { + auto pos = get_screen_pos(shader, pt, win_size); + draw.AddLine({pos.x(), pos.y()}, {last.x(), last.y()}, line_color, line_thickness); + draw.AddCircleFilled({pos.x(), pos.y()}, dot_radius, dot_color); + last = pos; + } } void path_test::update_pre(app& a) { + if (!has_pending) + return; + + has_result = false; + has_pending = false; + + auto& M = a.main(); + auto& w = M.world(); + auto& astar = M.astar(); + auto res = astar.Dijkstra(w, pending.from, pending.to, pending.own_id, pending.max_dist, pending.own_size, 1); + if (res) + { + has_result = true; + result.from = pending.from; + result.path = res.path(); + } } void path_test::update_post(app& a) { - + (void)a; } } // namespace floormat::tests |