diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-04-08 11:12:50 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-04-08 11:12:50 +0200 |
commit | d1984938e4f0cbc24b7b8cc6e219fa873d39418a (patch) | |
tree | d00c6cf0ba66c3285d145527360a0e3aeaef6671 | |
parent | d17ed6b4ba01a73d33e3ff3ca8f0f6fb25259223 (diff) |
a
-rw-r--r-- | editor/app.hpp | 3 | ||||
-rw-r--r-- | editor/draw.cpp | 99 | ||||
-rw-r--r-- | editor/events.cpp | 2 | ||||
-rw-r--r-- | editor/update.cpp | 48 | ||||
-rw-r--r-- | floormat/app.hpp | 3 | ||||
-rw-r--r-- | main/draw.cpp | 84 | ||||
-rw-r--r-- | serialize/world-writer.cpp | 2 | ||||
-rw-r--r-- | src/camera-offset.cpp | 7 | ||||
-rw-r--r-- | src/camera-offset.hpp | 2 | ||||
-rw-r--r-- | src/global-coords.hpp | 2 | ||||
-rw-r--r-- | src/world.cpp | 2 | ||||
-rw-r--r-- | src/world.hpp | 2 |
12 files changed, 141 insertions, 115 deletions
diff --git a/editor/app.hpp b/editor/app.hpp index 17dd80fe..a4d7c440 100644 --- a/editor/app.hpp +++ b/editor/app.hpp @@ -72,6 +72,7 @@ private: void update(float dt) override; void update_world(float dt); void update_cursor_tile(const Optional<Vector2i>& pixel); + z_bounds get_z_bounds() override; void set_cursor(); void maybe_initialize_chunk(const chunk_coords_& pos, chunk& c) override; void maybe_initialize_chunk_(const chunk_coords_& pos, chunk& c); @@ -86,7 +87,7 @@ private: void on_mouse_up_down(const mouse_button_event& event, bool is_down) noexcept override; void on_mouse_scroll(const mouse_scroll_event& event) noexcept override; void on_key_up_down(const key_event& event, bool is_down) noexcept override; - std::tuple<key, int> resolve_keybinding(int k, int mods) const; + std::tuple<key, int> resolve_keybinding(int k, int mods); void on_text_input_event(const text_input_event& event) noexcept override; //bool on_text_editing_event(const text_editing_event& event) noexcept override; void on_viewport_event(const Magnum::Math::Vector2<int>& size) noexcept override; diff --git a/editor/draw.cpp b/editor/draw.cpp index 285299b6..adbc7b60 100644 --- a/editor/draw.cpp +++ b/editor/draw.cpp @@ -66,6 +66,7 @@ void app::draw_cursor() void app::draw_collision_boxes() { + const auto [z_min, z_max] = get_z_bounds(); const auto [minx, maxx, miny, maxy] = M->get_draw_bounds(); const auto sz = M->window_size(); auto& world = M->world(); @@ -76,30 +77,31 @@ void app::draw_collision_boxes() using rtree_type = std::decay_t<decltype(*world[chunk_coords{}].rtree())>; using rect_type = typename rtree_type::Rect; - for (int16_t y = miny; y <= maxy; y++) - for (int16_t x = minx; x <= maxx; x++) - { - const chunk_coords pos{x, y}; - auto* c_ = world.at(pos); - if (!c_) - continue; - auto& c = *c_; - c.ensure_passability(); - const with_shifted_camera_offset o{shader, pos, {minx, miny}, {maxx, maxy}}; - if (floormat_main::check_chunk_visible(shader.camera_offset(), sz)) + for (int8_t z = z_min; z <= z_max; z++) + for (int16_t y = miny; y <= maxy; y++) + for (int16_t x = minx; x <= maxx; x++) { - constexpr float maxf = 1 << 24, max2f[] = { maxf, maxf }, min2f[] = { -maxf, -maxf }; - const auto* rtree = c.rtree(); - rtree->Search(min2f, max2f, [&](object_id data, const rect_type& rect) { - [[maybe_unused]] auto x = std::bit_cast<collision_data>(data); - Vector2 start(rect.m_min[0], rect.m_min[1]), end(rect.m_max[0], rect.m_max[1]); - auto size = (end - start); - auto center = Vector3(start + size*.5f, 0.f); - _wireframe_rect.draw(shader, { center, size, 3 }); - return true; - }); + const chunk_coords_ pos{x, y, z}; + auto* c_ = world.at(pos); + if (!c_) + continue; + auto& c = *c_; + c.ensure_passability(); + const with_shifted_camera_offset o{shader, pos, {minx, miny}, {maxx, maxy}}; + if (floormat_main::check_chunk_visible(shader.camera_offset(), sz)) + { + constexpr float maxf = 1 << 24, max2f[] = { maxf, maxf }, min2f[] = { -maxf, -maxf }; + const auto* rtree = c.rtree(); + rtree->Search(min2f, max2f, [&](object_id data, const rect_type& rect) { + [[maybe_unused]] auto x = std::bit_cast<collision_data>(data); + Vector2 start(rect.m_min[0], rect.m_min[1]), end(rect.m_max[0], rect.m_max[1]); + auto size = (end - start); + auto center = Vector3(start + size*.5f, 0.f); + _wireframe_rect.draw(shader, { center, size, 3 }); + return true; + }); + } } - } shader.set_tint({1, 0, 1, 1}); @@ -113,34 +115,35 @@ void app::draw_collision_boxes() const auto subpixel_ = Vector2(std::fmod(tile_[0], 1.f), std::fmod(tile_[1], 1.f)); const auto subpixel = m * Vector2(curchunk[0] < 0 ? 1 + subpixel_[0] : subpixel_[0], curchunk[1] < 0 ? 1 + subpixel_[1] : subpixel_[1]); - for (int16_t y = miny; y <= maxy; y++) - for (int16_t x = minx; x <= maxx; x++) - { - const chunk_coords c_pos{x, y}; - auto* c_ = world.at(c_pos); - if (!c_) - continue; - auto& c = *c_; - c.ensure_passability(); - const with_shifted_camera_offset o{shader, c_pos, {minx, miny}, {maxx, maxy}}; - if (floormat_main::check_chunk_visible(shader.camera_offset(), sz)) + for (int8_t z = z_min; z <= z_max; z++) + for (int16_t y = miny; y <= maxy; y++) + for (int16_t x = minx; x <= maxx; x++) { - constexpr auto half_tile = TILE_SIZE2/2; - constexpr auto chunk_size = TILE_SIZE2 * TILE_MAX_DIM; - auto chunk_dist = (curchunk - Vector2(c_pos))*chunk_size; - auto t0 = chunk_dist + curtile*TILE_SIZE2 + subpixel - half_tile; - auto t1 = t0+Vector2(1e-4f); - const auto* rtree = c.rtree(); - rtree->Search(t0.data(), t1.data(), [&](uint64_t data, const rect_type& rect) { - [[maybe_unused]] auto x = std::bit_cast<collision_data>(data); - Vector2 start(rect.m_min[0], rect.m_min[1]), end(rect.m_max[0], rect.m_max[1]); - auto size = end - start; - auto center = Vector3(start + size*.5f, 0.f); - _wireframe_rect.draw(shader, { center, size, 3 }); - return true; - }); + const chunk_coords_ c_pos{x, y, z}; + auto* c_ = world.at(c_pos); + if (!c_) + continue; + auto& c = *c_; + c.ensure_passability(); + 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 t1 = t0+Vector2(1e-4f); + const auto* rtree = c.rtree(); + rtree->Search(t0.data(), t1.data(), [&](uint64_t data, const rect_type& rect) { + [[maybe_unused]] auto x = std::bit_cast<collision_data>(data); + Vector2 start(rect.m_min[0], rect.m_min[1]), end(rect.m_max[0], rect.m_max[1]); + auto size = end - start; + auto center = Vector3(start + size*.5f, 0.f); + _wireframe_rect.draw(shader, { center, size, 3 }); + return true; + }); + } } - } } shader.set_tint({1, 1, 1, 1}); diff --git a/editor/events.cpp b/editor/events.cpp index 89bdf4a3..275ddf57 100644 --- a/editor/events.cpp +++ b/editor/events.cpp @@ -102,7 +102,7 @@ void app::on_mouse_scroll(const mouse_scroll_event& event) noexcept do_mouse_scroll((int)e.offset()[1]); } -auto app::resolve_keybinding(int k_, int mods_) const -> std::tuple<key, int> +auto app::resolve_keybinding(int k_, int mods_) -> std::tuple<key, int> { [[maybe_unused]] constexpr int CTRL = kmod_ctrl; [[maybe_unused]] constexpr int SHIFT = kmod_shift; diff --git a/editor/update.cpp b/editor/update.cpp index 6bb1ff66..f36b2905 100644 --- a/editor/update.cpp +++ b/editor/update.cpp @@ -185,33 +185,35 @@ void app::update_world(float dt) { auto& world = M->world(); const auto curframe = world.increment_frame_no(); + auto [z_min, z_max] = get_z_bounds(); auto [minx, maxx, miny, maxy] = M->get_draw_bounds(); minx--; miny--; maxx++; maxy++; - for (int16_t y = miny; y <= maxy; y++) - for (int16_t x = minx; x <= maxx; x++) - { - auto* c_ = world.at(chunk_coords{x, y}); - if (!c_) - continue; - auto& c = *c_; - const auto& es = c.entities(); -start: const auto size = es.size(); - for (auto i = size-1; i != (size_t)-1; i--) + for (int8_t z = z_min; z <= z_max; z++) + for (int16_t y = miny; y <= maxy; y++) + for (int16_t x = minx; x <= maxx; x++) { - auto& e = *es[i]; - fm_debug_assert(!(e.last_update > curframe)); - if (curframe > e.last_update) [[likely]] + auto* c_ = world.at({x, y, z}); + if (!c_) + continue; + auto& c = *c_; + const auto& es = c.entities(); +start: const auto size = es.size(); + for (auto i = size-1; i != (size_t)-1; i--) { - e.last_update = curframe; - auto status = e.update(i, dt); - if (status) + auto& e = *es[i]; + fm_debug_assert(!(e.last_update > curframe)); + if (curframe > e.last_update) [[likely]] { - //Debug{} << "goto start"; - goto start; + e.last_update = curframe; + auto status = e.update(i, dt); + if (status) + { + //Debug{} << "goto start"; + goto start; + } } } } - } } void app::update_character([[maybe_unused]] float dt) @@ -238,6 +240,14 @@ void app::set_cursor() set_cursor_from_imgui(); } +auto app::get_z_bounds() -> z_bounds +{ + if (_render_all_z_levels) + return { chunk_min_z, chunk_max_z }; + else + return { _z_level, _z_level }; +} + void app::update(float dt) { apply_commands(keys); diff --git a/floormat/app.hpp b/floormat/app.hpp index 63c8fb81..50dca6f9 100644 --- a/floormat/app.hpp +++ b/floormat/app.hpp @@ -18,6 +18,8 @@ struct chunk; struct floormat_app { + struct z_bounds final { int8_t min, max; }; + explicit floormat_app() noexcept; virtual ~floormat_app() noexcept; @@ -29,6 +31,7 @@ struct floormat_app virtual void update(float dt) = 0; virtual void maybe_initialize_chunk(const chunk_coords_& pos, chunk& c) = 0; virtual void draw() = 0; + virtual z_bounds get_z_bounds() = 0; virtual void on_mouse_move(const mouse_move_event& event) noexcept = 0; virtual void on_mouse_up_down(const mouse_button_event& event, bool is_down) noexcept = 0; diff --git a/main/draw.cpp b/main/draw.cpp index 521cad30..97d12579 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -4,7 +4,6 @@ #include "src/camera-offset.hpp" #include "src/anim-atlas.hpp" #include "main/clickable.hpp" -#include "world.hpp" #include <Corrade/Containers/ArrayView.h> #include <Magnum/GL/DefaultFramebuffer.h> #include <Magnum/GL/Renderer.h> @@ -104,32 +103,37 @@ auto main_impl::get_draw_bounds() const noexcept -> draw_bounds void main_impl::update_collect_threshold() { + // todo remove it? +#if 0 const auto [minx, maxx, miny, maxy] = get_draw_bounds(); const auto value = std::max(64uz, (size_t)(maxx-minx+4)*(size_t)(maxy-minx+4)); if (!(GL::Context::current().configurationFlags() & GL::Implementation::ContextConfigurationFlag::QuietLog)) fm_debug("collect threshold is now %zu", value); _world.set_collect_threshold(value); +#endif } void main_impl::draw_world() noexcept { + const auto [z_min, z_max] = app.get_z_bounds(); const auto [minx, maxx, miny, maxy] = get_draw_bounds(); const auto sz = window_size(); - for (int16_t y = miny; y <= maxy; y++) - for (int16_t x = minx; x <= maxx; x++) - { - const chunk_coords pos{x, y}; - if (pos == chunk_coords_{} && !_world.contains(pos)) - app.maybe_initialize_chunk(pos, _world[pos]); - auto* c_ = _world.at(pos); - if (!c_) - continue; - auto& c = *c_; - const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; - if (check_chunk_visible(_shader.camera_offset(), sz)) - _floor_mesh.draw(_shader, c); - } + for (int8_t z = z_min; z <= z_max; z++) + for (int16_t y = miny; y <= maxy; y++) + for (int16_t x = minx; x <= maxx; x++) + { + const chunk_coords_ pos{x, y, z}; + if (pos == chunk_coords_{} && !_world.contains(pos)) + app.maybe_initialize_chunk(pos, _world[pos]); + auto* c_ = _world.at(pos); + if (!c_) + continue; + auto& c = *c_; + const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; + if (check_chunk_visible(_shader.camera_offset(), sz)) + _floor_mesh.draw(_shader, c); + } GL::Renderer::enable(GL::Renderer::Feature::DepthTest); #ifdef FM_USE_DEPTH32 @@ -137,35 +141,37 @@ void main_impl::draw_world() noexcept #else GL::defaultFramebuffer.clearDepth(0); #endif - for (int16_t y = miny; y <= maxy; y++) - for (int16_t x = minx; x <= maxx; x++) - { - const chunk_coords pos{x, y}; - auto* c_ = _world.at(pos); - if (!c_) - continue; - auto& c = *c_; - const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; - if (check_chunk_visible(_shader.camera_offset(), sz)) - _wall_mesh.draw(_shader, c); - } + for (int8_t z = z_min; z <= z_max; z++) + for (int16_t y = miny; y <= maxy; y++) + for (int16_t x = minx; x <= maxx; x++) + { + const chunk_coords_ pos{x, y, z}; + auto* c_ = _world.at(pos); + if (!c_) + continue; + auto& c = *c_; + const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; + if (check_chunk_visible(_shader.camera_offset(), sz)) + _wall_mesh.draw(_shader, c); + } _clickable_scenery.clear(); GL::Renderer::setDepthMask(false); - for (int16_t y = miny; y <= maxy; y++) - for (int16_t x = minx; x <= maxx; x++) - { - const chunk_coords pos{x, y}; - auto* c_ = _world.at(pos); - if (!c_) - continue; - auto& c = *c_; - const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; - if (check_chunk_visible(_shader.camera_offset(), sz)) - _anim_mesh.draw(_shader, sz, c, _clickable_scenery); - } + for (int8_t z = z_min; z <= z_max; z++) + for (int16_t y = miny; y <= maxy; y++) + for (int16_t x = minx; x <= maxx; x++) + { + const chunk_coords_ pos{x, y, z}; + auto* c_ = _world.at(pos); + if (!c_) + continue; + auto& c = *c_; + const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; + if (check_chunk_visible(_shader.camera_offset(), sz)) + _anim_mesh.draw(_shader, sz, c, _clickable_scenery); + } GL::Renderer::setDepthMask(true); diff --git a/serialize/world-writer.cpp b/serialize/world-writer.cpp index 13751fc4..ee955c47 100644 --- a/serialize/world-writer.cpp +++ b/serialize/world-writer.cpp @@ -407,7 +407,7 @@ void writer_state::serialize_chunk(const chunk& c, chunk_coords_ coord) auto s = binary_writer{chunk_buf.begin()}; s << chunk_magic << coord.x << coord.y; - fm_assert(coord.z >= -8 && coord.z < 8); + fm_assert(coord.z >= chunk_min_z && coord.z <= chunk_max_z); s << coord.z; for (auto i = 0uz; i < TILE_COUNT; i++) diff --git a/src/camera-offset.cpp b/src/camera-offset.cpp index bf700138..88ebd0e4 100644 --- a/src/camera-offset.cpp +++ b/src/camera-offset.cpp @@ -4,16 +4,17 @@ namespace floormat { -with_shifted_camera_offset::with_shifted_camera_offset(tile_shader& shader, chunk_coords c, chunk_coords first, chunk_coords last) : +with_shifted_camera_offset::with_shifted_camera_offset(tile_shader& shader, chunk_coords_ c, chunk_coords first, chunk_coords last) : _shader{shader}, _camera{shader.camera_offset()} { fm_assert(shader.depth_offset() == 0.f); constexpr auto chunk_size = TILE_MAX_DIM20d*dTILE_SIZE; - const auto offset = _camera + tile_shader::project(Vector3d(c) * chunk_size); + const auto offset = _camera + tile_shader::project(Vector3d(c.x, c.y, 0) * chunk_size); first.x -= 8; first.y -= 8; last.x += 8; last.y += 8; // Z levels - const auto len_x = (float)(last.x - first.x), cx = (float)(c.x - first.x), cy = (float)(c.y - first.y); + auto len_x = (float)(last.x - first.x), cx = (float)(c.x - first.x), cy = (float)(c.y - first.y); + cx += c.z; cy += c.z; const float depth_offset = shader.depth_tile_size*(cy*TILE_MAX_DIM*len_x*TILE_MAX_DIM + cx*TILE_MAX_DIM); _shader.set_camera_offset(offset, depth_offset); diff --git a/src/camera-offset.hpp b/src/camera-offset.hpp index 80fc004e..f3b64177 100644 --- a/src/camera-offset.hpp +++ b/src/camera-offset.hpp @@ -9,7 +9,7 @@ struct tile_shader; struct with_shifted_camera_offset final { - explicit with_shifted_camera_offset(tile_shader& shader, chunk_coords c, chunk_coords first, chunk_coords last); + explicit with_shifted_camera_offset(tile_shader& shader, chunk_coords_ c, chunk_coords first, chunk_coords last); ~with_shifted_camera_offset(); private: tile_shader& _shader; // NOLINT diff --git a/src/global-coords.hpp b/src/global-coords.hpp index 9bdc311a..81ed1a70 100644 --- a/src/global-coords.hpp +++ b/src/global-coords.hpp @@ -38,6 +38,8 @@ struct chunk_coords_ final { constexpr bool operator==(const chunk_coords_&) const noexcept = default; }; +constexpr inline int8_t chunk_min_z = -8, chunk_max_z = 7; + struct global_coords final { using u0 = std::integral_constant<uint32_t, (1<<15)>; using s0 = std::integral_constant<int32_t, int32_t(u0::value)>; diff --git a/src/world.cpp b/src/world.cpp index ef78f313..f0818b44 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -81,7 +81,7 @@ world::world(size_t capacity) : _chunks{capacity} chunk& world::operator[](chunk_coords_ coord) noexcept { - fm_debug_assert(coord.z >= -8 && coord.z < 8); + fm_debug_assert(coord.z >= chunk_min_z && coord.z <= chunk_max_z); auto& [c, coord2] = _last_chunk; if (coord != coord2) c = &_chunks.try_emplace(coord, *this).first->second; diff --git a/src/world.hpp b/src/world.hpp index 793b3605..e6ec4f5b 100644 --- a/src/world.hpp +++ b/src/world.hpp @@ -21,7 +21,7 @@ struct world final { private: struct chunk_tuple final { - static constexpr chunk_coords_ invalid_coords = { -1 << 15, -1 << 15, -8 }; + static constexpr chunk_coords_ invalid_coords = { -1 << 15, -1 << 15, chunk_min_z }; chunk* c = nullptr; chunk_coords_ pos = invalid_coords; } _last_chunk; |