summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-04-08 11:12:50 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-04-08 11:12:50 +0200
commitd1984938e4f0cbc24b7b8cc6e219fa873d39418a (patch)
treed00c6cf0ba66c3285d145527360a0e3aeaef6671
parentd17ed6b4ba01a73d33e3ff3ca8f0f6fb25259223 (diff)
a
-rw-r--r--editor/app.hpp3
-rw-r--r--editor/draw.cpp99
-rw-r--r--editor/events.cpp2
-rw-r--r--editor/update.cpp48
-rw-r--r--floormat/app.hpp3
-rw-r--r--main/draw.cpp84
-rw-r--r--serialize/world-writer.cpp2
-rw-r--r--src/camera-offset.cpp7
-rw-r--r--src/camera-offset.hpp2
-rw-r--r--src/global-coords.hpp2
-rw-r--r--src/world.cpp2
-rw-r--r--src/world.hpp2
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;