Skip to content

Commit 02a37ec

Browse files
committed
add an example to test out API for compound shape options
It's not straightforward to do, that will likely need a solution similar to a dispatcher
1 parent 67bd749 commit 02a37ec

10 files changed

Lines changed: 150 additions & 35 deletions

File tree

crates/parry2d/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ oorandom = "11"
9393
ptree = "0.4.0"
9494
rand = { version = "0.8" }
9595
macroquad = "0.4.12"
96+
env_logger = "0.11"
9697

9798
[package.metadata.docs.rs]
9899
rustdoc-args = ["-Zunstable-options", "--generate-link-to-definition"]
@@ -162,6 +163,11 @@ name = "point_in_poly2d"
162163
path = "examples/point_in_poly2d.rs"
163164
doc-scrape-examples = true
164165

166+
[[example]]
167+
name = "point_query2d"
168+
path = "examples/point_query2d.rs"
169+
doc-scrape-examples = true
170+
165171
[[example]]
166172
name = "polygons_intersection2d"
167173
path = "examples/polygons_intersection2d.rs"

crates/parry2d/examples/debug_shape_cast2d.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use common_macroquad2d::draw_point;
44
use macroquad::prelude::*;
55
use nalgebra::{Isometry2, Point2};
66
use parry2d::math::{self, Isometry};
7-
use parry2d::query::gjk::eps_tol;
87
use parry2d::query::{self, DefaultQueryDispatcher, Ray, ShapeCastOptions};
98
use parry2d::shape::{Ball, ConvexPolygon, Shape};
109

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//! Builds on top of `point_in_poly2d` example but uses `QueryPoint`` methods and different shapes.
2+
3+
mod common_macroquad2d;
4+
5+
use common_macroquad2d::{draw_point, draw_polygon};
6+
use macroquad::prelude::*;
7+
use nalgebra::{Isometry, Point2, Rotation, Translation, UnitComplex, Vector2};
8+
use parry2d::query::PointQuery;
9+
use parry2d::shape::{ConvexPolygon, Shape, SharedShape};
10+
use parry2d::{shape::Compound, utils::point_in_poly2d};
11+
12+
const RENDER_SCALE: f32 = 30.0;
13+
14+
#[macroquad::main("points_in_poly2d")]
15+
async fn main() {
16+
env_logger::init();
17+
let mut compound_simple = simple_compound();
18+
let mut compound_simple2 = simple_compound();
19+
let test_points = grid_points();
20+
21+
let animation_rotation = UnitComplex::new(0.02);
22+
let polygon_render_pos = Point2::new(screen_width() / 2.0, screen_height() / 2.0);
23+
24+
for i in 0.. {
25+
let shape_to_query = if (i / 350) % 2 == 0 {
26+
&mut compound_simple
27+
} else {
28+
&mut compound_simple2
29+
};
30+
31+
clear_background(BLACK);
32+
33+
// TODO: Display the shape
34+
/* polygon
35+
.iter_mut()
36+
.for_each(|pt| *pt = animation_rotation * *pt);
37+
38+
draw_polygon(&polygon, RENDER_SCALE, polygon_render_pos, BLUE);
39+
*/
40+
/*
41+
* Compute polygon intersections.
42+
*/
43+
for point in &test_points {
44+
let pos12 = Isometry::default().inv_mul(&Isometry::from_parts(
45+
Translation::from(point.coords),
46+
Rotation::identity(),
47+
));
48+
if shape_to_query.contains_local_point(
49+
&(pos12 * point),
50+
// FIXME: Thierry (pr 298): options should contain everything necessary to be dispatched.
51+
&(),
52+
) {
53+
draw_point(*point, RENDER_SCALE, polygon_render_pos, RED);
54+
} else {
55+
draw_point(*point, RENDER_SCALE, polygon_render_pos, GREEN);
56+
}
57+
}
58+
59+
next_frame().await
60+
}
61+
}
62+
63+
fn simple_compound() -> Box<dyn Shape> {
64+
let to_cast_against = ConvexPolygon::from_convex_polyline(
65+
[
66+
[-24.0, 0.0].into(),
67+
[0.0, -24.0].into(),
68+
[24.0, 0.0].into(),
69+
[0.0, 24.0].into(),
70+
]
71+
.into(),
72+
)
73+
.unwrap();
74+
Box::new(Compound::new(vec![(
75+
Isometry::default(),
76+
SharedShape::new(to_cast_against),
77+
)]))
78+
}
79+
80+
fn grid_points() -> Vec<Point2<f32>> {
81+
let count = 80 * 5;
82+
let spacing = 0.6 / 5.0;
83+
let mut pts = vec![];
84+
for i in 0..count {
85+
for j in 0..count {
86+
pts.push(Point2::new(
87+
(i as f32 - count as f32 / 2.0) * spacing,
88+
(j as f32 - count as f32 / 2.0) * spacing,
89+
));
90+
}
91+
}
92+
pts
93+
}

crates/parry2d/tests/query/point_composite_shape.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
use na::Point2;
2-
use parry2d::{
3-
query::{gjk::GjkOptions, PointQuery},
4-
shape::TriMesh,
5-
};
2+
use parry2d::{query::PointQuery, shape::TriMesh};
63

