parry2d/query/sat/
sat_support_map_support_map.rs

1use crate::math::{Isometry, Real, Vector};
2use crate::shape::SupportMap;
3use na::Unit;
4
5/// Computes the separation distance between two convex shapes along a given direction.
6///
7/// This is the most general SAT separation computation function in Parry. It works with any
8/// two convex shapes that implement the [`SupportMap`] trait, which includes spheres, capsules,
9/// cones, convex polyhedra, and more.
10///
11/// # What is a Support Map?
12///
13/// A support map is a function that, given a direction vector, returns the furthest point on
14/// the shape in that direction. This is a fundamental operation in collision detection algorithms
15/// like GJK, EPA, and SAT.
16///
17/// # How This Function Works
18///
19/// 1. Finds the furthest point on `sm1` in direction `dir1` (the "support point")
20/// 2. Finds the furthest point on `sm2` in direction `-dir1` (opposite direction)
21/// 3. Transforms `sm2`'s support point to `sm1`'s coordinate space
22/// 4. Computes the signed distance between these points along `dir1`
23///
24/// # Parameters
25///
26/// - `sm1`: The first convex shape
27/// - `sm2`: The second convex shape
28/// - `pos12`: The position of `sm2` relative to `sm1`
29/// - `dir1`: The unit direction vector (in `sm1`'s local space) along which to compute separation
30///
31/// # Returns
32///
33/// The separation distance as a `Real`:
34/// - **Positive**: The shapes are separated by at least this distance along `dir1`
35/// - **Negative**: The shapes are overlapping (the absolute value is the penetration depth)
36/// - **Zero**: The shapes are exactly touching along this axis
37///
38/// # Example
39///
40/// ```rust
41/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
42/// use parry3d::shape::{Ball, Cuboid};
43/// use parry3d::query::sat::support_map_support_map_compute_separation;
44/// use nalgebra::{Isometry3, Vector3, Unit};
45///
46/// let sphere = Ball::new(1.0);
47/// let cube = Cuboid::new(Vector3::new(1.0, 1.0, 1.0));
48///
49/// // Position cube to the right of the sphere
50/// let pos12 = Isometry3::translation(3.0, 0.0, 0.0);
51///
52/// // Test separation along the X axis
53/// let dir = Unit::new_normalize(Vector3::x());
54/// let separation = support_map_support_map_compute_separation(
55///     &sphere,
56///     &cube,
57///     &pos12,
58///     &dir
59/// );
60///
61/// // They should be separated (sphere radius 1.0 + cube extent 1.0 = 2.0, distance 3.0)
62/// assert!(separation > 0.0);
63/// # }
64/// ```
65///
66/// # Use Cases
67///
68/// This function is typically used as a building block in SAT implementations. You would:
69/// 1. Generate candidate separating axes (face normals, edge cross products, etc.)
70/// 2. Call this function for each candidate axis
71/// 3. Track the axis with maximum separation
72/// 4. If the maximum separation is positive, the shapes don't collide
73///
74/// # Performance Note
75///
76/// This function is generic and works with any support map shapes, but specialized implementations
77/// (like [`cuboid_cuboid_find_local_separating_normal_oneway`](super::cuboid_cuboid_find_local_separating_normal_oneway))
78/// may be more efficient for specific shape pairs.
79#[allow(dead_code)]
80pub fn support_map_support_map_compute_separation(
81    sm1: &impl SupportMap,
82    sm2: &impl SupportMap,
83    pos12: &Isometry<Real>,
84    dir1: &Unit<Vector<Real>>,
85) -> Real {
86    let p1 = sm1.local_support_point_toward(dir1);
87    let p2 = sm2.support_point_toward(pos12, &-*dir1);
88    (p2 - p1).dot(dir1)
89}