generic_octree/
loc_code.rs1use std::{
2 fmt::Debug,
3 hash::Hash,
4 ops::{BitOr, Shl, Shr},
5};
6
7use crate::Orientation;
8
9pub trait LocCode:
10 Copy
11 + Clone
12 + Ord
13 + PartialOrd
14 + Eq
15 + PartialEq
16 + Debug
17 + Hash
18 + Send
19 + Sync
20 + Shl<Output = Self>
21 + Shr<Output = Self>
22 + BitOr<Output = Self>
23 + From<u8>
24 + BitOr<Orientation, Output = Self>
25{
26 fn zero() -> Self;
28
29 fn root() -> Self;
31
32 fn one() -> Self;
34
35 fn two() -> Self;
37
38 fn three() -> Self;
40
41 fn get_level(self) -> u32;
42 fn get_offset(self) -> u32;
43
44 fn get_center_u32(self) -> (u32, u32, u32);
45}
46
47macro_rules! impl_loc_code_num {
48 ($ty:ident) => {
49 impl BitOr<Orientation> for $ty {
50 type Output = Self;
51
52 fn bitor(self, rhs: Orientation) -> Self {
53 match rhs {
54 Orientation::LBU => self | 0,
55 Orientation::LFU => self | 1,
56 Orientation::LFD => self | 2,
57 Orientation::LBD => self | 3,
58 Orientation::RBD => self | 4,
59 Orientation::RFD => self | 5,
60 Orientation::RFU => self | 6,
61 Orientation::RBU => self | 7,
62 _ => self | 8,
63 }
64 }
65 }
66
67 impl LocCode for $ty {
68 fn root() -> Self {
69 Self::one()
70 }
71
72 fn one() -> Self {
73 1 as Self
74 }
75
76 fn zero() -> Self {
77 1 as Self
78 }
79
80 fn two() -> Self {
81 2 as Self
82 }
83
84 fn three() -> Self {
85 3 as Self
86 }
87
88 fn get_level(mut self) -> u32 {
89 let mut level = 1;
90 while self != 1 {
91 self >>= 3;
92 level += 1;
93 }
94 level as u32
95 }
96
97 fn get_offset(self) -> u32 {
98 2u32.pow(32 - self.get_level())
99 }
100
101 fn get_center_u32(self) -> (u32, u32, u32) {
102 if self == 1 {
103 return (i32::MAX as u32, i32::MAX as u32, i32::MAX as u32);
104 }
105 let offset = 2u32.pow(32 - self.get_level());
106 let mask = Self::MAX ^ 7;
107 let center = (self >> 3).get_center_u32();
108 match (self ^ mask) & !mask {
109 0 => (center.0 - offset, center.1 + offset, center.2 - offset),
110 1 => (center.0 - offset, center.1 + offset, center.2 + offset),
111 2 => (center.0 - offset, center.1 - offset, center.2 + offset),
112 3 => (center.0 - offset, center.1 - offset, center.2 - offset),
113 4 => (center.0 + offset, center.1 - offset, center.2 - offset),
114 5 => (center.0 + offset, center.1 - offset, center.2 + offset),
115 6 => (center.0 + offset, center.1 + offset, center.2 + offset),
116 7 => (center.0 + offset, center.1 + offset, center.2 - offset),
117 _ => (i32::MAX as u32, i32::MAX as u32, i32::MAX as u32),
118 }
119 }
120 }
121 };
122}
123
124impl_loc_code_num!(u8);
125impl_loc_code_num!(i16);
126impl_loc_code_num!(u16);
127impl_loc_code_num!(i32);
128impl_loc_code_num!(u32);
129impl_loc_code_num!(i64);
130impl_loc_code_num!(u64);