summaryrefslogtreecommitdiffhomepage
path: root/src/chunk-collision.cpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-03-14 07:33:47 +0100
committerStanislaw Halik <sthalik@misaki.pl>2023-03-14 07:33:47 +0100
commitdc5e66b5a29fd7de8ddf59852ceefd982289b7c3 (patch)
tree18bf0a274f1595d6d2d6cfb32a3b3825d843e315 /src/chunk-collision.cpp
parent29bdd5f2170b9d46a8b3b0973c4c0845d6a2b61e (diff)
a
Diffstat (limited to 'src/chunk-collision.cpp')
-rw-r--r--src/chunk-collision.cpp43
1 files changed, 27 insertions, 16 deletions
diff --git a/src/chunk-collision.cpp b/src/chunk-collision.cpp
index 3cf772ef..032c9d7d 100644
--- a/src/chunk-collision.cpp
+++ b/src/chunk-collision.cpp
@@ -18,10 +18,9 @@ constexpr Vector2 tile_start(std::size_t k)
return TILE_SIZE2 * Vector2(coord) - half_tile;
}
-constexpr Pair<Vector2i, Vector2i> scenery_tile(std::size_t k, const scenery& sc)
+Pair<Vector2i, Vector2i> scenery_tile(const entity& sc)
{
- const local_coords coord{k};
- auto center = iTILE_SIZE2 * Vector2i(coord) + Vector2i(sc.offset) + Vector2i(sc.bbox_offset);
+ auto center = iTILE_SIZE2 * Vector2i(sc.coord.local()) + Vector2i(sc.offset) + Vector2i(sc.bbox_offset);
auto start = center - Vector2i(sc.bbox_size);
auto size = Vector2i(sc.bbox_size)*2;
return { start, start + size, };
@@ -60,15 +59,13 @@ void chunk::ensure_passability() noexcept
_rtree.RemoveAll();
- for (auto i = 0_uz; i < TILE_COUNT; i++)
+ for (const std::shared_ptr<entity>& s : entities())
{
- if (auto s = operator[](i).scenery())
- {
- bbox box;
- if (_bbox_for_scenery(i, box))
- _add_bbox(box);
- }
+ bbox box;
+ if (_bbox_for_scenery(*s, box))
+ _add_bbox(box);
}
+
for (auto i = 0_uz; i < TILE_COUNT; i++)
{
if (const auto* atlas = ground_atlas_at(i))
@@ -99,24 +96,26 @@ void chunk::ensure_passability() noexcept
}
}
-bool chunk::_bbox_for_scenery(std::size_t i, bbox& value) noexcept
+bool chunk::_bbox_for_scenery(const entity& s, bbox& value) noexcept
{
- fm_debug_assert(i < TILE_COUNT);
- auto [atlas, s] = operator[](i).scenery();
- auto [start, end] = scenery_tile(i, s);
- auto id = make_id(collision_type::scenery, s.passability, i);
+ auto [start, end] = scenery_tile(s);
+ auto id = make_id(collision_type::scenery, s.pass, s.id);
value = { .id = id, .start = start, .end = end };
- return atlas && s.passability != pass_mode::pass && Vector2i(s.bbox_size).product() > 0;
+ return s.atlas && s.pass != pass_mode::pass;
}
void chunk::_remove_bbox(const bbox& x)
{
+ if (_scenery_modified)
+ return;
auto start = Vector2(x.start), end = Vector2(x.end);
_rtree.Remove(start.data(), end.data(), x.id);
}
void chunk::_add_bbox(const bbox& x)
{
+ if (_scenery_modified)
+ return;
auto start = Vector2(x.start), end = Vector2(x.end);
_rtree.Insert(start.data(), end.data(), x.id);
}
@@ -145,4 +144,16 @@ void chunk::_replace_bbox(const bbox& x0, const bbox& x1, bool b0, bool b1)
CORRADE_ASSUME(false);
}
+bool chunk::can_place_entity(const entity_proto& proto, local_coords pos)
+{
+ (void)ensure_scenery_mesh();
+
+ const auto center = Vector2(pos)*TILE_SIZE2 + Vector2(proto.offset) + Vector2(proto.bbox_offset),
+ half_bbox = Vector2(proto.bbox_size)*.5f,
+ min = center - half_bbox, max = center + half_bbox;
+ bool ret = true;
+ _rtree.Search(min.data(), max.data(), [&](auto, const auto&) { return ret = false; });
+ return ret;
+}
+
} // namespace floormat