MUDA
Loading...
Searching...
No Matches
morton_hash.h
1#pragma once
2#include <muda/muda_def.h>
3#include <cinttypes>
4#include <muda/ext/eigen/eigen_core_cxx20.h>
5
6namespace muda::spatial_hash
7{
8template <typename T>
9class Morton
10{
11 static_assert("Morton not implemented for this type.");
12};
13
14template <>
15class Morton<uint32_t>
16{
17 public:
18 using Vector3u = Eigen::Vector3<uint32_t>;
19
20 MUDA_GENERIC uint32_t operator()(const Vector3u& p) const
21 {
22 return (*this)(p.x(), p.y(), p.z());
23 }
24
25 constexpr MUDA_GENERIC uint32_t operator()(uint32_t x, uint32_t y, uint32_t z) const
26 {
27 x = expand_bits(x);
28 y = expand_bits(y);
29 z = expand_bits(z);
30 return x | y << 1 | z << 2;
31 }
32
33 private:
34 // Expands a 10-bit integer into 30 bits
35 // by inserting 2 zeros after each bit.
36 constexpr MUDA_GENERIC static uint32_t expand_bits(uint32_t v)
37 {
38 //v = (v * 0x00010001u) & 0xFF0000FFu;
39 //v = (v * 0x00000101u) & 0x0F00F00Fu;
40 //v = (v * 0x00000011u) & 0xC30C30C3u;
41 //v = (v * 0x00000005u) & 0x49249249u;
42
43 v &= 0x3ff;
44 v = (v | v << 16) & 0x30000ff;
45 v = (v | v << 8) & 0x300f00f;
46 v = (v | v << 4) & 0x30c30c3;
47 v = (v | v << 2) & 0x9249249;
48 return (uint32_t)v;
49 }
50};
51
52template <>
53class Morton<uint64_t>
54{
55 public:
56 using Vector3u = Eigen::Vector3<uint32_t>;
57
58 MUDA_GENERIC uint64_t operator()(const Vector3u& p) const
59 {
60 return (*this)(p.x(), p.y(), p.z());
61 }
62
63 constexpr MUDA_GENERIC uint64_t operator()(uint32_t x, uint32_t y, uint32_t z) const
64 {
65 x = expand_bits(x);
66 y = expand_bits(y);
67 z = expand_bits(z);
68 return x | y << 1 | z << 2;
69 }
70
71 private:
72 // Expands a 21-bit integer into 63 bits
73 // by inserting 2 zeros after each bit.
74 constexpr MUDA_GENERIC static uint64_t expand_bits(uint64_t v)
75 {
76 v &= 0x1fffff;
77 v = (v | v << 32) & 0x1f00000000ffff;
78 v = (v | v << 16) & 0x1f0000ff0000ff;
79 v = (v | v << 8) & 0x100f00f00f00f00f;
80 v = (v | v << 4) & 0x10c30c30c30c30c3;
81 v = (v | v << 2) & 0x1249249249249249;
82 return v;
83 }
84};
85} // namespace muda::spatial_hash
Definition morton_hash.h:10