use crate::glyph::GlyphId;
use glam::Vec3;
#[derive(Debug, Clone)]
pub struct RaycastHit {
pub glyph_id: GlyphId,
pub distance: f32,
pub point: Vec3,
pub normal: Vec3,
}
#[derive(Debug, Clone)]
pub struct SphereQuery {
pub center: Vec3,
pub radius: f32,
pub mask: u32,
}
#[derive(Debug, Clone)]
pub struct FrustumQuery {
pub planes: [(Vec3, f32); 6],
}
impl FrustumQuery {
pub fn contains_aabb(&self, min: Vec3, max: Vec3) -> bool {
for (normal, d) in &self.planes {
let p = Vec3::new(
if normal.x >= 0.0 { max.x } else { min.x },
if normal.y >= 0.0 { max.y } else { min.y },
if normal.z >= 0.0 { max.z } else { min.z },
);
if normal.dot(p) + d < 0.0 { return false; }
}
true
}
pub fn contains_sphere(&self, center: Vec3, radius: f32) -> bool {
for (normal, d) in &self.planes {
if normal.dot(center) + d < -radius { return false; }
}
true
}
}
pub struct SceneQuery;
impl SceneQuery {
pub fn frustum_from_vp(vp: &glam::Mat4) -> FrustumQuery {
let cols = vp.to_cols_array_2d();
let planes = [
(Vec3::new(cols[0][3] + cols[0][0], cols[1][3] + cols[1][0], cols[2][3] + cols[2][0]),
cols[3][3] + cols[3][0]),
(Vec3::new(cols[0][3] - cols[0][0], cols[1][3] - cols[1][0], cols[2][3] - cols[2][0]),
cols[3][3] - cols[3][0]),
(Vec3::new(cols[0][3] + cols[0][1], cols[1][3] + cols[1][1], cols[2][3] + cols[2][1]),
cols[3][3] + cols[3][1]),
(Vec3::new(cols[0][3] - cols[0][1], cols[1][3] - cols[1][1], cols[2][3] - cols[2][1]),
cols[3][3] - cols[3][1]),
(Vec3::new(cols[0][3] + cols[0][2], cols[1][3] + cols[1][2], cols[2][3] + cols[2][2]),
cols[3][3] + cols[3][2]),
(Vec3::new(cols[0][3] - cols[0][2], cols[1][3] - cols[1][2], cols[2][3] - cols[2][2]),
cols[3][3] - cols[3][2]),
];
FrustumQuery { planes }
}
}