1use cgmath::{Point2, Point3, Vector2, Vector3};
4use cgmath::prelude::*;
5use std::fmt::{Debug, Formatter};
6
7pub trait SpatialIndex: Clone + Copy + Default + Ord + Send + std::fmt::Debug {
39 type Diff: cgmath::VectorSpace<Scalar = u32>;
40 type Point: Copy + EuclideanSpace<Diff = Self::Diff, Scalar = u32>;
41
42 fn clamp_depth(_: u32) -> u32;
44
45 fn origin(self) -> Self::Point;
46 fn depth(self) -> u32;
47
48 fn set_origin(self, _: Self::Point) -> Self;
49 fn set_depth(self, _: u32) -> Self;
50
51 type SubdivideResult: AsRef<[Self]>;
52
53 fn subdivide(self) -> Option<Self::SubdivideResult>;
57
58 fn overlaps(self, other: Self) -> bool;
60
61 fn same_cell_at_depth(lhs: Self, rhs: Self, depth: u32) -> bool;
63}
64
65macro_rules! index_impl {
66 (index: $name:ident, $dim:tt, $bits:tt, $depth_bits:tt, $axis_bits:tt) => {
67 #[derive(Clone, Copy, Default, Eq, Ord, PartialEq, PartialOrd)]
68 #[cfg_attr(any(test, feature="serde"), derive(Deserialize, Serialize))]
69 pub struct $name(index_impl!{primitive_type: $bits});
70
71 impl $name {
72 const DEPTH_BITS: u32 = $depth_bits;
73 const DEPTH_SHIFT: u32 = 0;
74 const DEPTH_MASK: index_impl!{primitive_type: $bits} = (((1 as index_impl!{primitive_type: $bits}) << Self::DEPTH_BITS) - 1) << Self::DEPTH_SHIFT;
75 const AXIS_BITS: u32 = $axis_bits;
76 const ORIGIN_BITS: u32 = $dim * Self::AXIS_BITS;
77 const ORIGIN_SHIFT: u32 = Self::DEPTH_SHIFT + Self::DEPTH_BITS;
78 const ORIGIN_MASK: index_impl!{primitive_type: $bits} = (((1 as index_impl!{primitive_type: $bits}) << (Self::ORIGIN_BITS)) - 1) << Self::ORIGIN_SHIFT;
79
80 index_impl!{codec: $dim, $bits}
81
82 fn level_mask(depth: u32) -> index_impl!{primitive_type: $bits} {
83 if depth <= 0 { 0 } else {
84 (((1 as index_impl!{primitive_type: $bits}) << ($dim * depth)) - 1) << (Self::ORIGIN_BITS + Self::ORIGIN_SHIFT - $dim * depth)
85 }
86 }
87 }
88
89 impl SpatialIndex for $name {
90 type Diff = index_impl!{vector_type: $dim};
91 type Point = index_impl!{point_type: $dim};
92
93 fn clamp_depth(depth: u32) -> u32 {
94 std::cmp::min(depth, Self::AXIS_BITS)
95 }
96
97 index_impl!{origin: $dim}
98
99 fn depth(self) -> u32 {
100 let Self(index) = self;
101 ((index & Self::DEPTH_MASK) >> Self::DEPTH_SHIFT) as u32
102 }
103
104 index_impl!{set_origin: $dim}
105
106 fn set_depth(self, depth: u32) -> Self {
107 let Self(mut index) = self;
108 index &= !Self::DEPTH_MASK;
109 index |= Self::DEPTH_MASK & (
110 <index_impl!{primitive_type: $bits} as From<u32>>::from(Self::clamp_depth(depth)) << Self::DEPTH_SHIFT);
111 Self(index)
112 }
113
114 index_impl!{subdivide: $dim, $bits}
115
116 fn overlaps(self, other: Self) -> bool {
117 Self::same_cell_at_depth(self, other, std::cmp::min(self.depth(), other.depth()))
118 }
119
120 fn same_cell_at_depth(Self(lhs): Self, Self(rhs): Self, depth: u32) -> bool {
121 (lhs ^ rhs) & Self::level_mask(depth) == 0
122 }
123 }
124 };
125 (primitive_type: 32) => {u32};
126 (primitive_type: 64) => {u64};
127 (vector_type: 2) => {Vector2<u32>};
128 (vector_type: 3) => {Vector3<u32>};
129 (point_type: 2) => {Point2<u32>};
130 (point_type: 3) => {Point3::<u32>};
131 (codec: 2, $bits:tt) => {
132 #[allow(overflowing_literals)] #[inline]
134 fn decode_axis(origin: index_impl!{primitive_type: $bits}) -> u32 {
135 let axis00 = origin & 0x1111_1111_1111_1111 as index_impl!{primitive_type: $bits};
136 let axis01 = (origin & 0x4444_4444_4444_4444 as index_impl!{primitive_type: $bits}) >> 0x01;
137 let axis0_ = axis00 | axis01;
138 let axis10 = axis0_ & 0x0303_0303_0303_0303 as index_impl!{primitive_type: $bits};
139 let axis11 = (axis0_ & 0x3030_3030_3030_3030 as index_impl!{primitive_type: $bits}) >> 0x02;
140 let axis1_ = axis10 | axis11;
141 let axis20 = axis1_ & 0x000f_000f_000f_000f as index_impl!{primitive_type: $bits};
142 let axis21 = (axis1_ & 0x0f00_0f00_0f00_0f00 as index_impl!{primitive_type: $bits}) >> 0x04;
143 let axis2_ = axis20 | axis21;
144 let axis30 = axis2_ & 0x0000_00ff_0000_00ff as index_impl!{primitive_type: $bits};
145 let axis31 = (axis2_ & 0x00ff_0000_00ff_0000 as index_impl!{primitive_type: $bits}) >> 0x08;
146 let axis3_ = axis30 | axis31;
147 let axis40 = axis3_ & 0x0000_0000_0000_ffff as index_impl!{primitive_type: $bits};
148 let axis41 = (axis3_ & 0x0000_ffff_0000_0000 as index_impl!{primitive_type: $bits}) >> 0x10;
149 let axis4_ = axis40 | axis41;
150 (axis4_ as u32) << (32 - Self::AXIS_BITS)
151 }
152
153 #[allow(overflowing_literals)] #[inline]
155 fn encode_axis(origin: u32) -> index_impl!{primitive_type: $bits} {
156 let axis0_ = <index_impl!{primitive_type: $bits} as From<u32>>::from(origin >> (32 - Self::AXIS_BITS));
157 let axis00 = axis0_ & 0x0000_0000_0000_ffff as index_impl!{primitive_type: $bits};
158 let axis01 = (axis0_ << 0x10) & 0x0000_ffff_0000_0000 as index_impl!{primitive_type: $bits};
159 let axis1_ = axis00 | axis01;
160 let axis10 = axis1_ & 0x0000_00ff_0000_00ff as index_impl!{primitive_type: $bits};
161 let axis11 = (axis1_ << 0x08) & 0x00ff_0000_00ff_0000 as index_impl!{primitive_type: $bits};
162 let axis2_ = axis10 | axis11;
163 let axis20 = axis2_ & 0x000f_000f_000f_000f as index_impl!{primitive_type: $bits};
164 let axis21 = (axis2_ << 0x04) & 0x0f00_0f00_0f00_0f00 as index_impl!{primitive_type: $bits};
165 let axis3_ = axis20 | axis21;
166 let axis30 = axis3_ & 0x0303_0303_0303_0303 as index_impl!{primitive_type: $bits};
167 let axis31 = (axis3_ << 0x02) & 0x3030_3030_3030_3030 as index_impl!{primitive_type: $bits};
168 let axis4_ = axis30 | axis31;
169 let axis40 = axis4_ & 0x1111_1111_1111_1111 as index_impl!{primitive_type: $bits};
170 let axis41 = (axis4_ << 0x01) & 0x4444_4444_4444_4444 as index_impl!{primitive_type: $bits};
171 axis40 | axis41
172 }
173 };
174 (codec: 3, $bits:tt) => {
175 #[inline]
176 fn decode_axis(origin: index_impl!{primitive_type: $bits}) -> u32 {
177 let axis00 = origin & 0o1_001_001_001_001_001_001_001 as index_impl!{primitive_type: $bits};
178 let axis01 = (origin & 0o0_010_010_010_010_010_010_010 as index_impl!{primitive_type: $bits}) >> 0o02;
179 let axis02 = (origin & 0o0_100_100_100_100_100_100_100 as index_impl!{primitive_type: $bits}) >> 0o04;
180 let axis0_ = axis00 | axis01 | axis02;
181 let axis10 = axis0_ & 0o0_007_000_000_007_000_000_007 as index_impl!{primitive_type: $bits};
182 let axis11 = (axis0_ & 0o1_000_000_007_000_000_007_000 as index_impl!{primitive_type: $bits}) >> 0o06;
183 let axis12 = (axis0_ & 0o0_000_007_000_000_007_000_000 as index_impl!{primitive_type: $bits}) >> 0o14;
184 let axis1_ = axis10 | axis11 | axis12;
185 let axis20 = axis1_ & 0o0_000_000_000_000_000_000_777 as index_impl!{primitive_type: $bits};
186 let axis21 = (axis1_ & 0o0_000_000_000_777_000_000_000 as index_impl!{primitive_type: $bits}) >> 0o22;
187 let axis22 = (axis1_ & 0o0_777_000_000_000_000_000_000 as index_impl!{primitive_type: $bits}) >> 0o44;
188 let axis2_ = axis20 | axis21 | axis22;
189 (axis2_ as u32) << (32 - Self::AXIS_BITS)
190 }
191
192 #[inline]
193 fn encode_axis(origin: u32) -> index_impl!{primitive_type: $bits} {
194 let axis0_ = <index_impl!{primitive_type: $bits} as From<u32>>::from(origin >> (32 - Self::AXIS_BITS));
195 let axis00 = axis0_ & 0o0_000_000_000_000_000_000_777 as index_impl!{primitive_type: $bits};
196 let axis01 = (axis0_ << 0o22) & 0o0_000_000_000_777_000_000_000 as index_impl!{primitive_type: $bits};
197 let axis02 = (axis0_ << 0o44) & 0o0_777_000_000_000_000_000_000 as index_impl!{primitive_type: $bits};
198 let axis1_ = axis00 | axis01 | axis02;
199 let axis10 = axis1_ & 0o0_007_000_000_007_000_000_007 as index_impl!{primitive_type: $bits};
200 let axis11 = (axis1_ << 0o06) & 0o1_000_000_007_000_000_007_000 as index_impl!{primitive_type: $bits};
201 let axis12 = (axis1_ << 0o14) & 0o0_000_007_000_000_007_000_000 as index_impl!{primitive_type: $bits};
202 let axis2_ = axis10 | axis11 | axis12;
203 let axis20 = axis2_ & 0o1_001_001_001_001_001_001_001 as index_impl!{primitive_type: $bits};
204 let axis21 = (axis2_ << 0o02) & 0o0_010_010_010_010_010_010_010 as index_impl!{primitive_type: $bits};
205 let axis22 = (axis2_ << 0o04) & 0o0_100_100_100_100_100_100_100 as index_impl!{primitive_type: $bits};
206 axis20 | axis21 | axis22
207 }
208 };
209 (origin: 2) => {
210 fn origin(self) -> index_impl!{point_type: 2} {
211 let Self(index) = self;
212 let origin = (index & Self::ORIGIN_MASK) >> Self::ORIGIN_SHIFT;
213 Point2::new(
214 Self::decode_axis(origin),
215 Self::decode_axis(origin >> 1),
216 )
217 }
218 };
219 (origin: 3) => {
220 fn origin(self) -> index_impl!{point_type: 3} {
221 let Self(index) = self;
222 let origin = (index & Self::ORIGIN_MASK) >> Self::ORIGIN_SHIFT;
223 Point3::new(
224 Self::decode_axis(origin),
225 Self::decode_axis(origin >> 1),
226 Self::decode_axis(origin >> 2),
227 )
228 }
229 };
230 (set_origin: 2) => {
231 fn set_origin(self, origin: index_impl!{point_type: 2}) -> Self {
232 let origin = Self::encode_axis(origin.x)
233 | Self::encode_axis(origin.y) << 1;
234 let Self(mut index) = self;
235 index &= !Self::ORIGIN_MASK;
236 index |= Self::ORIGIN_MASK & (origin << Self::ORIGIN_SHIFT);
237 Self(index)
238 }
239 };
240 (set_origin: 3) => {
241 fn set_origin(self, origin: index_impl!{point_type: 3}) -> Self {
242 let origin = Self::encode_axis(origin.x)
243 | Self::encode_axis(origin.y) << 1
244 | Self::encode_axis(origin.z) << 2;
245 let Self(mut index) = self;
246 index &= !Self::ORIGIN_MASK;
247 index |= Self::ORIGIN_MASK & (origin << Self::ORIGIN_SHIFT);
248 Self(index)
249 }
250 };
251 (subdivide: 2, $bits:tt) => {
252 type SubdivideResult = [Self; 4];
253 fn subdivide(self) -> Option<[Self; 4]> {
254 let depth = self.depth();
255 if depth < Self::AXIS_BITS {
256 let Self(index) = self;
257 let shift = Self::ORIGIN_BITS + Self::ORIGIN_SHIFT - (2 * (depth + 1));
258 Some([
259 Self(index | (0b00 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
260 Self(index | (0b01 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
261 Self(index | (0b10 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
262 Self(index | (0b11 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1)
263 ])
264 } else {
265 None
266 }
267 }
268 };
269 (subdivide: 3, $bits:tt) => {
270 type SubdivideResult = [Self; 8];
271 fn subdivide(self) -> Option<[Self; 8]> {
272 let depth = self.depth();
273 if depth < Self::AXIS_BITS {
274 let Self(index) = self;
275 let shift = Self::ORIGIN_BITS + Self::ORIGIN_SHIFT - (3 * (depth + 1));
276 Some([
277 Self(index | (0b000 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
278 Self(index | (0b001 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
279 Self(index | (0b010 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
280 Self(index | (0b011 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
281 Self(index | (0b100 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
282 Self(index | (0b101 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
283 Self(index | (0b110 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1),
284 Self(index | (0b111 as index_impl!{primitive_type: $bits} << shift)).set_depth(depth + 1)
285 ])
286 } else {
287 None
288 }
289 }
290 };
291}
292
293index_impl!{index: Index32_2D, 2, 32, 4, 14}
294index_impl!{index: Index64_2D, 2, 64, 5, 29}
295index_impl!{index: Index64_3D, 3, 64, 5, 19}
296
297impl Debug for Index64_3D {
298 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
299 let Self(index) = self;
300 let origin_bits = (index & Self::ORIGIN_MASK) >> Self::ORIGIN_SHIFT;
301 let origin = self.origin();
302 write!(f, "Index64_3D{{origin={{0o{:019o}, <0x{:08x}, 0x{:08x}, 0x{:08x}>}}, depth={:}}}",
303 origin_bits,
304 origin.x,
305 origin.y,
306 origin.z,
307 self.depth())
308 }
309}
310
311impl Debug for Index32_2D {
312 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
313 let Self(index) = self;
314 let origin_bits = (index & Self::ORIGIN_MASK) >> Self::ORIGIN_SHIFT;
315 let origin = self.origin();
316 write!(f, "Index32_2D{{origin={{0x{:011x}, <0x{:04x}, 0x{:04x}>}}, depth={:}}}",
317 origin_bits,
318 origin.x,
319 origin.y,
320 self.depth())
321 }
322}
323
324impl Debug for Index64_2D {
325 fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
326 let Self(index) = self;
327 let origin_bits = (index & Self::ORIGIN_MASK) >> Self::ORIGIN_SHIFT;
328 let origin = self.origin();
329 write!(f, "Index64_2D{{origin={{0x{:022x}, <0x{:08x}, 0x{:08x}>}}, depth={:}}}",
330 origin_bits,
331 origin.x,
332 origin.y,
333 self.depth())
334 }
335}
336
337#[cfg(test)]
338mod tests {
339 use super::*;
340 use rand::prelude::*;
341
342 #[test]
343 fn decode() {
344 assert_eq!(
345 Index64_3D::decode_axis(0o0_001_111_111_111_111_111_111),
346 0o1_777_777u32 << 13
347 );
348 assert_eq!(
349 Index64_3D::decode_axis(0o0_006_666_666_666_666_666_666),
350 0o0_000_000u32 << 13
351 );
352 }
353
354 #[test]
355 fn encode() {
356 assert_eq!(
357 Index64_3D::encode_axis(0o1_777_777u32 << 13),
358 0o0_001_111_111_111_111_111_111
359 );
360 assert_eq!(
361 Index64_3D::encode_axis(0o0_000_000u32 << 13),
362 0o0_000_000_000_000_000_000_000
363 );
364 }
365
366 #[test]
367 fn round_trip_axis() {
368 let mut prng = rand_chacha::ChaChaRng::seed_from_u64(0);
369 for _ in 0..10000 {
370 let expected = prng.gen_range(0o0_000_000, 0o2_000_000) << 13;
371 let actual = Index64_3D::decode_axis(Index64_3D::encode_axis(expected));
372 assert_eq!(actual, expected);
373 }
374 }
375}