53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
use cord_decompile::crawler::oracle::SdfOracle;
|
|
use cord_decompile::crawler::scheduler::CrawlerScheduler;
|
|
use cord_decompile::crawler::CrawlerConfig;
|
|
use cord_decompile::mesh::{Vec3, AABB};
|
|
|
|
/// A perfect sphere oracle for testing (no mesh needed).
|
|
struct SphereOracle {
|
|
center: Vec3,
|
|
radius: f64,
|
|
}
|
|
|
|
impl SdfOracle for SphereOracle {
|
|
fn sdf(&self, p: Vec3) -> f64 {
|
|
(p - self.center).length() - self.radius
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn crawlers_find_sphere_surface() {
|
|
let oracle = SphereOracle {
|
|
center: Vec3::zero(),
|
|
radius: 1.0,
|
|
};
|
|
|
|
let bounds = AABB {
|
|
min: Vec3::new(-2.0, -2.0, -2.0),
|
|
max: Vec3::new(2.0, 2.0, 2.0),
|
|
};
|
|
|
|
let config = CrawlerConfig {
|
|
initial_probes: 32,
|
|
crawlers_per_contact: 2,
|
|
step_fraction: 0.01,
|
|
surface_epsilon: 1e-3,
|
|
max_steps: 2000,
|
|
..Default::default()
|
|
};
|
|
|
|
let mut scheduler = CrawlerScheduler::new(bounds, config);
|
|
let samples = scheduler.run(&oracle);
|
|
|
|
assert!(!samples.is_empty(), "should find surface samples");
|
|
|
|
// All samples should be on or very near the sphere surface
|
|
for s in &samples {
|
|
let dist = s.position.length();
|
|
assert!(
|
|
(dist - 1.0).abs() < 0.05,
|
|
"sample at distance {dist} from origin, expected ~1.0"
|
|
);
|
|
}
|
|
}
|