1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//! Finds pairs of entities with overlapping [`ColliderAabb`] and creates contacts
//! for the [narrow phase].
//!
//! [narrow phase]: crate::collision::narrow_phase
//!
//! # Overview
//!
//! To speed up collision detection, the broad phase quickly identifies pairs of entities
//! whose [`ColliderAabb`]s overlap. These contacts are then passed to the [narrow phase]
//! for more detailed collision checks.
//!
//! In Avian, the broad phase is implemented with two plugins:
//!
//! - [`BroadPhaseCorePlugin`]: Sets up resources, system sets, and diagnostics required for broad phase collision detection.
//! - [`BvhBroadPhasePlugin`]: Implements a broad phase using a [Bounding Volume Hierarchy (BVH)][BVH] to efficiently find overlapping AABBs.
//!
//! The former is required for all broad phase implementations, while the latter is an optional plugin
//! that can be replaced with another broad phase strategy if desired. See the following section for details.
//!
//! [BVH]: https://en.wikipedia.org/wiki/Bounding_volume_hierarchy
//!
//! # Custom Broad Phase Implementations
//!
//! By default, Avian uses the [`BvhBroadPhasePlugin`] for broad phase collision detection.
//! However, it is possible to replace it with a custom broad phase strategy, such as
//! sweep and prune (SAP) or some kind of spatial grid.
//!
//! For simplicity's sake, we will demonstrate how to create a simple brute-force O(n^2)
//! broad phase plugin that checks all pairs of colliders for AABB overlaps.
//!
//! In short, all we need to do is add a system to [`BroadPhaseSystems::CollectCollisions`]
//! that finds overlapping AABBs and creates contacts for them in the [`ContactGraph`] resource.
//! However, we are responsible for handling any pair filtering that we might need. This includes:
//!
//! - [`CollisionLayers`]
//! - [`CollisionHooks`]
//! - [`JointCollisionDisabled`]
//! - Skip collisions with parent rigid body
//! - Skip non-dynamic vs non-dynamic pairs
//!
//! and so on. We will only implement a subset of these for demonstration purposes,
//! but you can take a look at the source code of the [`BvhBroadPhasePlugin`] for a complete reference.
//!
//! First, we define our brute-force broad phase plugin:
//!
//! ```
//! use bevy::prelude::*;
//!
//! pub struct BruteForceBroadPhasePlugin;
//!
//! impl Plugin for BruteForceBroadPhasePlugin {
//! fn build(&self, app: &mut App) {
//! app.add_systems(
//! PhysicsSchedule,
//! collect_collision_pairs.in_set(BroadPhaseSystems::CollectCollisions),
//! );
//! }
//! }
//!
//! # fn collect_collision_pairs() {}
//! ```
//!
//! In `collect_collision_pairs`, we query all combinations of colliders,
//! check for AABB overlaps, and create contacts for overlapping colliders:
//!
//! ```
//! # use bevy::prelude::*;
//! #
//! fn collect_collision_pairs(
//! colliders: Query<(Entity, &ColliderAabb, &CollisionLayers, &ColliderOf)>,
//! bodies: Query<&RigidBody>,
//! mut contact_graph: ResMut<ContactGraph>,
//! joint_graph: Res<JointGraph>,
//! ) {
//! // Loop through all entity combinations and create contact pairs for overlapping AABBs.
//! for [
//! (collider1, aabb1, layers1, collider_of1),
//! (collider2, aabb2, layers2, collider_of2),
//! ] in colliders.iter_combinations()
//! {
//! // Get the rigid bodies of the colliders.
//! let Ok(rb1) = bodies.get(collider_of1.body) else {
//! continue;
//! };
//! let Ok(rb2) = bodies.get(collider_of2.body) else {
//! continue;
//! };
//!
//! // Skip pairs where both bodies are non-dynamic.
//! if !rb1.is_dynamic() && !rb2.is_dynamic() {
//! continue;
//! }
//!
//! // Check if the AABBs intersect.
//! if !aabb1.intersects(aabb2) {
//! continue;
//! }
//!
//! // Check collision layers.
//! if !layers1.interacts_with(*layers2) {
//! continue;
//! }
//!
//! // Check if a joint disables contacts between the two bodies.
//! if joint_graph
//! .joints_between(collider_of1.body, collider_of2.body)
//! .any(|edge| edge.collision_disabled)
//! {
//! continue;
//! }
//!
//! // Create a contact in the contact graph.
//! let mut contact_edge = ContactEdge::new(collider1, collider2);
//! contact_edge.body1 = Some(collider_of1.body);
//! contact_edge.body2 = Some(collider_of2.body);
//! contact_graph.add_edge(contact_edge);
//! }
//! }
//! ```
//!
//! Now, we can simply replace the [`BvhBroadPhasePlugin`] with our custom
//! `BruteForceBroadPhasePlugin` when building the app:
//!
//! ```
//! # use bevy::prelude::*;
//! #
//! # fn main() {
//! # let mut app = App::new();
//! #
//! app.add_plugins(
//! PhysicsPlugins::default()
//! .build()
//! .disable::<BvhBroadPhasePlugin>()
//! .add(BruteForceBroadPhasePlugin)
//! );
//! # }
//! #
//! # struct BruteForceBroadPhasePlugin;
//! # impl Plugin for BruteForceBroadPhasePlugin {
//! # fn build(&self, app: &mut App) {}
//! # }
//! ```
pub use BvhBroadPhasePlugin;
use crate::;
use *;
/// The core [broad phase](crate::collision::broad_phase) plugin that sets up the
/// resources, system sets, and diagnostics required for broad phase collision detection.
///
/// This does *not* implement any specific broad phase algorithm by itself,
/// but provides the foundation for other broad phase plugins to build upon.
/// By default, the [`BvhBroadPhasePlugin`] is used, but it can be replaced
/// with a custom strategy if desired.
///
/// See the [module-level documentation](crate::collision::broad_phase) for more information
/// and an example of creating a custom broad phase plugin.
;
/// System sets for systems running in [`PhysicsStepSystems::BroadPhase`].