EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
Classes | Typedefs | Enumerations | Functions | Variables
EBGeometry::BVH Namespace Reference

Namespace for various bounding volume hierarchy (BVH) functionalities. More...

Classes

struct  ClusterSpec
 Configuration for the ClusterSAH direct PackedBVH construction path. More...
 
class  PackedBVH
 Forward declaration of the linearised BVH. Needed so that TreeBVH::pack() and TreeBVH::packWith() can name their return types before PackedBVH is fully defined. More...
 
struct  SharedPtrStorage
 Default storage policy for PackedBVH: primitives stored as std::shared_ptr<const P>, exactly as PackedBVH has always stored them. More...
 
class  TreeBVH
 Forward declaration of the tree-structured BVH. Needed by LeafPredicate and the default-partitioner lambdas defined below. More...
 
struct  ValueStorage
 Storage policy that stores primitives directly by value, with no pointer indirection at all. More...
 

Typedefs

template<class P >
using PrimitiveList = std::vector< std::shared_ptr< const P > >
 Convenience alias for a list of shared primitive pointers.
 
template<class P , class BV >
using PrimAndBV = std::pair< std::shared_ptr< const P >, BV >
 Convenience alias for a (primitive, bounding-volume) pair.
 
template<class P , class BV >
using PrimAndBVList = std::vector< PrimAndBV< P, BV > >
 Convenience alias for a list of (primitive, bounding-volume) pairs.
 
template<class P , class BV , size_t K>
using Partitioner = std::function< std::array< PrimAndBVList< P, BV >, K >(PrimAndBVList< P, BV > a_primsAndBVs)>
 Polymorphic partitioner: splits a list of (primitive, BV) pairs into K sub-lists.
 
template<class T , class P , class BV , size_t K>
using LeafPredicate = std::function< bool(const TreeBVH< T, P, BV, K > &a_node)>
 Predicate for deciding when a TreeBVH node should become a leaf (i.e., no further splitting).
 
template<class P >
using LeafEvaluator = std::function< void(const PrimitiveList< P > &a_primitives)>
 Leaf-evaluation callback for TreeBVH::traverse.
 
template<class P , class StoragePolicy = SharedPtrStorage<P>>
using PackedLeafEvaluator = std::function< void(const std::vector< typename StoragePolicy::StorageType > &a_primitives, size_t a_offset, size_t a_count)>
 Leaf-evaluation callback for PackedBVH::traverse.
 
template<class NodeType , class NodeKey >
using PrunePredicate = std::function< bool(const NodeType &a_node, const NodeKey &a_nodeKey)>
 Node-visit predicate for BVH traversal.
 
template<class NodeType , class NodeKey , size_t K>
using ChildOrderer = std::function< void(std::array< std::pair< std::shared_ptr< const NodeType >, NodeKey >, K > &a_children)>
 Child-ordering callback for TreeBVH traversal.
 
template<class NodeKey , size_t K>
using PackedChildOrderer = std::function< void(std::array< std::pair< uint32_t, NodeKey >, K > &a_children)>
 Child-ordering callback for PackedBVH traversal.
 
template<class NodeType , class NodeKey >
using NodeKeyFactory = std::function< NodeKey(const NodeType &a_node)>
 Node-key factory called once per node during BVH traversal.
 

Enumerations

enum class  Build { TopDown , Morton , Nested , SAH }
 Enum for specifying the BVH construction strategy. More...
 

Functions

template<typename T >
constexpr size_t DefaultBranchingRatio () noexcept
 Returns the SIMD-optimal BVH branching factor for type T on the current target ISA.
 
template<class T , class P , class BV >
size_t SAH2WaySplit (PrimAndBVList< P, BV > &a_list, const size_t a_begin, const size_t a_end, const bool a_longestAxisOnly=false) noexcept
 Internal helper: 2-way binned SAH split on the sub-range [a_begin, a_end).
 
template<class T , class P , class BV >
void SAHKWaySplit (PrimAndBVList< P, BV > &a_list, const size_t a_begin, const size_t a_end, const size_t a_K, std::vector< std::pair< size_t, size_t > > &a_groups, const bool a_longestAxisOnly=false) noexcept
 Internal helper: recursively split [a_begin, a_end) into a_K groups via 2-way SAH.
 
template<class T , class P , class BV >
size_t Midpoint2WaySplit (PrimAndBVList< P, BV > &a_list, const size_t a_begin, const size_t a_end) noexcept
 Internal helper: 2-way spatial-midpoint split on the sub-range [a_begin, a_end).
 
