use std::ops::Mul; use na; use math::{Point, Isometry}; use partitioning::BVT; use bounding_volume::AABB; use shape::{Compound, TriMesh, Polyline}; use inspection::Repr; /// Trait implemented by shapes composed of multiple simpler shapes. /// /// A composite shape is composed of several shapes. Typically, it is a convex decomposition of /// a concave shape. pub trait CompositeShape { /// The number of parts on this composite shapes. fn len(&self) -> usize; /// Applies a function to each sub-shape of this concave shape. fn map_part_at(&self, usize, &mut FnMut(&M, &Repr)); /// Applies a transformation matrix and a function to each sub-shape of this concave /// shape. fn map_transformed_part_at(&self, usize, m: &M, &mut FnMut(&M, &Repr)); // FIXME: the following two methods really are not generic enough. /// Gets the AABB of the shape identified by the index `i`. fn aabb_at(&self, i: usize) -> &AABB

; /// Gets the acceleration structure of the concave shape. fn bvt(&self) -> &BVT>; } impl CompositeShape for Compound where P: Point, M: Copy + Mul { #[inline] fn len(&self) -> usize { self.shapes().len() } #[inline(always)] fn map_part_at(&self, i: usize, f: &mut FnMut(&M, &Repr)) { let &(ref m, ref g) = &self.shapes()[i]; f(m, g.as_ref()) } #[inline(always)] fn map_transformed_part_at(&self, i: usize, m: &M, f: &mut FnMut(&M, &Repr)) { let elt = &self.shapes()[i]; f(&(*m * elt.0), elt.1.as_ref()) } #[inline] fn aabb_at(&self, i: usize) -> &AABB

{ &self.bounding_volumes()[i] } #[inline] fn bvt(&self) -> &BVT> { self.bvt() } } impl CompositeShape for TriMesh

where P: Point, M: Isometry { #[inline] fn len(&self) -> usize { self.base_mesh().len() } #[inline(always)] fn map_part_at(&self, i: usize, f: &mut FnMut(&M, &Repr)) { let one: M = na::one(); self.map_transformed_part_at(i, &one, f) } #[inline(always)] fn map_transformed_part_at(&self, i: usize, m: &M, f: &mut FnMut(&M, &Repr)) { let element = self.triangle_at(i); f(m, &element) } #[inline] fn aabb_at(&self, i: usize) -> &AABB

{ &self.bounding_volumes()[i] } #[inline] fn bvt(&self) -> &BVT> { self.bvt() } } impl CompositeShape for Polyline

where P: Point, M: Isometry { #[inline] fn len(&self) -> usize { self.base_mesh().len() } #[inline(always)] fn map_part_at(&self, i: usize, f: &mut FnMut(&M, &Repr)) { let one: M = na::one(); self.map_transformed_part_at(i, &one, f) } #[inline(always)] fn map_transformed_part_at(&self, i: usize, m: &M, f: &mut FnMut(&M, &Repr)) { let element = self.segment_at(i); f(m, &element) } #[inline] fn aabb_at(&self, i: usize) -> &AABB

{ &self.bounding_volumes()[i] } #[inline] fn bvt(&self) -> &BVT> { self.bvt() } }