Skip to content

Commit

Permalink
fix: treat TriMesh as solid in project_local_point_and_get_feature wi…
Browse files Browse the repository at this point in the history
…th dim2 (#196)

* Treat TriMesh as solid in project_local_point_and_get_feature with = dim2

* Clean replace two cfg-feature checks with one

Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com>

* Add tests to ensure project_local_point_and_get_feature works from outside

---------

Co-authored-by: Benjamin Saunders <ben.e.saunders@gmail.com>
  • Loading branch information
wlinna and Ralith committed May 2, 2024
1 parent 1d530f8 commit dfa638c
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
1 change: 1 addition & 0 deletions crates/parry2d/tests/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
mod point_composite_shape;
mod point_triangle;
69 changes: 69 additions & 0 deletions crates/parry2d/tests/query/point_composite_shape.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use na::Point2;
use parry2d::{query::PointQuery, shape::TriMesh};

#[test]
fn project_local_point_and_get_feature_gets_the_enclosing_triangle() {
let vertices = vec![
Point2::new(0.0, 1.0),
Point2::new(0.0, 0.0),
Point2::new(1.0, 0.0),
Point2::new(1.0, 1.0),
];

let mesh = TriMesh::new(vertices, vec![[0, 1, 2], [3, 0, 2]]);
let query_pt = Point2::new(0.6, 0.6); // Inside the top-right triangle (index 1)

let (proj, feat) = mesh.project_local_point_and_get_feature(&query_pt);

let correct_tri_idx = 1;
let correct_tri = mesh.triangle(correct_tri_idx);

let is_inside_correct = correct_tri.contains_local_point(&query_pt);

assert!(is_inside_correct);
assert_eq!(proj.is_inside, is_inside_correct);
assert_eq!(feat.unwrap_face(), correct_tri_idx);
}

#[test]
fn project_local_point_and_get_feature_projects_correctly_from_outside() {
let vertices = vec![
Point2::new(0.0, 1.0),
Point2::new(0.0, 0.0),
Point2::new(1.0, 0.0),
Point2::new(1.0, 1.0),
];

let mesh = TriMesh::new(vertices, vec![[0, 1, 2], [3, 0, 2]]);

{
let query_pt = Point2::new(-1.0, 0.0); // Inside the top-right triangle (index 1)

let (proj, feat) = mesh.project_local_point_and_get_feature(&query_pt);

let correct_tri_idx = 0;
let correct_tri = mesh.triangle(correct_tri_idx);

let is_inside_correct = correct_tri.contains_local_point(&query_pt);

assert_eq!(is_inside_correct, false);
assert_eq!(proj.is_inside, is_inside_correct);
assert_eq!(proj.point, Point2::origin());
assert_eq!(feat.unwrap_face(), correct_tri_idx);
}
{
let query_pt = Point2::new(0.5, 2.0); // Inside the top-right triangle (index 1)

let (proj, feat) = mesh.project_local_point_and_get_feature(&query_pt);

let correct_tri_idx = 1;
let correct_tri = mesh.triangle(correct_tri_idx);

let is_inside_correct = correct_tri.contains_local_point(&query_pt);

assert_eq!(is_inside_correct, false);
assert_eq!(proj.is_inside, is_inside_correct);
assert_eq!(proj.point, Point2::new(0.5, 1.0));
assert_eq!(feat.unwrap_face(), correct_tri_idx);
}
}
4 changes: 3 additions & 1 deletion src/query/point/point_composite_shape.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ impl PointQuery for TriMesh {
return (proj, feature_id);
}

let solid = cfg!(feature = "dim2");

let mut visitor =
PointCompositeShapeProjWithFeatureBestFirstVisitor::new(self, point, false);
PointCompositeShapeProjWithFeatureBestFirstVisitor::new(self, point, solid);
let (proj, (id, _feature)) = self.qbvh().traverse_best_first(&mut visitor).unwrap().1;
let feature_id = FeatureId::Face(id);
(proj, feature_id)
Expand Down

0 comments on commit dfa638c

Please sign in to comment.