15#ifndef EBGEOMETRY_PACKEDBVH_HPP
16#define EBGEOMETRY_PACKEDBVH_HPP
28#if defined(__SSE4_1__) || defined(__AVX__)
153[[nodiscard]]
constexpr size_t
156 static_assert(std::is_floating_point_v<T>,
"BVH::DefaultBranchingRatio requires a floating-point T");
180[[nodiscard]]
constexpr size_t
183 static_assert(std::is_floating_point_v<T>,
"BVH::HostBranchingRatio requires a floating-point T");
184#if defined(__AVX512F__)
185 if constexpr (std::is_same_v<T, double>) {
191#elif defined(__AVX__)
192 if constexpr (std::is_same_v<T, double>) {
207template <
class T,
class P,
class BV,
size_t K>
220template <
class T,
class P,
size_t K>
228template <
class P,
class BV>
229using PrimAndBV = std::pair<std::shared_ptr<const P>, BV>;
236template <
class P,
class BV>
252template <
class P,
class BV,
size_t K>
264template <
class T,
class P,
class BV,
size_t K>
287template <
class NodeType,
class NodeKey>
288using PrunePredicate = std::function<bool(
const NodeType& a_node,
const NodeKey& a_nodeKey)>;
299template <
class NodeType,
class NodeKey,
size_t K>
300using ChildOrderer = std::function<void(
Array<std::pair<std::shared_ptr<const NodeType>, NodeKey>, K>& a_children)>;
311template <
class NodeType,
class NodeKey>
355template <
class T,
class P,
size_t K>
358 static_assert(std::is_floating_point_v<T>,
"PackedBVH: T must be a floating-point type");
359 static_assert(K >= 2,
"PackedBVH: branching factor K must be at least 2");
360 static_assert(K <= 256,
"PackedBVH: branching factor K must be at most 256, so a child slot fits in a byte");
361 static_assert(!isPoolHandle<P>,
362 "PackedBVH: a primitive stored in a pool must hold no location; store the handle's Layout "
363 "and pair it with this BVH's location() (see PoolHandle)");
590 template <class Q, class Converter>
624 std::vector<std::pair<P, BV>> a_primsAndBVs,
654 template <
class S = SFC::Morton>
657 buildBottomUp(
Pool& a_pool, std::vector<std::pair<P, BV>> a_primsAndBVs,
size_t a_targetLeafSize);
692 std::vector<std::pair<P, BV>> a_primsAndBVs,
709 std::vector<std::pair<P, BV>> a_primsAndBVs,
756 const std::vector<Node>& a_linearNodes,
757 const std::vector<BV>& a_nodeBoxes,
758 const std::vector<P>& a_primitives)
760 this->finalize(a_pool, a_linearNodes, a_nodeBoxes, a_primitives);
856 static constexpr
size_t
859#if defined(EBGEOMETRY_DEVICE_COMPILE)
1012 template <class Query,
1025 Order a_order = Order()) const noexcept;
1046 template <class BVConstructor>
1048 refit(const BVConstructor& a_bvConstructor);
1067 finalize(
Pool& a_pool,
1068 const std::vector<
Node>& a_linearNodes,
1069 const std::vector<
BV>& a_nodeBoxes,
1070 const std::vector<P>& a_primitives);
1145 uint8_t m_slots[K - 1];
1151 static_assert(K != 4 ||
sizeof(StackEntry) == 8,
"PackedBVH: a stack entry is 8 bytes at K = 4");
1161 static constexpr size_t
1162 stackEntriesFor(
const size_t a_depth)
noexcept
1177 maxNodeDepth(
const void* a_base)
const;
1190 requireDepthFits(
const void* a_base,
const size_t a_maxDepth,
const char* a_context)
const;
1206 requireWellFormed(
const std::vector<Node>& a_linearNodes,
const size_t a_numPrimitives);
1218 buildSoA(
Pool& a_pool,
const std::vector<BV>& a_nodeBoxes);
1228 setRowBox(ChildAABBSoA& a_soa,
size_t a_slot,
const BV& a_bv)
noexcept;
1238 rowBox(
const ChildAABBSoA& a_soa,
size_t a_slot)
noexcept;
1246static_assert(std::is_trivially_copyable_v<PackedBVH<float, Vec3T<float>, 4>>,
1247 "PackedBVH<float, ...> must be trivially copyable");
1248static_assert(std::is_trivially_copyable_v<PackedBVH<double, Vec3T<double>, 4>>,
1249 "PackedBVH<double, ...> must be trivially copyable");
1255#include "EBGeometry_PackedBVHImplem.hpp"
A fixed-size array that compiles for both host and device.
What PackedBVH::traverse() tracks through a tree: query types, the child-box rows they test,...
Declarations of bounding volume types used in bounding volume hierarchies.
#define EBGEOMETRY_HOST_DEVICE
Mark a function as callable from both host and device code (no-op on host compilers).
Definition EBGeometry_GPU.hpp:80
#define EBGEOMETRY_HOST
Mark a function as callable from host code only (no-op on host compilers).
Definition EBGeometry_GPU.hpp:83
Utility macros for EBGeometry.
#define EBGEOMETRY_EXPECT(cond)
Runtime precondition assertion for EBGeometry.
Definition EBGeometry_Macros.hpp:155
Scalar helpers and numeric limits that compile for both host and device.
Placement-independent POD array views for the GPU memory foundation.
Growable bump arena for the GPU memory foundation.
Declaration of 2D and 3D point/vector classes with templated precision, and free functions on them.
Forward declaration of the linearised BVH, defined below.
Definition EBGeometry_PackedBVH.hpp:357
static PackedBVH buildClusterSAH(Pool &a_pool, std::vector< std::pair< P, BV > > a_primsAndBVs, BVH::ClusterSpec a_spec)
Build directly via ClusterSAH: cluster primitives, then SAH over the clusters.
PODSpan< const P > getPrimitives() const noexcept
Get the global primitive list (in leaf-traversal order).
Layout layout() const noexcept
The BVH's arrays without its location, for storing it inside another pool-resident object.
static constexpr uint32_t RootBoxSlot
The box slot of the root, which has no parent row: its box is the BVH's own.
Definition EBGeometry_PackedBVH.hpp:517
T getDistanceToBoundingVolume2(const Node &a_node, const Vec3T< T > &a_point) const noexcept
Get the squared distance from a_point to one of this BVH's nodes' bounding volume.
EBGeometry::BoundingVolumes::AABBT< T > BV
AABB type used for all bounding volumes in this BVH.
Definition EBGeometry_PackedBVH.hpp:369
PackedBVH()=delete
Deleted default constructor. Use build() (or another static build), TreeBVH::pack() or TreeBVH::packW...
T getDistanceToChildBoundingVolume2(const Node &a_parent, size_t a_k, const Vec3T< T > &a_point) const noexcept
Get the squared distance from a_point to the bounding volume of child a_k of an interior node.
static constexpr size_t traversalStackDepth() noexcept
Traversal stack size, in entries, for the current compilation pass.
Definition EBGeometry_PackedBVH.hpp:857
BV computeBoundingVolume() const noexcept
Compute and return the bounding volume of this BVH.
void refit(const BVConstructor &a_bvConstructor)
Refit every node's bounding volume in place after the primitives have moved.
PackedBVH(Pool &a_pool, const std::vector< Node > &a_linearNodes, const std::vector< BV > &a_nodeBoxes, const std::vector< P > &a_primitives)
Adopt a node array, its boxes and a primitive array built elsewhere.
Definition EBGeometry_PackedBVH.hpp:755
~PackedBVH()=default
Destructor.
PackedBVH & operator=(const PackedBVH &a_other)=default
Copy assignment operator.
PackedBVH(const PackedBVH &a_other)=default
Copy constructor.
PackedBVH(PackedBVH &&a_other) noexcept=default
Move constructor.
PackedBVH & operator=(PackedBVH &&a_other) noexcept=default
Move assignment operator.
static PackedBVH buildBottomUp(Pool &a_pool, std::vector< std::pair< P, BV > > a_primsAndBVs, size_t a_targetLeafSize)
Build directly from a flat primitive list along a space-filling curve, without ever building a TreeBV...
void traverse(const Query &a_query, State &a_state, LeafEvaluator &&a_leaf, BoundFn &&a_bound, VisitFn &&a_visit=DescendAll(), Order a_order=Order()) const noexcept
Walk the tree with a query, depth first: the general traversal.
PODSpan< const Node > getNodes() const noexcept
Get the flat node array (depth-first pre-order, root at index 0).
PackedBVH rebasedView(const Pool &a_pool) const noexcept
Produce a copy of this BVH that resolves against a_pool.
PackedBVH deepCopy(Pool &a_dstPool) const
Duplicate this BVH's storage into a_dstPool.
PackedBVH(const Layout &a_layout, const PoolLocation &a_location) noexcept
Rebuild a handle from a stored layout and the location of the pool that holds it.
static PackedBVH buildTopDown(Pool &a_pool, std::vector< std::pair< P, BV > > a_primsAndBVs, const BVH::Partitioner< P, BV, K > &a_partitioner, const BVH::LeafPredicate< T, P, BV, K > &a_stopCrit)
Build directly from a flat primitive list via top-down (optionally SAH) recursive partitioning,...
const BV & getBoundingVolume() const noexcept
Get the bounding volume of the root node.
static PackedBVH buildTopDown(Pool &a_pool, std::vector< std::pair< P, BV > > a_primsAndBVs, const BVH::Partitioner< P, BV, K > &a_partitioner)
Build directly from a primitive list, top-down, with DefaultLeafPredicate.
static BVH::ConstructionOptions defaultConstructionOptions() noexcept
The leaf-size settings build() uses when it is given none.
Definition EBGeometry_PackedBVH.hpp:603
static PackedBVH build(Pool &a_pool, std::vector< std::pair< P, BV > > a_primsAndBVs, BVH::Construction a_construction, const BVH::ConstructionOptions &a_options=defaultConstructionOptions())
Build directly from a flat primitive list with one of the preset methods.
Forward declaration of the tree-structured BVH, defined in EBGeometry_TreeBVH.hpp....
Definition EBGeometry_TreeBVH.hpp:679
Axis-aligned bounding box (AABB) enclosing a set of 3D points.
Definition EBGeometry_BoundingVolumes.hpp:37
Base of every pool-resident handle: the one PoolLocation its arrays resolve against.
Definition EBGeometry_Pool.hpp:499
void * base() noexcept
The base address this handle's offsets resolve against; see PoolLocation::base().
Definition EBGeometry_Pool.hpp:575
Growable bump arena over a MemoryResource.
Definition EBGeometry_Pool.hpp:183
Three-dimensional vector class with arithmetic operators.
Definition EBGeometry_Vec.hpp:258
constexpr size_t HostTraversalDepth
Deepest tree, in node levels (the root alone is one level), that a host traversal handles.
Definition EBGeometry_PackedBVH.hpp:127
std::vector< std::shared_ptr< const P > > PrimitiveList
Convenience alias for a list of shared primitive pointers.
Definition EBGeometry_PackedBVH.hpp:215
std::function< bool(const NodeType &a_node, const NodeKey &a_nodeKey)> PrunePredicate
Node-visit predicate for TreeBVH::traverse().
Definition EBGeometry_PackedBVH.hpp:288
std::function< Array< PrimAndBVList< P, BV >, K >(PrimAndBVList< P, BV > a_primsAndBVs)> Partitioner
Polymorphic partitioner: splits a list of (primitive, BV) pairs into K sub-lists.
Definition EBGeometry_PackedBVH.hpp:253
std::vector< PrimAndBV< P, BV > > PrimAndBVList
Convenience alias for a list of (primitive, bounding-volume) pairs.
Definition EBGeometry_PackedBVH.hpp:237
std::function< bool(const TreeBVH< T, P, BV, K > &a_node)> LeafPredicate
Predicate for deciding when a TreeBVH node should become a leaf (i.e., no further splitting).
Definition EBGeometry_PackedBVH.hpp:265
std::pair< std::shared_ptr< const P >, BV > PrimAndBV
Convenience alias for a (primitive, bounding-volume) pair.
Definition EBGeometry_PackedBVH.hpp:229
std::function< void(const PrimitiveList< P > &a_primitives)> LeafEvaluator
Leaf-evaluation callback for TreeBVH::traverse.
Definition EBGeometry_PackedBVH.hpp:274
std::function< NodeKey(const NodeType &a_node)> NodeKeyFactory
Node-key factory called once per node during TreeBVH::traverse().
Definition EBGeometry_PackedBVH.hpp:312
constexpr size_t DeviceTraversalDepth
Deepest tree, in node levels, that a device traversal handles.
Definition EBGeometry_PackedBVH.hpp:135
constexpr size_t HostBranchingRatio() noexcept
The branching factor K that fills one SIMD register for type T under the compiler's SIMD flags.
Definition EBGeometry_PackedBVH.hpp:181
std::function< void(Array< std::pair< std::shared_ptr< const NodeType >, NodeKey >, K > &a_children)> ChildOrderer
Child-ordering callback for TreeBVH traversal.
Definition EBGeometry_PackedBVH.hpp:300
Construction
The preset BVH construction methods that the library's own BVH users accept.
Definition EBGeometry_PackedBVH.hpp:65
@ Nested
Bottom-up: leaves of consecutive primitives along a Nested (row-major) curve.
@ Hilbert
Bottom-up: leaves of consecutive primitives along a Hilbert curve.
@ Morton
Bottom-up: leaves of consecutive primitives along a Morton (Z-order) curve.
constexpr size_t DefaultBranchingRatio() noexcept
The default branching factor K: 4, for both float and double, in every translation unit.
Definition EBGeometry_PackedBVH.hpp:154
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_Affine.hpp:26
Fixed-size array with host- and device-callable members.
Definition EBGeometry_Array.hpp:33
The boxes of the K children of one interior node, in SoA layout: m_lo[axis][child] and m_hi[axis][chi...
Definition EBGeometry_BVHQuery.hpp:47
Configuration for the ClusterSAH direct PackedBVH construction path.
Definition EBGeometry_PackedBVH.hpp:94
size_t maxClusterSize
Maximum primitives per cluster (bucket); a leaf holds 1 to K-1 clusters. Must be > 0.
Definition EBGeometry_PackedBVH.hpp:95
Leaf-size settings for the preset construction methods, one per family of methods.
Definition EBGeometry_PackedBVH.hpp:115
size_t targetLeafSize
Morton, Nested, Hilbert: target primitives per leaf. Must be > 0.
Definition EBGeometry_PackedBVH.hpp:117
size_t maxLeafSize
SAH, CentroidSplit, MidpointSplit: most primitives in a leaf. Must be > 0.
Definition EBGeometry_PackedBVH.hpp:116
ClusterSpec cluster
ClusterSAH: the cluster size.
Definition EBGeometry_PackedBVH.hpp:118
The default visit callback of PackedBVH::traverse(): enter every node that passes the bound.
Definition EBGeometry_BVHQuery.hpp:101
Visit the children within the bound nearest first (smallest key first). The default: a nearest-primit...
Definition EBGeometry_BVHQuery.hpp:77
The BVH's arrays as offsets into its pool, and its root box: a PackedBVH minus its location.
Definition EBGeometry_PackedBVH.hpp:1105
PODVector< ChildAABBSoA > m_childAabbSoA
SoA child-box rows, one per interior node.
Definition EBGeometry_PackedBVH.hpp:1119
PODVector< BV > m_rootBox
The root's bounding volume (one element, or none for an empty BVH).
Definition EBGeometry_PackedBVH.hpp:1124
PODVector< P > m_primitives
Global primitive list in leaf-traversal order.
Definition EBGeometry_PackedBVH.hpp:1114
PODVector< Node > m_linearNodes
Flat depth-first node array.
Definition EBGeometry_PackedBVH.hpp:1109
Compact BVH node stored in the flat node array.
Definition EBGeometry_PackedBVH.hpp:381
void setNumPrimitives(uint32_t a_n) noexcept
Set the primitive count for this leaf node.
Definition EBGeometry_PackedBVH.hpp:429
void setPrimitivesOffset(uint32_t a_off) noexcept
Set the primitive offset for this leaf node.
Definition EBGeometry_PackedBVH.hpp:418
uint32_t m_boxSlot
Where this node's own box is stored: row * K + slot in the SIMD box array, the row being its parent's...
Definition EBGeometry_PackedBVH.hpp:410
void setChildOffset(uint32_t a_off, size_t a_k) noexcept
Set the depth-first index of the k-th child.
Definition EBGeometry_PackedBVH.hpp:441
uint32_t m_childBoxRow
Row of this interior node's children's boxes in PackedBVH's SIMD box array.
Definition EBGeometry_PackedBVH.hpp:403
const Array< uint32_t, K > & getChildOffsets() const noexcept
Get the child index table.
Definition EBGeometry_PackedBVH.hpp:475
uint32_t getPrimitivesOffset() const noexcept
Get the primitive offset (leaf nodes only).
Definition EBGeometry_PackedBVH.hpp:453
uint32_t getBoxSlot() const noexcept
Get where this node's own box is stored; see m_boxSlot.
Definition EBGeometry_PackedBVH.hpp:497
uint32_t m_primOff
Index of the first primitive in the global primitive list (leaf nodes only).
Definition EBGeometry_PackedBVH.hpp:385
bool isLeaf() const noexcept
Return true if this is a leaf node.
Definition EBGeometry_PackedBVH.hpp:508
uint32_t getNumPrimitives() const noexcept
Get the primitive count.
Definition EBGeometry_PackedBVH.hpp:464
uint32_t getChildBoxRow() const noexcept
Get the row of this interior node's children's boxes in the SIMD box array.
Definition EBGeometry_PackedBVH.hpp:486
Array< uint32_t, K > m_childOff
Depth-first indices of the K child nodes (interior nodes only).
Definition EBGeometry_PackedBVH.hpp:395
uint32_t m_numPrims
Number of primitives in this leaf (zero for interior nodes).
Definition EBGeometry_PackedBVH.hpp:390
Raw pointer + size view into a Pool block, for hot inner loops.
Definition EBGeometry_PODVector.hpp:52
Placement-independent descriptor of a POD array inside a Pool.
Definition EBGeometry_PODVector.hpp:119
Where a pool-resident descriptor resolves its offsets, and the rules for moving it.
Definition EBGeometry_Pool.hpp:99
Implementation of the Morton SFC.
Definition EBGeometry_SFC.hpp:72