1
+ #ifndef PBAT_GEOMETRY_MORTON_H
2
+ #define PBAT_GEOMETRY_MORTON_H
3
+
4
+ #include " pbat/HostDevice.h"
5
+
6
+ #include < array>
7
+ #include < cmath>
8
+ #include < cstddef>
9
+
10
+ namespace pbat {
11
+ namespace geometry {
12
+
13
+ using MortonCodeType = std::uint32_t ;
14
+
15
+ // NOTE:
16
+ // We make these (otherwise non-templated) functions inline so that they
17
+ // are compiled by nvcc whenever this header is included in cuda sources.
18
+
19
+ // Expands a 10-bit integer into 30 bits
20
+ // by inserting 2 zeros after each bit.
21
+ PBAT_HOST_DEVICE inline MortonCodeType ExpandBits (MortonCodeType v)
22
+ {
23
+ v = (v * 0x00010001u ) & 0xFF0000FFu ;
24
+ v = (v * 0x00000101u ) & 0x0F00F00Fu ;
25
+ v = (v * 0x00000011u ) & 0xC30C30C3u ;
26
+ v = (v * 0x00000005u ) & 0x49249249u ;
27
+ return v;
28
+ }
29
+
30
+ // Calculates a 30-bit Morton code for the
31
+ // given 3D point located within the unit cube [0,1].
32
+ [[maybe_unused]] PBAT_HOST_DEVICE inline MortonCodeType Morton3D (std::array<float , 3 > x)
33
+ {
34
+ using namespace std ;
35
+ x[0 ] = min (max (x[0 ] * 1024 .0f , 0 .0f ), 1023 .0f );
36
+ x[1 ] = min (max (x[1 ] * 1024 .0f , 0 .0f ), 1023 .0f );
37
+ x[2 ] = min (max (x[2 ] * 1024 .0f , 0 .0f ), 1023 .0f );
38
+ MortonCodeType xx = ExpandBits (static_cast <MortonCodeType>(x[0 ]));
39
+ MortonCodeType yy = ExpandBits (static_cast <MortonCodeType>(x[1 ]));
40
+ MortonCodeType zz = ExpandBits (static_cast <MortonCodeType>(x[2 ]));
41
+ return xx * 4 + yy * 2 + zz;
42
+ }
43
+
44
+ } // namespace geometry
45
+ } // namespace pbat
46
+
47
+ #endif // PBAT_GEOMETRY_MORTON_H
0 commit comments