summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-01-31 21:02:25 +0100
committerMel <einebeere@gmail.com>2024-01-31 21:02:25 +0100
commit286261c1c730f3d8f3412b0f502ace366ba1ea76 (patch)
treeadc0cf8de5507c7e1a442ad55558f98434d89bb4 /src
parent9bdc36787a5ace22e16d5b24c77218fa349c691e (diff)
downloadmeowcraft-286261c1c730f3d8f3412b0f502ace366ba1ea76.tar.zst
meowcraft-286261c1c730f3d8f3412b0f502ace366ba1ea76.zip
Fix collisions phasing through ground at chunk borders
Diffstat (limited to 'src')
-rw-r--r--src/Entities/Player.cpp32
1 files changed, 15 insertions, 17 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index fd22247..7a415ec 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -1,5 +1,7 @@
#include "Player.hpp"
+#include <unordered_set>
+
namespace MC::Entities {
void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera, World::World& world) {
@@ -91,7 +93,7 @@ std::vector<AABB> Player::terrain_collision_domain(
// Make the box a bit bigger so we don't clip through blocks.
auto domain_box = bounding_box_for_position(from)
.unite(bounding_box_for_position(to))
- .unite(AABB{{1, 1, 1}});
+ .sum(AABB{{1, 1, 1}});
std::vector<AABB> colliding_blocks;
@@ -100,25 +102,21 @@ std::vector<AABB> Player::terrain_collision_domain(
// This will be more efficient and actually accurate,
// since right now if you're fast enough you can clip
// through whole chunks.
- auto add_colliding = [&](Position::World chunk_pos, Position::BlockLocal pos, World::Chunk::BlockData& b) {
- if (!b.type.is_solid()) return;
- auto block_bounds = World::Chunk::block_bounds(pos).offset(chunk_pos);
- if (domain_box.collides(block_bounds)) colliding_blocks.push_back(block_bounds);
- };
- auto chunk_from = world.chunks().find(to);
- if (chunk_from.chunk.has_value()) {
- auto position = chunk_from.chunk.value().position();
- chunk_from.chunk->for_each([&](auto p, auto b) { add_colliding(position, p, b); });
+ std::unordered_set<World::ChunkIndex> chunks_to_check;
+ for (auto corner : domain_box.corners()) {
+ chunks_to_check.insert(World::ChunkIndex::from_position(corner));
}
- if (World::ChunkIndex::from_position(to) == World::ChunkIndex::from_position(from))
- return colliding_blocks;
-
- auto chunk_to = world.chunks().find(to);
- if (chunk_to.chunk.has_value()) {
- auto position = chunk_to.chunk.value().position();
- chunk_to.chunk->for_each([&](auto p, auto b) { add_colliding(position, p, b); });
+ for (auto chunk_index : chunks_to_check) {
+ auto chunk = world.chunks().get(chunk_index);
+ if (!chunk.chunk.has_value()) continue;
+ auto chunk_position = chunk.chunk.value().position();
+ chunk.chunk->for_each([&](auto p, auto b) {
+ if (!b.type.is_solid()) return;
+ auto block_bounds = World::Chunk::block_bounds(p).offset(chunk_position);
+ if (domain_box.collides(block_bounds)) colliding_blocks.push_back(block_bounds);
+ });
}
return colliding_blocks;