From cce1f768e7399b838a2b865511915bdd576dbbf4 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Sun, 23 Oct 2022 17:31:31 +0200 Subject: a --- editor/camera.cpp | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 editor/camera.cpp (limited to 'editor/camera.cpp') diff --git a/editor/camera.cpp b/editor/camera.cpp new file mode 100644 index 00000000..7af77211 --- /dev/null +++ b/editor/camera.cpp @@ -0,0 +1,88 @@ +#include "app.hpp" +#include + +namespace floormat { + +void app::do_camera(double dt) +{ + if (keys[key::camera_reset]) + reset_camera_offset(); + else + { + Vector2d dir{}; + + if (keys[key::camera_up]) + dir += Vector2d{0, -1}; + else if (keys[key::camera_down]) + dir += Vector2d{0, 1}; + if (keys[key::camera_left]) + dir += Vector2d{-1, 0}; + else if (keys[key::camera_right]) + dir += Vector2d{1, 0}; + + if (dir != Vector2d{}) + { + constexpr double screens_per_second = 1; + const auto pixels_per_second = windowSize().length() / screens_per_second; + auto camera_offset = _shader.camera_offset(); + const auto max_camera_offset = Vector2d(windowSize() * 10); + + camera_offset -= dir.normalized() * dt * pixels_per_second; + camera_offset[0] = std::clamp(camera_offset[0], -max_camera_offset[0], max_camera_offset[0]); + camera_offset[1] = std::clamp(camera_offset[1], -max_camera_offset[1], max_camera_offset[1]); + + _shader.set_camera_offset(camera_offset); + } + else + return; + } + recalc_cursor_tile(); + if (_cursor_tile) + do_mouse_move(*_cursor_tile); +} + +void app::reset_camera_offset() +{ + _shader.set_camera_offset(tile_shader::project({TILE_MAX_DIM*-.5*dTILE_SIZE[0], TILE_MAX_DIM*-.5*dTILE_SIZE[1], 0})); + recalc_cursor_tile(); +} + +void app::recalc_cursor_tile() +{ + if (_cursor_pixel && !_cursor_in_imgui) + _cursor_tile = pixel_to_tile(Vector2d(*_cursor_pixel)); + else + _cursor_tile = std::nullopt; +} + +global_coords app::pixel_to_tile(Vector2d position) const +{ + constexpr Vector2d pixel_size{dTILE_SIZE[0], dTILE_SIZE[1]}; + constexpr Vector2d half{.5, .5}; + const Vector2d px = position - Vector2d{windowSize()}*.5 - _shader.camera_offset()*.5; + const Vector2d vec = tile_shader::unproject(px) / pixel_size + half; + const auto x = (std::int32_t)std::floor(vec[0]), y = (std::int32_t)std::floor(vec[1]); + return { x, y }; +} + +std::array app::get_draw_bounds() const noexcept +{ + + using limits = std::numeric_limits; + auto x0 = limits::max(), x1 = limits::min(), y0 = limits::max(), y1 = limits::min(); + + for (const auto win = Vector2d(windowSize()); + auto p : {pixel_to_tile(Vector2d{0, 0}).chunk(), + pixel_to_tile(Vector2d{win[0]-1, 0}).chunk(), + pixel_to_tile(Vector2d{0, win[1]-1}).chunk(), + pixel_to_tile(Vector2d{win[0]-1, win[1]-1}).chunk()}) + { + x0 = std::min(x0, p.x); + x1 = std::max(x1, p.x); + y0 = std::min(y0, p.y); + y1 = std::max(y1, p.y); + } + return {x0, x1, y0, y1}; +} + +} // namespace floormat -- cgit v1.2.3