|
|
|||
File indexing completed on 2026-10-27 09:40:38
0001 //------------------------------- -*- C++ -*- -------------------------------// 0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details 0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT) 0004 //---------------------------------------------------------------------------// 0005 //! \file orange/detail/BvhData.hh 0006 //! \todo move to orange/BvhTreeData 0007 //---------------------------------------------------------------------------// 0008 #pragma once 0009 0010 #include "corecel/Types.hh" 0011 #include "corecel/cont/EnumArray.hh" 0012 #include "corecel/data/Collection.hh" 0013 #include "geocel/BoundingBox.hh" // IWYU pragma: keep 0014 0015 #include "../OrangeTypes.hh" 0016 0017 namespace celeritas 0018 { 0019 namespace detail 0020 { 0021 //---------------------------------------------------------------------------//! 0022 // The maximum depth of the BVH tree (single leaf node is 1) 0023 inline constexpr size_type max_bvh_depth = 18; 0024 0025 //---------------------------------------------------------------------------// 0026 /*! 0027 * Data for a single internal node in a Bounding Volume Hierarchy. 0028 * 0029 * As a convention, a node's LEFT edge corresponds to the half space that is 0030 * less than the partition value. In other words, the LEFT bounding plane 0031 * position is the far right boundary of the left side of the tree, and the 0032 * RIGHT bounding plane position is the far left boundary of the right side of 0033 * the tree. Since the halfspaces created by the bounding planes may overlap, 0034 * the LEFT bounding plane position could be either left or right of the RIGHT 0035 * bounding plane position. 0036 */ 0037 struct BvhInternalNode 0038 { 0039 struct Edge 0040 { 0041 //! The child node connected to this edge 0042 BvhNodeId child; 0043 //! Bbox created by clipping an inf bbox with the bounding planes 0044 //! between this edge (inclusive) and the root. 0045 FastBBox bbox; 0046 }; 0047 0048 enum class Side 0049 { 0050 left, 0051 right, 0052 size_ 0053 }; 0054 0055 Axis axis; //!< Axis that the partition is performed on 0056 EnumArray<Side, Edge> edges; //!< Left/right edges 0057 0058 explicit CELER_FUNCTION operator bool() const 0059 { 0060 return this->edges[Side::left].child && this->edges[Side::right].child; 0061 } 0062 }; 0063 0064 //---------------------------------------------------------------------------// 0065 /*! 0066 * Data for a single leaf node in a Bounding Volume Hierarchy. 0067 */ 0068 struct BvhLeafNode 0069 { 0070 ItemRange<LocalVolumeId> vol_ids; 0071 0072 explicit CELER_FUNCTION operator bool() const { return !vol_ids.empty(); } 0073 }; 0074 0075 //---------------------------------------------------------------------------// 0076 /*! 0077 * Bounding Volume Hierarchy tree. 0078 * 0079 * Infinite bounding boxes are not included in the tree itself. They are stored 0080 * separately and checked after traversing the tree. 0081 */ 0082 struct BvhTreeRecord 0083 { 0084 //// TYPES //// 0085 struct Metadata 0086 { 0087 //! The number of finite bounding boxes in the tree 0088 size_type num_finite_bboxes{}; 0089 //! The number of infinite bounding boxes, i.e., those not included in 0090 //! the tree itself. 0091 size_type num_infinite_bboxes{}; 0092 //! The depth of the most embedded leaf node. This has a value of 1 0093 //! when the root node is a leaf. 0094 size_type depth{}; 0095 }; 0096 0097 //// DATA //// 0098 0099 //! All bounding boxes managed by the BVH 0100 ItemMap<LocalVolumeId, FastBBoxId> bboxes; 0101 0102 //! Internal (branch) nodes, the first being the root 0103 ItemRange<BvhInternalNode> internal_nodes; 0104 0105 //! Leaf nodes 0106 ItemRange<BvhLeafNode> leaf_nodes; 0107 0108 //! Local volumes that have infinite bounding boxes 0109 ItemRange<LocalVolumeId> inf_vol_ids; 0110 0111 //! The metadata for this tree 0112 Metadata metadata; 0113 0114 //// METHODS //// 0115 0116 explicit CELER_FUNCTION operator bool() const 0117 { 0118 if (!internal_nodes.empty()) 0119 { 0120 return !bboxes.empty() && !leaf_nodes.empty(); 0121 } 0122 else 0123 { 0124 // Degenerate single leaf node case. This occurs when a tree 0125 // contains either: 0126 // a) a single volume 0127 // b) multiple non-partitionable volumes, 0128 // b) only infinite volumes. 0129 return !bboxes.empty() && leaf_nodes.size() == 1; 0130 } 0131 } 0132 }; 0133 0134 //---------------------------------------------------------------------------// 0135 /*! 0136 * Persistent data used by all BVH trees. 0137 */ 0138 template<Ownership W, MemSpace M> 0139 struct BvhTreeData 0140 { 0141 template<class T> 0142 using Items = Collection<T, W, M>; 0143 0144 // Low-level storage 0145 Items<FastBBox> bboxes; 0146 Items<LocalVolumeId> local_volume_ids; 0147 Items<detail::BvhInternalNode> internal_nodes; 0148 Items<detail::BvhLeafNode> leaf_nodes; 0149 0150 //! True if assigned 0151 explicit CELER_FUNCTION operator bool() const 0152 { 0153 // Note that internal_nodes may be empty for single-node trees 0154 return !bboxes.empty() && !local_volume_ids.empty() 0155 && !leaf_nodes.empty(); 0156 } 0157 0158 //! Assign from another set of data 0159 template<Ownership W2, MemSpace M2> 0160 BvhTreeData& operator=(BvhTreeData<W2, M2> const& other) 0161 { 0162 bboxes = other.bboxes; 0163 local_volume_ids = other.local_volume_ids; 0164 internal_nodes = other.internal_nodes; 0165 leaf_nodes = other.leaf_nodes; 0166 0167 CELER_ENSURE(static_cast<bool>(*this) == static_cast<bool>(other)); 0168 return *this; 0169 } 0170 }; 0171 0172 //---------------------------------------------------------------------------// 0173 } // namespace detail 0174 } // namespace celeritas
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|