Skip to main content

paraxis/encoding/
mod.rs

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        // We want to capture the 'most detailed' bits.
38        // If the bitset is long, the detail is usually at the end.
39        let len = self.bits.len();
40        let take = len.min(64);
41        for i in 0..take {
42            // Try reading from the end of the bit array
43            if self.bits[len - 1 - i] {
44                out |= 1u64 << i;
45            }
46        }
47        out
48    }
49}