parry3d/query/shape_cast/
shape_cast_halfspace_support_map.rs1use crate::math::{Isometry, Real, Vector};
2use crate::query::details::ShapeCastOptions;
3use crate::query::{Ray, RayCast, ShapeCastHit, ShapeCastStatus};
4use crate::shape::{HalfSpace, RoundShapeRef, SupportMap};
5
6pub fn cast_shapes_halfspace_support_map<G: ?Sized + SupportMap>(
8 pos12: &Isometry<Real>,
9 vel12: &Vector<Real>,
10 halfspace: &HalfSpace,
11 other: &G,
12 options: ShapeCastOptions,
13) -> Option<ShapeCastHit> {
14 if !options.stop_at_penetration && vel12.dot(&halfspace.normal) > 0.0 {
17 return None;
18 }
19
20 let support_point = if options.target_distance > 0.0 {
21 let round_other = RoundShapeRef {
22 inner_shape: other,
23 border_radius: options.target_distance,
24 };
25 round_other.support_point(pos12, &-halfspace.normal)
26 } else {
27 other.support_point(pos12, &-halfspace.normal)
28 };
29 let closest_point = support_point;
30 let ray = Ray::new(closest_point, *vel12);
31
32 if let Some(time_of_impact) = halfspace.cast_local_ray(&ray, options.max_time_of_impact, true) {
33 if time_of_impact > options.max_time_of_impact {
34 return None;
35 }
36
37 let witness2 = support_point + *halfspace.normal * options.target_distance;
38 let mut witness1 = ray.point_at(time_of_impact);
39 witness1 -= *halfspace.normal * witness1.coords.dot(&halfspace.normal);
42
43 let status = if support_point.coords.dot(&halfspace.normal) < 0.0 {
44 ShapeCastStatus::PenetratingOrWithinTargetDist
45 } else {
46 ShapeCastStatus::Converged
47 };
48
49 Some(ShapeCastHit {
50 time_of_impact,
51 normal1: halfspace.normal,
52 normal2: pos12.inverse_transform_unit_vector(&-halfspace.normal),
53 witness1,
54 witness2: pos12.inverse_transform_point(&witness2),
55 status,
56 })
57 } else {
58 None
59 }
60}
61
62pub fn cast_shapes_support_map_halfspace<G: ?Sized + SupportMap>(
64 pos12: &Isometry<Real>,
65 vel12: &Vector<Real>,
66 other: &G,
67 halfspace: &HalfSpace,
68 options: ShapeCastOptions,
69) -> Option<ShapeCastHit> {
70 cast_shapes_halfspace_support_map(
71 &pos12.inverse(),
72 &-pos12.inverse_transform_vector(vel12),
73 halfspace,
74 other,
75 options,
76 )
77 .map(|hit| hit.swapped())
78}