Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-17 09:13:46

0001 #ifndef BVH_V2_INDEX_H
0002 #define BVH_V2_INDEX_H
0003 
0004 #include "bvh/v2/utils.h"
0005 
0006 #include <cassert>
0007 #include <cstddef>
0008 
0009 namespace bvh::v2 {
0010 
0011 /// Packed index data structure. This index can either refer to a range of primitives for a BVH
0012 /// leaf, or to the children of a BVH node. In either case, the index corresponds to a contiguous
0013 /// range, which means that:
0014 ///
0015 /// - For leaves, primitives in a BVH node should be accessed via:
0016 ///
0017 ///     size_t begin = index.first_id();
0018 ///     size_t end   = begin + index.prim_count();
0019 ///     for (size_t i = begin; i < end; ++i) {
0020 ///         size_t prim_id = bvh.prim_ids[i];
0021 ///         // ...
0022 ///     }
0023 ///
0024 ///   Note that for efficiency, reordering the original data to avoid the indirection via
0025 ///   `bvh.prim_ids` is preferable.
0026 ///
0027 /// - For inner nodes, children should be accessed via:
0028 ///
0029 ///   auto& left_child = bvh.nodes[index.first_id()];
0030 ///   auto& right_child = bvh.nodes[index.first_id() + 1];
0031 ///
0032 template <size_t Bits, size_t PrimCountBits>
0033 struct Index {
0034     using Type = UnsignedIntType<Bits>;
0035 
0036     static constexpr size_t bits = Bits;
0037     static constexpr size_t prim_count_bits = PrimCountBits;
0038     static constexpr Type max_prim_count = make_bitmask<Type>(prim_count_bits);
0039     static constexpr Type max_first_id   = make_bitmask<Type>(bits - prim_count_bits);
0040 
0041     static_assert(PrimCountBits < Bits);
0042 
0043     Type value;
0044 
0045     Index() = default;
0046     explicit Index(Type value) : value(value) {}
0047 
0048     //bool operator == (const Index&) const = default;
0049     //bool operator != (const Index&) const = default;
0050     bool operator == (const Index& other) const {
0051         return other.value == value;
0052     }
0053     bool operator != (const Index& other) const {
0054         return other.value != value;
0055     }
0056 
0057     BVH_ALWAYS_INLINE Type first_id() const { return value >> prim_count_bits; }
0058     BVH_ALWAYS_INLINE Type prim_count() const { return value & max_prim_count; }
0059     BVH_ALWAYS_INLINE bool is_leaf() const { return prim_count() != 0; }
0060     BVH_ALWAYS_INLINE bool is_inner() const { return !is_leaf(); }
0061 
0062     BVH_ALWAYS_INLINE void set_first_id(size_t first_id) {
0063         *this = Index { first_id, prim_count() };
0064     }
0065 
0066     BVH_ALWAYS_INLINE void set_prim_count(size_t prim_count) {
0067         *this = Index { first_id(), prim_count };
0068     }
0069 
0070     static BVH_ALWAYS_INLINE Index make_leaf(size_t first_prim, size_t prim_count) {
0071         assert(prim_count != 0);
0072         return Index { first_prim, prim_count };
0073     }
0074 
0075     static BVH_ALWAYS_INLINE Index make_inner(size_t first_child) {
0076         return Index { first_child, 0 };
0077     }
0078 
0079 private:
0080     explicit Index(size_t first_id, size_t prim_count)
0081         : Index(
0082             (static_cast<Type>(first_id) << prim_count_bits) |
0083             (static_cast<Type>(prim_count) & max_prim_count))
0084     {
0085         assert(first_id   <= static_cast<size_t>(max_first_id));
0086         assert(prim_count <= static_cast<size_t>(max_prim_count));
0087     }
0088 };
0089 
0090 } // namespace bvh::v2
0091 
0092 #endif