parry2d/query/intersection_test/intersection_test.rs
1use crate::math::{Isometry, Real};
2use crate::query::{DefaultQueryDispatcher, QueryDispatcher, Unsupported};
3use crate::shape::Shape;
4
5/// Tests whether two shapes are intersecting (overlapping).
6///
7/// This is the fastest collision query, returning only a boolean result without
8/// computing contact points, normals, or penetration depth. Use this when you only
9/// need to know **if** shapes collide, not **where** or **how much**.
10///
11/// # Behavior
12///
13/// Returns `true` if:
14/// - Shapes are **touching** (surfaces just make contact)
15/// - Shapes are **penetrating** (overlapping with any amount)
16///
17/// Returns `false` if:
18/// - Shapes are **separated** (any distance apart, even very close)
19///
20/// # Performance
21///
22/// This is the fastest collision detection query:
23/// - **Ball-Ball**: Extremely fast (just distance check)
24/// - **AABB-AABB**: Very fast (6 comparisons in 3D)
25/// - **Convex-Convex**: Fast (early-exit GJK algorithm)
26/// - **Concave shapes**: Uses BVH for acceleration
27///
28/// Significantly faster than `contact()` or `distance()` because it can
29/// terminate early once any intersection is found.
30///
31/// # Arguments
32///
33/// * `pos1` - Position and orientation of the first shape
34/// * `g1` - The first shape
35/// * `pos2` - Position and orientation of the second shape
36/// * `g2` - The second shape
37///
38/// # Returns
39///
40/// * `Ok(true)` - Shapes are intersecting
41/// * `Ok(false)` - Shapes are not intersecting
42/// * `Err(Unsupported)` - This shape pair combination is not supported
43///
44/// # Example
45///
46/// ```rust
47/// # #[cfg(all(feature = "dim3", feature = "f32"))] {
48/// use parry3d::query::intersection_test;
49/// use parry3d::shape::Ball;
50/// use nalgebra::Isometry3;
51///
52/// let ball1 = Ball::new(1.0);
53/// let ball2 = Ball::new(1.0);
54///
55/// // Overlapping balls
56/// let pos1 = Isometry3::translation(0.0, 0.0, 0.0);
57/// let pos2 = Isometry3::translation(1.5, 0.0, 0.0);
58///
59/// let intersecting = intersection_test(&pos1, &ball1, &pos2, &ball2).unwrap();
60/// assert!(intersecting); // Distance 1.5 < combined radii 2.0
61///
62/// // Separated balls
63/// let pos3 = Isometry3::translation(5.0, 0.0, 0.0);
64/// let not_intersecting = intersection_test(&pos1, &ball1, &pos3, &ball2).unwrap();
65/// assert!(!not_intersecting); // Distance 5.0 > combined radii 2.0
66/// # }
67/// ```
68///
69/// # Use Cases
70///
71/// - **Trigger volumes**: Detect when player enters an area
72/// - **Broad-phase**: Quickly filter out distant object pairs
73/// - **Game logic**: Simple overlap detection (pickup items, damage zones)
74/// - **Optimization**: Pre-check before expensive narrow-phase queries
75///
76/// # When to Use Other Queries
77///
78/// - Need contact points/normal? → Use [`contact`](crate::query::contact())
79/// - Need penetration depth? → Use [`contact`](crate::query::contact())
80/// - Need separation distance? → Use [`distance`](crate::query::distance())
81/// - Need closest points? → Use [`closest_points`](crate::query::closest_points())
82///
83/// # See Also
84///
85/// - [`contact`](crate::query::contact()) - Get contact information if intersecting
86/// - [`distance`](crate::query::distance()) - Get separation distance
87/// - [`closest_points`](crate::query::closest_points()) - Get closest point locations
88pub fn intersection_test(
89 pos1: &Isometry<Real>,
90 g1: &dyn Shape,
91 pos2: &Isometry<Real>,
92 g2: &dyn Shape,
93) -> Result<bool, Unsupported> {
94 let pos12 = pos1.inv_mul(pos2);
95 DefaultQueryDispatcher.intersection_test(&pos12, g1, g2)
96}