1use bitvec::{array::BitArray, order::Msb0};
2use num_traits::Float;
3
4use crate::maths::vec::Vector;
5
6pub struct MortonCode<T: Float, const N: usize> {
7 pub bits: BitArray<[u32; N], Msb0>,
8 pub position: Vector<T, N>,
9}
10impl<'a, T: Float, const N: usize> MortonCode<T, N> {
11 pub fn from_vector(position: Vector<T, N>, min: &Vector<T, N>) -> Self {
12 let mut quantized = [0u64; N];
13 let mut bits = BitArray::<[u32; N], Msb0>::ZERO;
14 for i in 0..N {
15 let axis_diff = position.inner[i] - min.inner[i];
16 quantized[i] = axis_diff.to_u64().unwrap_or(0u64);
17 }
18 let mut current_bit = 0;
19 for bit in (0..32).rev() {
20 for axis in 0..N {
21 let is_set = (quantized[axis] >> bit) & 1 == 1;
22 if is_set {
23 bits.set(current_bit, true);
24 }
25 current_bit += 1;
26 if current_bit >= N * 32 {
27 break;
28 }
29 }
30 }
31 Self { bits, position }
32 }
33}
34impl<T: Float> MortonCode<T, 3> {
35 pub fn to_u64(&self) -> u64 {
36 let mut out = 0u64;
37 let len = self.bits.len();
40 let take = len.min(64);
41 for i in 0..take {
42 if self.bits[len - 1 - i] {
44 out |= 1u64 << i;
45 }
46 }
47 out
48 }
49}