Skip to main content

paraxis/encoding/
mod.rs

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