Skip to content

Commit

Permalink
fix simplification on unmerged obstacles (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
mockersf committed Jun 28, 2024
1 parent 0450cd8 commit 8e8a6da
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/input/triangulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,11 @@ impl Triangulation {
/// Epsilon is the minimum area a point should contribute to a polygon.
#[cfg_attr(feature = "tracing", instrument(skip_all))]
pub fn simplify(&mut self, epsilon: f32) {
self.inner = self.inner.simplify_vw_preserve(&epsilon);
self.inner.interiors_mut(|interiors| {
for interior in interiors {
*interior = interior.simplify_vw_preserve(&epsilon);
}
});
}

#[cfg_attr(feature = "tracing", instrument(skip_all))]
Expand Down
76 changes: 76 additions & 0 deletions tests/triangulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,79 @@ fn is_in_mesh_overlapping_merged() {
}
}
}

#[test]
fn is_in_mesh_simplified() {
let mut triangulation = Triangulation::from_outer_edges(&[
vec2(0.0, 0.0),
vec2(10.0, 0.0),
vec2(10.0, 10.0),
vec2(0.0, 10.0),
]);
// adding a circle obstacle in the middle
let nb_points = 100;
let radius = 2.5;
triangulation.add_obstacle(
(0..nb_points)
.map(|i| {
let angle = i as f32 * std::f32::consts::TAU / nb_points as f32;
let (x, y) = angle.sin_cos();
vec2(x, y) * radius + vec2(5.0, 5.0)
})
.collect(),
);
let polygons_before = triangulation.as_navmesh().polygons;
triangulation.simplify(0.1);
let mesh: Mesh = triangulation.as_navmesh();
assert!(dbg!(polygons_before.len()) > dbg!(mesh.polygons.len()));
for i in 0..20 {
for j in 0..20 {
let point = vec2(i as f32 / 2.0, j as f32 / 2.0);
if point.distance(vec2(5.0, 5.0)) < radius {
assert!(!mesh.point_in_mesh(point));
} else {
assert!(mesh.point_in_mesh(point));
}
}
}
}

#[test]
fn is_in_mesh_overlapping_simplified() {
let mut triangulation = Triangulation::from_outer_edges(&[
vec2(0.0, 0.0),
vec2(10.0, 0.0),
vec2(10.0, 10.0),
vec2(0.0, 10.0),
]);
// adding a circle obstacle in the middle
let nb_points = 1000;
let radius = 2.5;
triangulation.add_obstacle(
(0..nb_points)
.map(|i| {
let angle = i as f32 * std::f32::consts::TAU / nb_points as f32;
let (x, y) = angle.sin_cos();
vec2(x, y) * radius + vec2(5.0, 5.0)
})
.collect(),
);
triangulation.add_obstacle(vec![
vec2(2.5, 2.5),
vec2(2.5, 5.0),
vec2(5.0, 5.0),
vec2(5.0, 2.5),
]);

let mesh_before = triangulation.as_navmesh();
triangulation.simplify(0.01);
let mesh: Mesh = triangulation.as_navmesh();
assert!(dbg!(mesh_before.polygons.len()) > dbg!(mesh.polygons.len()));
let resolution = 5;
for i in 0..(10 * resolution) {
for j in 0..(10 * resolution) {
let point = vec2(i as f32 / resolution as f32, j as f32 / resolution as f32);
assert_eq!(mesh.point_in_mesh(point), mesh_before.point_in_mesh(point));
}
}
}

0 comments on commit 8e8a6da

Please sign in to comment.