Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:00:07

0001 // This file is part of VecGeom and is distributed under the
0002 // conditions in the file LICENSE.txt in the top directory.
0003 // For the full list of authors see CONTRIBUTORS.txt and `git log`.
0004 
0005 /// \file management/NavIndexTableLayout.h
0006 /// \brief Field offsets and helper routines for encoded navigation table records.
0007 
0008 #ifndef VECGEOM_MANAGEMENT_NAVINDEXTABLELAYOUT_H_
0009 #define VECGEOM_MANAGEMENT_NAVINDEXTABLELAYOUT_H_
0010 
0011 #include "VecGeom/base/Global.h"
0012 
0013 namespace vecgeom {
0014 inline namespace VECGEOM_IMPL_NAMESPACE {
0015 namespace NavIndexTableLayout {
0016 
0017 /// \brief Byte-level alignment helper for `Precision` data stored in a `NavIndex_t` table.
0018 VECCORE_ATT_HOST_DEVICE
0019 VECGEOM_FORCE_INLINE
0020 bool NeedsPrecisionPadding(NavIndex_t element) { return (element * sizeof(NavIndex_t)) % sizeof(Precision) != 0; }
0021 
0022 /**
0023  * @brief Layout of the expanded navigation table used by `NavStateIndex`.
0024  *
0025  * @details Each touchable has one record in the table, addressed by a
0026  * `NavIndex_t`. The record starts with parent, touchable id, placed-volume id,
0027  * child id, logical-volume id, and one packed metadata word. The daughter block
0028  * follows immediately after these fixed fields and stores the navigation index
0029  * of each daughter touchable. Optional padding aligns the following cached
0030  * transformation block to `Precision` alignment.
0031  *
0032  * The packed metadata word stores the global level and transformation flags in
0033  * byte-sized fields, followed by the daughter count as an unsigned short. The
0034  * daughter count is therefore limited by the range of that field.
0035  *
0036  * For the rationale behind this representation and its tradeoffs with the
0037  * tuple table, see @ref navigation_state_tables.
0038  */
0039 namespace Index {
0040 
0041 /// \brief `NavStateIndex` record fields, expressed as `NavIndex_t` offsets from the record start.
0042 static constexpr NavIndex_t kParent        = 0;
0043 static constexpr NavIndex_t kTouchableId   = 1;
0044 static constexpr NavIndex_t kPlacedVolume  = 2;
0045 static constexpr NavIndex_t kChildId       = 3;
0046 static constexpr NavIndex_t kLogicalVolume = 4;
0047 static constexpr NavIndex_t kPacked        = 5;
0048 static constexpr NavIndex_t kDaughters     = 6;
0049 
0050 /// \brief Byte offsets inside the packed `NavStateIndex` field at `kPacked`.
0051 static constexpr unsigned int kLevelByte         = 0;
0052 static constexpr unsigned int kMatrixFlagsByte   = 1;
0053 static constexpr unsigned int kDaughterCountByte = 2;
0054 
0055 /// \brief Bits stored in the `kMatrixFlagsByte` byte.
0056 static constexpr unsigned char kHasRotationFlag     = 0x01;
0057 static constexpr unsigned char kHasTranslationFlag  = 0x02;
0058 static constexpr unsigned char kHasStoredMatrixFlag = 0x04;
0059 
0060 /// \brief Number of `Precision` values stored for a cached `NavStateIndex` transform.
0061 static constexpr unsigned int kStoredTransformPrecisionCount = 12;
0062 
0063 /// \brief Returns the first table element after the daughter-index block, before alignment padding.
0064 VECCORE_ATT_HOST_DEVICE
0065 VECGEOM_FORCE_INLINE
0066 NavIndex_t TransformBase(NavIndex_t record, unsigned int ndaughters)
0067 {
0068   return record + kDaughters + ndaughters + ((ndaughters + 1) & 1);
0069 }
0070 
0071 /// \brief Returns the aligned table element where cached transform data starts.
0072 VECCORE_ATT_HOST_DEVICE
0073 VECGEOM_FORCE_INLINE
0074 NavIndex_t TransformStart(NavIndex_t record, unsigned int ndaughters)
0075 {
0076   auto start = TransformBase(record, ndaughters);
0077   start += unsigned{NeedsPrecisionPadding(start)};
0078   return start;
0079 }
0080 
0081 } // namespace Index
0082 
0083 /**
0084  * @brief Layout of the scene-compressed navigation table used by `NavStateTuple`.
0085  *
0086  * @details The tuple representation separates touchable records from shared
0087  * logical-volume records. A touchable record stores the parent within the
0088  * current scene, placed-volume id, child id, touchable id, logical-record
0089  * address, packed scene ids, and packed metadata. Optional transform data can
0090  * follow these fixed fields. The logical-volume record stores the compact
0091  * logical-volume id, daughter count, and daughter touchable-record addresses.
0092  *
0093  * A `NavStateTuple` stores one scene-local touchable index per active scene.
0094  * When traversal enters a new scene, a new tuple component is pushed instead of
0095  * expanding the repeated subtree for every parent context. The scene field
0096  * stores the parent scene id and the current scene id as two unsigned-short
0097  * halves.
0098  *
0099  * For the rationale behind this representation and its tradeoffs with the
0100  * expanded index table, see @ref navigation_state_tables.
0101  */
0102 namespace Tuple {
0103 
0104 /// \brief `NavStateTuple` touchable-record fields, expressed as `NavIndex_t` offsets from the record start.
0105 static constexpr NavIndex_t kParent                      = 0;
0106 static constexpr NavIndex_t kPlacedVolume                = 1;
0107 static constexpr NavIndex_t kChildId                     = 2;
0108 static constexpr NavIndex_t kTouchableId                 = 3;
0109 static constexpr NavIndex_t kLogicalRecord               = 4;
0110 static constexpr NavIndex_t kScenes                      = 5;
0111 static constexpr NavIndex_t kPacked                      = 6;
0112 static constexpr NavIndex_t kRecordFieldsBeforeTransform = 7;
0113 
0114 /// \brief Half-word offsets inside the packed scene field at `kScenes`.
0115 static constexpr unsigned int kParentSceneHalf  = 0;
0116 static constexpr unsigned int kCurrentSceneHalf = 1;
0117 
0118 /// \brief Byte offsets inside the packed tuple field at `kPacked`.
0119 static constexpr unsigned int kLevelByte           = 0;
0120 static constexpr unsigned int kTransformOffsetByte = 1;
0121 static constexpr unsigned int kHasTranslationByte  = 2;
0122 static constexpr unsigned int kHasRotationByte     = 3;
0123 
0124 /// \brief Logical-volume record fields, expressed as `NavIndex_t` offsets from that logical record start.
0125 static constexpr NavIndex_t kLogicalVolumeId = 0;
0126 static constexpr NavIndex_t kDaughterCount   = 1;
0127 static constexpr NavIndex_t kDaughters       = 2;
0128 
0129 } // namespace Tuple
0130 
0131 } // namespace NavIndexTableLayout
0132 } // namespace VECGEOM_IMPL_NAMESPACE
0133 } // namespace vecgeom
0134 
0135 #endif // VECGEOM_MANAGEMENT_NAVINDEXTABLELAYOUT_H_