use std::sync::OnceLock;
use std::time::Instant;
use glam::{vec2, Vec2};
use polyanya::{Layer, Mesh, PolyanyaFile, Triangulation};
fn aurora_layer() -> &'static Layer {
static AURORA: OnceLock<Layer> = OnceLock::new();
AURORA.get_or_init(|| {
let mut aurora: Mesh = PolyanyaFile::from_file("meshes/v2/aurora-merged.mesh")
.try_into()
.unwrap();
let mut layer = aurora.layers.remove(0);
layer.bake();
layer
})
}
fn mesh_with_an_unreachable_island(copies: usize) -> Mesh {
let mut island = Triangulation::from_outer_edges(&[
vec2(1000.0, 1000.0),
vec2(1010.0, 1000.0),
vec2(1010.0, 1010.0),
vec2(1000.0, 1010.0),
])
.as_layer();
island.bake();
let mut mesh = Mesh::default();
mesh.layers.push(island);
for _ in 0..copies {
mesh.layers.push(aurora_layer().clone());
}
mesh.stitch_at_vertices(vec![], false);
mesh
}
#[test]
fn unreachable_target_is_not_a_path() {
let mesh = mesh_with_an_unreachable_island(1);
assert_eq!(
mesh.path(Vec2::new(1005.0, 1005.0), Vec2::new(233.0, 501.0)),
None
);
assert_eq!(
mesh.path(Vec2::new(233.0, 501.0), Vec2::new(1005.0, 1005.0)),
None
);
}
#[test]
fn saying_no_path_does_not_cost_the_whole_mesh() {
let small = mesh_with_an_unreachable_island(1);
let large = mesh_with_an_unreachable_island(8);
let time = |mesh: &Mesh| {
let (from, to) = (Vec2::new(1005.0, 1005.0), Vec2::new(233.0, 501.0));
let started = Instant::now();
for _ in 0..100 {
assert_eq!(mesh.path(from, to), None);
}
started.elapsed()
};
let small = time(&small);
let large = time(&large);
assert!(
large < small * 3,
"answering \"no path\" scaled with the size of the mesh the search never \
entered: {small:?} with one extra layer against {large:?} with eight"
);
}