avian3d/collider_tree/
mod.rs1mod diagnostics;
25mod obvhs_ext;
26mod optimization;
27mod proxy_key;
28mod traverse;
29mod tree;
30mod update;
31
32pub use diagnostics::ColliderTreeDiagnostics;
33pub use obvhs_ext::Bvh2Ext;
34pub(crate) use obvhs_ext::obvhs_ray;
35pub use optimization::{ColliderTreeOptimization, TreeOptimizationMode};
36pub use proxy_key::{ColliderTreeProxyKey, ColliderTreeType, ProxyId};
37pub use tree::{ColliderTree, ColliderTreeProxy, ColliderTreeProxyFlags, ColliderTreeWorkspace};
38pub use update::{MovedProxies, update_moved_collider_aabbs};
39
40use optimization::ColliderTreeOptimizationPlugin;
41use update::ColliderTreeUpdatePlugin;
42
43use core::marker::PhantomData;
44
45use crate::prelude::*;
46use bevy::prelude::*;
47
48pub struct ColliderTreePlugin<C: AnyCollider>(PhantomData<C>);
50
51impl<C: AnyCollider> Default for ColliderTreePlugin<C> {
52 fn default() -> Self {
53 Self(PhantomData)
54 }
55}
56
57impl<C: AnyCollider> Plugin for ColliderTreePlugin<C> {
58 fn build(&self, app: &mut App) {
59 let _ = app.try_register_required_components_with::<C, ColliderTreeProxyKey>(|| {
61 ColliderTreeProxyKey::PLACEHOLDER
63 });
64
65 app.add_plugins(ColliderTreeUpdatePlugin::<C>::default());
67
68 if !app.is_plugin_added::<ColliderTreeOptimizationPlugin>() {
70 app.add_plugins(ColliderTreeOptimizationPlugin);
71 }
72
73 app.init_resource::<ColliderTrees>()
75 .init_resource::<MovedProxies>();
76
77 app.configure_sets(
79 PhysicsSchedule,
80 ColliderTreeSystems::UpdateAabbs
81 .in_set(PhysicsStepSystems::BroadPhase)
82 .after(BroadPhaseSystems::First)
83 .before(BroadPhaseSystems::CollectCollisions),
84 );
85 app.configure_sets(
86 PhysicsSchedule,
87 ColliderTreeSystems::BeginOptimize.in_set(BroadPhaseSystems::Last),
88 );
89 app.configure_sets(
90 PhysicsSchedule,
91 ColliderTreeSystems::EndOptimize.in_set(PhysicsStepSystems::Finalize),
92 );
93 }
94
95 fn finish(&self, app: &mut App) {
96 app.register_physics_diagnostics::<ColliderTreeDiagnostics>();
98 }
99}
100
101#[derive(SystemSet, Clone, Copy, Debug, PartialEq, Eq, Hash)]
103pub enum ColliderTreeSystems {
104 UpdateAabbs,
106 BeginOptimize,
110 EndOptimize,
114}
115
116#[derive(Resource, Default)]
120pub struct ColliderTrees {
121 pub dynamic_tree: ColliderTree,
123 pub kinematic_tree: ColliderTree,
125 pub static_tree: ColliderTree,
127 pub standalone_tree: ColliderTree,
129}
130
131impl ColliderTrees {
132 #[inline]
134 pub const fn tree_for_type(&self, tree_type: ColliderTreeType) -> &ColliderTree {
135 match tree_type {
136 ColliderTreeType::Dynamic => &self.dynamic_tree,
137 ColliderTreeType::Kinematic => &self.kinematic_tree,
138 ColliderTreeType::Static => &self.static_tree,
139 ColliderTreeType::Standalone => &self.standalone_tree,
140 }
141 }
142
143 #[inline]
145 pub const fn tree_for_type_mut(&mut self, tree_type: ColliderTreeType) -> &mut ColliderTree {
146 match tree_type {
147 ColliderTreeType::Dynamic => &mut self.dynamic_tree,
148 ColliderTreeType::Kinematic => &mut self.kinematic_tree,
149 ColliderTreeType::Static => &mut self.static_tree,
150 ColliderTreeType::Standalone => &mut self.standalone_tree,
151 }
152 }
153
154 #[inline]
156 pub fn iter_trees(&self) -> impl Iterator<Item = &ColliderTree> {
157 [
158 &self.dynamic_tree,
159 &self.kinematic_tree,
160 &self.static_tree,
161 &self.standalone_tree,
162 ]
163 .into_iter()
164 }
165
166 #[inline]
168 pub fn iter_trees_mut(&mut self) -> impl Iterator<Item = &mut ColliderTree> {
169 [
170 &mut self.dynamic_tree,
171 &mut self.kinematic_tree,
172 &mut self.static_tree,
173 &mut self.standalone_tree,
174 ]
175 .into_iter()
176 }
177
178 #[inline]
180 pub fn get_proxy(&self, key: ColliderTreeProxyKey) -> Option<&ColliderTreeProxy> {
181 self.tree_for_type(key.tree_type())
182 .proxies
183 .get(key.id().index())
184 }
185
186 #[inline]
188 pub fn get_proxy_mut(&mut self, key: ColliderTreeProxyKey) -> Option<&mut ColliderTreeProxy> {
189 self.tree_for_type_mut(key.tree_type())
190 .proxies
191 .get_mut(key.id().index())
192 }
193}