summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2023-04-10 00:30:00 +0200
committerStanislaw Halik <sthalik@misaki.pl>2023-04-10 00:31:59 +0200
commit385fb319018fb138f1e6e466adfa407f369328ce (patch)
treeac355c70c57bddbf68be75415f3f445ee78f358a /src
parent2b9e97e28ed0504de15d73ff5e1dd0ff9deb6d09 (diff)
src/entity: check collisions with neighbor chunks
Diffstat (limited to 'src')
-rw-r--r--src/entity.cpp48
1 files changed, 38 insertions, 10 deletions
diff --git a/src/entity.cpp b/src/entity.cpp
index f382db75..be91db7f 100644
--- a/src/entity.cpp
+++ b/src/entity.cpp
@@ -126,6 +126,34 @@ Pair<global_coords, Vector2b> entity::normalize_coords(global_coords coord, Vect
return { coord, Vector2b(off_new) };
}
+template<bool neighbor = true>
+static bool do_search(struct chunk* c, chunk_coords_ coord, object_id id, Vector2 min, Vector2 max, Vector2i off = {})
+{
+ if constexpr(neighbor)
+ {
+ const auto ch = chunk_coords{(int16_t)(coord.x + off[0]), (int16_t)(coord.y + off[1])};
+ constexpr auto size = TILE_SIZE2 * TILE_MAX_DIM, grace = TILE_SIZE2 * 4;
+ const auto off_ = Vector2(off) * size;
+ min -= off_;
+ max -= off_;
+ if (!(min + grace >= Vector2{} && max - grace <= size)) [[likely]]
+ return true;
+ auto& w = c->world();
+ c = w.at({ch, coord.z});
+ if (!c) [[unlikely]]
+ return true;
+ }
+ bool ret = true;
+ c->rtree()->Search(min.data(), max.data(), [&](object_id data, const auto&) {
+ auto x = std::bit_cast<collision_data>(data);
+ if (x.data != id && x.pass != (uint64_t)pass_mode::pass)
+ return ret = false;
+ else
+ return true;
+ });
+ return ret;
+}
+
bool entity::can_move_to(Vector2i delta, global_coords coord2, Vector2b offset, Vector2b bbox_offset, Vector2ub bbox_size)
{
auto [coord_, offset_] = normalize_coords(coord2, offset, delta);
@@ -139,16 +167,16 @@ bool entity::can_move_to(Vector2i delta, global_coords coord2, Vector2b offset,
const auto center = Vector2(coord_.local())*TILE_SIZE2 + Vector2(offset_) + Vector2(bbox_offset),
half_bbox = Vector2(bbox_size)*.5f,
min = center - half_bbox, max = min + Vector2(bbox_size);
-
- bool ret = true;
- c_.rtree()->Search(min.data(), max.data(), [&](object_id data, const auto&) {
- auto id2 = std::bit_cast<collision_data>(data).data;
- if (id2 != id)
- return ret = false;
- else
- return true;
- });
- return ret;
+ auto ch = chunk_coords_{coord_.chunk(), coord_.z()};
+ return do_search<false>(&c_, ch, id, min, max) &&
+ do_search(&c_, ch, id, min, max, {-1, -1}) &&
+ do_search(&c_, ch, id, min, max, {-1, 0}) &&
+ do_search(&c_, ch, id, min, max, { 0, -1}) &&
+ do_search(&c_, ch, id, min, max, { 1, 1}) &&
+ do_search(&c_, ch, id, min, max, { 1, 0}) &&
+ do_search(&c_, ch, id, min, max, { 0, 1}) &&
+ do_search(&c_, ch, id, min, max, { 1, -1}) &&
+ do_search(&c_, ch, id, min, max, {-1, 1});
}
bool entity::can_move_to(Vector2i delta)