blob: 08c9903644711131c2f1e550bbc3c22238c00255 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
// This file breaks the Ray.hpp <-> AABB.hpp dependency cycle.
#include "AABB.hpp"
#include "Ray.hpp"
// Returns a pushout vector for avoiding collision 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).
Vec3 AABB::pushout(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, v_magnitude);
if (!raycast.hit) return {};
// 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;
// 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);
}
|