parry3d/query/shape_cast/
shape_cast_composite_shape_shape.rs1use crate::bounding_volume::Aabb;
2use crate::math::{Isometry, Point, Real, Vector};
3use crate::partitioning::BvhNode;
4use crate::query::shape_cast::ShapeCastOptions;
5use crate::query::{QueryDispatcher, Ray, RayCast, ShapeCastHit};
6use crate::shape::{CompositeShapeRef, Shape, TypedCompositeShape};
7
8impl<S: ?Sized + TypedCompositeShape> CompositeShapeRef<'_, S> {
9 pub fn cast_shape<D: ?Sized + QueryDispatcher>(
15 &self,
16 dispatcher: &D,
17 pose12: &Isometry<Real>,
18 vel12: &Vector<Real>,
19 g2: &dyn Shape,
20 options: ShapeCastOptions,
21 ) -> Option<(u32, ShapeCastHit)> {
22 let ls_aabb2 = g2.compute_aabb(pose12);
23 let ray = Ray::new(Point::origin(), *vel12);
24 let msum_shift = -ls_aabb2.center().coords;
25 let msum_margin = ls_aabb2.half_extents() + Vector::repeat(options.target_distance);
26
27 self.0.bvh().find_best(
28 options.max_time_of_impact,
29 |node: &BvhNode, best_so_far| {
30 let msum = Aabb {
32 mins: node.mins() + msum_shift - msum_margin,
33 maxs: node.maxs() + msum_shift + msum_margin,
34 };
35
36 msum.cast_local_ray(&ray, best_so_far, true)
38 .unwrap_or(Real::MAX)
39 },
40 |part_id, _| {
41 self.0
42 .map_untyped_part_at(part_id, |part_pose1, part_g1, _| {
43 if let Some(part_pose1) = part_pose1 {
44 dispatcher
45 .cast_shapes(
46 &part_pose1.inv_mul(pose12),
47 &part_pose1.inverse_transform_vector(vel12),
48 part_g1,
49 g2,
50 options,
51 )
52 .ok()?
53 .map(|hit| hit.transform1_by(part_pose1))
54 } else {
55 dispatcher
56 .cast_shapes(pose12, vel12, part_g1, g2, options)
57 .ok()?
58 }
59 })?
60 },
61 )
62 }
63}
64
65pub fn cast_shapes_composite_shape_shape<D, G1>(
67 dispatcher: &D,
68 pos12: &Isometry<Real>,
69 vel12: &Vector<Real>,
70 g1: &G1,
71 g2: &dyn Shape,
72 options: ShapeCastOptions,
73) -> Option<ShapeCastHit>
74where
75 D: ?Sized + QueryDispatcher,
76 G1: ?Sized + TypedCompositeShape,
77{
78 CompositeShapeRef(g1)
79 .cast_shape(dispatcher, pos12, vel12, g2, options)
80 .map(|hit| hit.1)
81}
82
83pub fn cast_shapes_shape_composite_shape<D, G2>(
85 dispatcher: &D,
86 pos12: &Isometry<Real>,
87 vel12: &Vector<Real>,
88 g1: &dyn Shape,
89 g2: &G2,
90 options: ShapeCastOptions,
91) -> Option<ShapeCastHit>
92where
93 D: ?Sized + QueryDispatcher,
94 G2: ?Sized + TypedCompositeShape,
95{
96 cast_shapes_composite_shape_shape(
97 dispatcher,
98 &pos12.inverse(),
99 &-pos12.inverse_transform_vector(vel12),
100 g2,
101 g1,
102 options,
103 )
104 .map(|time_of_impact| time_of_impact.swapped())
105}