use alloc::{boxed::Box, vec::Vec};
use core::fmt;
use nalgebra::{
ClosedAddAssign, ClosedDivAssign, ClosedMulAssign, ClosedSubAssign, Point, Scalar,
SimdPartialOrd,
};
use num_traits::{Float, FromPrimitive, Signed};
use crate::aabb::{Bounded, IntersectsAabb};
use crate::bvh::BvhNodeBuildArgs;
#[cfg(feature = "rayon")]
use crate::bvh::rayon_executor;
use crate::point_query::PointDistance;
pub trait BHValue:
Scalar
+ Copy
+ FromPrimitive
+ ClosedSubAssign
+ ClosedAddAssign
+ SimdPartialOrd
+ ClosedMulAssign
+ ClosedDivAssign
+ Float
+ Signed
+ fmt::Display
{
}
impl<T> BHValue for T where
T: Scalar
+ Copy
+ FromPrimitive
+ ClosedSubAssign
+ ClosedAddAssign
+ SimdPartialOrd
+ ClosedMulAssign
+ ClosedDivAssign
+ Float
+ Signed
+ fmt::Display
{
}
pub trait BHShape<T: BHValue, const D: usize>: Bounded<T, D> {
fn set_bh_node_index(&mut self, _: usize);
fn bh_node_index(&self) -> usize;
}
impl<T: BHValue, const D: usize, S: BHShape<T, D>> BHShape<T, D> for &mut S {
fn set_bh_node_index(&mut self, idx: usize) {
S::set_bh_node_index(self, idx)
}
fn bh_node_index(&self) -> usize {
S::bh_node_index(self)
}
}
impl<T: BHValue, const D: usize, S: BHShape<T, D>> BHShape<T, D> for Box<S> {
fn set_bh_node_index(&mut self, idx: usize) {
S::set_bh_node_index(self, idx)
}
fn bh_node_index(&self) -> usize {
S::bh_node_index(self)
}
}
pub trait BoundingHierarchy<T: BHValue, const D: usize> {
fn build<Shape: BHShape<T, D>>(shapes: &mut [Shape]) -> Self;
fn build_with_executor<
Shape: BHShape<T, D>,
Executor: FnMut(BvhNodeBuildArgs<'_, Shape, T, D>, BvhNodeBuildArgs<'_, Shape, T, D>),
>(
shapes: &mut [Shape],
executor: Executor,
) -> Self;
#[cfg(feature = "rayon")]
fn build_par<Shape: BHShape<T, D> + Send>(shapes: &mut [Shape]) -> Self
where
T: Send,
Self: Sized,
{
Self::build_with_executor(shapes, rayon_executor)
}
fn traverse<'a, Query: IntersectsAabb<T, D>, Shape: BHShape<T, D>>(
&'a self,
query: &Query,
shapes: &'a [Shape],
) -> Vec<&'a Shape>;
fn nearest_to<'a, Shape: BHShape<T, D> + PointDistance<T, D>>(
&'a self,
query: Point<T, D>,
shapes: &'a [Shape],
) -> Option<(&'a Shape, T)>;
fn pretty_print(&self) {}
}
impl<T: BHValue, const D: usize, H: BoundingHierarchy<T, D>> BoundingHierarchy<T, D> for Box<H> {
fn build<Shape: BHShape<T, D>>(shapes: &mut [Shape]) -> Self {
Box::new(H::build(shapes))
}
fn traverse<'a, Query: IntersectsAabb<T, D>, Shape: BHShape<T, D>>(
&'a self,
query: &Query,
shapes: &'a [Shape],
) -> Vec<&'a Shape> {
H::traverse(self, query, shapes)
}
fn nearest_to<'a, Shape: BHShape<T, D> + PointDistance<T, D>>(
&'a self,
query: Point<T, D>,
shapes: &'a [Shape],
) -> Option<(&'a Shape, T)> {
H::nearest_to(self, query, shapes)
}
fn build_with_executor<
Shape: BHShape<T, D>,
Executor: FnMut(BvhNodeBuildArgs<'_, Shape, T, D>, BvhNodeBuildArgs<'_, Shape, T, D>),
>(
shapes: &mut [Shape],
executor: Executor,
) -> Self {
Box::new(H::build_with_executor(shapes, executor))
}
}