summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2022-12-08 12:00:45 +0100
committerStanislaw Halik <sthalik@misaki.pl>2022-12-08 12:00:45 +0100
commit9acf4738b15738cb2b9646481b75ba0c05a01e78 (patch)
treed8a8ce5007ea77f86d33136cdfa014e45d31d72b
parenta083f5c2124a6a907727b35a5c43d8175d396d73 (diff)
draw, editor: visualize bounding boxes
-rw-r--r--draw/quad-floor.hpp2
-rw-r--r--draw/quad-wall-n.hpp2
-rw-r--r--draw/quad-wall-w.hpp2
-rw-r--r--draw/quad.cpp30
-rw-r--r--draw/quad.hpp29
-rw-r--r--editor/app.hpp6
-rw-r--r--editor/draw.cpp45
-rw-r--r--editor/events.cpp29
-rw-r--r--editor/imgui.cpp7
-rw-r--r--editor/keys.hpp1
-rw-r--r--editor/update.cpp9
-rw-r--r--floormat/main.hpp1
-rw-r--r--main/draw.cpp2
-rw-r--r--main/main-impl.hpp1
-rw-r--r--src/chunk-bbox.cpp14
-rw-r--r--src/chunk.hpp4
16 files changed, 153 insertions, 31 deletions
diff --git a/draw/quad-floor.hpp b/draw/quad-floor.hpp
index 7a8ec59a..7d974798 100644
--- a/draw/quad-floor.hpp
+++ b/draw/quad-floor.hpp
@@ -13,7 +13,7 @@ struct quad_floor final
quad_floor(Vector3 center, Vector2 size, float line_width);
static constexpr std::size_t num_vertices = 4, num_indexes = 0;
- static constexpr GL::MeshPrimitive primitive = GL::MeshPrimitive::LineLoop;
+ static constexpr auto primitive = GL::MeshPrimitive::LineLoop;
using vertex_array = std::array<Vector3, num_vertices>;
diff --git a/draw/quad-wall-n.hpp b/draw/quad-wall-n.hpp
index 30d69e01..f07d7d06 100644
--- a/draw/quad-wall-n.hpp
+++ b/draw/quad-wall-n.hpp
@@ -12,7 +12,7 @@ struct quad_wall_n final
quad_wall_n(Vector3 center, Vector3 size, float line_width);
static constexpr std::size_t num_vertices = 4, num_indexes = 0;
- static constexpr GL::MeshPrimitive primitive = GL::MeshPrimitive::LineLoop;
+ static constexpr auto primitive = GL::MeshPrimitive::LineLoop;
using vertex_array = std::array<Vector3, num_vertices>;
diff --git a/draw/quad-wall-w.hpp b/draw/quad-wall-w.hpp
index fb087865..cca70b30 100644
--- a/draw/quad-wall-w.hpp
+++ b/draw/quad-wall-w.hpp
@@ -12,7 +12,7 @@ struct quad_wall_w final
quad_wall_w(Vector3 center, Vector3 size, float line_width);
static constexpr std::size_t num_vertices = 4, num_indexes = 0;
- static constexpr GL::MeshPrimitive primitive = GL::MeshPrimitive::LineLoop;
+ static constexpr auto primitive = GL::MeshPrimitive::LineLoop;
using vertex_array = std::array<Vector3, num_vertices>;
diff --git a/draw/quad.cpp b/draw/quad.cpp
new file mode 100644
index 00000000..d7be52f2
--- /dev/null
+++ b/draw/quad.cpp
@@ -0,0 +1,30 @@
+#include "quad.hpp"
+#include "wireframe.hpp"
+#include <Magnum/GL/Renderer.h>
+
+namespace floormat::wireframe {
+
+quad::quad(Vector3 center, Vector2 size, float line_width) :
+ center{center}, size{size}, line_width{line_width}
+{}
+
+quad::vertex_array quad::make_vertex_array() const
+{
+ const auto Sx = size[0]*.5f, Sy = size[1]*.5f;
+ const auto Cx_0 = center[0] - Sx, Cx_1 = center[0] + Sx;
+ const auto Cy_0 = center[1] - Sy, Cy_1 = center[1] + Sy;
+ const auto Cz = center[2] + 0;
+ return {{
+ { Cx_0, Cy_0, Cz },
+ { Cx_1, Cy_0, Cz },
+ { Cx_1, Cy_1, Cz },
+ { Cx_0, Cy_1, Cz },
+ }};
+}
+
+void quad::on_draw() const
+{
+ mesh_base::set_line_width(line_width);
+}
+
+} // namespace floormat::wireframe
diff --git a/draw/quad.hpp b/draw/quad.hpp
new file mode 100644
index 00000000..7bccebae
--- /dev/null
+++ b/draw/quad.hpp
@@ -0,0 +1,29 @@
+#pragma once
+#include <array>
+#include <Corrade/Containers/ArrayViewStl.h>
+#include <Magnum/Math/Vector3.h>
+#include <Magnum/GL/Mesh.h>
+
+namespace floormat::wireframe {
+
+struct quad final
+{
+ quad(Vector3 start, Vector2 size, float line_width);
+
+ static constexpr std::size_t num_vertices = 4, num_indexes = 0;
+ static constexpr GL::MeshPrimitive primitive = GL::MeshPrimitive::LineLoop;
+
+ using vertex_array = std::array<Vector3, num_vertices>;
+ using index_array = std::array<UnsignedShort, num_indexes>;
+
+ vertex_array make_vertex_array() const;
+ static ArrayView<const void> make_index_array() { return {}; }
+ void on_draw() const;
+
+private:
+ Vector3 center;
+ Vector2 size;
+ float line_width = 2;
+};
+
+} // namespace floormat::wireframe
diff --git a/editor/app.hpp b/editor/app.hpp
index c34b7ebd..ba1133d7 100644
--- a/editor/app.hpp
+++ b/editor/app.hpp
@@ -6,12 +6,11 @@
#include "draw/quad-floor.hpp"
#include "draw/quad-wall-n.hpp"
#include "draw/quad-wall-w.hpp"
+#include "draw/quad.hpp"
#include "draw/box.hpp"
#include "floormat/app.hpp"
#include "keys.hpp"
-
#include <memory>
-
#include <Corrade/Containers/Pointer.h>
#include <Corrade/Containers/Optional.h>
#include <Magnum/ImGuiIntegration/Context.h>
@@ -93,6 +92,7 @@ private:
void do_quickload();
void do_new_file();
+ void draw_collision_boxes();
void draw_editor_pane(float main_menu_height);
void draw_editor_tile_pane_atlas(tile_editor& ed, StringView name, const std::shared_ptr<tile_atlas>& atlas);
void draw_editor_scenery_pane(scenery_editor& ed);
@@ -122,10 +122,12 @@ private:
wireframe_mesh<wireframe::quad_wall_n> _wireframe_wall_n {_wireframe_texture};
wireframe_mesh<wireframe::quad_wall_w> _wireframe_wall_w {_wireframe_texture};
wireframe_mesh<wireframe::box> _wireframe_box {_wireframe_texture};
+ wireframe_mesh<wireframe::quad> _wireframe_rect {_wireframe_texture};
editor _editor;
key_set keys;
std::array<int, key_set::COUNT> key_modifiers = {};
cursor_state cursor;
+ bool _draw_collision_boxes : 1 = false;
};
} // namespace floormat
diff --git a/editor/draw.cpp b/editor/draw.cpp
index 275d99fc..32319c1b 100644
--- a/editor/draw.cpp
+++ b/editor/draw.cpp
@@ -6,6 +6,8 @@
#include "src/anim-atlas.hpp"
#include "draw/anim.hpp"
#include "src/camera-offset.hpp"
+#include "src/world.hpp"
+#include "src/collision.hpp"
#include <Magnum/Math/Color.h>
#include <Magnum/Math/Vector3.h>
@@ -54,10 +56,53 @@ void app::draw_cursor()
}
}
}
+ shader.set_tint({1, 1, 1, 1});
+}
+
+void app::draw_collision_boxes()
+{
+ const auto [minx, maxx, miny, maxy] = M->get_draw_bounds();
+ const auto sz = M->window_size();
+ auto& world = M->world();
+ auto& shader = M->shader();
+
+ shader.set_tint({0, .5f, 1, 1});
+
+ for (std::int16_t y = miny; y <= maxy; y++)
+ for (std::int16_t x = minx; x <= maxx; x++)
+ {
+ const chunk_coords pos{x, y};
+ auto& c = world[pos];
+ if (c.empty())
+ continue;
+ c.ensure_passability();
+ auto* lqt = c.lqt_from_collision_type(collision::move);
+ if (!lqt)
+ continue;
+ const with_shifted_camera_offset o{shader, pos, {minx, miny}, {maxx, maxy}};
+ if (floormat_main::check_chunk_visible(shader.camera_offset(), sz))
+ {
+ auto bb = lqt->GetLooseBoundingBox();
+ bb.left -= bb.width; bb.top -= bb.height;
+ bb.width *= 2; bb.height *= 2;
+ auto q = lqt->QueryInsideRegion(bb);
+ using extractor = std::decay_t<decltype(*lqt)>::BoundingBoxExtractor;
+ while (!q.EndOfQuery())
+ {
+ loose_quadtree::BoundingBox<std::int16_t> bb{0, 0, 0, 0};
+ extractor::ExtractBoundingBox(q.GetCurrent(), &bb);
+ _wireframe_rect.draw(shader, { Vector3(bb.left+bb.width/2.f, bb.top+bb.height/2.f, 0), Vector2(bb.width, bb.height), 3 });
+ q.Next();
+ }
+ }
+ }
+ shader.set_tint({1, 1, 1, 1});
}
void app::draw()
{
+ if (_draw_collision_boxes)
+ draw_collision_boxes();
if (_editor.current_tile_editor() || _editor.current_scenery_editor())
draw_cursor();
draw_ui();
diff --git a/editor/events.cpp b/editor/events.cpp
index 6bf4b3e7..96f5c82c 100644
--- a/editor/events.cpp
+++ b/editor/events.cpp
@@ -113,20 +113,21 @@ auto app::resolve_keybinding(int k_, int mods_) const -> std::tuple<key, int>
switch (int mods = k2 & kmod_mask; k2)
{
default: continue;
- case SDLK_w: return { key_camera_up, mods };
- case SDLK_a: return { key_camera_left, mods };
- case SDLK_s: return { key_camera_down, mods };
- case SDLK_d: return { key_camera_right, mods };
- case SDLK_HOME: return { key_camera_reset, mods };
- case SDLK_r: return { key_rotate_tile, mods };
- case SDLK_1: return { key_mode_none, mods };
- case SDLK_2: return { key_mode_floor, mods };
- case SDLK_3: return { key_mode_walls, mods };
- case SDLK_4: return { key_mode_scenery, mods };
- case SDLK_F5: return { key_quicksave, mods };
- case SDLK_F9: return { key_quickload, mods };
- case SDLK_q | CTRL: return { key_quit, mods };
- case SDLK_n | CTRL: return { key_new_file, mods };
+ case SDLK_w: return { key_camera_up, mods };
+ case SDLK_a: return { key_camera_left, mods };
+ case SDLK_s: return { key_camera_down, mods };
+ case SDLK_d: return { key_camera_right, mods };
+ case SDLK_HOME: return { key_camera_reset, mods };
+ case SDLK_r: return { key_rotate_tile, mods };
+ case SDLK_1: return { key_mode_none, mods };
+ case SDLK_2: return { key_mode_floor, mods };
+ case SDLK_3: return { key_mode_walls, mods };
+ case SDLK_4: return { key_mode_scenery, mods };
+ case SDLK_F5: return { key_quicksave, mods };
+ case SDLK_F9: return { key_quickload, mods };
+ case SDLK_q | CTRL: return { key_quit, mods };
+ case SDLK_n | CTRL: return { key_new_file, mods };
+ case SDLK_b | ALT: return { key_collision_boxes, mods };
}
}
}
diff --git a/editor/imgui.cpp b/editor/imgui.cpp
index 1b219561..69037861 100644
--- a/editor/imgui.cpp
+++ b/editor/imgui.cpp
@@ -77,6 +77,13 @@ float app::draw_main_menu()
if (b_rotate)
do_key(key_rotate_tile);
}
+ if (auto b = begin_menu("View"))
+ {
+ bool show_collisions = _draw_collision_boxes;
+ ImGui::MenuItem("Collision boxes", "Alt+B", &show_collisions);
+ if (show_collisions)
+ do_key(key_collision_boxes);
+ }
main_menu_height = ImGui::GetContentRegionMax().y;
}
diff --git a/editor/keys.hpp b/editor/keys.hpp
index 1f56cb69..3311a69c 100644
--- a/editor/keys.hpp
+++ b/editor/keys.hpp
@@ -17,6 +17,7 @@ enum key : unsigned {
key_NO_REPEAT,
key_rotate_tile,
key_mode_none, key_mode_floor, key_mode_walls, key_mode_scenery,
+ key_collision_boxes,
key_GLOBAL,
key_new_file,
key_quit,
diff --git a/editor/update.cpp b/editor/update.cpp
index f6d64411..4dde4ffc 100644
--- a/editor/update.cpp
+++ b/editor/update.cpp
@@ -104,6 +104,8 @@ void app::do_key(key k, int mods)
return _editor.set_mode(editor_mode::walls);
case key_mode_scenery:
return _editor.set_mode(editor_mode::scenery);
+ case key_collision_boxes:
+ return void(_draw_collision_boxes = !_draw_collision_boxes);
case key_quicksave:
return do_quicksave();
case key_quickload:
@@ -130,9 +132,14 @@ void app::update_world(float dt)
minx--; miny--; maxx++; maxy++;
for (std::int16_t y = miny; y <= maxy; y++)
for (std::int16_t x = minx; x <= maxx; x++)
- for (chunk_coords c{x, y}; auto [x, k, pt] : world[c])
+ for (auto& c = world[chunk_coords{x, y}]; auto [x, k, pt] : c)
if (auto [atlas, scenery] = x.scenery(); atlas != nullptr)
+ {
+ auto pass0 = scenery.passability;
scenery.update(dt, *atlas);
+ if (pass0 != scenery.passability)
+ c.mark_scenery_modified();
+ }
}
void app::update(float dt)
diff --git a/floormat/main.hpp b/floormat/main.hpp
index 7803cd3c..84f25eda 100644
--- a/floormat/main.hpp
+++ b/floormat/main.hpp
@@ -56,6 +56,7 @@ struct floormat_main
virtual global_coords pixel_to_tile(Vector2d position) 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;
virtual struct world& world() noexcept = 0;
diff --git a/main/draw.cpp b/main/draw.cpp
index 88cd2745..1cb9b396 100644
--- a/main/draw.cpp
+++ b/main/draw.cpp
@@ -127,7 +127,7 @@ void main_impl::draw_world() noexcept
GL::Renderer::disable(GL::Renderer::Feature::DepthTest);
}
-bool main_impl::check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept
+bool floormat_main::check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept
{
constexpr Vector3d len = dTILE_SIZE * TILE_MAX_DIM20d;
enum : std::size_t { x, y, };
diff --git a/main/main-impl.hpp b/main/main-impl.hpp
index 2ea8f940..9178d8a6 100644
--- a/main/main-impl.hpp
+++ b/main/main-impl.hpp
@@ -90,7 +90,6 @@ private:
void draw_world() noexcept;
draw_bounds get_draw_bounds() const noexcept override;
- [[nodiscard]] static bool check_chunk_visible(const Vector2d& offset, const Vector2i& size) noexcept;
char maybe_register_debug_callback(fm_gpu_debug flag);
void register_debug_callback();
diff --git a/src/chunk-bbox.cpp b/src/chunk-bbox.cpp
index 8d99515b..b951da10 100644
--- a/src/chunk-bbox.cpp
+++ b/src/chunk-bbox.cpp
@@ -118,7 +118,7 @@ auto chunk::query_collisions(Vector4s vec, collision type) const -> Query
{
const_cast<chunk&>(*this).ensure_passability();
loose_quadtree::BoundingBox<std::int16_t> bbox { vec[0], vec[1], vec[2], vec[3] };
- return { lqt_from_collision_type(type).QueryIntersectsRegion(bbox) };
+ return { lqt_from_collision_type(type)->QueryIntersectsRegion(bbox) };
}
auto chunk::query_collisions(Vector2s position, Vector2us size, collision type) const -> Query
@@ -127,7 +127,7 @@ auto chunk::query_collisions(Vector2s position, Vector2us size, collision type)
constexpr auto half = sTILE_SIZE2/2;
const auto start = position - half;
loose_quadtree::BoundingBox<std::int16_t> bbox {start[0], start[1], (Short)size[0], (Short)size[1] };
- return { lqt_from_collision_type(type).QueryIntersectsRegion(bbox) };
+ return { lqt_from_collision_type(type)->QueryIntersectsRegion(bbox) };
}
auto chunk::query_collisions(local_coords p, Vector2us size, Vector2s offset, collision type) const -> Query
@@ -136,19 +136,19 @@ auto chunk::query_collisions(local_coords p, Vector2us size, Vector2s offset, co
const auto pos = Vector2s(p.x, p.y) * sTILE_SIZE2 + offset;
const auto start = pos - Vector2s(size/2);
loose_quadtree::BoundingBox<std::int16_t> bbox { start[0], start[1], (Short)size[0], (Short)size[1] };
- return { lqt_from_collision_type(type).QueryIntersectsRegion(bbox) };
+ return { lqt_from_collision_type(type)->QueryIntersectsRegion(bbox) };
}
-auto chunk::lqt_from_collision_type(collision type) const noexcept -> lqt&
+auto chunk::lqt_from_collision_type(collision type) const noexcept -> lqt*
{
switch (type)
{
case collision::move:
- return *_lqt_move;
+ return _lqt_move.get();
case collision::shoot:
- return *_lqt_shoot;
+ return _lqt_shoot.get();
case collision::view:
- return *_lqt_view;
+ return _lqt_view.get();
}
fm_abort("wrong collision type '%hhu'", std::uint8_t(type));
}
diff --git a/src/chunk.hpp b/src/chunk.hpp
index d0df8e5d..ebe58d5a 100644
--- a/src/chunk.hpp
+++ b/src/chunk.hpp
@@ -107,6 +107,8 @@ struct chunk final
Query query_collisions(local_coords p, Vector2us size, Vector2s offset, collision type) const;
Query query_collisions(Vector4s vec, collision type) const;
+ lqt* lqt_from_collision_type(collision type) const noexcept;
+
private:
std::array<std::shared_ptr<tile_atlas>, TILE_COUNT> _ground_atlases;
std::array<std::uint8_t, TILE_COUNT> ground_indexes = {};
@@ -129,8 +131,6 @@ private:
_walls_modified : 1 = true,
_scenery_modified : 1 = true,
_pass_modified : 1 = true;
-
- lqt& lqt_from_collision_type(collision type) const noexcept;
static std::unique_ptr<lqt> make_lqt();
void cleanup_lqt();
};