summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-04-02 05:31:06 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-04-02 05:31:06 +0200
commitab16b95656fbcf719604072263f8375cd80213c2 (patch)
tree41b52d7a95126e85c8f44adc6d7138a319746cb8
parent93880a5b068239768ba8b6e562a21e3d9103c124 (diff)
a
-rw-r--r--draw/anim.cpp32
-rw-r--r--draw/anim.hpp6
-rw-r--r--editor/imgui.cpp15
-rw-r--r--main/clickable.hpp3
-rw-r--r--main/draw.cpp6
-rw-r--r--src/chunk-scenery.cpp6
-rw-r--r--src/chunk-scenery.hpp5
-rw-r--r--src/chunk.hpp2
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)
{