1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
use crate;
use crate;
use crateShape;
/// Computes the minimum distance separating two shapes.
///
/// This is one of the most fundamental geometric queries in collision detection.
/// It calculates the shortest distance between any two points on the surfaces of
/// the two shapes.
///
/// # Behavior
///
/// - Returns the **shortest distance** between the two shape surfaces
/// - Returns `0.0` if the shapes are **touching** (surfaces just make contact)
/// - Returns `0.0` if the shapes are **penetrating** (overlapping)
/// - Always returns a **non-negative** value
///
/// # Arguments
///
/// * `pos1` - Position and orientation of the first shape in world space
/// * `g1` - The first shape (can be any shape implementing the `Shape` trait)
/// * `pos2` - Position and orientation of the second shape in world space
/// * `g2` - The second shape (can be any shape implementing the `Shape` trait)
///
/// # Returns
///
/// * `Ok(distance)` - The minimum distance between the shapes
/// * `Err(Unsupported)` - If this shape pair combination is not supported
///
/// # Performance
///
/// Performance varies by shape type:
/// - **Ball-Ball**: Very fast (analytical solution)
/// - **Cuboid-Cuboid**: Fast (SAT-based)
/// - **Convex-Convex**: Moderate (GJK algorithm)
/// - **Concave shapes**: Slower (requires BVH traversal)
///
/// # Example
///
/// ```rust
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::query::distance;
/// use parry3d::shape::Ball;
/// use parry3d::math::Pose;
///
/// // Create two balls
/// let ball1 = Ball::new(1.0);
/// let ball2 = Ball::new(2.0);
///
/// // Position them 10 units apart along the x-axis
/// let pos1 = Pose::translation(0.0, 0.0, 0.0);
/// let pos2 = Pose::translation(10.0, 0.0, 0.0);
///
/// // Compute distance
/// let dist = distance(&pos1, &ball1, &pos2, &ball2).unwrap();
///
/// // Distance = 10.0 (separation) - 1.0 (radius1) - 2.0 (radius2) = 7.0
/// assert_eq!(dist, 7.0);
/// # }
/// ```
///
/// ```rust
/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
/// use parry3d::query::distance;
/// use parry3d::shape::Cuboid;
/// use parry3d::math::{Pose, Vector};
///
/// // Create two boxes
/// let box1 = Cuboid::new(Vector::new(1.0, 1.0, 1.0));
/// let box2 = Cuboid::new(Vector::new(0.5, 0.5, 0.5));
///
/// // Position them so they're touching
/// let pos1 = Pose::translation(0.0, 0.0, 0.0);
/// let pos2 = Pose::translation(1.5, 0.0, 0.0); // Edge to edge
///
/// let dist = distance(&pos1, &box1, &pos2, &box2).unwrap();
///
/// // They're touching, so distance is 0.0
/// assert_eq!(dist, 0.0);
/// # }
/// ```
///
/// # See Also
///
/// - [`closest_points`](crate::query::closest_points()) - For finding the actual closest points
/// - [`contact`](crate::query::contact()) - For penetration depth when overlapping
/// - [`intersection_test`](crate::query::intersection_test()) - For boolean overlap test