summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--editor/camera.cpp32
-rw-r--r--editor/draw.cpp17
-rw-r--r--floormat/main.hpp5
-rw-r--r--main/main-impl.hpp3
-rw-r--r--main/projection.cpp19
5 files changed, 34 insertions, 42 deletions
diff --git a/editor/camera.cpp b/editor/camera.cpp
index 4bd316e1..3fa8d9d3 100644
--- a/editor/camera.cpp
+++ b/editor/camera.cpp
@@ -71,22 +71,15 @@ object_id app::get_object_colliding_with_cursor()
auto& shader = M->shader();
using rtree_type = std::decay_t<decltype(*world[chunk_coords_{}].rtree())>;
- using rect_type = typename rtree_type::Rect;
+ using rect_type = rtree_type::Rect;
if (cursor.pixel)
{
auto pos = tile_shader::project(Vector3d{0., 0., -_z_level*dTILE_SIZE[2]});
- auto pixel = Vector2d{*cursor.pixel} + pos;
- auto coord = M->pixel_to_tile(pixel);
- auto tile = global_coords{coord.chunk(), coord.local(), 0};
-
- constexpr auto eps = 1e-6f;
- constexpr auto m = TILE_SIZE2 * Vector2(1- eps, 1- eps);
- const auto tile_ = Vector2(M->pixel_to_tile_(Vector2d(pixel)));
+ const auto [tile, subpixelʹ] = M->pixel_to_point(Vector2d{*cursor.pixel} + pos);
const auto curchunk = Vector2(tile.chunk()), curtile = Vector2(tile.local());
- const auto subpixelʹ = Math::fmod(tile_, 1.f);
- const auto subpixel = m * Vector2(curchunk[0] < 0 ? 1 + subpixelʹ[0] : subpixelʹ[0],
- curchunk[1] < 0 ? 1 + subpixelʹ[1] : subpixelʹ[1]);
+ const auto subpixel = Vector2(subpixelʹ);
+
for (int16_t y = miny; y <= maxy; y++)
for (int16_t x = minx; x <= maxx; x++)
{
@@ -99,10 +92,9 @@ object_id app::get_object_colliding_with_cursor()
const with_shifted_camera_offset o{shader, c_pos, {minx, miny}, {maxx, maxy}};
if (floormat_main::check_chunk_visible(shader.camera_offset(), sz))
{
- constexpr auto half_tile = TILE_SIZE2/2;
constexpr auto chunk_size = TILE_SIZE2 * TILE_MAX_DIM;
auto chunk_dist = (curchunk - Vector2(c_pos.x, c_pos.y))*chunk_size;
- auto t0 = chunk_dist + curtile*TILE_SIZE2 + subpixel - half_tile;
+ auto t0 = chunk_dist + curtile*TILE_SIZE2 + subpixel;
auto t1 = t0+Vector2(1e-4f);
const auto* rtree = c.rtree();
object_id ret = 0;
@@ -136,19 +128,9 @@ void app::update_cursor_tile(const Optional<Vector2i>& pixel)
// assert_invariant !!cursor.tile == !!cursor.subpixel;
if (pixel)
{
- auto coord = M->pixel_to_tile(Vector2d{*pixel});
- auto tile = global_coords{coord.chunk(), coord.local(), _z_level};
+ auto [tile, subpixel] = M->pixel_to_point(Vector2d(*pixel), _z_level);
cursor.tile = tile;
-
- const auto tile_ = Vector2(M->pixel_to_tile_(Vector2d(*pixel)));
- const auto curchunk = Vector2(tile.chunk());
- const auto subpixelʹ = Math::fmod(tile_, 1.f);
- auto subpixel = TILE_SIZE2 * Vector2(curchunk.x() < 0 ? 1 + subpixelʹ.x() : subpixelʹ.x(),
- curchunk.y() < 0 ? 1 + subpixelʹ.y() : subpixelʹ.y());
- constexpr auto half_tile = Vector2(iTILE_SIZE2/2);
- subpixel -= half_tile;
- subpixel = Math::clamp(Math::round(subpixel), -half_tile, half_tile-Vector2{1.f});
- cursor.subpixel = Vector2b(subpixel);
+ cursor.subpixel = subpixel;
}
else
{
diff --git a/editor/draw.cpp b/editor/draw.cpp
index 590c2ff1..f0d642bc 100644
--- a/editor/draw.cpp
+++ b/editor/draw.cpp
@@ -155,17 +155,9 @@ void app::draw_collision_boxes()
{
auto pos = tile_shader::project(Vector3d{0., 0., -_z_level*dTILE_SIZE[2]});
auto pixel = Vector2d{*cursor.pixel} + pos;
- auto coord = M->pixel_to_tile(pixel);
- auto tile = global_coords{coord.chunk(), coord.local(), 0};
-
- constexpr auto eps = 1e-6f;
- constexpr auto m = TILE_SIZE2 * Vector2(1- eps, 1- eps);
- const auto tile_ = Vector2(M->pixel_to_tile_(Vector2d(pixel)));
- const auto curchunk = Vector2(tile.chunk()), curtile = Vector2(tile.local());
- const auto subpixelʹ = Math::fmod(tile_, 1.f);
- // todo use this formula for dragging objs
- const auto subpixel = m * Vector2(curchunk[0] < 0 ? 1 + subpixelʹ[0] : subpixelʹ[0],
- curchunk[1] < 0 ? 1 + subpixelʹ[1] : subpixelʹ[1]);
+ const auto [coord, subpixelʹ] = M->pixel_to_point(Vector2d(pixel));
+ const auto curchunk = Vector2(coord.chunk()), curtile = Vector2(coord.local());
+ const auto subpixel = Vector2(subpixelʹ);
for (int16_t y = miny; y <= maxy; y++)
for (int16_t x = minx; x <= maxx; x++)
{
@@ -178,10 +170,9 @@ void app::draw_collision_boxes()
const with_shifted_camera_offset o{shader, c_pos, {minx, miny}, {maxx, maxy}};
if (floormat_main::check_chunk_visible(shader.camera_offset(), sz))
{
- constexpr auto half_tile = TILE_SIZE2/2;
constexpr auto chunk_size = TILE_SIZE2 * TILE_MAX_DIM;
auto chunk_dist = (curchunk - Vector2(c_pos.x, c_pos.y))*chunk_size;
- auto t0 = chunk_dist + curtile*TILE_SIZE2 + subpixel - half_tile;
+ auto t0 = chunk_dist + curtile*TILE_SIZE2 + subpixel;
auto t1 = t0+Vector2(1e-4f);
const auto* rtree = c.rtree();
rtree->Search(t0.data(), t1.data(), [&](uint64_t data, const rect_type& rect) {
diff --git a/floormat/main.hpp b/floormat/main.hpp
index 2ed8518f..8239a05a 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -24,6 +24,7 @@ struct anim_mesh;
struct texture_unit_cache;
class path_search;
class astar;
+struct point;
struct floormat_main
{
@@ -68,8 +69,10 @@ struct floormat_main
virtual void set_cursor(uint32_t cursor) noexcept = 0;
virtual uint32_t cursor() const noexcept = 0;
- virtual global_coords pixel_to_tile(Vector2d position) const noexcept = 0;
+ virtual global_coords pixel_to_tile(Vector2d position, int8_t z_level = 0) const noexcept = 0;
virtual Vector2d pixel_to_tile_(Vector2d position) const noexcept = 0;
+ virtual point pixel_to_point(Vector2d position, int8_t z_level = 0) const noexcept = 0;
+
virtual draw_bounds get_draw_bounds() const noexcept = 0;
[[nodiscard]] static bool check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept;
virtual struct meshes meshes() noexcept = 0;
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index 39e07d4c..66f143d1 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -65,8 +65,9 @@ struct main_impl final : Platform::Sdl2Application, floormat_main
fm_settings& settings() noexcept override;
const fm_settings& settings() const noexcept override;
- global_coords pixel_to_tile(Vector2d position) const noexcept override;
+ global_coords pixel_to_tile(Vector2d position, int8_t z_level = 0) const noexcept override;
Vector2d pixel_to_tile_(Vector2d position) const noexcept override;
+ point pixel_to_point(Vector2d position, int8_t z_level = 0) const noexcept override;
ArrayView<const clickable> clickable_scenery() const noexcept override;
ArrayView<clickable> clickable_scenery() noexcept override;
diff --git a/main/projection.cpp b/main/projection.cpp
index 8b32777e..b7ee01da 100644
--- a/main/projection.cpp
+++ b/main/projection.cpp
@@ -1,15 +1,16 @@
#include "main-impl.hpp"
#include "src/tile-constants.hpp"
+#include "src/point.hpp"
#include <algorithm>
#include <limits>
namespace floormat {
-global_coords main_impl::pixel_to_tile(Vector2d position) const noexcept
+global_coords main_impl::pixel_to_tile(Vector2d position, int8_t z_level) const noexcept
{
auto vec = pixel_to_tile_(position);
auto vec_ = Math::floor(vec);
- return { (int32_t)vec_.x(), (int32_t)vec_.y(), 0 };
+ return { (int32_t)vec_.x(), (int32_t)vec_.y(), z_level };
}
Vector2d main_impl::pixel_to_tile_(Vector2d position) const noexcept
@@ -20,6 +21,20 @@ Vector2d main_impl::pixel_to_tile_(Vector2d position) const noexcept
return tile_shader::unproject(px*.5) / pixel_size + half;
}
+point main_impl::pixel_to_point(Vector2d pixel, int8_t z_level) const noexcept
+{
+ const auto tileʹ = pixel_to_tile_(pixel);
+ const auto tileʹʹ = Math::floor(tileʹ);
+ const auto tile = global_coords{(int)tileʹʹ.x(), (int)tileʹʹ.y(), z_level};
+ const auto subpixelʹ = Math::fmod(Vector2(tileʹ), 1.f);
+ const auto subpixelʹ_neg = Vector2{Vector2i(tile.chunk()) < Vector2i{}};
+ auto subpixel = TILE_SIZE2 * (subpixelʹ + subpixelʹ_neg);
+ constexpr auto half_tile = Vector2(iTILE_SIZE2/2);
+ subpixel -= half_tile;
+ subpixel = Math::clamp(Math::round(subpixel), -half_tile, half_tile-Vector2{1.f});
+ return point{ tile, Vector2b{subpixel} };
+}
+
auto main_impl::get_draw_bounds() const noexcept -> draw_bounds
{
using limits = std::numeric_limits<int16_t>;