parry3d/query/ray/
ray_composite_shape.rs1use crate::math::Real;
2use crate::partitioning::BvhNode;
3use crate::query::{Ray, RayCast, RayIntersection};
4use crate::shape::{CompositeShapeRef, Compound, Polyline, TypedCompositeShape};
5
6impl<S: TypedCompositeShape> CompositeShapeRef<'_, S> {
7 #[inline]
20 pub fn cast_local_ray(
21 &self,
22 ray: &Ray,
23 max_time_of_impact: Real,
24 solid: bool,
25 ) -> Option<(u32, Real)> {
26 let hit = self
27 .0
28 .bvh()
29 .cast_ray(ray, max_time_of_impact, |primitive, best_so_far| {
30 self.0.map_typed_part_at(primitive, |pose, part, _| {
31 if let Some(pose) = pose {
32 part.cast_ray(pose, ray, best_so_far, solid)
33 } else {
34 part.cast_local_ray(ray, best_so_far, solid)
35 }
36 })?
37 })?;
38 (hit.1 < max_time_of_impact).then_some(hit)
39 }
40
41 #[inline]
43 pub fn cast_local_ray_and_get_normal(
44 &self,
45 ray: &Ray,
46 max_time_of_impact: Real,
47 solid: bool,
48 ) -> Option<(u32, RayIntersection)> {
49 self.0.bvh().find_best(
50 max_time_of_impact,
51 |node: &BvhNode, best_so_far| node.cast_ray(ray, best_so_far),
52 |primitive, best_so_far| {
53 self.0.map_typed_part_at(primitive, |pose, part, _| {
54 if let Some(pose) = pose {
55 part.cast_ray_and_get_normal(pose, ray, best_so_far, solid)
56 } else {
57 part.cast_local_ray_and_get_normal(ray, best_so_far, solid)
58 }
59 })?
60 },
61 )
62 }
63}
64
65impl RayCast for Polyline {
66 #[inline]
67 fn cast_local_ray(&self, ray: &Ray, max_time_of_impact: Real, solid: bool) -> Option<Real> {
68 CompositeShapeRef(self)
69 .cast_local_ray(ray, max_time_of_impact, solid)
70 .map(|hit| hit.1)
71 }
72
73 #[inline]
74 fn cast_local_ray_and_get_normal(
75 &self,
76 ray: &Ray,
77 max_time_of_impact: Real,
78 solid: bool,
79 ) -> Option<RayIntersection> {
80 CompositeShapeRef(self)
81 .cast_local_ray_and_get_normal(ray, max_time_of_impact, solid)
82 .map(|hit| hit.1)
83 }
84}
85
86impl RayCast for Compound {
87 #[inline]
88 fn cast_local_ray(&self, ray: &Ray, max_time_of_impact: Real, solid: bool) -> Option<Real> {
89 CompositeShapeRef(self)
90 .cast_local_ray(ray, max_time_of_impact, solid)
91 .map(|hit| hit.1)
92 }
93
94 #[inline]
95 fn cast_local_ray_and_get_normal(
96 &self,
97 ray: &Ray,
98 max_time_of_impact: Real,
99 solid: bool,
100 ) -> Option<RayIntersection> {
101 CompositeShapeRef(self)
102 .cast_local_ray_and_get_normal(ray, max_time_of_impact, solid)
103 .map(|hit| hit.1)
104 }
105}