use na::Translate;
use na;
use bounding_volume::{self, AABB, BoundingVolume};
use partitioning::BVT;
use math::{Point, Isometry};
use shape::ShapeHandle;
pub struct Compound<P: Point, M> {
shapes: Vec<(M, ShapeHandle<P, M>)>,
bvt: BVT<usize, AABB<P>>,
bvs: Vec<AABB<P>>
}
impl<P: Point, M: Clone> Clone for Compound<P, M> {
fn clone(&self) -> Compound<P, M> {
Compound {
shapes: self.shapes.clone(),
bvt: self.bvt.clone(),
bvs: self.bvs.clone()
}
}
}
impl<P, M> Compound<P, M>
where P: Point,
P::Vect: Translate<P>,
M: Isometry<P, P::Vect> {
pub fn new(shapes: Vec<(M, ShapeHandle<P, M>)>) -> Compound<P, M> {
let mut bvs = Vec::new();
let mut leaves = Vec::new();
for (i, &(ref delta, ref shape)) in shapes.iter().enumerate() {
let bv = bounding_volume::aabb(shape.as_ref(), delta).loosened(na::cast(0.04f64));
bvs.push(bv.clone());
leaves.push((i, bv));
}
let bvt = BVT::new_balanced(leaves);
Compound {
shapes: shapes,
bvt: bvt,
bvs: bvs
}
}
}
impl<P: Point, M> Compound<P, M> {
#[inline]
pub fn shapes(&self) -> &[(M, ShapeHandle<P, M>)] {
&self.shapes[..]
}
#[inline]
pub fn bvt(&self) -> &BVT<usize, AABB<P>> {
&self.bvt
}
#[inline]
pub fn bounding_volumes(&self) -> &[AABB<P>] {
&self.bvs[..]
}
#[inline]
pub fn aabb_at(&self, i: usize) -> &AABB<P> {
&self.bvs[i]
}
}