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
#![deny(missing_docs)]
use collide::{Collider, CollisionInfo};
use num_traits::real::Real;
use vector_space::{InnerSpace, VectorSpace};
#[derive(Copy, Clone)]
pub struct Sphere<V: VectorSpace> {
pub pos: V,
pub rad: V::Scalar,
}
impl<V: InnerSpace> Sphere<V> {
pub fn new(pos: V, rad: V::Scalar) -> Self {
Self { pos, rad }
}
}
impl<V: InnerSpace> Collider for Sphere<V> {
type Vector = V;
fn check_collision(&self, other: &Self) -> bool {
let rad = self.rad + other.rad;
let rad2 = rad * rad;
let vec = other.pos - self.pos;
vec.magnitude2() <= rad2
}
fn collision_info(&self, other: &Self) -> Option<CollisionInfo<Self::Vector>> {
let rad = self.rad + other.rad;
let rad2 = rad * rad;
let vec = other.pos - self.pos;
let mag2 = vec.magnitude2();
if mag2 <= rad2 {
let mag = mag2.sqrt();
let direction = vec / mag;
Some(CollisionInfo {
self_contact: self.pos + direction * self.rad,
other_contact: other.pos - direction * other.rad,
vector: direction * (mag - rad),
})
} else {
None
}
}
}