1use std::io::{self, Read, Write};
2
3use cgmath::{Point3, MetricSpace};
4use std::f32;
5use Encode;
6
7const INFINITE_AABB: Aabb = Aabb {
8 lower: Point3 { x: f32::INFINITY, y: f32::INFINITY, z: f32::INFINITY},
9 upper: Point3 { x: -f32::INFINITY, y: -f32::INFINITY, z: -f32::INFINITY}
10};
11
12pub struct CenterBuilder(Aabb);
13impl CenterBuilder {
14 pub fn begin() -> Self {
15 CenterBuilder(INFINITE_AABB)
16 }
17
18 pub fn update(&mut self, point: Point3<f32>) {
19 self.0 = self.0.with(point);
20 }
21
22 pub fn build(&self) -> Point3<f32> {
23 Point3 {
24 x: (self.0.upper.x + self.0.lower.x) / 2.0,
25 y: (self.0.upper.y + self.0.lower.y) / 2.0,
26 z: (self.0.upper.z + self.0.lower.z) / 2.0
27 }
28 }
29}
30
31#[derive(Debug, Default, Copy, Clone, PartialEq)]
32pub struct Collider {
33 pub aabb: Aabb,
34 pub radius: f32
35}
36
37#[derive(Debug)]
38pub struct ColliderBuilder {
39 center: Point3<f32>,
40 aabb: Aabb,
41 radius_squared: f32
42}
43
44impl ColliderBuilder {
45 pub fn begin(center: Point3<f32>) -> Self {
46 ColliderBuilder {
47 center,
48 aabb: INFINITE_AABB,
49 radius_squared: 0.0
50 }
51 }
52
53 pub fn update(&mut self, point: Point3<f32>) {
54 self.radius_squared = self.radius_squared.max (
55 point.distance2(self.center)
56 );
57
58 self.aabb = self.aabb.with(point);
59 }
60
61 pub fn build(&self) -> Collider {
62 Collider {
63 aabb: if self.aabb == INFINITE_AABB { Aabb::default() } else { self.aabb },
64 radius: self.radius_squared.sqrt()
65 }
66 }
67}
68
69#[derive(Debug, Copy, Clone, PartialEq)]
71pub struct Aabb {
72 pub lower: Point3<f32>,
73 pub upper: Point3<f32>
74}
75
76impl Aabb {
77 pub fn with(self, point: Point3<f32>) -> Aabb {
78 Aabb {
79 lower: Point3 {
80 x: self.lower.x.min(point.x),
81 y: self.lower.y.min(point.y),
82 z: self.lower.z.min(point.z)
83 },
84 upper: Point3 {
85 x: self.upper.x.max(point.x),
86 y: self.upper.y.max(point.y),
87 z: self.upper.z.max(point.z)
88 }
89 }
90 }
91}
92
93impl Encode for Aabb {
94 fn read<R>(r: &mut R) -> io::Result<Self> where R: Read {
95 Ok(Aabb {
96 lower: Point3::read(r)?,
97 upper: Point3::read(r)?
98 })
99 }
100
101 fn write<W>(&self, w: &mut W) -> io::Result<()> where W: Write {
102 self.lower.write(w)?;
103 self.upper.write(w)
104 }
105}
106
107impl Default for Aabb {
108 fn default() -> Self {
109 Aabb {
110 lower: Point3::new(0.0, 0.0, 0.0),
111 upper: Point3::new(0.0, 0.0, 0.0)
112 }
113 }
114}