// This file breaks the Ray.hpp <-> AABB.hpp dependency cycle. #include "AABB.hpp" #include "Ray.hpp" // 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). AABB::CollisionResponse 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, v_magnitude); if (!raycast.hit) return {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; // 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 { .v_to_collision = raycast.point - origin, .v_slide = projected_velocity, .normal = raycast.normal, }; }