parry2d/query/shape_cast/
shape_cast_ball_ball.rs

1use crate::math::{Pose, Vector};
2use crate::query::details::ShapeCastOptions;
3use crate::query::{self, Ray, ShapeCastHit, ShapeCastStatus};
4use crate::shape::Ball;
5use num::Zero;
6
7/// Time Of Impact of two balls under translational movement.
8#[inline]
9pub fn cast_shapes_ball_ball(
10    pos12: &Pose,
11    vel12: Vector,
12    b1: &Ball,
13    b2: &Ball,
14    options: ShapeCastOptions,
15) -> Option<ShapeCastHit> {
16    let rsum = b1.radius + b2.radius + options.target_distance;
17    let radius = rsum;
18    let center = -pos12.translation;
19    let ray = Ray::new(Vector::ZERO, vel12);
20
21    if let (inside, Some(time_of_impact)) =
22        query::details::ray_toi_with_ball(center, radius, &ray, true)
23    {
24        if time_of_impact > options.max_time_of_impact {
25            return None;
26        }
27
28        let dpt = ray.point_at(time_of_impact) - center;
29        let normal1;
30        let normal2;
31        let witness1;
32        let witness2;
33
34        if radius.is_zero() {
35            normal1 = Vector::X;
36            normal2 = pos12.rotation.inverse() * -Vector::X;
37            witness1 = Vector::ZERO;
38            witness2 = Vector::ZERO;
39        } else {
40            normal1 = dpt / radius;
41            normal2 = pos12.rotation.inverse() * -normal1;
42            witness1 = normal1 * b1.radius;
43            witness2 = normal2 * b2.radius;
44        }
45
46        if !options.stop_at_penetration && time_of_impact < 1.0e-5 && normal1.dot(vel12) >= 0.0 {
47            return None;
48        }
49
50        let status = if inside && center.length_squared() < rsum * rsum {
51            ShapeCastStatus::PenetratingOrWithinTargetDist
52        } else {
53            ShapeCastStatus::Converged
54        };
55
56        Some(ShapeCastHit {
57            time_of_impact,
58            normal1,
59            normal2,
60            witness1,
61            witness2,
62            status,
63        })
64    } else {
65        None
66    }
67}