template<class T , class P , class BV >
void MidpointKWaySplit (PrimAndBVList< P, BV > &a_list, const size_t a_begin, const size_t a_end, const size_t a_K, std::vector< std::pair< size_t, size_t > > &a_groups) noexcept
 Internal helper: recursively split [a_begin, a_end) into a_K groups via 2-way midpoint splits.
 

Variables

template<class X , size_t K>
auto EqualCounts
 Utility: split a vector into K almost-equal contiguous chunks.
 
template<class T , class P , class BV , size_t K>
auto PrimitiveCentroidPartitioner
 Partitioner that sorts primitives by centroid along the longest axis and splits into K pieces.
 
template<class T , class P , class BV , size_t K>
auto BVCentroidPartitioner
 Partitioner that sorts primitives by bounding-volume centroid along the longest axis and splits into K pieces.
 
template<class T , class P , class BV , size_t K, bool LongestAxisOnly = false>
auto BinnedSAHPartitioner
 Partitioner using binned SAH with recursive 2-way subdivision into K groups.
 
template<class T , class P , class BV , size_t K>
auto MidpointPartitioner
 Partitioner that recursively bisects primitives by spatial midpoint (no sorting).
 
template<class T , class P , class BV , size_t K>
auto DefaultLeafPredicate
 Default stop function: stop partitioning when the node holds fewer than K primitives.
 

Detailed Description

Namespace for various bounding volume hierarchy (BVH) functionalities.

Typedef Documentation

◆ ChildOrderer

template<class NodeType , class NodeKey , size_t K>
using EBGeometry::BVH::ChildOrderer = typedef std::function<void(std::array<std::pair<std::shared_ptr<const NodeType>, NodeKey>, K>& a_children)>

Child-ordering callback for TreeBVH traversal.

Sorts an array of (child-node-pointer, key) pairs in-place so that the most promising child is visited first.

Template Parameters
NodeTypeNode type (TreeBVH).
NodeKeyPer-node key attached to each stack entry.
KTree branching factor.
Parameters
[in,out]a_childrenK child nodes together with their node keys.

◆ LeafEvaluator

Leaf-evaluation callback for TreeBVH::traverse.

Called once for every leaf node visited during traversal.

Template Parameters
PPrimitive type.
Parameters
[in]a_primitivesPrimitive list stored in the leaf.

◆ LeafPredicate

template<class T , class P , class BV , size_t K>
using EBGeometry::BVH::LeafPredicate = typedef std::function<bool(const TreeBVH<T, P, BV, K>& a_node)>

Predicate for deciding when a TreeBVH node should become a leaf (i.e., no further splitting).

Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding volume type.
KTree branching factor.
Parameters
[in]a_nodeBVH node under consideration.
Returns
True if the node should not be sub-divided further.

◆ NodeKeyFactory

Node-key factory called once per node during BVH traversal.

Produces the NodeKey value that will be passed to PrunePredicate and ChildOrderer for each child of the current node.

Template Parameters
NodeTypeNode type (TreeBVH or PackedBVH::Node).
NodeKeyPer-node key type to produce.
Parameters
[in]a_nodeCurrent node.
Returns
NodeKey value for a_node's children.

◆ PackedChildOrderer

template<class NodeKey , size_t K>
using EBGeometry::BVH::PackedChildOrderer = typedef std::function<void(std::array<std::pair<uint32_t, NodeKey>, K>& a_children)>

Child-ordering callback for PackedBVH traversal.

Same role as ChildOrderer but uses 32-bit node indices instead of shared_ptrs, halving the stack-entry size.

Template Parameters
NodeKeyPer-node key attached to each stack entry.
KTree branching factor.
Parameters
[in,out]a_childrenK (node-index, key) pairs to sort.

◆ PackedLeafEvaluator

template<class P , class StoragePolicy = SharedPtrStorage<P>>
using EBGeometry::BVH::PackedLeafEvaluator = typedef std::function<void( const std::vector<typename StoragePolicy::StorageType>& a_primitives, size_t a_offset, size_t a_count)>

Leaf-evaluation callback for PackedBVH::traverse.

Receives a view into the global primitive array (offset + count) rather than a temporary sub-list, avoiding a heap allocation per leaf visit. The primitive array's element type depends on the PackedBVH's storage policy (StorageType), not necessarily std::shared_ptr<const P> – see SharedPtrStorage/ValueStorage.

