mod diagnostics;
mod obvhs_ext;
mod optimization;
mod proxy_key;
mod traverse;
mod tree;
mod update;
pub use diagnostics::ColliderTreeDiagnostics;
pub use obvhs_ext::Bvh2Ext;
pub(crate) use obvhs_ext::obvhs_ray;
pub use optimization::{ColliderTreeOptimization, TreeOptimizationMode};
pub use proxy_key::{ColliderTreeProxyKey, ColliderTreeType, ProxyId};
pub use tree::{ColliderTree, ColliderTreeProxy, ColliderTreeProxyFlags, ColliderTreeWorkspace};
pub use update::{MovedProxies, update_moved_collider_aabbs};
use optimization::ColliderTreeOptimizationPlugin;
use update::ColliderTreeUpdatePlugin;
use core::marker::PhantomData;
use crate::prelude::*;
use bevy::prelude::*;
pub struct ColliderTreePlugin<C: AnyCollider>(PhantomData<C>);
impl<C: AnyCollider> Default for ColliderTreePlugin<C> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<C: AnyCollider> Plugin for ColliderTreePlugin<C> {
fn build(&self, app: &mut App) {
let _ = app.try_register_required_components_with::<C, ColliderTreeProxyKey>(|| {
ColliderTreeProxyKey::PLACEHOLDER
});
app.add_plugins(ColliderTreeUpdatePlugin::<C>::default());
if !app.is_plugin_added::<ColliderTreeOptimizationPlugin>() {
app.add_plugins(ColliderTreeOptimizationPlugin);
}
app.init_resource::<ColliderTrees>()
.init_resource::<MovedProxies>();
app.configure_sets(
PhysicsSchedule,
ColliderTreeSystems::UpdateAabbs
.in_set(PhysicsStepSystems::BroadPhase)
.after(BroadPhaseSystems::First)
.before(BroadPhaseSystems::CollectCollisions),
);
app.configure_sets(
PhysicsSchedule,
ColliderTreeSystems::BeginOptimize.in_set(BroadPhaseSystems::Last),
);
app.configure_sets(
PhysicsSchedule,
ColliderTreeSystems::EndOptimize.in_set(SolverSystems::Finalize),
);
}
fn finish(&self, app: &mut App) {
app.register_physics_diagnostics::<ColliderTreeDiagnostics>();
}
}
#[derive(SystemSet, Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum ColliderTreeSystems {
UpdateAabbs,
BeginOptimize,
EndOptimize,
}
#[derive(Resource, Default)]
pub struct ColliderTrees {
pub dynamic_tree: ColliderTree,
pub kinematic_tree: ColliderTree,
pub static_tree: ColliderTree,
pub standalone_tree: ColliderTree,
}
impl ColliderTrees {
#[inline]
pub const fn tree_for_type(&self, tree_type: ColliderTreeType) -> &ColliderTree {
match tree_type {
ColliderTreeType::Dynamic => &self.dynamic_tree,
ColliderTreeType::Kinematic => &self.kinematic_tree,
ColliderTreeType::Static => &self.static_tree,
ColliderTreeType::Standalone => &self.standalone_tree,
}
}
#[inline]
pub const fn tree_for_type_mut(&mut self, tree_type: ColliderTreeType) -> &mut ColliderTree {
match tree_type {
ColliderTreeType::Dynamic => &mut self.dynamic_tree,
ColliderTreeType::Kinematic => &mut self.kinematic_tree,
ColliderTreeType::Static => &mut self.static_tree,
ColliderTreeType::Standalone => &mut self.standalone_tree,
}
}
#[inline]
pub fn iter_trees(&self) -> impl Iterator<Item = &ColliderTree> {
[
&self.dynamic_tree,
&self.kinematic_tree,
&self.static_tree,
&self.standalone_tree,
]
.into_iter()
}
#[inline]
pub fn iter_trees_mut(&mut self) -> impl Iterator<Item = &mut ColliderTree> {
[
&mut self.dynamic_tree,
&mut self.kinematic_tree,
&mut self.static_tree,
&mut self.standalone_tree,
]
.into_iter()
}
#[inline]
pub fn get_proxy(&self, key: ColliderTreeProxyKey) -> Option<&ColliderTreeProxy> {
self.tree_for_type(key.tree_type())
.proxies
.get(key.id().index())
}
#[inline]
pub fn get_proxy_mut(&mut self, key: ColliderTreeProxyKey) -> Option<&mut ColliderTreeProxy> {
self.tree_for_type_mut(key.tree_type())
.proxies
.get_mut(key.id().index())
}
}