From a76679fce6f4746b0f0d9adb2a69479ee4cc1a21 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 13 Jan 2025 12:02:14 +0100 Subject: [PATCH 1/4] basic forward dispatcher --- crates/parry3d/examples/custom_dispatcher.rs | 167 +++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 crates/parry3d/examples/custom_dispatcher.rs diff --git a/crates/parry3d/examples/custom_dispatcher.rs b/crates/parry3d/examples/custom_dispatcher.rs new file mode 100644 index 00000000..5179cdd2 --- /dev/null +++ b/crates/parry3d/examples/custom_dispatcher.rs @@ -0,0 +1,167 @@ +extern crate nalgebra as na; + +use parry3d::{ + bounding_volume::{Aabb, BoundingSphere}, + mass_properties::MassProperties, + math::{Isometry, Point, Vector}, + query::{ + ClosestPoints, Contact, DefaultQueryDispatcher, NonlinearRigidMotion, PointProjection, + PointQuery, QueryDispatcher, Ray, RayCast, RayIntersection, ShapeCastHit, ShapeCastOptions, + Unsupported, + }, + shape::{Ball, Cuboid, FeatureId, Shape, ShapeType, TypedShape}, +}; + +fn main() { + let cube = Cuboid::new(Vector::new(1.0, 1.0, 1.0)); + let ball = CustomBall(Ball::new(1.0)); + + let pos12 = Isometry::identity(); + let dispatcher = CustomBallDispatcher; + + let contact = dispatcher.contact(&pos12, &cube, &ball.0, 0.0); + + dbg!(contact); +} + +pub struct CustomBall(pub Ball); + +impl PointQuery for CustomBall { + fn project_local_point(&self, pt: &Point, solid: bool) -> PointProjection { + self.0.project_local_point(pt, solid) + } + + fn project_local_point_and_get_feature(&self, pt: &Point) -> (PointProjection, FeatureId) { + self.0.project_local_point_and_get_feature(pt) + } +} + +impl RayCast for CustomBall { + fn cast_local_ray_and_get_normal( + &self, + ray: &Ray, + max_time_of_impact: f32, + solid: bool, + ) -> Option { + self.0 + .cast_local_ray_and_get_normal(ray, max_time_of_impact, solid) + } +} + +impl Shape for CustomBall { + fn compute_local_aabb(&self) -> Aabb { + self.0.compute_local_aabb() + } + + fn compute_local_bounding_sphere(&self) -> BoundingSphere { + self.0.compute_local_bounding_sphere() + } + + fn clone_dyn(&self) -> Box { + Box::new(Self(self.0)) + } + + fn scale_dyn(&self, scale: &Vector, num_subdivisions: u32) -> Option> { + Some(self.0.scale_dyn(scale, num_subdivisions)?) + } + + fn mass_properties(&self, density: f32) -> MassProperties { + self.0.mass_properties(density) + } + + fn shape_type(&self) -> ShapeType { + self.0.shape_type() + } + + fn as_typed_shape(&self) -> TypedShape { + self.0.as_typed_shape() + } + + fn ccd_thickness(&self) -> f32 { + self.0.ccd_thickness() + } + + fn ccd_angular_thickness(&self) -> f32 { + self.0.ccd_angular_thickness() + } +} + +pub struct CustomBallDispatcher; + +impl QueryDispatcher for CustomBallDispatcher { + fn intersection_test( + &self, + pos12: &Isometry, + g1: &dyn Shape, + g2: &dyn Shape, + ) -> Result { + let dispatcher = DefaultQueryDispatcher; + dispatcher.intersection_test(pos12, g1, g2) + } + + fn distance( + &self, + pos12: &Isometry, + g1: &dyn Shape, + g2: &dyn Shape, + ) -> Result { + let dispatcher = DefaultQueryDispatcher; + dispatcher.distance(pos12, g1, g2) + } + + fn contact( + &self, + pos12: &Isometry, + g1: &dyn Shape, + g2: &dyn Shape, + prediction: f32, + ) -> Result, Unsupported> { + let dispatcher = DefaultQueryDispatcher; + dispatcher.contact(pos12, g1, g2, prediction) + } + + fn closest_points( + &self, + pos12: &Isometry, + g1: &dyn Shape, + g2: &dyn Shape, + max_dist: f32, + ) -> Result { + let dispatcher = DefaultQueryDispatcher; + dispatcher.closest_points(pos12, g1, g2, max_dist) + } + + fn cast_shapes( + &self, + pos12: &Isometry, + local_vel12: &Vector, + g1: &dyn Shape, + g2: &dyn Shape, + options: ShapeCastOptions, + ) -> Result, Unsupported> { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes(pos12, local_vel12, g1, g2, options) + } + + fn cast_shapes_nonlinear( + &self, + motion1: &NonlinearRigidMotion, + g1: &dyn Shape, + motion2: &NonlinearRigidMotion, + g2: &dyn Shape, + start_time: f32, + end_time: f32, + stop_at_penetration: bool, + ) -> Result, Unsupported> { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes_nonlinear( + motion1, + g1, + motion2, + g2, + start_time, + end_time, + stop_at_penetration, + ) + } +} From b9b6fa85b404140d066a96c2d2cffeaba6d3d5fe Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 20 Jan 2025 11:46:47 +0100 Subject: [PATCH 2/4] use underlying functions for dispatcher --- crates/parry3d/examples/custom_dispatcher.rs | 204 +++++++++++++++++-- 1 file changed, 182 insertions(+), 22 deletions(-) diff --git a/crates/parry3d/examples/custom_dispatcher.rs b/crates/parry3d/examples/custom_dispatcher.rs index 5179cdd2..a56975b1 100644 --- a/crates/parry3d/examples/custom_dispatcher.rs +++ b/crates/parry3d/examples/custom_dispatcher.rs @@ -12,6 +12,8 @@ use parry3d::{ shape::{Ball, Cuboid, FeatureId, Shape, ShapeType, TypedShape}, }; +pub struct CustomBall(pub Ball); + fn main() { let cube = Cuboid::new(Vector::new(1.0, 1.0, 1.0)); let ball = CustomBall(Ball::new(1.0)); @@ -24,8 +26,6 @@ fn main() { dbg!(contact); } -pub struct CustomBall(pub Ball); - impl PointQuery for CustomBall { fn project_local_point(&self, pt: &Point, solid: bool) -> PointProjection { self.0.project_local_point(pt, solid) @@ -95,8 +95,31 @@ impl QueryDispatcher for CustomBallDispatcher { g1: &dyn Shape, g2: &dyn Shape, ) -> Result { - let dispatcher = DefaultQueryDispatcher; - dispatcher.intersection_test(pos12, g1, g2) + let (ball1, ball2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), + ); + + match (ball1, ball2) { + (Some(ball1), Some(ball2)) => { + let p12 = Point::from(pos12.translation.vector); + return Ok(parry3d::query::details::intersection_test_ball_ball( + &p12, &ball1.0, &ball2.0, + )); + } + (Some(ball1), None) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.intersection_test(pos12, &ball1.0, g2) + } + (None, Some(ball2)) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.intersection_test(pos12, g1, &ball2.0) + } + _ => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.intersection_test(pos12, g1, g2) + } + } } fn distance( @@ -105,8 +128,31 @@ impl QueryDispatcher for CustomBallDispatcher { g1: &dyn Shape, g2: &dyn Shape, ) -> Result { - let dispatcher = DefaultQueryDispatcher; - dispatcher.distance(pos12, g1, g2) + let (ball1, ball2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), + ); + + match (ball1, ball2) { + (Some(ball1), Some(ball2)) => { + let p2 = Point::from(pos12.translation.vector); + return Ok(parry3d::query::details::distance_ball_ball( + &ball1.0, &p2, &ball2.0, + )); + } + (Some(ball1), None) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.distance(pos12, &ball1.0, g2) + } + (None, Some(ball2)) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.distance(pos12, g1, &ball2.0) + } + _ => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.distance(pos12, g1, g2) + } + } } fn contact( @@ -116,8 +162,30 @@ impl QueryDispatcher for CustomBallDispatcher { g2: &dyn Shape, prediction: f32, ) -> Result, Unsupported> { - let dispatcher = DefaultQueryDispatcher; - dispatcher.contact(pos12, g1, g2, prediction) + let (ball1, ball2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), + ); + + match (ball1, ball2) { + (Some(ball1), Some(ball2)) => { + return Ok(parry3d::query::details::contact_ball_ball( + pos12, &ball1.0, &ball2.0, prediction, + )); + } + (Some(ball1), None) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.contact(pos12, &ball1.0, g2, prediction) + } + (None, Some(ball2)) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.contact(pos12, g1, &ball2.0, prediction) + } + _ => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.contact(pos12, g1, g2, prediction) + } + } } fn closest_points( @@ -127,8 +195,30 @@ impl QueryDispatcher for CustomBallDispatcher { g2: &dyn Shape, max_dist: f32, ) -> Result { - let dispatcher = DefaultQueryDispatcher; - dispatcher.closest_points(pos12, g1, g2, max_dist) + let (ball1, ball2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), + ); + + match (ball1, ball2) { + (Some(ball1), Some(ball2)) => { + return Ok(parry3d::query::details::closest_points_ball_ball( + pos12, &ball1.0, &ball2.0, max_dist, + )); + } + (Some(ball1), None) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.closest_points(pos12, &ball1.0, g2, max_dist) + } + (None, Some(ball2)) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.closest_points(pos12, g1, &ball2.0, max_dist) + } + _ => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.closest_points(pos12, g1, g2, max_dist) + } + } } fn cast_shapes( @@ -139,8 +229,34 @@ impl QueryDispatcher for CustomBallDispatcher { g2: &dyn Shape, options: ShapeCastOptions, ) -> Result, Unsupported> { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes(pos12, local_vel12, g1, g2, options) + let (ball1, ball2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), + ); + + match (ball1, ball2) { + (Some(ball1), Some(ball2)) => { + return Ok(parry3d::query::details::cast_shapes_ball_ball( + pos12, + local_vel12, + &ball1.0, + &ball2.0, + options, + )); + } + (Some(ball1), None) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes(pos12, local_vel12, &ball1.0, g2, options) + } + (None, Some(ball2)) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes(pos12, local_vel12, g1, &ball2.0, options) + } + _ => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes(pos12, local_vel12, g1, g2, options) + } + } } fn cast_shapes_nonlinear( @@ -153,15 +269,59 @@ impl QueryDispatcher for CustomBallDispatcher { end_time: f32, stop_at_penetration: bool, ) -> Result, Unsupported> { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes_nonlinear( - motion1, - g1, - motion2, - g2, - start_time, - end_time, - stop_at_penetration, - ) + let (ball1, ball2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), + ); + + match (ball1, ball2) { + (Some(ball1), Some(ball2)) => { + return parry3d::query::details::cast_shapes_nonlinear( + motion1, + &ball1.0, + motion2, + &ball2.0, + start_time, + end_time, + stop_at_penetration, + ); + } + (Some(ball1), None) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes_nonlinear( + motion1, + &ball1.0, + motion2, + g2, + start_time, + end_time, + stop_at_penetration, + ) + } + (None, Some(ball2)) => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes_nonlinear( + motion1, + g1, + motion2, + &ball2.0, + start_time, + end_time, + stop_at_penetration, + ) + } + _ => { + let dispatcher = DefaultQueryDispatcher; + dispatcher.cast_shapes_nonlinear( + motion1, + g1, + motion2, + g2, + start_time, + end_time, + stop_at_penetration, + ) + } + } } } From a9d27f29b06b963531a54a61639592d6a7cb713e Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 27 Jan 2025 09:32:31 +0100 Subject: [PATCH 3/4] address PR feedback better naming + less complex impl --- crates/parry3d/examples/custom_dispatcher.rs | 166 ++++++------------- 1 file changed, 54 insertions(+), 112 deletions(-) diff --git a/crates/parry3d/examples/custom_dispatcher.rs b/crates/parry3d/examples/custom_dispatcher.rs index a56975b1..8557ccb4 100644 --- a/crates/parry3d/examples/custom_dispatcher.rs +++ b/crates/parry3d/examples/custom_dispatcher.rs @@ -12,21 +12,21 @@ use parry3d::{ shape::{Ball, Cuboid, FeatureId, Shape, ShapeType, TypedShape}, }; -pub struct CustomBall(pub Ball); +pub struct CustomShape(pub Ball); fn main() { let cube = Cuboid::new(Vector::new(1.0, 1.0, 1.0)); - let ball = CustomBall(Ball::new(1.0)); + let custom_shape = CustomShape(Ball::new(1.0)); let pos12 = Isometry::identity(); - let dispatcher = CustomBallDispatcher; + let dispatcher = CustomShapeDispatcher; - let contact = dispatcher.contact(&pos12, &cube, &ball.0, 0.0); + let contact = dispatcher.contact(&pos12, &cube, &custom_shape.0, 0.0); - dbg!(contact); + _ = dbg!(contact); } -impl PointQuery for CustomBall { +impl PointQuery for CustomShape { fn project_local_point(&self, pt: &Point, solid: bool) -> PointProjection { self.0.project_local_point(pt, solid) } @@ -36,7 +36,7 @@ impl PointQuery for CustomBall { } } -impl RayCast for CustomBall { +impl RayCast for CustomShape { fn cast_local_ray_and_get_normal( &self, ray: &Ray, @@ -48,7 +48,7 @@ impl RayCast for CustomBall { } } -impl Shape for CustomBall { +impl Shape for CustomShape { fn compute_local_aabb(&self) -> Aabb { self.0.compute_local_aabb() } @@ -86,35 +86,28 @@ impl Shape for CustomBall { } } -pub struct CustomBallDispatcher; +pub struct CustomShapeDispatcher; -impl QueryDispatcher for CustomBallDispatcher { +impl QueryDispatcher for CustomShapeDispatcher { fn intersection_test( &self, pos12: &Isometry, g1: &dyn Shape, g2: &dyn Shape, ) -> Result { - let (ball1, ball2) = ( - g1.downcast_ref::(), - g2.downcast_ref::(), + let (maybe_custom1, maybe_custom2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), ); - match (ball1, ball2) { - (Some(ball1), Some(ball2)) => { + match (maybe_custom1, maybe_custom2) { + (Some(custom1), Some(custom2)) => { let p12 = Point::from(pos12.translation.vector); return Ok(parry3d::query::details::intersection_test_ball_ball( - &p12, &ball1.0, &ball2.0, + &p12, &custom1.0, &custom2.0, )); } - (Some(ball1), None) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.intersection_test(pos12, &ball1.0, g2) - } - (None, Some(ball2)) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.intersection_test(pos12, g1, &ball2.0) - } + // TODO: implement the algorithm for each shape type combination you want to support. _ => { let dispatcher = DefaultQueryDispatcher; dispatcher.intersection_test(pos12, g1, g2) @@ -128,26 +121,19 @@ impl QueryDispatcher for CustomBallDispatcher { g1: &dyn Shape, g2: &dyn Shape, ) -> Result { - let (ball1, ball2) = ( - g1.downcast_ref::(), - g2.downcast_ref::(), + let (maybe_custom1, maybe_custom2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), ); - match (ball1, ball2) { - (Some(ball1), Some(ball2)) => { + match (maybe_custom1, maybe_custom2) { + (Some(custom1), Some(custom2)) => { let p2 = Point::from(pos12.translation.vector); return Ok(parry3d::query::details::distance_ball_ball( - &ball1.0, &p2, &ball2.0, + &custom1.0, &p2, &custom2.0, )); } - (Some(ball1), None) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.distance(pos12, &ball1.0, g2) - } - (None, Some(ball2)) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.distance(pos12, g1, &ball2.0) - } + // TODO: implement the algorithm for each shape type combination you want to support. _ => { let dispatcher = DefaultQueryDispatcher; dispatcher.distance(pos12, g1, g2) @@ -162,25 +148,18 @@ impl QueryDispatcher for CustomBallDispatcher { g2: &dyn Shape, prediction: f32, ) -> Result, Unsupported> { - let (ball1, ball2) = ( - g1.downcast_ref::(), - g2.downcast_ref::(), + let (maybe_custom1, maybe_custom2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), ); - match (ball1, ball2) { - (Some(ball1), Some(ball2)) => { + match (maybe_custom1, maybe_custom2) { + (Some(custom1), Some(custom2)) => { return Ok(parry3d::query::details::contact_ball_ball( - pos12, &ball1.0, &ball2.0, prediction, + pos12, &custom1.0, &custom2.0, prediction, )); } - (Some(ball1), None) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.contact(pos12, &ball1.0, g2, prediction) - } - (None, Some(ball2)) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.contact(pos12, g1, &ball2.0, prediction) - } + // TODO: implement the algorithm for each shape type combination you want to support. _ => { let dispatcher = DefaultQueryDispatcher; dispatcher.contact(pos12, g1, g2, prediction) @@ -195,25 +174,18 @@ impl QueryDispatcher for CustomBallDispatcher { g2: &dyn Shape, max_dist: f32, ) -> Result { - let (ball1, ball2) = ( - g1.downcast_ref::(), - g2.downcast_ref::(), + let (maybe_custom1, maybe_custom2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), ); - match (ball1, ball2) { - (Some(ball1), Some(ball2)) => { + match (maybe_custom1, maybe_custom2) { + (Some(custom1), Some(custom2)) => { return Ok(parry3d::query::details::closest_points_ball_ball( - pos12, &ball1.0, &ball2.0, max_dist, + pos12, &custom1.0, &custom2.0, max_dist, )); } - (Some(ball1), None) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.closest_points(pos12, &ball1.0, g2, max_dist) - } - (None, Some(ball2)) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.closest_points(pos12, g1, &ball2.0, max_dist) - } + // TODO: implement the algorithm for each shape type combination you want to support. _ => { let dispatcher = DefaultQueryDispatcher; dispatcher.closest_points(pos12, g1, g2, max_dist) @@ -229,29 +201,22 @@ impl QueryDispatcher for CustomBallDispatcher { g2: &dyn Shape, options: ShapeCastOptions, ) -> Result, Unsupported> { - let (ball1, ball2) = ( - g1.downcast_ref::(), - g2.downcast_ref::(), + let (maybe_custom1, maybe_custom2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), ); - match (ball1, ball2) { - (Some(ball1), Some(ball2)) => { + match (maybe_custom1, maybe_custom2) { + (Some(custom1), Some(custom2)) => { return Ok(parry3d::query::details::cast_shapes_ball_ball( pos12, local_vel12, - &ball1.0, - &ball2.0, + &custom1.0, + &custom2.0, options, )); } - (Some(ball1), None) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes(pos12, local_vel12, &ball1.0, g2, options) - } - (None, Some(ball2)) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes(pos12, local_vel12, g1, &ball2.0, options) - } + // TODO: implement the algorithm for each shape type combination you want to support. _ => { let dispatcher = DefaultQueryDispatcher; dispatcher.cast_shapes(pos12, local_vel12, g1, g2, options) @@ -269,47 +234,24 @@ impl QueryDispatcher for CustomBallDispatcher { end_time: f32, stop_at_penetration: bool, ) -> Result, Unsupported> { - let (ball1, ball2) = ( - g1.downcast_ref::(), - g2.downcast_ref::(), + let (maybe_custom1, maybe_custom2) = ( + g1.downcast_ref::(), + g2.downcast_ref::(), ); - match (ball1, ball2) { - (Some(ball1), Some(ball2)) => { + match (maybe_custom1, maybe_custom2) { + (Some(custom1), Some(custom2)) => { return parry3d::query::details::cast_shapes_nonlinear( motion1, - &ball1.0, + &custom1.0, motion2, - &ball2.0, + &custom2.0, start_time, end_time, stop_at_penetration, ); } - (Some(ball1), None) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes_nonlinear( - motion1, - &ball1.0, - motion2, - g2, - start_time, - end_time, - stop_at_penetration, - ) - } - (None, Some(ball2)) => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes_nonlinear( - motion1, - g1, - motion2, - &ball2.0, - start_time, - end_time, - stop_at_penetration, - ) - } + // TODO: implement the algorithm for each shape type combination you want to support. _ => { let dispatcher = DefaultQueryDispatcher; dispatcher.cast_shapes_nonlinear( From 1c607079d3eebe450fd155ab58d0ce471210ded9 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Mon, 3 Mar 2025 10:14:29 +0100 Subject: [PATCH 4/4] use Dispatcher.chain --- crates/parry3d/examples/custom_dispatcher.rs | 41 ++++---------------- 1 file changed, 8 insertions(+), 33 deletions(-) diff --git a/crates/parry3d/examples/custom_dispatcher.rs b/crates/parry3d/examples/custom_dispatcher.rs index 8557ccb4..02ea43ee 100644 --- a/crates/parry3d/examples/custom_dispatcher.rs +++ b/crates/parry3d/examples/custom_dispatcher.rs @@ -19,7 +19,8 @@ fn main() { let custom_shape = CustomShape(Ball::new(1.0)); let pos12 = Isometry::identity(); - let dispatcher = CustomShapeDispatcher; + // You can chain your custom dispatcher with the default one. + let dispatcher = CustomShapeDispatcher.chain(DefaultQueryDispatcher); let contact = dispatcher.contact(&pos12, &cube, &custom_shape.0, 0.0); @@ -108,10 +109,7 @@ impl QueryDispatcher for CustomShapeDispatcher { )); } // TODO: implement the algorithm for each shape type combination you want to support. - _ => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.intersection_test(pos12, g1, g2) - } + _ => Err(Unsupported), } } @@ -134,10 +132,7 @@ impl QueryDispatcher for CustomShapeDispatcher { )); } // TODO: implement the algorithm for each shape type combination you want to support. - _ => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.distance(pos12, g1, g2) - } + _ => Err(Unsupported), } } @@ -160,10 +155,7 @@ impl QueryDispatcher for CustomShapeDispatcher { )); } // TODO: implement the algorithm for each shape type combination you want to support. - _ => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.contact(pos12, g1, g2, prediction) - } + _ => Err(Unsupported), } } @@ -186,10 +178,7 @@ impl QueryDispatcher for CustomShapeDispatcher { )); } // TODO: implement the algorithm for each shape type combination you want to support. - _ => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.closest_points(pos12, g1, g2, max_dist) - } + _ => Err(Unsupported), } } @@ -217,10 +206,7 @@ impl QueryDispatcher for CustomShapeDispatcher { )); } // TODO: implement the algorithm for each shape type combination you want to support. - _ => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes(pos12, local_vel12, g1, g2, options) - } + _ => Err(Unsupported), } } @@ -252,18 +238,7 @@ impl QueryDispatcher for CustomShapeDispatcher { ); } // TODO: implement the algorithm for each shape type combination you want to support. - _ => { - let dispatcher = DefaultQueryDispatcher; - dispatcher.cast_shapes_nonlinear( - motion1, - g1, - motion2, - g2, - start_time, - end_time, - stop_at_penetration, - ) - } + _ => Err(Unsupported), } } }