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}