Skip to main content

bevy_rapier3d/pipeline/
query_filter.rs

1use bevy::prelude::Entity;
2
3pub use rapier::pipeline::QueryFilterFlags;
4
5use crate::geometry::CollisionGroups;
6use rapier::geometry::Collider as RapierCollider;
7
8/// A filter that describes what collider should be included or excluded from a scene query.
9#[derive(Copy, Clone, Default)]
10pub struct QueryFilter<'a> {
11    /// Flags indicating what particular type of colliders should be excluded.
12    pub flags: QueryFilterFlags,
13    /// If set, only colliders with collision groups compatible with this one will
14    /// be included in the scene query.
15    ///
16    /// The [`CollisionGroups::test_mode`] of both groups is taken into account.
17    pub groups: Option<CollisionGroups>,
18    /// If set, the collider attached to that entity will be excluded from the query.
19    pub exclude_collider: Option<Entity>,
20    /// If set, any collider attached to the rigid-body attached to that entity
21    /// will be excluded from the query.
22    pub exclude_rigid_body: Option<Entity>,
23    /// If set, any collider for which this closure returns false will be excluded from the query.
24    ///
25    /// The closure is given the collider’s entity and its Rapier collider, which gives access to
26    /// its shape, position, parent, etc.
27    #[allow(clippy::type_complexity)]
28    pub predicate: Option<&'a dyn Fn(Entity, &RapierCollider) -> bool>,
29}
30
31impl From<QueryFilterFlags> for QueryFilter<'_> {
32    fn from(flags: QueryFilterFlags) -> Self {
33        Self {
34            flags,
35            ..QueryFilter::default()
36        }
37    }
38}
39
40impl From<CollisionGroups> for QueryFilter<'_> {
41    fn from(groups: CollisionGroups) -> Self {
42        Self {
43            groups: Some(groups),
44            ..QueryFilter::default()
45        }
46    }
47}
48
49impl<'a> QueryFilter<'a> {
50    /// A query filter that doesn’t exclude any collider.
51    pub fn new() -> Self {
52        Self::default()
53    }
54
55    /// Exclude from the query any collider attached to a fixed rigid-body and colliders with no rigid-body attached.
56    pub fn exclude_fixed() -> Self {
57        QueryFilterFlags::EXCLUDE_FIXED.into()
58    }
59
60    /// Exclude from the query any collider attached to a kinematic rigid-body.
61    pub fn exclude_kinematic() -> Self {
62        QueryFilterFlags::EXCLUDE_KINEMATIC.into()
63    }
64
65    /// Exclude from the query any collider attached to a dynamic rigid-body.
66    pub fn exclude_dynamic() -> Self {
67        QueryFilterFlags::EXCLUDE_DYNAMIC.into()
68    }
69
70    /// Excludes all colliders not attached to a dynamic rigid-body.
71    pub fn only_dynamic() -> Self {
72        QueryFilterFlags::ONLY_DYNAMIC.into()
73    }
74
75    /// Excludes all colliders not attached to a kinematic rigid-body.
76    pub fn only_kinematic() -> Self {
77        QueryFilterFlags::ONLY_KINEMATIC.into()
78    }
79
80    /// Exclude all colliders attached to a non-fixed rigid-body
81    /// (this will not exclude colliders not attached to any rigid-body).
82    pub fn only_fixed() -> Self {
83        QueryFilterFlags::ONLY_FIXED.into()
84    }
85
86    /// Exclude from the query any collider that is a sensor.
87    pub fn exclude_sensors(mut self) -> Self {
88        self.flags |= QueryFilterFlags::EXCLUDE_SENSORS;
89        self
90    }
91
92    /// Exclude from the query any collider that is not a sensor.
93    pub fn exclude_solids(mut self) -> Self {
94        self.flags |= QueryFilterFlags::EXCLUDE_SOLIDS;
95        self
96    }
97
98    /// Only colliders with collision groups compatible with this one will
99    /// be included in the scene query.
100    ///
101    /// The [`CollisionGroups::test_mode`] of both groups is taken into account.
102    pub fn groups(mut self, groups: CollisionGroups) -> Self {
103        self.groups = Some(groups);
104        self
105    }
106
107    /// Set the collider that will be excluded from the scene query.
108    pub fn exclude_collider(mut self, collider: Entity) -> Self {
109        self.exclude_collider = Some(collider);
110        self
111    }
112
113    /// Set the rigid-body that will be excluded from the scene query.
114    pub fn exclude_rigid_body(mut self, rigid_body: Entity) -> Self {
115        self.exclude_rigid_body = Some(rigid_body);
116        self
117    }
118
119    /// Set the predicate to apply a custom collider filtering during the scene query.
120    ///
121    /// The predicate is given the collider’s entity and its Rapier collider.
122    pub fn predicate(mut self, predicate: &'a impl Fn(Entity, &RapierCollider) -> bool) -> Self {
123        self.predicate = Some(predicate);
124        self
125    }
126}