makepad/libs/remesh/tests/kernels.rs
Admin fbe877d746 Land glTF writers, remesh, PBR paint, and xatlas from rik2.
Animation/skin writers, COLOR_0, and the mesh tools the renderer uses.
2026-08-18 14:23:58 +02:00

135 lines
4.8 KiB
Rust

//! Kernel-exactness tests against the validated CPU oracle fixtures
//! (local/faithc_ref/fixtures/*.bin, generated by make_fixtures.py from the
//! polyfill that itself passed fp64 reference validation).
//!
//! These pin the two known risk areas: SAT epsilon discipline (1e-6 actually
//! used; 1e-4 narrowing) and the clip/centroid/area conventions — all
//! BIT-EXACT, including the 9-gon clips and degenerate/contact cases.
mod common;
use common::{faithc_ref_dir, FcDump};
use makepad_remesh::sat::{clip_tri_box, tri_box_sat};
use makepad_remesh::spatial::{
closest_tri, ray_tri_intersect, segment_nearest_hit, tri_barycentric, tri_closest_point,
BinGrid,
};
use makepad_remesh::math::*;
fn fixture(name: &str) -> Option<FcDump> {
let dir = faithc_ref_dir()?;
let path = dir.join("fixtures").join(name);
if !path.is_file() {
eprintln!("SKIP: fixture {name} not found");
return None;
}
Some(FcDump::load(&path).unwrap())
}
#[test]
fn sat_and_clip_bit_exact() {
let Some(fx) = fixture("satclip.bin") else { return };
let tris = fx.tris("tris");
let bmin = fx.v3s("bmin");
let bmax = fx.v3s("bmax");
let (_, sat6) = fx.i8("sat6");
let (_, sat4) = fx.i8("sat4");
let (_, clip_hit) = fx.i8("clip_hit");
let cents = fx.v3s("clip_centroid");
let (_, areas) = fx.f32("clip_area");
let n = tris.len();
assert!(n > 4000);
let mut hits6 = 0;
for i in 0..n {
let s6 = tri_box_sat(&tris[i], bmin[i], bmax[i], 1e-6);
let s4 = tri_box_sat(&tris[i], bmin[i], bmax[i], 1e-4);
assert_eq!(s6 as i8, sat6[i], "case {i}: SAT(1e-6) mismatch");
assert_eq!(s4 as i8, sat4[i], "case {i}: SAT(1e-4) mismatch");
// oracle clip ran on ALL pairs (not gated on SAT)
let c = clip_tri_box(&tris[i], bmin[i], bmax[i]);
assert_eq!(c.hit as i8, clip_hit[i], "case {i}: clip hit mismatch");
if c.hit {
hits6 += 1;
for d in 0..3 {
assert_eq!(
c.centroid[d].to_bits(),
cents[i][d].to_bits(),
"case {i}: centroid[{d}] {} vs {}",
c.centroid[d],
cents[i][d]
);
}
assert_eq!(
c.area.to_bits(),
areas[i].to_bits(),
"case {i}: area {} vs {}",
c.area,
areas[i]
);
}
}
assert!(hits6 > 1000, "only {hits6} clip hits exercised");
}
#[test]
fn segment_nearest_and_udf_bit_exact() {
let Some(fx) = fixture("rayudf.bin") else { return };
let scene = fx.tris("scene_tris");
let grid = BinGrid::build(&scene);
// ---- segments ----
let s0 = fx.v3s("seg_start");
let s1 = fx.v3s("seg_end");
let (_, seg_hit) = fx.i8("seg_hit");
let (_, seg_face) = fx.i64("seg_face");
let (_, seg_t) = fx.f32("seg_t");
let (_, max_t_arr) = fx.f32("seg_max_t");
// torch preamble replicated in f32
let lens: Vec<f32> = s0
.iter()
.zip(&s1)
.map(|(a, b)| norm3(sub3(*b, *a)))
.collect();
let max_t = lens.iter().fold(f32::NEG_INFINITY, |m, &l| m.max(l));
assert_eq!(max_t.to_bits(), max_t_arr[0].to_bits());
let mut hits = 0;
for i in 0..s0.len() {
let d = sub3(s1[i], s0[i]);
let inv = lens[i] + 1e-8;
let rd = [d[0] / inv, d[1] / inv, d[2] / inv];
let (t, face) = segment_nearest_hit(&grid, &scene, s0[i], s1[i], s0[i], rd, max_t);
let hit = face >= 0 && t <= lens[i];
assert_eq!(hit as i8, seg_hit[i], "seg {i}: hit mismatch");
assert_eq!(face, seg_face[i], "seg {i}: face mismatch");
assert_eq!(t.to_bits(), seg_t[i].to_bits(), "seg {i}: t {} vs {}", t, seg_t[i]);
if hit {
hits += 1;
}
}
assert!(hits > 1000, "only {hits} segment hits exercised");
// basic MT sanity: a miss returns 1e10
assert_eq!(ray_tri_intersect([5.0, 5.0, 5.0], [1.0, 0.0, 0.0], &scene[0]), 1e10);
// ---- UDF ----
let pts = fx.v3s("udf_points");
let (_, udf_face) = fx.i64("udf_face");
let (_, udf_dist) = fx.f32("udf_dist");
let closest = fx.v3s("udf_closest");
let uvw = fx.v3s("udf_uvw");
for i in 0..pts.len() {
let (dsq, tid) = closest_tri(&grid, &scene, pts[i]);
assert_eq!(tid, udf_face[i], "udf {i}: face mismatch");
let dist = dsq.sqrt();
assert_eq!(dist.to_bits(), udf_dist[i].to_bits(), "udf {i}: dist");
let cp = tri_closest_point(pts[i], &scene[tid as usize]);
let bc = tri_barycentric(cp, &scene[tid as usize]);
for d in 0..3 {
assert_eq!(cp[d].to_bits(), closest[i][d].to_bits(), "udf {i}: closest[{d}]");
assert_eq!(bc[d].to_bits(), uvw[i][d].to_bits(), "udf {i}: uvw[{d}]");
}
}
}