#pragma once #include #include #include "Vector.hpp" #include "../Common/Lambda.hpp" struct AABB { AABB() = default; AABB(Vector<3> min, Vector<3> max) : min(min), max(max) {} explicit AABB(Vector<3> max) : max(max) {} static AABB from_center(Vector<3> center, Vector<3> size) { auto min = center - size / 2.0; auto max = min + size; return {min, max}; } Vector<3> size() const { return max - min; } Vector<3> center() const { return (min + max) / 2; } Bool contains(Vector<3> point) const { return point.x() >= min.x() && point.x() <= max.x() && point.y() >= min.y() && point.y() <= max.y() && point.z() >= min.z() && point.z() <= max.z(); } Bool intersects_on_x(AABB other) const { return Math::floats_less(min.x(), other.max.x()) && Math::floats_less(other.min.x(), max.x()); } Bool intersects_on_y(AABB other) const { return Math::floats_less(min.y(), other.max.y()) && Math::floats_less(other.min.y(), max.y()); } Bool intersects_on_z(AABB other) const { return Math::floats_less(min.z(), other.max.z()) && Math::floats_less(other.min.z(), max.z()); } Bool collides(AABB other) const { return intersects_on_x(other) && intersects_on_y(other) && intersects_on_z(other); } Bool collides(std::vector others) { for (auto& other : others) { if (collides(other)) return true; } return false; } std::array, 8> corners() const { return {{ {min.x(), min.y(), min.z()}, {min.x(), min.y(), max.z()}, {min.x(), max.y(), min.z()}, {min.x(), max.y(), max.z()}, {max.x(), min.y(), min.z()}, {max.x(), min.y(), max.z()}, {max.x(), max.y(), min.z()}, {max.x(), max.y(), max.z()}, }}; } AABB offset(Vector<3> by) const { return {min + by, max + by}; } AABB sum(AABB with) const { auto new_size = size() + with.size(); return {center() - new_size / 2, center() + new_size / 2}; } AABB unite(AABB with) const { return { min.zip(with.min, LAMBDA(std::min, 2)), max.zip(with.max, LAMBDA(std::max, 2)) }; } 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; // Normal of the collision plane. Vec3 normal; }; CollisionResponse collision_response(Vector<3> v, AABB against) const; Vector<3> min, max; };