Fermat
morton.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2010-2018, NVIDIA Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of NVIDIA Corporation nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
32 #pragma once
33 
34 #include <cugar/basic/types.h>
35 #include <cugar/linalg/vector.h>
36 
37 namespace cugar {
38 
52 
55 
60 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 morton_code(
61  uint32 x,
62  uint32 y)
63 {
64  x &= 0x0000ffff;
65  y &= 0x0000ffff;
66 
67  x = (x | (x << 8)) & 0x00FF00FF;
68  x = (x | (x << 4)) & 0x0F0F0F0F;
69  x = (x | (x << 2)) & 0x33333333;
70  x = (x | (x << 1)) & 0x55555555;
71 
72  y = (y | (y << 8)) & 0x00FF00FF;
73  y = (y | (y << 4)) & 0x0F0F0F0F;
74  y = (y | (y << 2)) & 0x33333333;
75  y = (y | (y << 1)) & 0x55555555;
76 
77  return x | (y << 1);
78 }
79 
85 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 morton_code(
86  uint32 x,
87  uint32 y,
88  uint32 z)
89 {
90  x = (x | (x << 16)) & 0x030000FF;
91  x = (x | (x << 8)) & 0x0300F00F;
92  x = (x | (x << 4)) & 0x030C30C3;
93  x = (x | (x << 2)) & 0x09249249;
94 
95  y = (y | (y << 16)) & 0x030000FF;
96  y = (y | (y << 8)) & 0x0300F00F;
97  y = (y | (y << 4)) & 0x030C30C3;
98  y = (y | (y << 2)) & 0x09249249;
99 
100  z = (z | (z << 16)) & 0x030000FF;
101  z = (z | (z << 8)) & 0x0300F00F;
102  z = (z | (z << 4)) & 0x030C30C3;
103  z = (z | (z << 2)) & 0x09249249;
104 
105  return x | (y << 1) | (z << 2);
106 }
107 
112 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint64 morton_code60(
113  uint32 _x,
114  uint32 _y)
115 {
116  uint64 x = _x;
117  uint64 y = _y;
118 
119  x = (x | (x << 16)) & 0x0000FFFF0000FFFFull;
120  x = (x | (x << 8)) & 0x00FF00FF00FF00FFull;
121  x = (x | (x << 4)) & 0x0F0F0F0F0F0F0F0Full;
122  x = (x | (x << 2)) & 0x3333333333333333ull;
123  x = (x | (x << 1)) & 0x5555555555555555ull;
124 
125  y = (y | (y << 16)) & 0x0000FFFF0000FFFFull;
126  y = (y | (y << 8)) & 0x00FF00FF00FF00FFull;
127  y = (y | (y << 4)) & 0x0F0F0F0F0F0F0F0Full;
128  y = (y | (y << 2)) & 0x3333333333333333ull;
129  y = (y | (y << 1)) & 0x5555555555555555ull;
130 
131  return x | (y << 1);
132 }
133 
139 CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint64 morton_code60(
140  uint32 x,
141  uint32 y,
142  uint32 z)
143 {
144  uint32 lo_x = x & 1023u;
145  uint32 lo_y = y & 1023u;
146  uint32 lo_z = z & 1023u;
147  uint32 hi_x = x >> 10u;
148  uint32 hi_y = y >> 10u;
149  uint32 hi_z = z >> 10u;
150 
151  return
152  (uint64(morton_code( hi_x, hi_y, hi_z )) << 30) |
153  uint64(morton_code( lo_x, lo_y, lo_z ));
154 }
155 
156 
159 template <typename Integer, uint32 DIM, typename BboxType>
160 struct morton_functor {};
161 
164 template <typename BboxType>
165 struct morton_functor<uint32, 2u, BboxType>
166 {
167  typedef typename BboxType::value_type value_type;
168  typedef typename BboxType::vector_type vector_type;
169 
173  CUGAR_HOST_DEVICE morton_functor(const Bbox2f& bbox) :
174  m_base( bbox[0] ),
175  m_inv(
176  value_type(1.0) / (bbox[1][0] - bbox[0][0]),
177  value_type(1.0) / (bbox[1][1] - bbox[0][1]) )
178  {}
179 
180  template <typename Point_type>
181  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 operator() (const Point_type point) const
182  {
183  uint32 x = quantize( (point[0] - m_base[0]) * m_inv[0], 65536u );
184  uint32 y = quantize( (point[1] - m_base[1]) * m_inv[1], 65536u );
185 
186  return morton_code( x, y );
187  }
188 
189  const vector_type m_base;
190  const vector_type m_inv;
191 };
192 
195 template <typename BboxType>
196 struct morton_functor<uint64, 2u, BboxType>
197 {
198  typedef typename BboxType::value_type value_type;
199  typedef typename BboxType::vector_type vector_type;
200 
204  CUGAR_HOST_DEVICE morton_functor(const Bbox2f& bbox) :
205  m_base( bbox[0] ),
206  m_inv(
207  value_type(1.0) / (bbox[1][0] - bbox[0][0]),
208  value_type(1.0) / (bbox[1][1] - bbox[0][1]) )
209  {}
210 
211  template <typename Point_type>
212  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint64 operator() (const Point_type point) const
213  {
214  uint32 x = quantize( (point[0] - m_base[0]) * m_inv[0], 0xFFFFFFFFu );
215  uint32 y = quantize( (point[1] - m_base[1]) * m_inv[1], 0xFFFFFFFFu );
216 
217  return morton_code60( x, y );
218  }
219 
220  const vector_type m_base;
221  const vector_type m_inv;
222 };
223 
226 template <typename BboxType>
227 struct morton_functor<uint32, 3u, BboxType>
228 {
229  typedef typename BboxType::value_type value_type;
230  typedef typename BboxType::vector_type vector_type;
231 
235  CUGAR_HOST_DEVICE morton_functor(const BboxType& bbox) :
236  m_base( bbox[0] ),
237  m_inv(
238  value_type(1.0) / (bbox[1][0] - bbox[0][0]),
239  value_type(1.0) / (bbox[1][1] - bbox[0][1]),
240  value_type(1.0) / (bbox[1][2] - bbox[0][2]) )
241  {}
242 
243  template <typename Point_type>
244  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 operator() (const Point_type point) const
245  {
246  uint32 x = quantize( (point[0] - m_base[0]) * m_inv[0], 1024u );
247  uint32 y = quantize( (point[1] - m_base[1]) * m_inv[1], 1024u );
248  uint32 z = quantize( (point[2] - m_base[2]) * m_inv[2], 1024u );
249 
250  return morton_code( x, y, z );
251  }
252 
253  const vector_type m_base;
254  const vector_type m_inv;
255 };
256 
259 template <typename BboxType>
260 struct morton_functor<uint64, 3u, BboxType>
261 {
262  typedef typename BboxType::value_type value_type;
263  typedef typename BboxType::vector_type vector_type;
264 
268  CUGAR_HOST_DEVICE morton_functor(const BboxType& bbox) :
269  m_base( bbox[0] ),
270  m_inv(
271  value_type(1.0) / (bbox[1][0] - bbox[0][0]),
272  value_type(1.0) / (bbox[1][1] - bbox[0][1]),
273  value_type(1.0) / (bbox[1][2] - bbox[0][2]) )
274  {}
275 
276  template <typename Point_type>
277  CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint64 operator() (const Point_type point) const
278  {
279  uint32 x = quantize( (point[0] - m_base[0]) * m_inv[0], 1u << 20 );
280  uint32 y = quantize( (point[1] - m_base[1]) * m_inv[1], 1u << 20 );
281  uint32 z = quantize( (point[2] - m_base[2]) * m_inv[2], 1u << 20 );
282 
283  return morton_code60( x, y, z );
284  }
285 
286  const vector_type m_base;
287  const vector_type m_inv;
288 };
289 
291 
292 } // namespace cugar
CUGAR_HOST_DEVICE morton_functor(const BboxType &bbox)
Definition: morton.h:235
CUGAR_HOST_DEVICE uint32 quantize(const float x, const uint32 n)
Definition: numbers.h:600
CUGAR_HOST_DEVICE morton_functor(const Bbox2f &bbox)
Definition: morton.h:204
Definition: morton.h:160
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint32 morton_code(uint32 x, uint32 y)
Definition: morton.h:60
Definition: bbox.h:59
CUGAR_FORCEINLINE CUGAR_HOST_DEVICE uint64 morton_code60(uint32 _x, uint32 _y)
Definition: morton.h:112
Define a vector_view POD type and plain_view() for std::vector.
Definition: diff.h:38
CUGAR_HOST_DEVICE morton_functor(const BboxType &bbox)
Definition: morton.h:268
CUGAR_HOST_DEVICE morton_functor(const Bbox2f &bbox)
Definition: morton.h:173