1#![deny(missing_docs)]
2
3use collide::{Collider, CollisionInfo};
8use num_traits::real::Real;
9use vector_space::{InnerSpace, VectorSpace};
10
11#[derive(Copy, Clone)]
12pub struct Sphere<V: VectorSpace> {
14 pub pos: V,
16 pub rad: V::Scalar,
18}
19
20impl<V: InnerSpace> Sphere<V> {
21 pub fn new(pos: V, rad: V::Scalar) -> Self {
23 Self { pos, rad }
24 }
25}
26
27impl<V: InnerSpace> Collider for Sphere<V> {
28 type Vector = V;
29
30 fn check_collision(&self, other: &Self) -> bool {
31 let rad = self.rad + other.rad;
32 let rad2 = rad * rad;
33 let vec = other.pos - self.pos;
34 vec.magnitude2() <= rad2
35 }
36
37 fn collision_info(&self, other: &Self) -> Option<CollisionInfo<Self::Vector>> {
38 let rad = self.rad + other.rad;
39 let rad2 = rad * rad;
40 let vec = other.pos - self.pos;
41 let mag2 = vec.magnitude2();
42 if mag2 <= rad2 {
43 let mag = mag2.sqrt();
44 let direction = vec / mag;
45 Some(CollisionInfo {
46 self_contact: self.pos + direction * self.rad,
47 other_contact: other.pos - direction * other.rad,
48 vector: direction * (mag - rad),
49 })
50 } else {
51 None
52 }
53 }
54}