16template <
typename Node>
70 template <
bool IsAnyHit,
typename Stack,
typename LeafFn,
typename InnerFn>
78 template <
bool IsAnyHit,
bool IsRobust,
typename Stack,
typename LeafFn,
typename InnerFn = IgnoreArgs>
83 template <
typename LeafFn = IgnoreArgs,
typename InnerFn = IgnoreArgs>
87 template <
typename LeafFn = IgnoreArgs>
94template <
typename Node>
99 bvh.nodes.emplace_back();
101 std::stack<std::pair<size_t, size_t>> stack;
103 while (!stack.empty()) {
112 prim_ids.begin() +
src_node.index.first_id(),
114 std::back_inserter(
bvh.prim_ids));
117 stack.emplace(
src_node.index.first_id() + 0,
bvh.nodes.size() + 0);
118 stack.emplace(
src_node.index.first_id() + 1,
bvh.nodes.size() + 1);
120 bvh.nodes.emplace_back();
121 bvh.nodes.emplace_back();
127template <
typename Node>
128template <
bool IsAnyHit,
typename Stack,
typename LeafFn,
typename InnerFn>
133 while (!stack.is_empty()) {
134 auto top = stack.pop();
135 while (top.prim_count() == 0) {
136 auto& left = nodes[top.first_id()];
137 auto& right = nodes[top.first_id() + 1];
164template <
typename Node>
165template <
bool IsAnyHit,
bool IsRobust,
typename Stack,
typename LeafFn,
typename InnerFn>
181 return std::make_tuple(
188template <
typename Node>
189template <
typename LeafFn,
typename InnerFn>
191 std::vector<size_t>
parents(nodes.size(), 0);
192 for (
size_t i = 0; i < nodes.size(); ++i) {
193 if (nodes[i].is_leaf())
195 parents[nodes[i].index.first_id()] = i;
196 parents[nodes[i].index.first_id() + 1] = i;
198 std::vector<bool>
seen(nodes.size(),
false);
199 for (
size_t i = nodes.size(); i-- > 0;) {
200 if (!nodes[i].is_leaf())
205 auto& node = nodes[
j];
206 if (
seen[
j] || !
seen[node.index.first_id()] || !
seen[node.index.first_id() + 1])
214template <
typename Node>
215template <
typename LeafFn>
220 node.
set_bbox(left.get_bbox().extend(right.get_bbox()));
224template <
typename Node>
226 stream.
write(nodes.size());
227 stream.
write(prim_ids.size());
228 for (
auto&& node : nodes)
229 node.serialize(stream);
230 for (
auto&&
prim_id : prim_ids)
234template <
typename Node>
237 bvh.nodes.resize(stream.
read<
size_t>());
238 bvh.prim_ids.resize(stream.
read<
size_t>());
239 for (
auto& node :
bvh.nodes)
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
Stream of data that can be used to serialize data structures.
bool write(const T &data)
bool operator==(const Bvh &other) const
bool operator!=(const Bvh &other) const
std::vector< Node > nodes
void refit(LeafFn &&={})
Refits the BVH, using the given function object to recompute the bounding box of the leaves.
static BVH_ALWAYS_INLINE bool is_left_sibling(size_t node_id)
Returns whether the node located at the given index is the left child of its parent.
void intersect(const Ray &ray, Index start, Stack &, LeafFn &&, InnerFn &&={}) const
Intersects the BVH with a single ray, using the given function to intersect the contents of a leaf.
void serialize(OutputStream &) const
static Bvh deserialize(InputStream &)
Bvh extract_bvh(size_t root_id) const
Extracts the BVH rooted at the given node index.
Bvh & operator=(Bvh &&)=default
typename Node::Scalar Scalar
static BVH_ALWAYS_INLINE size_t get_sibling_id(size_t node_id)
Returns the index of a sibling of a node.
void traverse_top_down(Index start, Stack &, LeafFn &&, InnerFn &&) const
Traverses the BVH from the given index in start using the provided stack.
static BVH_ALWAYS_INLINE size_t get_left_sibling_id(size_t node_id)
Returns the index of the left sibling of the node.
static BVH_ALWAYS_INLINE size_t get_right_sibling_id(size_t node_id)
Returns the index of the right sibling of the node.
std::vector< size_t > prim_ids
typename Node::Index Index
void traverse_bottom_up(LeafFn &&={}, InnerFn &&={})
Traverses this BVH from the bottom to the top, using the given function objects to process leaves and...
BVH_ALWAYS_INLINE const Node & get_root() const
Returns the root node of this BVH.
BVH_ALWAYS_INLINE Type first_id() const
Binary BVH node, containing its bounds and an index into its children or the primitives it contains.
static BVH_ALWAYS_INLINE Node deserialize(InputStream &stream)
bvh::v2::Index< IndexBits, PrimCountBits > Index
BVH_ALWAYS_INLINE std::pair< T, T > intersect_robust(const Ray< T, Dim > &ray, const Vec< T, Dim > &inv_dir, const Vec< T, Dim > &inv_dir_pad, const Octant &octant) const
Robust ray-node intersection routine. See "Robust BVH Ray Traversal", by T. Ize.
BVH_ALWAYS_INLINE void set_bbox(const BBox< T, Dim > &bbox)
Index index
Index to the children of an inner node, or to the primitives for a leaf node.
BVH_ALWAYS_INLINE std::pair< T, T > intersect_fast(const Ray< T, Dim > &ray, const Vec< T, Dim > &inv_dir, const Vec< T, Dim > &inv_org, const Octant &octant) const