summaryrefslogtreecommitdiff
path: root/src/Math
diff options
context:
space:
mode:
authorMel <einebeere@gmail.com>2024-02-01 00:52:45 +0100
committerMel <einebeere@gmail.com>2024-02-01 00:52:45 +0100
commit7b107078a2a3b9f62a076f91e873f5ad0597d167 (patch)
treebf7f5d0f2d75996d5b021211651f6f33531bbbe8 /src/Math
parent286261c1c730f3d8f3412b0f502ace366ba1ea76 (diff)
downloadmeowcraft-7b107078a2a3b9f62a076f91e873f5ad0597d167.tar.zst
meowcraft-7b107078a2a3b9f62a076f91e873f5ad0597d167.zip
Correctly sort collision responses and apply in correct order
Diffstat (limited to 'src/Math')
-rw-r--r--src/Math/AABB.cpp13
-rw-r--r--src/Math/AABB.hpp10
2 files changed, 17 insertions, 6 deletions
diff --git a/src/Math/AABB.cpp b/src/Math/AABB.cpp
index 08c9903..b16960e 100644
--- a/src/Math/AABB.cpp
+++ b/src/Math/AABB.cpp
@@ -3,10 +3,11 @@
#include "AABB.hpp"
#include "Ray.hpp"
-// Returns a pushout vector for avoiding collision with `against`.
+// Returns a velocity vectors that avoid collision with `against`, while sliding along it.
+// If no collision is detected, returns the original velocity.
// Algorithm is kind of based on "https://www.gamedev.net/tutorials/_/technical/game-programming/swept-aabb-collision-detection-and-response-r3084/",
// but very different (and mine's better :3).
-Vec3 AABB::pushout(Vector<3> v, AABB against) const {
+AABB::CollisionResponse AABB::collision_response(Vector<3> v, AABB against) const {
auto origin = center();
Ray ray{origin, v};
@@ -14,7 +15,7 @@ Vec3 AABB::pushout(Vector<3> v, AABB against) const {
auto expanded_target = against.sum(*this);
auto raycast = ray.cast(expanded_target, v_magnitude);
- if (!raycast.hit) return {};
+ if (!raycast.hit) return {v};
// Slide along the collision plane.
@@ -25,6 +26,8 @@ Vec3 AABB::pushout(Vector<3> v, AABB against) const {
// Project the remaining velocity onto the plane, to which the normal is perpendicular.
auto projected_velocity = v_remaining - v_remaining.project_onto(raycast.normal);
- auto resulting_point = raycast.point + projected_velocity;
- return resulting_point - (v + origin);
+ return {
+ .v_to_collision = raycast.point - origin,
+ .v_slide = projected_velocity,
+ };
}
diff --git a/src/Math/AABB.hpp b/src/Math/AABB.hpp
index 4ad5534..b50ba56 100644
--- a/src/Math/AABB.hpp
+++ b/src/Math/AABB.hpp
@@ -76,7 +76,15 @@ struct AABB {
};
}
- Vec3 pushout(Vector<3> v, AABB against) const;
+ struct CollisionResponse {
+ // Velocity until the collision.
+ // Always has the same direction as the original velocity, and lower magnitude.
+ Vec3 v_to_collision;
+ // Velocity sliding along the collision plane.
+ // Projection of the fraction of the original velocity that was blocked by collision, onto the collision plane.
+ Vec3 v_slide;
+ };
+ CollisionResponse collision_response(Vector<3> v, AABB against) const;
Vector<3> min, max;
};