diff options
| author | Mel <einebeere@gmail.com> | 2023-12-07 01:26:04 +0100 |
|---|---|---|
| committer | Mel <einebeere@gmail.com> | 2023-12-07 01:26:04 +0100 |
| commit | 581f50e0bd45a19282d7958975997d376512b195 (patch) | |
| tree | db42e31524efc49caab06efeb3d1a1331ec4f2b5 /src/Math/AABB.cpp | |
| parent | acc6e0e53d981428c15baf5b7efe568d98044290 (diff) | |
| download | meowcraft-581f50e0bd45a19282d7958975997d376512b195.tar.zst meowcraft-581f50e0bd45a19282d7958975997d376512b195.zip | |
AABB-AABB dynamic-static collision response with sliding
Diffstat (limited to 'src/Math/AABB.cpp')
| -rw-r--r-- | src/Math/AABB.cpp | 27 |
1 files changed, 20 insertions, 7 deletions
diff --git a/src/Math/AABB.cpp b/src/Math/AABB.cpp index aa814a1..ea48f71 100644 --- a/src/Math/AABB.cpp +++ b/src/Math/AABB.cpp @@ -3,15 +3,28 @@ #include "AABB.hpp" #include "Ray.hpp" -AABB AABB::cast_box(Vector<3> v, AABB against) const { - auto ray = Ray{center(), v}; +// Returns new AABB after colliding with `against`. +// 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). +AABB AABB::collision_response(Vector<3> v, AABB against) const { + auto origin = center(); + Ray ray{origin, v}; + + auto v_magnitude = v.magnitude(); auto expanded_target = against.sum(*this); - auto raycast = ray.cast(expanded_target); - if (!raycast.hit) return *this; + auto raycast = ray.cast(expanded_target, v_magnitude); + if (!raycast.hit) return offset(v); + + // Slide along the collision plane. + + auto fulfilled_ratio = (raycast.point - origin).magnitude() / v_magnitude; + auto remaining_ratio = 1.0 - fulfilled_ratio; + auto v_remaining = v * remaining_ratio; - auto result_from = raycast.point - size() / 2.0; - auto result_to = result_from + size(); + // Project the remaining velocity onto the plane, to which the normal is perpendicular. + auto projected_velocity = v_remaining - v_remaining.project_onto(raycast.normal); - return {result_from, result_to}; + auto result = raycast.point + projected_velocity; + return from_center(result, size()); } |
