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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
use std::io::{self, Read, Write};
use cgmath::{Point3, MetricSpace};
use std::f32;
use Encode;
const INFINITE_AABB: Aabb = Aabb {
lower: Point3 { x: f32::INFINITY, y: f32::INFINITY, z: f32::INFINITY},
upper: Point3 { x: -f32::INFINITY, y: -f32::INFINITY, z: -f32::INFINITY}
};
pub struct CenterBuilder(Aabb);
impl CenterBuilder {
pub fn begin() -> Self {
CenterBuilder(INFINITE_AABB)
}
pub fn update(&mut self, point: Point3<f32>) {
self.0 = self.0.with(point);
}
pub fn build(&self) -> Point3<f32> {
Point3 {
x: (self.0.upper.x + self.0.lower.x) / 2.0,
y: (self.0.upper.y + self.0.lower.y) / 2.0,
z: (self.0.upper.z + self.0.lower.z) / 2.0
}
}
}
#[derive(Debug, Default, Copy, Clone, PartialEq)]
pub struct Collider {
pub aabb: Aabb,
pub radius: f32
}
#[derive(Debug)]
pub struct ColliderBuilder {
center: Point3<f32>,
aabb: Aabb,
radius_squared: f32
}
impl ColliderBuilder {
pub fn begin(center: Point3<f32>) -> Self {
ColliderBuilder {
center,
aabb: INFINITE_AABB,
radius_squared: 0.0
}
}
pub fn update(&mut self, point: Point3<f32>) {
self.radius_squared = self.radius_squared.max (
point.distance2(self.center)
);
self.aabb = self.aabb.with(point);
}
pub fn build(&self) -> Collider {
Collider {
aabb: if self.aabb == INFINITE_AABB { Aabb::default() } else { self.aabb },
radius: self.radius_squared.sqrt()
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub struct Aabb {
pub lower: Point3<f32>,
pub upper: Point3<f32>
}
impl Aabb {
pub fn with(self, point: Point3<f32>) -> Aabb {
Aabb {
lower: Point3 {
x: self.lower.x.min(point.x),
y: self.lower.y.min(point.y),
z: self.lower.z.min(point.z)
},
upper: Point3 {
x: self.upper.x.max(point.x),
y: self.upper.y.max(point.y),
z: self.upper.z.max(point.z)
}
}
}
}
impl Encode for Aabb {
fn read<R>(r: &mut R) -> io::Result<Self> where R: Read {
Ok(Aabb {
lower: Point3::read(r)?,
upper: Point3::read(r)?
})
}
fn write<W>(&self, w: &mut W) -> io::Result<()> where W: Write {
self.lower.write(w)?;
self.upper.write(w)
}
}
impl Default for Aabb {
fn default() -> Self {
Aabb {
lower: Point3::new(0.0, 0.0, 0.0),
upper: Point3::new(0.0, 0.0, 0.0)
}
}
}