summary refs log tree commit diff
path: root/modules/packages.nix
Path not found
='#n1'>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 31 32 33 34
// 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,
    };
}