#pragma once
#include "core/math_rtm.h"
struct DebugRay {
vec3 origin = vec3(0.0f);
vec3 dir = vec3(0.0f, 0.0f, 1.0f); // normalized
};
inline DebugRay debug_unproject(f32 ndc_x, f32 ndc_y, vec3 eye_pos, const mat4 &inv_view_proj) {
vec4 near_p = transform_point(vec3(ndc_x, ndc_y, 1.0f), inv_view_proj);
vec3 n = vec3(near_p.x / near_p.w, near_p.y / near_p.w, near_p.z / near_p.w);
DebugRay r;
r.origin = eye_pos;
r.dir = (n - eye_pos).normalized();
return r;
}
// returns true + nearest positive t on hit
inline bool debug_ray_vs_aabb(const DebugRay &ray, vec3 mn, vec3 mx, f32 &t_out) {
f32 tmin = 0.0f;
f32 tmax = 1e30f;
const f32 o[3] = {ray.origin.x, ray.origin.y, ray.origin.z};
const f32 d[3] = {ray.dir.x, ray.dir.y, ray.dir.z};
const f32 bmin[3] = {mn.x, mn.y, mn.z};
const f32 bmax[3] = {mx.x, mx.y, mx.z};
for (int i = 0; i < 3; ++i) {
if (d[i] == 0.0f) {
if (o[i] < bmin[i] || o[i] > bmax[i]) {
return false;
}
} else {
f32 inv = 1.0f / d[i];
f32 t0 = (bmin[i] - o[i]) * inv;
f32 t1 = (bmax[i] - o[i]) * inv;
if (t0 > t1) {
f32 tmp = t0;
t0 = t1;
t1 = tmp;
}
tmin = t0 > tmin ? t0 : tmin;
tmax = t1 < tmax ? t1 : tmax;
if (tmax < tmin) {
return false;
}
}
}
t_out = tmin;
return true;
}
inline bool debug_ray_vs_sphere(const DebugRay &ray, vec3 center, f32 radius, f32 &t_out) {
vec3 oc = ray.origin - center;
f32 b = oc.dot(ray.dir);
f32 c = oc.dot(oc) - radius * radius;
f32 disc = b * b - c;
if (disc < 0.0f) {
return false;
}
f32 t = -b - sqrtf(disc);
if (t < 0.0f) {
return false;
}
t_out = t;
return true;
}