ncollide3d/query/contact/
contact_ball_ball.rs

1use crate::math::{Point, Vector};
2use crate::query::Contact;
3use crate::shape::Ball;
4use na::{self, RealField, Unit};
5
6/// Contact between balls.
7#[inline]
8pub fn contact_ball_ball<N: RealField + Copy>(
9    center1: &Point<N>,
10    b1: &Ball<N>,
11    center2: &Point<N>,
12    b2: &Ball<N>,
13    prediction: N,
14) -> Option<Contact<N>> {
15    let r1 = b1.radius;
16    let r2 = b2.radius;
17    let delta_pos = *center2 - *center1;
18    let distance_squared = delta_pos.norm_squared();
19    let sum_radius = r1 + r2;
20    let sum_radius_with_error = sum_radius + prediction;
21
22    if distance_squared < sum_radius_with_error * sum_radius_with_error {
23        let normal = if !distance_squared.is_zero() {
24            Unit::new_normalize(delta_pos)
25        } else {
26            Vector::x_axis()
27        };
28
29        Some(Contact::new(
30            *center1 + *normal * r1,
31            *center2 + *normal * (-r2),
32            normal,
33            sum_radius - distance_squared.sqrt(),
34        ))
35    } else {
36        None
37    }
38}