use super::NORMALIZE_EPSILON;
use crate::{Mesh, Point3, Vector3};
pub(in crate::router::voids) fn wall_frame_from_depth(
depth: Vector3<f64>,
) -> Option<[Vector3<f64>; 3]> {
let d = depth.try_normalize(NORMALIZE_EPSILON)?;
if d.z.abs() > 0.2 {
return None; }
let up = Vector3::new(0.0, 0.0, 1.0);
let len = up.cross(&d).try_normalize(NORMALIZE_EPSILON)?;
let up = d.cross(&len).try_normalize(NORMALIZE_EPSILON)?; Some([len, up, d])
}
pub(in crate::router::voids) fn mesh_to_frame(
mesh: &Mesh,
axes: &[Vector3<f64>; 3],
center: Vector3<f64>,
) -> Mesh {
let mut positions = Vec::with_capacity(mesh.positions.len());
for ch in mesh.positions.chunks_exact(3) {
let p = Vector3::new(ch[0] as f64, ch[1] as f64, ch[2] as f64) - center;
positions.push(p.dot(&axes[0]) as f32);
positions.push(p.dot(&axes[1]) as f32);
positions.push(p.dot(&axes[2]) as f32);
}
let mut normals = Vec::with_capacity(mesh.normals.len());
for ch in mesh.normals.chunks_exact(3) {
let n = Vector3::new(ch[0] as f64, ch[1] as f64, ch[2] as f64);
normals.push(n.dot(&axes[0]) as f32);
normals.push(n.dot(&axes[1]) as f32);
normals.push(n.dot(&axes[2]) as f32);
}
Mesh {
positions,
normals,
indices: mesh.indices.clone(),
rtc_applied: mesh.rtc_applied,
origin: mesh.origin,
instance_meta: None,
local_bounds: None,
local_to_world: None,
welded_in_object_frame: false,
}
}
pub(in crate::router::voids) fn project_aabb_in_frame(
mesh: &Mesh,
axes: &[Vector3<f64>; 3],
center: Vector3<f64>,
) -> Option<(Point3<f64>, Point3<f64>)> {
let mut lo = [f64::INFINITY; 3];
let mut hi = [f64::NEG_INFINITY; 3];
for ch in mesh.positions.chunks_exact(3) {
let p = Vector3::new(ch[0] as f64, ch[1] as f64, ch[2] as f64) - center;
for k in 0..3 {
let v = p.dot(&axes[k]);
lo[k] = lo[k].min(v);
hi[k] = hi[k].max(v);
}
}
(lo.iter().all(|v| v.is_finite()) && hi.iter().all(|v| v.is_finite())).then(|| {
(
Point3::new(lo[0], lo[1], lo[2]),
Point3::new(hi[0], hi[1], hi[2]),
)
})
}