summary refs log tree commit diff
path: root/src/Entities
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2023-11-21 02:28:00 +0100
committerMel <einebeere@gmail.com>2023-11-21 02:28:00 +0100
commitca8b16620ec207f2b32edd1f5d46f7b0bfb0a14c (patch)
tree02746322c4229431e36b892f11f07a81ce21e439 /src/Entities
parent272e6a63df7369e5afcb16c5a6c14f7dd6a75893 (diff)
downloadmeowcraft-ca8b16620ec207f2b32edd1f5d46f7b0bfb0a14c.tar.zst
meowcraft-ca8b16620ec207f2b32edd1f5d46f7b0bfb0a14c.zip
Clumsy non-swept AABB collision system for Player
Diffstat (limited to 'src/Entities')
-rw-r--r--src/Entities/Player.cpp23
-rw-r--r--src/Entities/Player.hpp4
2 files changed, 24 insertions, 3 deletions
diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp
index 6c94490..4fa481e 100644
--- a/src/Entities/Player.cpp
+++ b/src/Entities/Player.cpp
@@ -16,10 +16,16 @@ void Player::update(const Time& time, GFX::Window& window, GFX::Camera& camera,
     auto rotation_speed = 0.1f;
 
     auto direction = m_transform.right() * x + Vec3(0, y, 0) + m_transform.forward() * z;
-    auto position = m_transform.position() + direction * move_speed;
+    auto destination = m_transform.position() + direction * move_speed;
 
-    auto collisions = colliding_terrain(position, world);
-    if (collisions.empty()) move_to(position);
+    auto collisions = colliding_terrain(destination, world);
+    if (!collisions.empty()) {
+        for (auto collision : collisions) {
+            destination = collision_reposition(m_transform.position(), destination, collision);
+        }
+    }
+
+    move_to(destination);
     rotate({r.y() * rotation_speed, r.x() * rotation_speed, 0.0f});
 
     update_camera_position(camera);
@@ -84,4 +90,15 @@ AABB Player::bounding_box_for_position(Position::World position) {
     return s_bounds.offset(box_start);
 }
 
+Position::World Player::position_for_bounding_box(AABB box) {
+    auto center = box.center();
+    return {center.x(), box.min.y(), center.z()};
+}
+
+Position::World Player::collision_reposition(Position::World from, Position::World to, AABB colliding) {
+    if (from == to) return from;
+    auto resulting_bounding_box = bounding_box_for_position(from).cast_box(to - from, colliding);
+    return position_for_bounding_box(resulting_bounding_box); // Ugly, we convert to AABB and back.
+}
+
 }
diff --git a/src/Entities/Player.hpp b/src/Entities/Player.hpp
index 0422509..7238e80 100644
--- a/src/Entities/Player.hpp
+++ b/src/Entities/Player.hpp
@@ -33,6 +33,10 @@ private:
 
     // Creates a bounding box where `position` is at the center of the bottom face.
     static AABB bounding_box_for_position(Position::World position);
+    // Returns position of the center of the bottom face of `box`.
+    static Position::World position_for_bounding_box(AABB box);
+
+    static Position::World collision_reposition(Position::World from, Position::World to, AABB colliding);
 
     Transform m_transform;