diff options
| author | Mel <einebeere@gmail.com> | 2024-01-31 21:02:25 +0100 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2024-01-31 21:02:25 +0100 |
| commit | 286261c1c730f3d8f3412b0f502ace366ba1ea76 (patch) | |
| tree | adc0cf8de5507c7e1a442ad55558f98434d89bb4 /src/Entities | |
| parent | 9bdc36787a5ace22e16d5b24c77218fa349c691e (diff) | |
| download | meowcraft-286261c1c730f3d8f3412b0f502ace366ba1ea76.tar.zst meowcraft-286261c1c730f3d8f3412b0f502ace366ba1ea76.zip | |
Fix collisions phasing through ground at chunk borders
Diffstat (limited to 'src/Entities')
| -rw-r--r-- | src/Entities/Player.cpp | 32 |
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; |
