pub struct QueryPipeline<'a> {
pub dispatcher: &'a dyn QueryDispatcher,
pub bvh: &'a Bvh,
pub bodies: &'a RigidBodySet,
pub colliders: &'a ColliderSet,
pub filter: QueryFilter<'a>,
}Expand description
A query system for performing spatial queries on your physics world (raycasts, shape casts, intersections).
Think of this as a “search engine” for your physics world. Use it to answer questions like:
- “What does this ray hit?”
- “What colliders are near this point?”
- “If I move this shape, what will it collide with?”
Get a QueryPipeline from your BroadPhaseBvh using as_query_pipeline().
§Example
let query_pipeline = broad_phase.as_query_pipeline(
narrow_phase.query_dispatcher(),
&bodies,
&colliders,
QueryFilter::default()
);
// Cast a ray downward
let ray = Ray::new(point![0.0, 10.0, 0.0], vector![0.0, -1.0, 0.0]);
if let Some((handle, toi)) = query_pipeline.cast_ray(&ray, Real::MAX, false) {
println!("Hit collider {:?} at distance {}", handle, toi);
}Fields§
§dispatcher: &'a dyn QueryDispatcherThe query dispatcher for running geometric queries on leaf geometries.
bvh: &'a BvhA bvh containing collider indices at its leaves.
bodies: &'a RigidBodySetRigid-bodies potentially involved in the scene queries.
colliders: &'a ColliderSetColliders potentially involved in the scene queries.
filter: QueryFilter<'a>The query filters for controlling what colliders should be ignored by the queries.
Implementations§
Source§impl<'a> QueryPipeline<'a>
impl<'a> QueryPipeline<'a>
Sourcepub fn with_filter(self, filter: QueryFilter<'a>) -> Self
pub fn with_filter(self, filter: QueryFilter<'a>) -> Self
Replaces Self::filter with different filtering rules.
Sourcepub fn cast_ray(
&self,
ray: &Ray,
max_toi: f32,
solid: bool,
) -> Option<(ColliderHandle, f32)>
pub fn cast_ray( &self, ray: &Ray, max_toi: f32, solid: bool, ) -> Option<(ColliderHandle, f32)>
Casts a ray through the world and returns the first collider it hits.
This is one of the most common operations - use it for line-of-sight checks, projectile trajectories, mouse picking, laser beams, etc.
Returns Some((handle, distance)) if the ray hits something, where:
handleis which collider was hitdistanceis how far along the ray the hit occurred (time-of-impact)
§Parameters
ray- The ray to cast (origin + direction). Create withRay::new(origin, direction)max_toi- Maximum distance to check. UseReal::MAXfor unlimited rangesolid- Iftrue, detects hits even if the ray starts inside a shape. Iffalse, the ray “passes through” from the inside until it exits
§Example
// Raycast downward from (0, 10, 0)
let ray = Ray::new(point![0.0, 10.0, 0.0], vector![0.0, -1.0, 0.0]);
if let Some((handle, toi)) = query_pipeline.cast_ray(&ray, Real::MAX, true) {
let hit_point = ray.origin + ray.dir * toi;
println!("Hit at {:?}, distance = {}", hit_point, toi);
}Sourcepub fn cast_ray_and_get_normal(
&self,
ray: &Ray,
max_toi: f32,
solid: bool,
) -> Option<(ColliderHandle, RayIntersection)>
pub fn cast_ray_and_get_normal( &self, ray: &Ray, max_toi: f32, solid: bool, ) -> Option<(ColliderHandle, RayIntersection)>
Casts a ray and returns detailed information about the hit (including surface normal).
Like cast_ray(), but returns more information useful for things like:
- Decals (need surface normal to orient the texture)
- Bullet holes (need to know what part of the mesh was hit)
- Ricochets (need normal to calculate bounce direction)
Returns Some((handle, intersection)) where intersection contains:
toi: Distance to impactnormal: Surface normal at the hit pointfeature: Which geometric feature was hit (vertex, edge, face)
§Example
if let Some((handle, hit)) = query_pipeline.cast_ray_and_get_normal(&ray, 100.0, true) {
println!("Hit at distance {}, surface normal: {:?}", hit.time_of_impact, hit.normal);
}Sourcepub fn intersect_ray(
&'a self,
ray: Ray,
max_toi: f32,
solid: bool,
) -> impl Iterator<Item = (ColliderHandle, &'a Collider, RayIntersection)> + 'a
pub fn intersect_ray( &'a self, ray: Ray, max_toi: f32, solid: bool, ) -> impl Iterator<Item = (ColliderHandle, &'a Collider, RayIntersection)> + 'a
Returns ALL colliders that a ray passes through (not just the first).
Unlike cast_ray() which stops at the first hit, this returns
every collider along the ray’s path. Useful for:
- Penetrating weapons that go through multiple objects
- Checking what’s in a line (e.g., visibility through glass)
- Counting how many objects are between two points
Returns an iterator of (handle, collider, intersection) tuples.
§Example
for (handle, collider, hit) in query_pipeline.intersect_ray(ray, 100.0, true) {
println!("Ray passed through {:?} at distance {}", handle, hit.time_of_impact);
}Sourcepub fn project_point(
&self,
point: &Point<f32>,
_max_dist: f32,
solid: bool,
) -> Option<(ColliderHandle, PointProjection)>
pub fn project_point( &self, point: &Point<f32>, _max_dist: f32, solid: bool, ) -> Option<(ColliderHandle, PointProjection)>
Finds the closest point on any collider to the given point.
Returns the collider and information about where on its surface the closest point is. Useful for:
- Finding nearest cover/obstacle
- Snap-to-surface mechanics
- Distance queries
§Parameters
solid- Iftrue, a point inside a shape projects to itself. Iffalse, it projects to the nearest point on the shape’s boundary
§Example
let point = point![5.0, 0.0, 0.0];
if let Some((handle, projection)) = query_pipeline.project_point(&point, std::f32::MAX, true) {
println!("Closest collider: {:?}", handle);
println!("Closest point: {:?}", projection.point);
println!("Distance: {}", (point - projection.point).norm());
}Sourcepub fn intersect_point(
&'a self,
point: Point<f32>,
) -> impl Iterator<Item = (ColliderHandle, &'a Collider)> + 'a
pub fn intersect_point( &'a self, point: Point<f32>, ) -> impl Iterator<Item = (ColliderHandle, &'a Collider)> + 'a
Returns ALL colliders that contain the given point.
A point is “inside” a collider if it’s within its volume. Useful for:
- Detecting what area/trigger zones a point is in
- Checking if a position is inside geometry
- Finding all overlapping volumes at a location
§Example
let point = point![0.0, 0.0, 0.0];
for (handle, collider) in query_pipeline.intersect_point(point) {
println!("Point is inside {:?}", handle);
}Sourcepub fn project_point_and_get_feature(
&self,
point: &Point<f32>,
) -> Option<(ColliderHandle, PointProjection, FeatureId)>
pub fn project_point_and_get_feature( &self, point: &Point<f32>, ) -> Option<(ColliderHandle, PointProjection, FeatureId)>
Find the projection of a point on the closest collider.
The results include the ID of the feature hit by the point.
§Parameters
point- The point to project.
Sourcepub fn intersect_aabb_conservative(
&'a self,
aabb: Aabb,
) -> impl Iterator<Item = (ColliderHandle, &'a Collider)> + 'a
pub fn intersect_aabb_conservative( &'a self, aabb: Aabb, ) -> impl Iterator<Item = (ColliderHandle, &'a Collider)> + 'a
Sourcepub fn cast_shape(
&self,
shape_pos: &Isometry<f32>,
shape_vel: &Vector<f32>,
shape: &dyn Shape,
options: ShapeCastOptions,
) -> Option<(ColliderHandle, ShapeCastHit)>
pub fn cast_shape( &self, shape_pos: &Isometry<f32>, shape_vel: &Vector<f32>, shape: &dyn Shape, options: ShapeCastOptions, ) -> Option<(ColliderHandle, ShapeCastHit)>
Sweeps a shape through the world to find what it would collide with.
Like raycasting, but instead of a thin ray, you’re moving an entire shape (sphere, box, etc.) through space. This is also called “shape casting” or “sweep testing”. Useful for:
- Predicting where a moving object will hit something
- Checking if a movement is valid before executing it
- Thick raycasts (e.g., character controller collision prediction)
- Area-of-effect scanning along a path
Returns the first collision: (collider_handle, hit_details) where hit contains
time-of-impact, witness points, and surface normal.
§Parameters
shape_pos- Starting position/orientation of the shapeshape_vel- Direction and speed to move the shape (velocity vector)shape- The shape to sweep (ball, cuboid, capsule, etc.)options- Maximum distance, collision filtering, etc.
§Example
// Sweep a sphere downward
let shape = Ball::new(0.5);
let start_pos = Isometry::translation(0.0, 10.0, 0.0);
let velocity = vector![0.0, -1.0, 0.0];
let options = ShapeCastOptions::default();
if let Some((handle, hit)) = query_pipeline.cast_shape(&start_pos, &velocity, &shape, options) {
println!("Shape would hit {:?} at time {}", handle, hit.time_of_impact);
}Sourcepub fn cast_shape_nonlinear(
&self,
shape_motion: &NonlinearRigidMotion,
shape: &dyn Shape,
start_time: f32,
end_time: f32,
stop_at_penetration: bool,
) -> Option<(ColliderHandle, ShapeCastHit)>
pub fn cast_shape_nonlinear( &self, shape_motion: &NonlinearRigidMotion, shape: &dyn Shape, start_time: f32, end_time: f32, stop_at_penetration: bool, ) -> Option<(ColliderHandle, ShapeCastHit)>
Casts a shape with an arbitrary continuous motion and retrieve the first collider it hits.
In the resulting TOI, witness and normal 1 refer to the world collider, and are in world
space.
§Parameters
shape_motion- The motion of the shape.shape- The shape to cast.start_time- The starting time of the interval where the motion takes place.end_time- The end time of the interval where the motion takes place.stop_at_penetration- If the casted shape starts in a penetration state with any collider, two results are possible. Ifstop_at_penetrationistruethen, the result will have atoiequal tostart_time. Ifstop_at_penetrationisfalsethen the nonlinear shape-casting will see if further motion with respect to the penetration normal would result in tunnelling. If it does not (i.e. we have a separating velocity along that normal) then the nonlinear shape-casting will attempt to find another impact, at a time> start_timethat could result in tunnelling.
Sourcepub fn intersect_shape(
&'a self,
shape_pos: Isometry<f32>,
shape: &'a dyn Shape,
) -> impl Iterator<Item = (ColliderHandle, &'a Collider)> + 'a
pub fn intersect_shape( &'a self, shape_pos: Isometry<f32>, shape: &'a dyn Shape, ) -> impl Iterator<Item = (ColliderHandle, &'a Collider)> + 'a
Retrieve all the colliders intersecting the given shape.
§Parameters
shapePos- The pose of the shape to test.shape- The shape to test.
Trait Implementations§
Source§impl<'a> Clone for QueryPipeline<'a>
impl<'a> Clone for QueryPipeline<'a>
Source§fn clone(&self) -> QueryPipeline<'a>
fn clone(&self) -> QueryPipeline<'a>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl CompositeShape for QueryPipeline<'_>
impl CompositeShape for QueryPipeline<'_>
Source§impl TypedCompositeShape for QueryPipeline<'_>
impl TypedCompositeShape for QueryPipeline<'_>
type PartNormalConstraints = ()
type PartShape = dyn Shape
fn map_typed_part_at<T>( &self, shape_id: u32, f: impl FnMut(Option<&Isometry<f32>>, &Self::PartShape, Option<&Self::PartNormalConstraints>) -> T, ) -> Option<T>
fn map_untyped_part_at<T>( &self, shape_id: u32, f: impl FnMut(Option<&Isometry<f32>>, &dyn Shape, Option<&dyn NormalConstraints>) -> T, ) -> Option<T>
impl<'a> Copy for QueryPipeline<'a>
Auto Trait Implementations§
impl<'a> Freeze for QueryPipeline<'a>
impl<'a> !RefUnwindSafe for QueryPipeline<'a>
impl<'a> !Send for QueryPipeline<'a>
impl<'a> !Sync for QueryPipeline<'a>
impl<'a> Unpin for QueryPipeline<'a>
impl<'a> !UnwindSafe for QueryPipeline<'a>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.