use crate::bounding_hierarchy::{BHShape, BHValue};
use crate::bvh::ShapeIndex;
use crate::{aabb::Aabb, bvh::Shapes};
use nalgebra::Scalar;
use num_traits::Float;
#[inline(always)]
#[allow(dead_code)]
pub fn fast_min<T: Scalar + Copy + PartialOrd>(x: T, y: T) -> T {
if x < y { x } else { y }
}
#[inline(always)]
#[allow(dead_code)]
pub fn fast_max<T: Scalar + Copy + PartialOrd>(x: T, y: T) -> T {
if x > y { x } else { y }
}
#[derive(Clone, Copy)]
pub struct Bucket<T: BHValue, const D: usize> {
pub size: usize,
pub aabb: Aabb<T, D>,
pub centroid: Aabb<T, D>,
}
impl<T: BHValue, const D: usize> Bucket<T, D> {
pub fn empty() -> Bucket<T, D> {
Bucket {
size: 0,
aabb: Aabb::empty(),
centroid: Aabb::empty(),
}
}
pub fn add_aabb(&mut self, aabb: &Aabb<T, D>) {
self.size += 1;
self.aabb = self.aabb.join(aabb);
self.centroid.grow_mut(&aabb.center());
}
pub fn join_bucket(a: Bucket<T, D>, b: &Bucket<T, D>) -> Bucket<T, D> {
Bucket {
size: a.size + b.size,
aabb: a.aabb.join(&b.aabb),
centroid: a.centroid.join(&b.centroid),
}
}
}
pub(crate) fn joint_aabb_of_shapes<T: BHValue, const D: usize, Shape: BHShape<T, D>>(
indices: &[ShapeIndex],
shapes: &Shapes<Shape>,
) -> (Aabb<T, D>, Aabb<T, D>) {
let mut aabb = Aabb::empty();
let mut centroid = Aabb::empty();
for index in indices {
let shape = shapes.get(*index);
aabb.join_mut(&shape.aabb());
centroid.grow_mut(&shape.aabb().center());
}
(aabb, centroid)
}
#[inline(always)]
pub(crate) fn has_nan<'a, T: Float + 'a>(iter: impl IntoIterator<Item = &'a T>) -> bool {
iter.into_iter().any(|f| f.is_nan())
}