Template Parameters
PPrimitive type.
StoragePolicyPackedBVH storage policy (default: SharedPtrStorage

, matching every PackedBVH<T, P, K> that does not name a storage policy explicitly).

Parameters
[in]a_primitivesGlobal primitive array (element type StoragePolicy::StorageType).
[in]a_offsetIndex of the first primitive belonging to this leaf.
[in]a_countNumber of primitives in this leaf.

◆ Partitioner

template<class P , class BV , size_t K>
using EBGeometry::BVH::Partitioner = typedef std::function<std::array<PrimAndBVList<P, BV>, K>(PrimAndBVList<P, BV> a_primsAndBVs)>

Polymorphic partitioner: splits a list of (primitive, BV) pairs into K sub-lists.

The input list is taken by value (a sink): callers move their list in, and an implementation should partition it in place and move the K sub-lists out – so a whole top-down build reorders primitive handles rather than repeatedly copying them (the built-in partitioners all do this). The split arithmetic is the cheap part; avoiding the copies is what keeps construction fast.

Template Parameters
PPrimitive type.
BVBounding volume type.
KTree branching factor.
Parameters
[in]a_primsAndBVsInput primitives and their bounding volumes (consumed).
Returns
K-element array of sub-lists.

◆ PrimAndBV

template<class P , class BV >
using EBGeometry::BVH::PrimAndBV = typedef std::pair<std::shared_ptr<const P>, BV>

Convenience alias for a (primitive, bounding-volume) pair.

Template Parameters
PPrimitive type.
BVBounding volume type.

◆ PrimAndBVList

template<class P , class BV >
using EBGeometry::BVH::PrimAndBVList = typedef std::vector<PrimAndBV<P, BV> >

Convenience alias for a list of (primitive, bounding-volume) pairs.

Template Parameters
PPrimitive type.
BVBounding volume type enclosing the implicit surface of each primitive.

◆ PrimitiveList

template<class P >
using EBGeometry::BVH::PrimitiveList = typedef std::vector<std::shared_ptr<const P> >

Convenience alias for a list of shared primitive pointers.

Template Parameters
PPrimitive type bounded by the BVH.

◆ PrunePredicate

Node-visit predicate for BVH traversal.

Must return true to descend into the node and false to prune it.

Template Parameters
NodeTypeNode type (TreeBVH or PackedBVH::Node).
NodeKeyCaller-supplied per-node key attached to each stack entry (e.g. a running minimum distance).
Parameters
[in]a_nodeNode under consideration.
[in]a_nodeKeyCaller-supplied key for this stack entry.
Returns
True if the subtree rooted at a_node should be visited.

Enumeration Type Documentation

◆ Build

Enum for specifying the BVH construction strategy.

Enumerator
TopDown 

Recursive top-down partitioning.

Morton 

Bottom-up construction along a Morton space-filling curve.

Nested 

Bottom-up construction along a Nested space-filling curve.

SAH 

Recursive top-down with binned Surface Area Heuristic splitting. This is the recommended default: generally produces better-balanced trees and lower traversal cost than TopDown. Use with BinnedSAHPartitioner. See BinnedSAHPartitioner for recommended K values per ISA.

Function Documentation

◆ DefaultBranchingRatio()

template<typename T >
constexpr size_t EBGeometry::BVH::DefaultBranchingRatio ( )
constexprnoexcept

Returns the SIMD-optimal BVH branching factor for type T on the current target ISA.

Maps the floating-point type and the compile-time ISA to the K that fills one SIMD register exactly:

ISA T=float T=double
AVX-512F 16 8
AVX 8 4
SSE4.1 4 4
fallback 4 4

Usage: size_t K = BVH::DefaultBranchingRatio<T>() as a template-parameter default.

Template Parameters
TFloating-point precision type (float or double).
Returns
Optimal K for the current ISA and T.

◆ Midpoint2WaySplit()

template<class T , class P , class BV >
size_t EBGeometry::BVH::Midpoint2WaySplit ( PrimAndBVList< P, BV > &  a_list,
const size_t  a_begin,
const size_t  a_end 
)
inlinenoexcept

Internal helper: 2-way spatial-midpoint split on the sub-range [a_begin, a_end).

