1use std::fmt;
8use *;
9
10#[derive(Clone, Copy, PartialEq)]
12pub struct BCube {
13 pub(crate) center: Vector,
14 pub(crate) half_len: f32,
15}
16
17impl fmt::Debug for BCube {
18 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19 write!(f, "{:?}±{:?}", self.center, self.half_len)
20 }
21}
22
23impl BCube {
24 pub fn empty() -> BCube {
26 let z = 0.0;
27
28 BCube { center: Vector::new(z, z, z), half_len: -1.0 }
29 }
30
31 pub fn new(p: Vector) -> BCube {
33 BCube { center: p, half_len: 1.0 }
34 }
35
36 pub fn extend(&mut self, p: BBox) {
38self.center = self.move_center(p);
40 self.half_len *= 2.0;
41 }
42
43 fn move_center(&self, p: BBox) -> Vector {
44 let (maxx, maxy, maxz) = p.bcube_sides(*self);
45
46let min = self.center - vector!(self.half_len);
49 let max = self.center + vector!(self.half_len);
50
51 match (maxx, maxy, maxz) {
52 (false, false, false) => Vector::new(min.x, min.y, min.z),
53 (false, false, true) => Vector::new(min.x, min.y, max.z),
54 (false, true, false) => Vector::new(min.x, max.y, min.z),
55 (false, true, true) => Vector::new(min.x, max.y, max.z),
56 (true, false, false) => Vector::new(max.x, min.y, min.z),
57 (true, false, true) => Vector::new(max.x, min.y, max.z),
58 (true, true, false) => Vector::new(max.x, max.y, min.z),
59 (true, true, true) => Vector::new(max.x, max.y, max.z),
60 }
61 }
62
63 pub fn contains(&self, p: Vector) -> bool {
65 let Vector { x, y, z } = self.center;
66 let hl = self.half_len;
67 (p.x >= x - hl) &&
68 (p.x < x + hl) &&
69 (p.y >= y - hl) &&
70 (p.y < y + hl) &&
71 (p.z >= z - hl) &&
72 (p.z < z + hl)
73 }
74
75 pub fn to_point_pair(&self) -> (Vector, Vector) {
77 let half_cube = Vector::new(self.half_len, self.half_len,
78 self.half_len);
79
80 (self.center + half_cube, self.center - half_cube)
81 }
82
83 pub fn to_bbox(&self) -> BBox {
85 let (max, min) = self.to_point_pair();
86 BBox::new(min, max)
87 }
88
89 pub fn all_points(&self) -> [Vector; 7] {
91 let z = 0.0;
92
93 [
94 self.center,
95 self.center + Vector::new(self.half_len, z, z),
96 self.center + Vector::new(z, self.half_len, z),
97 self.center + Vector::new(z, z, self.half_len),
98 self.center + Vector::new(-self.half_len, z, z),
99 self.center + Vector::new(z, -self.half_len, z),
100 self.center + Vector::new(z, z, -self.half_len),
101 ]
102 }
103
104 pub fn pn_pair_from_normal(&self, normal: Vector)
107 -> (Vector, Vector)
108 {
109 let mut pvertex = self.center;
110 let mut nvertex = self.center;
111
112 if normal.x >= 0.0 {
113 pvertex.x += self.half_len;
114 nvertex.x -= self.half_len;
115 } else {
116 nvertex.x += self.half_len;
117 pvertex.x -= self.half_len;
118 }
119
120 if normal.y >= 0.0 {
121 pvertex.y += self.half_len;
122 nvertex.y -= self.half_len;
123 } else {
124 nvertex.y += self.half_len;
125 pvertex.y -= self.half_len;
126 }
127
128 if normal.z >= 0.0 {
129 pvertex.z += self.half_len;
130 nvertex.z -= self.half_len;
131 } else {
132 nvertex.z += self.half_len;
133 pvertex.z -= self.half_len;
134 }
135
136 (nvertex, pvertex)
137 }
138}