209 ELEMTYPE globalMin[NUMDIMS];
210 ELEMTYPE globalMax[NUMDIMS];
212 for(
int d = 0; d < NUMDIMS; ++d )
214 globalMin[d] = std::numeric_limits<ELEMTYPE>::max();
215 globalMax[d] = std::numeric_limits<ELEMTYPE>::lowest();
220 for(
int d = 0; d < NUMDIMS; ++d )
222 ELEMTYPE
center = item.min[d] / 2 + item.max[d] / 2;
224 if(
center < globalMin[d] )
227 if(
center > globalMax[d] )
233 std::vector<uint64_t> hilbertValues( n );
235 for(
size_t i = 0; i < n; ++i )
237 uint32_t coords[NUMDIMS];
239 for(
int d = 0; d < NUMDIMS; ++d )
242 double range =
static_cast<double>( globalMax[d] ) - globalMin[d];
246 double normalized = (
static_cast<double>(
center ) - globalMin[d] ) / range;
247 coords[d] =
static_cast<uint32_t
>(
normalized *
static_cast<double>( UINT32_MAX ) );
259 std::vector<size_t> indices( n );
261 for(
size_t i = 0; i < n; ++i )
264 std::sort( indices.begin(), indices.end(),
265 [&hilbertValues](
size_t a,
size_t b )
267 return hilbertValues[a] < hilbertValues[b];
273 for(
size_t i = 0; i < n; ++i )
277 size_t numLeafNodes = ( n + FANOUT - 1 ) / FANOUT;
280 std::vector<size_t> nodesPerLevel;
281 nodesPerLevel.push_back( numLeafNodes );
283 size_t levelNodes = numLeafNodes;
285 while( levelNodes > 1 )
287 levelNodes = ( levelNodes + FANOUT - 1 ) / FANOUT;
288 nodesPerLevel.push_back( levelNodes );
292 size_t totalNodes = 0;
294 for(
size_t cnt : nodesPerLevel )
298 for(
int axis = 0; axis < NUMDIMS * 2; ++axis )
299 tree.
m_bounds[axis].resize( totalNodes * FANOUT, std::numeric_limits<ELEMTYPE>::max() );
301 tree.
m_counts.resize( totalNodes, 0 );
307 for(
size_t lev = 0; lev < nodesPerLevel.size(); ++lev )
310 offset += nodesPerLevel[lev];
314 for(
size_t i = 0; i < n; ++i )
316 size_t nodeIdx = i / FANOUT;
317 int slot =
static_cast<int>( i % FANOUT );
322 for(
int d = 0; d < NUMDIMS; ++d )
324 tree.
m_bounds[d * 2][globalNodeIdx * FANOUT + slot] = item.
min[d];
325 tree.
m_bounds[d * 2 + 1][globalNodeIdx * FANOUT + slot] = item.
max[d];
328 tree.
m_counts[globalNodeIdx] = slot + 1;
332 for(
size_t lev = 1; lev < nodesPerLevel.size(); ++lev )
335 size_t childLevelCount = nodesPerLevel[lev - 1];
338 for(
size_t ci = 0; ci < childLevelCount; ++ci )
340 size_t parentIdx = ci / FANOUT;
341 int slot =
static_cast<int>( ci % FANOUT );
342 size_t globalParentIdx = parentLevelOffset + parentIdx;
343 size_t globalChildIdx = childLevelOffset + ci;
346 ELEMTYPE childMin[NUMDIMS];
347 ELEMTYPE childMax[NUMDIMS];
349 for(
int d = 0; d < NUMDIMS; ++d )
351 childMin[d] = std::numeric_limits<ELEMTYPE>::max();
352 childMax[d] = std::numeric_limits<ELEMTYPE>::lowest();
355 int childCount = tree.
m_counts[globalChildIdx];
357 for(
int s = 0; s < childCount; ++s )
359 for(
int d = 0; d < NUMDIMS; ++d )
361 ELEMTYPE mn = tree.
m_bounds[d * 2][globalChildIdx * FANOUT + s];
362 ELEMTYPE mx = tree.
m_bounds[d * 2 + 1][globalChildIdx * FANOUT + s];
364 if( mn < childMin[d] )
367 if( mx > childMax[d] )
373 for(
int d = 0; d < NUMDIMS; ++d )
375 tree.
m_bounds[d * 2][globalParentIdx * FANOUT + slot] = childMin[d];
376 tree.
m_bounds[d * 2 + 1][globalParentIdx * FANOUT + slot] = childMax[d];
379 tree.
m_counts[globalParentIdx] = slot + 1;