Unlike SAH2WaySplit (which evaluates 32 binned candidate planes) or BVCentroidPartitioner (which sorts by centroid), this computes exactly one split plane – the midpoint of the centroid bounding box along its longest axis – and partitions around it with a single std::partition pass. No sorting and no per-plane cost evaluation, at the cost of not adapting to the primitive distribution the way SAH does: entirely sort-less, O(N) per split.

Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding-volume type.
Parameters
[in,out]a_listPrimitives and their bounding volumes; partitioned in place around the split.
[in]a_beginFirst index of the sub-range to split.
[in]a_endOne-past-the-last index of the sub-range to split.
Returns
Split index (index of the first element of the right group).

◆ MidpointKWaySplit()

template<class T , class P , class BV >
void EBGeometry::BVH::MidpointKWaySplit ( PrimAndBVList< P, BV > &  a_list,
const size_t  a_begin,
const size_t  a_end,
const size_t  a_K,
std::vector< std::pair< size_t, size_t > > &  a_groups 
)
inlinenoexcept

Internal helper: recursively split [a_begin, a_end) into a_K groups via 2-way midpoint splits.

Splits into std::floor(a_K/2) and std::ceil(a_K/2) sub-groups recursively – exact for power-of-two K; a reasonable approximation for other values. Structurally identical to SAHKWaySplit, just calling Midpoint2WaySplit instead of SAH2WaySplit at each level.

Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding-volume type.
Parameters
[in,out]a_listPrimitives and their bounding volumes; partitioned in place.
[in]a_beginFirst index of the sub-range to split.
[in]a_endOne-past-the-last index of the sub-range to split.
[in]a_KNumber of groups to split the sub-range into.
[out]a_groupsResulting groups as [begin, end) index pairs.

◆ SAH2WaySplit()

template<class T , class P , class BV >
size_t EBGeometry::BVH::SAH2WaySplit ( PrimAndBVList< P, BV > &  a_list,
const size_t  a_begin,
const size_t  a_end,
const bool  a_longestAxisOnly = false 
)
inlinenoexcept

Internal helper: 2-way binned SAH split on the sub-range [a_begin, a_end).

Evaluates 32 bins per axis and picks the split plane that minimises SA(left)*N_left + SA(right)*N_right. Partitions a_list in-place and returns the split index (first element of the right group).

Note
Requires BV == AABBT<T>: BV must support getLowCorner(), getHighCorner(), getArea(), and construction from two Vec3T<T> corner arguments.
Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding-volume type (must be AABBT<T>).
Parameters
[in,out]a_listPrimitives and their bounding volumes; partitioned in place around the split.
[in]a_beginFirst index of the sub-range to split.
[in]a_endOne-past-the-last index of the sub-range to split.
[in]a_longestAxisOnlyIf true, evaluate candidate planes on only the longest centroid-bbox axis instead of all three – roughly a third of the binning work, for a small tree-quality cost that is negligible on near-uniform inputs (e.g. point clouds). Default false (full 3-axis SAH).
Returns
Split index (index of the first element of the right group).

◆ SAHKWaySplit()

template<class T , class P , class BV >
void EBGeometry::BVH::SAHKWaySplit ( PrimAndBVList< P, BV > &  a_list,
const size_t  a_begin,
const size_t  a_end,
const size_t  a_K,
std::vector< std::pair< size_t, size_t > > &  a_groups,
const bool  a_longestAxisOnly = false 
)
inlinenoexcept

Internal helper: recursively split [a_begin, a_end) into a_K groups via 2-way SAH.

Splits into std::floor(a_K/2) and std::ceil(a_K/2) sub-groups recursively. For power-of-two K this is equivalent to a balanced binary subdivision tree applied a_K times.

Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding-volume type (must be AABBT<T>).
Parameters
[in,out]a_listPrimitives and their bounding volumes; partitioned in place.
[in]a_beginFirst index of the sub-range to split.
[in]a_endOne-past-the-last index of the sub-range to split.
[in]a_KNumber of groups to split the sub-range into.
[out]a_groupsResulting groups as [begin, end) index pairs.
[in]a_longestAxisOnlyForwarded to SAH2WaySplit: bin only the longest centroid-bbox axis.

Variable Documentation

◆ BinnedSAHPartitioner

