#pragma once #include "../Common/Lambda.hpp" #include "AABB.hpp" #include "Vector.hpp" struct Ray { struct RaycastResult { Bool hit = false; Vec3 point; Vec3 normal; }; // https://gdbooks.gitbooks.io/3dcollisions/content/Chapter3/raycast_aabb.html RaycastResult cast(AABB box) const { Vec3 t_from = (box.min - origin) / direction; Vec3 t_to = (box.max - origin) / direction; Real t_min = t_from.zip(t_to, LAMBDA(std::min, 2)).reduce(LAMBDA(std::max, 2)); Real t_max = t_from.zip(t_to, LAMBDA(std::max, 2)).reduce(LAMBDA(std::min, 2)); if (t_max < 0 || t_min > t_max) return {}; return { .hit = true, .point = origin + direction * t_min, .normal = t_from.zip(t_to, [](auto a, auto b) { return a < b ? -1.0 : 1.0; }) }; } Vec3 origin; Vec3 direction; };