74
#[test]
85
fn project_local_point_and_get_feature_gets_the_enclosing_triangle() {

src/query/point/point_round_shape.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use log::warn;
2+
13
use crate::math::{Point, Real};
2-
use crate::query::gjk::VoronoiSimplex;
4+
use crate::query::gjk::{GjkOptions, VoronoiSimplex};
35
use crate::query::point::point_query::QueryOptions;
46
use crate::query::{PointProjection, PointQuery};
57
use crate::shape::{FeatureId, RoundShape, SupportMap};
@@ -18,16 +20,27 @@ impl<S: SupportMap> PointQuery for RoundShape<S> {
1820
return unimplemented!(
1921
"The projection of points on a round shapes isn’t supported on no-std platforms yet."
2022
);
21-
let options = options.as_any().downcast_ref().unwrap();
2223

2324
#[cfg(feature = "std")] // TODO: can’t be used without std because of EPA
24-
return crate::query::details::local_point_projection_on_support_map(
25-
self,
26-
&mut VoronoiSimplex::new(),
27-
point,
28-
solid,
29-
options,
30-
);
25+
{
26+
let Some(options) = options.as_any().downcast_ref() else {
27+
warn!("Incorrect option passed to project_local_point: using default options.");
28+
return crate::query::details::local_point_projection_on_support_map(
29+
self,
30+
&mut VoronoiSimplex::new(),
31+
point,
32+
solid,
33+
&GjkOptions::default(),
34+
);
35+
};
36+
return crate::query::details::local_point_projection_on_support_map(
37+
self,
38+
&mut VoronoiSimplex::new(),
39+
point,
40+
solid,
41+
options,
42+
);
43+
}
3144
}
3245

3346
#[inline]

src/query/point/point_support_map.rs

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,22 @@ impl PointQuery for ConvexPolyhedron {
6565
solid: bool,
6666
options: &dyn QueryOptions,
6767
) -> PointProjection {
68+
let Some(options) = options.as_any().downcast_ref() else {
69+
log::warn!("Incorrect option passed to project_local_point: using default options.");
70+
return local_point_projection_on_support_map(
71+
self,
72+
&mut VoronoiSimplex::new(),
73+
point,
74+
solid,
75+
&GjkOptions::default(),
76+
);
77+
};
6878
local_point_projection_on_support_map(
6979
self,
7080
&mut VoronoiSimplex::new(),
7181
point,
7282
solid,
73-
options.as_any().downcast_ref().unwrap(),
83+
options,
7484
)
7585
}
7686

@@ -102,13 +112,24 @@ impl PointQuery for ConvexPolygon {
102112
solid: bool,
103113
options: &dyn QueryOptions,
104114
) -> PointProjection {
105-
local_point_projection_on_support_map(
115+
let Some(options) = options.as_any().downcast_ref() else {
116+
log::warn!("Incorrect option passed to local_point_projection_on_support_map: using default options.");
117+
return local_point_projection_on_support_map(
118+
self,
119+
&mut VoronoiSimplex::new(),
120+
point,
121+
solid,
122+
&GjkOptions::default(),
123+
);
124+
};
125+
126+
return local_point_projection_on_support_map(
106127
self,
107128
&mut VoronoiSimplex::new(),
108129
point,
109130
solid,
110-
options.as_any().downcast_ref().unwrap(),
111-
)
131+
&options,
132+
);
112133
}
113134

114135
#[inline]

src/query/split/split_trimesh.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,6 @@ impl TriMesh {
322322
vertices_lhs[idx1[2] as usize],
323323
);
324324

325-
// FIXME: Thierry: pass an option?
326325
if self.contains_local_point(&tri.center(), &()) {
327326
indices_lhs.push(idx1);
328327

src/query/visitors/composite_point_containment_test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ impl<S: TypedSimdCompositeShape> SimdVisitor<S::PartId, SimdAabb>
4949
self.shape.map_typed_part_at(*data, |part_pos, obj, _| {
5050
if obj.contains_local_point(
5151
&part_pos.inverse_transform_point(self.point),
52-
// FIXME: Thierry: safer type checking
52+
// FIXME: Thierry: passed option should be depending on shape...
5353
&(),
5454
) {
5555
self.found = true;

src/transformation/mesh_intersection/mesh_intersection.rs

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,6 @@ fn extract_connected_components(
324324
if flip2
325325
^ mesh2.contains_local_point(
326326
&pos12.inverse_transform_point(&tri1.center()),
327-
// FIXME: Thierry: safer type checking
328327
&(),
329328
)
330329
{
@@ -372,12 +371,7 @@ fn extract_connected_components(
372371
let repr_pt = mesh1.triangle(repr_face).center();
373372
let indices = mesh1.indices();
374373

375-
if flip2
376-
^ mesh2.contains_local_point(
377-
&pos12.inverse_transform_point(&repr_pt),
378-
// FIXME: Thierry: safer type checking
379-
&(),
380-
)
374+
if flip2 ^ mesh2.contains_local_point(&pos12.inverse_transform_point(&repr_pt), &())
381375
{
382376
new_indices1.extend(
383377
cc.grouped_faces[range[0]..range[1]]
@@ -391,13 +385,7 @@ fn extract_connected_components(
391385
// Deal with the case where there is no intersection between the meshes.
392386
let repr_pt = mesh1.triangle(0).center();
393387

394-
if flip2
395-
^ mesh2.contains_local_point(
396-
&pos12.inverse_transform_point(&repr_pt),
397-
// FIXME: Thierry: safer type checking
398-
&(),
399-
)
400-
{
388+
if flip2 ^ mesh2.contains_local_point(&pos12.inverse_transform_point(&repr_pt), &()) {
401389
new_indices1.extend_from_slice(mesh1.indices());
402390
}
403391
}

src/transformation/mesh_intersection/triangle_triangle_intersection.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ fn debug_check_intersections(
231231
) {
232232
let proj = |vect: Vector<Real>| Point2::new(vect.dot(&basis[0]), vect.dot(&basis[1]));
233233
let mut incorrect = false;
234-
// FIXME: Thierry: safer type checking. (associated type?)
235234
let options = ();
236235
for pt in intersections {
237236
if !tri1

0 commit comments

Comments
 (0)