template<class T , class P , class BV , size_t K, bool LongestAxisOnly = false>
auto EBGeometry::BVH::BinnedSAHPartitioner
Initial value:
= [](PrimAndBVList<P, BV> a_primsAndBVs) -> std::array<PrimAndBVList<P, BV>, K> {
EBGEOMETRY_EXPECT(!a_primsAndBVs.empty());
std::vector<std::pair<size_t, size_t>> groups;
groups.reserve(K);
SAHKWaySplit<T, P, BV>(a_primsAndBVs, 0, a_primsAndBVs.size(), K, groups, LongestAxisOnly);
std::array<PrimAndBVList<P, BV>, K> result;
for (size_t k = 0; k < K; k++) {
const auto [b, e] = groups[k];
result[k] = PrimAndBVList<P, BV>(std::make_move_iterator(a_primsAndBVs.begin() + b),
std::make_move_iterator(a_primsAndBVs.begin() + e));
}
return result;
}
#define EBGEOMETRY_EXPECT(cond)
Runtime precondition assertion for EBGeometry.
Definition EBGeometry_Macros.hpp:62
Three-dimensional vector class with arithmetic operators.
Definition EBGeometry_Vec.hpp:225

Partitioner using binned SAH with recursive 2-way subdivision into K groups.

For each split, evaluates 32 candidate planes per axis and picks the one minimising SA(left)*N_left + SA(right)*N_right (the standard ray-tracing SAH cost without the traversal constant). K groups are produced by recursively splitting into std::floor(K/2) and std::ceil(K/2) subsets — exact for power-of-two K; a reasonable approximation for other values.

Recommended K values by ISA:

  • AVX-512F, float → K=16 (one _mm512_load_ps covers all K children)
  • AVX-512F, double → K=8 (one _mm512_load_pd covers all K children)
  • AVX, float → K=8 (one _mm256_load_ps)
  • AVX, double → K=4 (one _mm256_load_pd)
  • SSE4.1, float → K=4 (one _mm_load_ps)
Note
Requires BV == AABBT<T>.
Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding-volume type (must be AABBT<T>).
KNumber of output sub-lists (branching factor of the resulting BVH).
LongestAxisOnlyIf true, bin candidate planes on only the longest centroid-bbox axis per split instead of all three – ~a third of the binning work (measured ~20% faster builds on point clouds) for a tree-quality cost that is negligible on near-uniform inputs. Default false.
Parameters
[in]a_primsAndBVsInput (primitive, BV) pairs.
Returns
K sub-lists.

◆ BVCentroidPartitioner

