use na::Identity; use math::{Point, Vector}; use entities::partitioning::{BVTCostFn, BVTVisitor}; use ray::{RayCast, Ray, RayIntersection}; /// A search thet selects the objects that has the smallest time of impact with a given ray. pub struct RayIntersectionCostFn<'a, P: 'a + Point> { ray: &'a Ray

, solid: bool, uvs: bool } impl<'a, P: Point> RayIntersectionCostFn<'a, P> { /// Creates a new `BestRayInterferenceSearch`. pub fn new(ray: &'a Ray

, solid: bool, uvs: bool) -> RayIntersectionCostFn<'a, P> { RayIntersectionCostFn { ray: ray, solid: solid, uvs: uvs } } } impl<'a, P, B, BV> BVTCostFn<::Scalar, B, BV> for RayIntersectionCostFn<'a, P> where P: Point, B: RayCast, BV: RayCast { type UserData = RayIntersection; #[inline] fn compute_bv_cost(&mut self, bv: &BV) -> Option<::Scalar> { bv.toi_with_ray(&Identity::new(), self.ray, true) } #[inline] fn compute_b_cost(&mut self, b: &B) -> Option<(::Scalar, RayIntersection)> { if self.uvs { b.toi_and_normal_and_uv_with_ray(&Identity::new(), self.ray, self.solid).map(|i| (i.toi, i)) } else { b.toi_and_normal_with_ray(&Identity::new(), self.ray, self.solid).map(|i| (i.toi, i)) } } } /// Bounding Volume Tree visitor collecting interferences with a given ray. pub struct RayInterferencesCollector<'a, P: 'a + Point, B: 'a> { ray: &'a Ray

, collector: &'a mut Vec } impl<'a, P: Point, B> RayInterferencesCollector<'a, P, B> { /// Creates a new `RayInterferencesCollector`. #[inline] pub fn new(ray: &'a Ray

, buffer: &'a mut Vec) -> RayInterferencesCollector<'a, P, B> { RayInterferencesCollector { ray: ray, collector: buffer } } } impl<'a, P, B, BV> BVTVisitor for RayInterferencesCollector<'a, P, B> where P: Point, B: Clone, BV: RayCast { #[inline] fn visit_internal(&mut self, bv: &BV) -> bool { bv.intersects_ray(&Identity::new(), self.ray) } #[inline] fn visit_leaf(&mut self, b: &B, bv: &BV) { if bv.intersects_ray(&Identity::new(), self.ray) { self.collector.push(b.clone()) } } }