use crate::math::Pose;
use crate::partitioning::Bvh;
use crate::query::details::NormalConstraints;
use crate::shape::Shape;
#[cfg(feature = "alloc")]
pub trait CompositeShape {
fn map_part_at(
&self,
shape_id: u32,
f: &mut dyn FnMut(Option<&Pose>, &dyn Shape, Option<&dyn NormalConstraints>),
);
fn bvh(&self) -> &Bvh;
fn is_deformable(&self) -> bool {
false
}
}
#[cfg(feature = "alloc")]
pub trait TypedCompositeShape: CompositeShape {
type PartShape: ?Sized + Shape;
type PartNormalConstraints: ?Sized + NormalConstraints;
fn map_typed_part_at<T>(
&self,
shape_id: u32,
f: impl FnMut(Option<&Pose>, &Self::PartShape, Option<&Self::PartNormalConstraints>) -> T,
) -> Option<T>;
fn map_untyped_part_at<T>(
&self,
shape_id: u32,
f: impl FnMut(Option<&Pose>, &dyn Shape, Option<&dyn NormalConstraints>) -> T,
) -> Option<T>;
}
macro_rules! impl_typed_composite_shape_for_dyn {
($($object:tt)+) => {
#[cfg(feature = "alloc")]
impl TypedCompositeShape for $($object)+ {
type PartShape = dyn Shape;
type PartNormalConstraints = dyn NormalConstraints;
fn map_typed_part_at<T>(
&self,
shape_id: u32,
mut f: impl FnMut(
Option<&Pose>,
&Self::PartShape,
Option<&Self::PartNormalConstraints>,
) -> T,
) -> Option<T> {
let mut result = None;
self.map_part_at(shape_id, &mut |pose, part, normals| {
result = Some(f(pose, part, normals));
});
result
}
fn map_untyped_part_at<T>(
&self,
shape_id: u32,
mut f: impl FnMut(Option<&Pose>, &dyn Shape, Option<&dyn NormalConstraints>) -> T,
) -> Option<T> {
let mut result = None;
self.map_part_at(shape_id, &mut |pose, part, normals| {
result = Some(f(pose, part, normals));
});
result
}
}
};
}
impl_typed_composite_shape_for_dyn!(dyn CompositeShape + '_);
impl_typed_composite_shape_for_dyn!(dyn CompositeShape + Sync + '_);
pub struct CompositeShapeRef<'a, S: ?Sized>(pub &'a S);