template<class T , class P , class BV , size_t K>
auto EBGeometry::BVH::BVCentroidPartitioner
Initial value:
= [](PrimAndBVList<P, BV> a_primsAndBVs) -> std::array<PrimAndBVList<P, BV>, K> {
EBGEOMETRY_EXPECT(!a_primsAndBVs.empty());
Vec3T<T> lo = +Vec3T<T>::max();
Vec3T<T> hi = -Vec3T<T>::max();
for (const auto& pbv : a_primsAndBVs) {
lo = min(lo, pbv.second.getCentroid());
hi = max(hi, pbv.second.getCentroid());
}
const size_t splitDir = (hi - lo).maxDir(true);
std::sort(a_primsAndBVs.begin(),
[splitDir](const PrimAndBV<P, BV>& pbv1, const PrimAndBV<P, BV>& pbv2) -> bool {
return pbv1.second.getCentroid()[splitDir] < pbv2.second.getCentroid()[splitDir];
});
return BVH::EqualCounts<PrimAndBV<P, BV>, K>(std::move(a_primsAndBVs));
}
Vec2T< T > min(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Component-wise minimum of two vectors.
Vec2T< T > max(const Vec2T< T > &u, const Vec2T< T > &v) noexcept
Component-wise maximum of two vectors.

Partitioner that sorts primitives by bounding-volume centroid along the longest axis and splits into K pieces.

Template Parameters
TFloating-point precision used for centroid comparisons.
PPrimitive type.
BVBounding volume type.
KNumber of output sub-lists (tree branching factor).
Parameters
[in]a_primsAndBVsInput (primitive, BV) pairs.
Returns
K sub-lists.

◆ DefaultLeafPredicate

template<class T , class P , class BV , size_t K>
auto EBGeometry::BVH::DefaultLeafPredicate
Initial value:
=
[](const BVH::TreeBVH<T, P, BV, K>& a_node) noexcept -> bool { return (a_node.getPrimitives()).size() < K; }

Default stop function: stop partitioning when the node holds fewer than K primitives.

Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding volume type.
KTree branching factor.
Parameters
[in]a_nodeBVH node.
Returns
True if the node has fewer than K primitives.

◆ EqualCounts

template<class X , size_t K>
auto EBGeometry::BVH::EqualCounts
Initial value:
= [](std::vector<X> a_primitives) noexcept -> std::array<std::vector<X>, K> {
static_assert(K >= 2, "EqualCounts<X, K>: branching factor K must be at least 2");
EBGEOMETRY_EXPECT(!a_primitives.empty());
const int length = a_primitives.size() / K;
int remain = a_primitives.size() % K;
int begin = 0;
int end = 0;
std::array<std::vector<X>, K> chunks;
for (size_t k = 0; k < K; k++) {
end += (remain > 0) ? length + 1 : length;
remain--;
chunks[k] = std::vector<X>(std::make_move_iterator(a_primitives.begin() + begin),
std::make_move_iterator(a_primitives.begin() + end));
begin = end;
}
return chunks;
}
T length(const Vec2T< T > &v) noexcept
Euclidean length of a 2D vector.

Utility: split a vector into K almost-equal contiguous chunks.

Template Parameters
XElement type.
KNumber of chunks.
Parameters
[in]a_primitivesInput vector.
Returns
Array of K sub-vectors whose sizes differ by at most 1.

◆ MidpointPartitioner

template<class T , class P , class BV , size_t K>
auto EBGeometry::BVH::MidpointPartitioner
Initial value:
= [](PrimAndBVList<P, BV> a_primsAndBVs) -> std::array<PrimAndBVList<P, BV>, K> {
EBGEOMETRY_EXPECT(!a_primsAndBVs.empty());
std::vector<std::pair<size_t, size_t>> groups;
groups.reserve(K);
MidpointKWaySplit<T, P, BV>(a_primsAndBVs, 0, a_primsAndBVs.size(), K, groups);
std::array<PrimAndBVList<P, BV>, K> result;
for (size_t k = 0; k < K; k++) {
const auto [b, e] = groups[k];
result[k] = PrimAndBVList<P, BV>(std::make_move_iterator(a_primsAndBVs.begin() + b),
std::make_move_iterator(a_primsAndBVs.begin() + e));
}
return result;
}

Partitioner that recursively bisects primitives by spatial midpoint (no sorting).

At every split, computes the midpoint of the centroid bounding box along its longest axis and partitions primitives around it in one O(N) std::partition pass – unlike BVCentroidPartitioner (sorts by centroid) or BinnedSAHPartitioner (evaluates 32 candidate planes per axis), no sorting or per-plane cost evaluation happens anywhere. K groups are produced by recursively splitting into std::floor(K/2) and std::ceil(K/2) subsets, mirroring BinnedSAHPartitioner's own K-way structure exactly (see MidpointKWaySplit).

This is the fastest of the three top-down partitioners to build (no sort, no per-axis binning), at the cost of build quality: it does not adapt to the primitive distribution at all, so a heavily clustered or skewed input can produce noticeably less balanced (and less query-efficient) trees than BVCentroidPartitioner or BinnedSAHPartitioner would.

Template Parameters
TFloating-point precision.
PPrimitive type.
BVBounding-volume type.
KNumber of output sub-lists (branching factor of the resulting BVH).
Parameters
[in]a_primsAndBVsInput (primitive, BV) pairs.
Returns
K sub-lists.

◆ PrimitiveCentroidPartitioner

template<class T , class P , class BV , size_t K>
auto EBGeometry::BVH::PrimitiveCentroidPartitioner
Initial value:
=
[](PrimAndBVList<P, BV> a_primsAndBVs) noexcept -> std::array<PrimAndBVList<P, BV>, K> {
EBGEOMETRY_EXPECT(!a_primsAndBVs.empty());
Vec3T<T> lo = +Vec3T<T>::max();
Vec3T<T> hi = -Vec3T<T>::max();
for (const auto& pbv : a_primsAndBVs) {
lo = min(lo, pbv.first->getCentroid());
hi = max(hi, pbv.first->getCentroid());
}
const size_t splitDir = (hi - lo).maxDir(true);
std::sort(a_primsAndBVs.begin(),
[splitDir](const PrimAndBV<P, BV>& pbv1, const PrimAndBV<P, BV>& pbv2) -> bool {
return pbv1.first->getCentroid(splitDir) < pbv2.first->getCentroid(splitDir);
});
return BVH::EqualCounts<PrimAndBV<P, BV>, K>(std::move(a_primsAndBVs));
}

Partitioner that sorts primitives by centroid along the longest axis and splits into K pieces.

Template Parameters
TFloating-point precision used for centroid comparisons.
PPrimitive type.
BVBounding volume type.
KNumber of output sub-lists (tree branching factor).
Parameters
[in]a_primsAndBVsInput (primitive, BV) pairs.
Returns
K sub-lists.