parry3d/query/contact_manifolds/
contact_manifolds_ball_ball.rs

1use crate::math::{Isometry, Real, Vector};
2use crate::query::{ContactManifold, TrackedContact};
3use crate::shape::{Ball, PackedFeatureId, Shape};
4
5/// Computes the contact manifold between two balls given as `Shape` trait-objects.
6pub fn contact_manifold_ball_ball_shapes<ManifoldData, ContactData: Default + Copy>(
7    pos12: &Isometry<Real>,
8    shape1: &dyn Shape,
9    shape2: &dyn Shape,
10    prediction: Real,
11    manifold: &mut ContactManifold<ManifoldData, ContactData>,
12) {
13    if let (Some(ball1), Some(ball2)) = (shape1.as_ball(), shape2.as_ball()) {
14        contact_manifold_ball_ball(pos12, ball1, ball2, prediction, manifold);
15    }
16}
17
18/// Computes the contact manifold between two balls.
19pub fn contact_manifold_ball_ball<ManifoldData, ContactData: Default + Copy>(
20    pos12: &Isometry<Real>,
21    ball1: &Ball,
22    ball2: &Ball,
23    prediction: Real,
24    manifold: &mut ContactManifold<ManifoldData, ContactData>,
25) {
26    let radius_a = ball1.radius;
27    let radius_b = ball2.radius;
28
29    let dcenter = pos12.translation.vector;
30    let center_dist = dcenter.magnitude();
31    let dist = center_dist - radius_a - radius_b;
32
33    if dist < prediction {
34        let local_n1 = if center_dist != 0.0 {
35            dcenter / center_dist
36        } else {
37            Vector::y()
38        };
39
40        let local_n2 = pos12.inverse_transform_vector(&-local_n1);
41        let local_p1 = local_n1 * radius_a;
42        let local_p2 = local_n2 * radius_b;
43        let fid = PackedFeatureId::face(0);
44        let contact = TrackedContact::new(local_p1.into(), local_p2.into(), fid, fid, dist);
45
46        if !manifold.points.is_empty() {
47            manifold.points[0].copy_geometry_from(contact);
48        } else {
49            manifold.points.push(contact);
50        }
51
52        manifold.local_n1 = local_n1;
53        manifold.local_n2 = local_n2;
54    } else {
55        manifold.points.clear();
56    }
57}