diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2023-04-02 05:31:06 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2023-04-02 05:31:06 +0200 |
commit | ab16b95656fbcf719604072263f8375cd80213c2 (patch) | |
tree | 41b52d7a95126e85c8f44adc6d7138a319746cb8 | |
parent | 93880a5b068239768ba8b6e562a21e3d9103c124 (diff) |
a
-rw-r--r-- | draw/anim.cpp | 32 | ||||
-rw-r--r-- | draw/anim.hpp | 6 | ||||
-rw-r--r-- | editor/imgui.cpp | 15 | ||||
-rw-r--r-- | main/clickable.hpp | 3 | ||||
-rw-r--r-- | main/draw.cpp | 6 | ||||
-rw-r--r-- | src/chunk-scenery.cpp | 6 | ||||
-rw-r--r-- | src/chunk-scenery.hpp | 5 | ||||
-rw-r--r-- | src/chunk.hpp | 2 |
8 files changed, 50 insertions, 25 deletions
diff --git a/draw/anim.cpp b/draw/anim.cpp index ff0914c8..e8aa4e3b 100644 --- a/draw/anim.cpp +++ b/draw/anim.cpp @@ -26,31 +26,41 @@ std::array<UnsignedShort, 6> anim_mesh::make_index_array() }}; } -void anim_mesh::add_clickable(tile_shader& shader, const Vector2i& win_size, const std::shared_ptr<entity>& s, std::vector<clickable>& list) +void anim_mesh::add_clickable(tile_shader& shader, const Vector2i& win_size, + entity* s_, const chunk::topo_sort_data& data, + std::vector<clickable>& list) { - const auto& a = *s->atlas; - const auto& g = a.group(s->r); - const auto& f = a.frame(s->r, s->frame); - const auto world_pos = TILE_SIZE20 * Vector3(s->coord.local()) + Vector3(g.offset) + Vector3(Vector2(s->offset), 0); + const auto& s = *s_; + const auto& a = *s.atlas; + const auto& g = a.group(s.r); + const auto& f = a.frame(s.r, s.frame); + const auto world_pos = TILE_SIZE20 * Vector3(s.coord.local()) + Vector3(g.offset) + Vector3(Vector2(s.offset), 0); const Vector2i offset((Vector2(shader.camera_offset()) + Vector2(win_size)*.5f) + shader.project(world_pos) - Vector2(f.ground)); if (offset < win_size && offset + Vector2i(f.size) >= Vector2i()) { clickable item = { - { f.offset, f.offset + f.size }, { offset, offset + Vector2i(f.size) }, - a.bitmask(), &*s, s->ordinal(), - a.info().pixel_size[0], - !g.mirror_from.isEmpty(), + .src = { f.offset, f.offset + f.size }, + .dest = { offset, offset + Vector2i(f.size) }, + .bitmask = a.bitmask(), + .e = s_, + .depth = s.ordinal(), + .slope = data.slope, + .stride = a.info().pixel_size[0], + .mirrored = !g.mirror_from.isEmpty(), }; list.push_back(item); } } -void anim_mesh::draw(tile_shader& shader, chunk& c) +void anim_mesh::draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector<clickable>& list) { constexpr auto quad_index_count = 6; auto [mesh_, es, size] = c.ensure_scenery_mesh(_draw_array); + for (const auto& x : es) + add_clickable(shader, win_size, x.data.in, x.data, list); + GL::MeshView mesh{mesh_}; [[maybe_unused]] size_t draw_count = 0; const auto max_index = uint32_t(size*quad_index_count - 1); @@ -75,7 +85,7 @@ void anim_mesh::draw(tile_shader& shader, chunk& c) for (auto k = 0uz; k < size; k++) { fm_assert(es[k].e); - const auto& e = *es[k].e; + auto& e = *es[k].e; auto& atlas = *e.atlas; if (last && &atlas != last.atlas) { diff --git a/draw/anim.hpp b/draw/anim.hpp index 9574f1d1..96c1de7e 100644 --- a/draw/anim.hpp +++ b/draw/anim.hpp @@ -26,10 +26,12 @@ struct anim_mesh final { anim_mesh(); - void draw(tile_shader& shader, chunk& c); + void draw(tile_shader& shader, const Vector2i& win_size, chunk& c, std::vector<clickable>& list); void draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, const Vector3& pos, float depth); void draw(tile_shader& shader, anim_atlas& atlas, rotation r, size_t frame, local_coords xy, Vector2b offset, float depth_offset); - static void add_clickable(tile_shader& shader, const Vector2i& win_size, const std::shared_ptr<entity>& s, std::vector<clickable>& list); + static void add_clickable(tile_shader& shader, const Vector2i& win_size, + entity* s_, const chunk::topo_sort_data& data, + std::vector<clickable>& list); private: static std::array<UnsignedShort, 6> make_index_array(); diff --git a/editor/imgui.cpp b/editor/imgui.cpp index 9a83d780..73095134 100644 --- a/editor/imgui.cpp +++ b/editor/imgui.cpp @@ -3,6 +3,7 @@ #include "compat/format.hpp" #include "src/world.hpp" #include "src/anim-atlas.hpp" +#include "shaders/tile.hpp" #include "main/clickable.hpp" #include "imgui-raii.hpp" @@ -113,13 +114,25 @@ void app::draw_clickables() { ImDrawList& draw = *ImGui::GetForegroundDrawList(); const auto color = ImGui::ColorConvertFloat4ToU32({0, .8f, .8f, .95f}); + constexpr float thickness = 2.5f; + const auto& shader = M->shader(); + const auto win_size = M->window_size(); for (const auto& x : M->clickable_scenery()) { auto dest = Math::Range2D<float>(x.dest); auto min = dest.min(), max = dest.max(); draw.AddRect({ min.x(), min.y() }, { max.x(), max.y() }, - color, 0, ImDrawFlags_None, 2.5f); + color, 0, ImDrawFlags_None, thickness); + if (x.slope != 0.f) + { + const auto& e = *x.e; + const auto bb_min_ = -tile_shader::project(Vector3(Vector2(e.bbox_size/2), 0)); + const auto bb_max_ = bb_min_ + tile_shader::project(Vector3(Vector2(e.bbox_size), 0)); + const auto bb_min = min + tile_shader::project(Vector3(bb_min_, 0)); + const auto bb_max = min + tile_shader::project(Vector3(bb_max_, 0)); + draw.AddLine({ bb_min[0], bb_min[1] }, { bb_max[0], bb_max[1] }, color, thickness); + } } } diff --git a/main/clickable.hpp b/main/clickable.hpp index 0b491a52..7a192fb3 100644 --- a/main/clickable.hpp +++ b/main/clickable.hpp @@ -2,6 +2,7 @@ #include "src/global-coords.hpp" #include <memory> #include <Corrade/Containers/BitArrayView.h> +#include <Magnum/Math/Vector2.h> #include <Magnum/Math/Range.h> namespace floormat { @@ -13,7 +14,7 @@ struct clickable final { Math::Range2D<int> dest; BitArrayView bitmask; entity* e; - float depth; + float depth, slope; uint32_t stride; bool mirrored; }; diff --git a/main/draw.cpp b/main/draw.cpp index cf8ab20a..37b88e7c 100644 --- a/main/draw.cpp +++ b/main/draw.cpp @@ -134,11 +134,7 @@ void main_impl::draw_world() noexcept continue; const with_shifted_camera_offset o{_shader, pos, {minx, miny}, {maxx, maxy}}; if (check_chunk_visible(_shader.camera_offset(), sz)) - { - _anim_mesh.draw(_shader, c); - for (const auto& e : c.entities()) - _anim_mesh.add_clickable(_shader, window_size(), e, _clickable_scenery); - } + _anim_mesh.draw(_shader, sz, c, _clickable_scenery); } GL::Renderer::setDepthMask(true); diff --git a/src/chunk-scenery.cpp b/src/chunk-scenery.cpp index b89baeb9..7852088f 100644 --- a/src/chunk-scenery.cpp +++ b/src/chunk-scenery.cpp @@ -71,7 +71,7 @@ static void topological_sort(Array<chunk::entity_draw_order>& array, size_t size fm_assert(output == (size_t)-1); } -auto chunk::make_topo_sort_data(const entity& e) -> topo_sort_data +auto chunk::make_topo_sort_data(entity& e) -> topo_sort_data { const auto& a = *e.atlas; const auto& f = a.frame(e.r, e.frame); @@ -100,10 +100,12 @@ auto chunk::make_topo_sort_data(const entity& e) -> topo_sort_data const auto bb_min = tile_shader::project(Vector3(Vector2(bb_min_[0], bb_max_[1]), 0)); const auto bb_max = tile_shader::project(Vector3(Vector2(bb_max_[0], bb_min_[1]), 0)); const auto bb_len = bb_max[0] - bb_min[0]; - if (bb_len >= 1 && a.info().pixel_size.x() > iTILE_SIZE[0]) + if (bb_len >= 1 && f.size[0] > iTILE_SIZE[0]) { data.slope = (bb_max[1]-bb_min[1])/bb_len; data.mode = topo_sort_data::mode_static; + data.bb_min = Vector2s(bb_min); + data.bb_max = Vector2s(bb_max); } break; } diff --git a/src/chunk-scenery.hpp b/src/chunk-scenery.hpp index fcb59c50..cbe2ea83 100644 --- a/src/chunk-scenery.hpp +++ b/src/chunk-scenery.hpp @@ -9,9 +9,10 @@ struct chunk::topo_sort_data { enum m : uint8_t { mode_none, mode_static, mode_character, }; - const entity* in = nullptr; + entity* in = nullptr; Vector2i min, max, center; float slope = 0, ord; + Vector2s bb_min = {}, bb_max = {}; m mode : 2 = mode_none; uint8_t visited : 1 = false; @@ -19,7 +20,7 @@ struct chunk::topo_sort_data }; struct chunk::entity_draw_order { - const entity *e; + entity *e; float ord; topo_sort_data data; }; diff --git a/src/chunk.hpp b/src/chunk.hpp index ddcf2c50..385ba72e 100644 --- a/src/chunk.hpp +++ b/src/chunk.hpp @@ -138,7 +138,7 @@ private: _entities_sorted : 1 = true; void ensure_scenery_draw_array(Array<entity_draw_order>& array); - static topo_sort_data make_topo_sort_data(const entity& e); + static topo_sort_data make_topo_sort_data(entity& e); struct bbox final // NOLINT(cppcoreguidelines-pro-type-member-init) { |