1use crate::vector3d::*;
3use crate::HashSetFnv;
4
5#[derive(Eq, PartialEq, Default, Hash, Copy, Clone, Debug)]
7pub struct Box3D {
8 pub position: Vector3D::<u64>,
10 pub size: Vector3D::<u64>,
12 pub id: usize,
14 pub origin: u16,
16}
17
18impl Box3D {
19
20 pub fn from_position_size(position: Vector3D::<u64>, size: Vector3D::<u64>, id: usize, origin: u16) -> Box3D
22 {
23 Box3D { position, size, id, origin }
24 }
25
26 pub fn from_xyz_whl(x: u64, y: u64, z: u64, w: u64, h: u64, l: u64, id: usize, origin: u16) -> Box3D
28 {
29 let position = Vector3D::<u64>::new(x,y,z);
30 let size = Vector3D::<u64>::new(w,h,l);
31 Box3D { position, size, id, origin }
32 }
33
34 pub fn volume(&self) -> u64
36 {
37 self.size.x * self.size.y * self.size.z
38 }
39
40 pub fn fits_in(&self, other: &Box3D) -> bool
42 {
43 self.size.x <= other.size.x && self.size.y <= other.size.y && self.size.z <= other.size.z
44 }
45
46 pub fn is_in(&self, other: &Box3D) -> bool
48 { self.position.x >= other.position.x && self.position.y >= other.position.y && self.position.z >= other.position.z && self.x2() <= other.x2() && self.y2() <= other.y2() && self.z2() <= other.z2() }
58
59 pub fn x2(&self) -> u64
60 {
61 self.position.x + self.size.x
62 }
63 pub fn y2(&self) -> u64
64 {
65 self.position.y + self.size.y
66 }
67 pub fn z2(&self) -> u64
68 {
69 self.position.z + self.size.z
70 }
71
72 pub fn intersects(&self, other: &Box3D) -> bool
74 {
75 range_overlap(self.position.x, self.x2(), other.position.x, other.x2()) &&
76 range_overlap(self.position.y, self.y2(), other.position.y, other.y2()) &&
77 range_overlap(self.position.z, self.z2(), other.position.z, other.z2())
78 }
79
80 pub fn is_covered_among(&self, boxes: &HashSetFnv<Box3D>) -> bool
82 {
83 boxes.iter().any(|other| self.is_in(other))
84 }
85
86 pub fn get_rotations(&self) -> Vec<Box3D>
88 {
89 vec![
90 Box3D::from_position_size(self.position, Vector3D::<u64>::new(self.size.x, self.size.y, self.size.z), self.id, self.origin), Box3D::from_position_size(self.position, Vector3D::<u64>::new(self.size.y, self.size.x, self.size.z), self.id, self.origin), Box3D::from_position_size(self.position, Vector3D::<u64>::new(self.size.z, self.size.y, self.size.x), self.id, self.origin), Box3D::from_position_size(self.position, Vector3D::<u64>::new(self.size.x, self.size.z, self.size.y), self.id, self.origin), Box3D::from_position_size(self.position, Vector3D::<u64>::new(self.size.z, self.size.x, self.size.y), self.id, self.origin), Box3D::from_position_size(self.position, Vector3D::<u64>::new(self.size.y, self.size.z, self.size.x), self.id, self.origin) ]
97 }
98}
99
100fn range_overlap<T: std::cmp::PartialOrd>(amin: T, amax: T, bmin: T, bmax: T) -> bool
102{
103 amax > bmin && bmax > amin
104}