From 0f5b4a4d886fc5cec7ddd4fd807ea4c5d5383842 Mon Sep 17 00:00:00 2001 From: Thierry Berger Date: Thu, 24 Jul 2025 16:21:55 +0200 Subject: [PATCH] feat: changed some QueryPipeline API to be more library friendly (#863) --- examples2d/debug_intersection2.rs | 2 +- examples2d/utils/character.rs | 4 ++-- examples3d/utils/character.rs | 4 ++-- src/control/character_controller.rs | 11 ++++------- src/dynamics/ccd/ccd_solver.rs | 6 +++--- src/pipeline/query_pipeline.rs | 20 ++++++++++---------- 6 files changed, 22 insertions(+), 25 deletions(-) diff --git a/examples2d/debug_intersection2.rs b/examples2d/debug_intersection2.rs index fc762dc..c61cb5d 100644 --- a/examples2d/debug_intersection2.rs +++ b/examples2d/debug_intersection2.rs @@ -53,7 +53,7 @@ pub fn init_world(testbed: &mut Testbed) { ); for intersection in query_pipeline.intersect_shape( - &Isometry::translation(slow_time.cos() * 10.0, slow_time.sin() * 10.0), + Isometry::translation(slow_time.cos() * 10.0, slow_time.sin() * 10.0), &Ball::new(rad / 2.0), ) { if let Some(graphics) = graphics.as_deref_mut() { diff --git a/examples2d/utils/character.rs b/examples2d/utils/character.rs index 7e4b5b5..491d839 100644 --- a/examples2d/utils/character.rs +++ b/examples2d/utils/character.rs @@ -140,7 +140,7 @@ fn update_kinematic_controller( let Some(broad_phase) = phx.broad_phase.downcast_ref::() else { return; }; - let query_pipeline = broad_phase.as_query_pipeline_mut( + let mut query_pipeline = broad_phase.as_query_pipeline_mut( phx.narrow_phase.query_dispatcher(), &mut phx.bodies, &mut phx.colliders, @@ -165,7 +165,7 @@ fn update_kinematic_controller( controller.solve_character_collision_impulses( phx.integration_parameters.dt, - query_pipeline, + &mut query_pipeline, &*character_shape, character_mass, &*collisions, diff --git a/examples3d/utils/character.rs b/examples3d/utils/character.rs index eb466bf..71f68bd 100644 --- a/examples3d/utils/character.rs +++ b/examples3d/utils/character.rs @@ -150,7 +150,7 @@ fn update_kinematic_controller( let Some(broad_phase) = phx.broad_phase.downcast_ref::() else { return; }; - let query_pipeline = broad_phase.as_query_pipeline_mut( + let mut query_pipeline = broad_phase.as_query_pipeline_mut( phx.narrow_phase.query_dispatcher(), &mut phx.bodies, &mut phx.colliders, @@ -175,7 +175,7 @@ fn update_kinematic_controller( controller.solve_character_collision_impulses( phx.integration_parameters.dt, - query_pipeline, + &mut query_pipeline, &*character_shape, character_mass, &*collisions, diff --git a/src/control/character_controller.rs b/src/control/character_controller.rs index 65b720e..e480c6a 100644 --- a/src/control/character_controller.rs +++ b/src/control/character_controller.rs @@ -423,7 +423,7 @@ impl KinematicCharacterController { let mut grounded = false; - 'outer: for (_, collider) in queries.intersect_aabb_conservative(&character_aabb) { + 'outer: for (_, collider) in queries.intersect_aabb_conservative(character_aabb) { manifolds.clear(); let pos12 = character_pos.inv_mul(collider.position()); let _ = dispatcher.contact_manifolds( @@ -770,7 +770,7 @@ impl KinematicCharacterController { pub fn solve_character_collision_impulses<'a>( &self, dt: Real, - mut queries: QueryPipelineMut, + queries: &mut QueryPipelineMut, character_shape: &dyn Shape, character_mass: Real, collisions: impl IntoIterator, @@ -778,7 +778,7 @@ impl KinematicCharacterController { for collision in collisions { self.solve_single_character_collision_impulse( dt, - &mut queries, + queries, character_shape, character_mass, collision, @@ -813,10 +813,7 @@ impl KinematicCharacterController { .compute_aabb(&collision.character_pos) .loosened(prediction); - for (_, collider) in queries - .as_ref() - .intersect_aabb_conservative(&character_aabb) - { + for (_, collider) in queries.as_ref().intersect_aabb_conservative(character_aabb) { if let Some(parent) = collider.parent { if let Some(body) = queries.bodies.get(parent.handle) { if body.is_dynamic() { diff --git a/src/dynamics/ccd/ccd_solver.rs b/src/dynamics/ccd/ccd_solver.rs index 4e8417a..e8834c7 100644 --- a/src/dynamics/ccd/ccd_solver.rs +++ b/src/dynamics/ccd/ccd_solver.rs @@ -168,7 +168,7 @@ impl CCDSolver { .shape .compute_swept_aabb(&co1.pos, &predicted_collider_pos1); - for (ch2, _) in query_pipeline.intersect_aabb_conservative(&aabb1) { + for (ch2, _) in query_pipeline.intersect_aabb_conservative(aabb1) { if *ch1 == ch2 { // Ignore self-intersection. continue; @@ -301,7 +301,7 @@ impl CCDSolver { .shape .compute_swept_aabb(&co1.pos, &predicted_collider_pos1); - for (ch2, _) in query_pipeline.intersect_aabb_conservative(&aabb1) { + for (ch2, _) in query_pipeline.intersect_aabb_conservative(aabb1) { if *ch1 == ch2 { // Ignore self-intersection. continue; @@ -433,7 +433,7 @@ impl CCDSolver { let co_next_pos1 = rb1.pos.next_position * co1_parent.pos_wrt_parent; let aabb = co1.shape.compute_swept_aabb(&co1.pos, &co_next_pos1); - for (ch2, _) in query_pipeline.intersect_aabb_conservative(&aabb) { + for (ch2, _) in query_pipeline.intersect_aabb_conservative(aabb) { let co2 = &colliders[ch2]; let bh1 = co1.parent.map(|p| p.handle); diff --git a/src/pipeline/query_pipeline.rs b/src/pipeline/query_pipeline.rs index 4b24ce2..2474bb3 100644 --- a/src/pipeline/query_pipeline.rs +++ b/src/pipeline/query_pipeline.rs @@ -211,19 +211,19 @@ impl<'a> QueryPipeline<'a> { #[profiling::function] pub fn intersect_ray( &'a self, - ray: &'a Ray, + ray: Ray, max_toi: Real, solid: bool, ) -> impl Iterator + 'a { // TODO: add this to CompositeShapeRef? self.bvh - .leaves(move |node: &BvhNode| node.aabb().intersects_local_ray(ray, max_toi)) + .leaves(move |node: &BvhNode| node.aabb().intersects_local_ray(&ray, max_toi)) .filter_map(move |leaf| { let (co, co_handle) = self.colliders.get_unknown_gen(leaf)?; if self.filter.test(self.bodies, co_handle, co) { if let Some(intersection) = co.shape - .cast_ray_and_get_normal(co.position(), ray, max_toi, solid) + .cast_ray_and_get_normal(co.position(), &ray, max_toi, solid) { return Some((co_handle, co, intersection)); } @@ -259,15 +259,15 @@ impl<'a> QueryPipeline<'a> { #[profiling::function] pub fn intersect_point( &'a self, - point: &'a Point, + point: Point, ) -> impl Iterator + 'a { // TODO: add to CompositeShapeRef? self.bvh - .leaves(move |node: &BvhNode| node.aabb().contains_local_point(point)) + .leaves(move |node: &BvhNode| node.aabb().contains_local_point(&point)) .filter_map(move |leaf| { let (co, co_handle) = self.colliders.get_unknown_gen(leaf)?; if self.filter.test(self.bodies, co_handle, co) - && co.shape.contains_point(co.position(), point) + && co.shape.contains_point(co.position(), &point) { return Some((co_handle, co)); } @@ -299,11 +299,11 @@ impl<'a> QueryPipeline<'a> { #[profiling::function] pub fn intersect_aabb_conservative( &'a self, - aabb: &'a Aabb, + aabb: Aabb, ) -> impl Iterator + 'a { // TODO: add to ColliderRef? self.bvh - .leaves(move |node: &BvhNode| node.aabb().intersects(aabb)) + .leaves(move |node: &BvhNode| node.aabb().intersects(&aabb)) .filter_map(move |leaf| { let (co, co_handle) = self.colliders.get_unknown_gen(leaf)?; // NOTE: do **not** recompute and check the latest collider AABB. @@ -388,11 +388,11 @@ impl<'a> QueryPipeline<'a> { #[profiling::function] pub fn intersect_shape( &'a self, - shape_pos: &'a Isometry, + shape_pos: Isometry, shape: &'a dyn Shape, ) -> impl Iterator + 'a { // TODO: add this to CompositeShapeRef? - let shape_aabb = shape.compute_aabb(shape_pos); + let shape_aabb = shape.compute_aabb(&shape_pos); self.bvh .leaves(move |node: &BvhNode| node.aabb().intersects(&shape_aabb)) .filter_map(move |leaf| {