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, SubShapeId, 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<(SubShapeId, 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]
47 pub fn cast_local_ray_and_get_normal(
48 &self,
49 ray: &Ray,
50 max_time_of_impact: Real,
51 solid: bool,
52 ) -> Option<(SubShapeId, RayIntersection)> {
53 self.0.bvh().find_best(
54 max_time_of_impact,
55 |node: &BvhNode, best_so_far| node.cast_ray(ray, best_so_far),
56 |primitive, best_so_far| {
57 self.0.map_typed_part_at(primitive, |pose, part, _| {
58 if let Some(pose) = pose {
59 part.cast_ray_and_get_normal(pose, ray, best_so_far, solid)
60 } else {
61 part.cast_local_ray_and_get_normal(ray, best_so_far, solid)
62 }
63 })?
64 },
65 )
66 }
67}
68
69impl RayCast for Polyline {
70 #[inline]
71 fn cast_local_ray(&self, ray: &Ray, max_time_of_impact: Real, solid: bool) -> Option<Real> {
72 CompositeShapeRef(self)
73 .cast_local_ray(ray, max_time_of_impact, solid)
74 .map(|hit| hit.1)
75 }
76
77 #[inline]
78 fn cast_local_ray_and_get_normal(
79 &self,
80 ray: &Ray,
81 max_time_of_impact: Real,
82 solid: bool,
83 ) -> Option<RayIntersection> {
84 CompositeShapeRef(self)
85 .cast_local_ray_and_get_normal(ray, max_time_of_impact, solid)
86 .map(|(segment_id, hit)| hit.with_subshape(segment_id))
87 }
88}
89
90impl RayCast for Compound {
91 #[inline]
92 fn cast_local_ray(&self, ray: &Ray, max_time_of_impact: Real, solid: bool) -> Option<Real> {
93 CompositeShapeRef(self)
94 .cast_local_ray(ray, max_time_of_impact, solid)
95 .map(|hit| hit.1)
96 }
97
98 #[inline]
99 fn cast_local_ray_and_get_normal(
100 &self,
101 ray: &Ray,
102 max_time_of_impact: Real,
103 solid: bool,
104 ) -> Option<RayIntersection> {
105 CompositeShapeRef(self)
106 .cast_local_ray_and_get_normal(ray, max_time_of_impact, solid)
107 .map(|(part_id, hit)| hit.with_subshape(part_id))
108 }
109}