20 #ifndef ANTKEEPER_GEOM_MORTON_HPP
21 #define ANTKEEPER_GEOM_MORTON_HPP
35 template <std::
unsigned_
integral T>
40 x &= (1 << (
sizeof(T) << 2)) - 1;
42 if constexpr(
sizeof(T) >= 8)
44 x = (x ^ (x << 16)) & T(0x0000ffff0000ffff);
46 if constexpr(
sizeof(T) >= 4)
48 x = (x ^ (x << 8)) & T(0x00ff00ff00ff00ff);
50 if constexpr(
sizeof(T) >= 2)
52 x = (x ^ (x << 4)) & T(0x0f0f0f0f0f0f0f0f);
55 x = (x ^ (x << 2)) & T(0x3333333333333333);
56 x = (x ^ (x << 1)) & T(0x5555555555555555);
73 template <std::
unsigned_
integral T>
78 if constexpr(
sizeof(T) == 1)
81 x = (x | x << 2) & T(0x9);
83 else if constexpr(
sizeof(T) == 2)
86 x = (x | x << 8) & T(0x100f);
87 x = (x | x << 4) & T(0x10c3);
88 x = (x | x << 2) & T(0x1249);
90 else if constexpr(
sizeof(T) == 4)
93 x = (x | x << 16) & T(0x30000ff);
94 x = (x | x << 8) & T(0x300f00f);
95 x = (x | x << 4) & T(0x30c30c3);
96 x = (x | x << 2) & T(0x9249249);
98 else if constexpr(
sizeof(T) == 8)
100 x &= T(0x00000000001fffff);
101 x = (x | x << 32) & T(0x001f00000000ffff);
102 x = (x | x << 16) & T(0x001f0000ff0000ff);
103 x = (x | x << 8) & T(0x100f00f00f00f00f);
104 x = (x | x << 4) & T(0x10c30c30c30c30c3);
105 x = (x | x << 2) & T(0x1249249249249249);
121 template <std::
unsigned_
integral T>
126 x &= T(0x5555555555555555);
127 x = (x ^ (x >> 1)) & T(0x3333333333333333);
128 x = (x ^ (x >> 2)) & T(0x0f0f0f0f0f0f0f0f);
130 if constexpr(
sizeof(T) >= 2)
132 x = (x ^ (x >> 4)) & T(0x00ff00ff00ff00ff);
134 if constexpr(
sizeof(T) >= 4)
136 x = (x ^ (x >> 8)) & T(0x0000ffff0000ffff);
138 if constexpr(
sizeof(T) >= 8)
140 x = (x ^ (x >> 16)) & T(0x00000000ffffffff);
158 template <std::
unsigned_
integral T>
163 if constexpr(
sizeof(T) == 1)
166 x = (x ^ x >> 2) & T(0x3);
168 else if constexpr(
sizeof(T) == 2)
171 x = (x ^ x >> 2) & T(0x10c3);
172 x = (x ^ x >> 4) & T(0x100f);
173 x = (x ^ x >> 8) & T(0x001f);
175 else if constexpr(
sizeof(T) == 4)
178 x = (x ^ x >> 2) & T(0x30c30c3);
179 x = (x ^ x >> 4) & T(0x300f00f);
180 x = (x ^ x >> 8) & T(0x30000ff);
181 x = (x ^ x >> 16) & T(0x00003ff);
183 else if constexpr(
sizeof(T) == 8)
185 x &= T(0x1249249249249249);
186 x = (x ^ x >> 2) & T(0x10c30c30c30c30c3);
187 x = (x ^ x >> 4) & T(0x100f00f00f00f00f);
188 x = (x ^ x >> 8) & T(0x001f0000ff0000ff);
189 x = (x ^ x >> 16) & T(0x001f00000000ffff);
190 x = (x ^ x >> 32) & T(0x00000000001fffff);
constexpr T compress(T x) noexcept
Compresses the even bits of a value into the lower half, then clears the upper half.
constexpr T expand(T x) noexcept
Moves bits from the lower half of a value to occupy all even bits, and clears all odd bits.
constexpr T morton_encode(T x, T y) noexcept
Encodes 2D coordinates as a Morton location code.
void morton_decode(T code, T &x, T &y) noexcept
Decodes 2D coordinates from a Morton location code.