215 ELEMTYPE globalMin[NUMDIMS];
216 ELEMTYPE globalMax[NUMDIMS];
218 for(
int d = 0; d < NUMDIMS; ++d )
220 globalMin[d] = std::numeric_limits<ELEMTYPE>::max();
221 globalMax[d] = std::numeric_limits<ELEMTYPE>::lowest();
226 for(
int d = 0; d < NUMDIMS; ++d )
228 ELEMTYPE
center = item.min[d] / 2 + item.max[d] / 2;
230 if(
center < globalMin[d] )
233 if(
center > globalMax[d] )
239 std::vector<uint64_t> hilbertValues( n );
241 for(
size_t i = 0; i < n; ++i )
243 uint32_t coords[NUMDIMS];
245 for(
int d = 0; d < NUMDIMS; ++d )
248 double range =
static_cast<double>( globalMax[d] ) - globalMin[d];
252 double normalized = (
static_cast<double>(
center ) - globalMin[d] )
254 coords[d] =
static_cast<uint32_t
>(
255 normalized *
static_cast<double>( UINT32_MAX ) );
267 std::vector<size_t> indices( n );
269 for(
size_t i = 0; i < n; ++i )
272 std::sort( indices.begin(), indices.end(),
273 [&hilbertValues](
size_t a,
size_t b )
275 return hilbertValues[a] < hilbertValues[b];
281 for(
size_t i = 0; i < n; ++i )
285 size_t numLeafNodes = ( n + FANOUT - 1 ) / FANOUT;
288 std::vector<size_t> nodesPerLevel;
289 nodesPerLevel.push_back( numLeafNodes );
291 size_t levelNodes = numLeafNodes;
293 while( levelNodes > 1 )
295 levelNodes = ( levelNodes + FANOUT - 1 ) / FANOUT;
296 nodesPerLevel.push_back( levelNodes );
300 size_t totalNodes = 0;
302 for(
size_t cnt : nodesPerLevel )
306 for(
int axis = 0; axis < NUMDIMS * 2; ++axis )
307 tree.
m_bounds[axis].resize( totalNodes * FANOUT,
308 std::numeric_limits<ELEMTYPE>::max() );
310 tree.
m_counts.resize( totalNodes, 0 );
316 for(
size_t lev = 0; lev < nodesPerLevel.size(); ++lev )
319 offset += nodesPerLevel[lev];
323 for(
size_t i = 0; i < n; ++i )
325 size_t nodeIdx = i / FANOUT;
326 int slot =
static_cast<int>( i % FANOUT );
331 for(
int d = 0; d < NUMDIMS; ++d )
333 tree.
m_bounds[d * 2][globalNodeIdx * FANOUT + slot] = item.
min[d];
334 tree.
m_bounds[d * 2 + 1][globalNodeIdx * FANOUT + slot] = item.
max[d];
337 tree.
m_counts[globalNodeIdx] = slot + 1;
341 for(
size_t lev = 1; lev < nodesPerLevel.size(); ++lev )
344 size_t childLevelCount = nodesPerLevel[lev - 1];
347 for(
size_t ci = 0; ci < childLevelCount; ++ci )
349 size_t parentIdx = ci / FANOUT;
350 int slot =
static_cast<int>( ci % FANOUT );
351 size_t globalParentIdx = parentLevelOffset + parentIdx;
352 size_t globalChildIdx = childLevelOffset + ci;
355 ELEMTYPE childMin[NUMDIMS];
356 ELEMTYPE childMax[NUMDIMS];
358 for(
int d = 0; d < NUMDIMS; ++d )
360 childMin[d] = std::numeric_limits<ELEMTYPE>::max();
361 childMax[d] = std::numeric_limits<ELEMTYPE>::lowest();
364 int childCount = tree.
m_counts[globalChildIdx];
366 for(
int s = 0; s < childCount; ++s )
368 for(
int d = 0; d < NUMDIMS; ++d )
370 ELEMTYPE mn = tree.
m_bounds[d * 2][globalChildIdx * FANOUT + s];
371 ELEMTYPE mx = tree.
m_bounds[d * 2 + 1][globalChildIdx * FANOUT + s];
373 if( mn < childMin[d] )
376 if( mx > childMax[d] )
382 for(
int d = 0; d < NUMDIMS; ++d )
384 tree.
m_bounds[d * 2][globalParentIdx * FANOUT + slot] = childMin[d];
385 tree.
m_bounds[d * 2 + 1][globalParentIdx * FANOUT + slot] = childMax[d];
388 tree.
m_counts[globalParentIdx] = slot + 1;