File indexing completed on 2026-11-13 11:00:22
0001
0002
0003
0004 #ifndef VECGEOM_VOLUMES_KERNEL_HALFSPACEIMPLEMENTATION_H_
0005 #define VECGEOM_VOLUMES_KERNEL_HALFSPACEIMPLEMENTATION_H_
0006
0007 #include "VecGeom/base/Global.h"
0008 #include "VecGeom/base/Vector3D.h"
0009 #include "VecGeom/volumes/HalfSpaceStruct.h"
0010 #include "VecGeom/volumes/SurfaceHitView.h"
0011
0012 #include <VecCore/VecCore>
0013
0014 namespace vecgeom {
0015
0016 VECGEOM_DEVICE_FORWARD_DECLARE(struct HalfSpaceImplementation;);
0017 VECGEOM_DEVICE_DECLARE_CONV(struct, HalfSpaceImplementation);
0018
0019 inline namespace VECGEOM_IMPL_NAMESPACE {
0020
0021 class PlacedHalfSpace;
0022 class UnplacedHalfSpace;
0023
0024
0025
0026
0027
0028 struct HalfSpaceImplementation {
0029 using PlacedShape_t = PlacedHalfSpace;
0030 using UnplacedStruct_t = HalfSpaceStruct<Precision>;
0031 using UnplacedVolume_t = UnplacedHalfSpace;
0032
0033
0034
0035
0036
0037
0038 template <typename Real_v>
0039 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Real_v SignedDistance(UnplacedStruct_t const &halfspace,
0040 Vector3D<Real_v> const &point)
0041 {
0042 return (point - Vector3D<Real_v>(halfspace.fPoint)).Dot(Vector3D<Real_v>(halfspace.fNormal));
0043 }
0044
0045
0046
0047
0048
0049 template <typename Real_v>
0050 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Contains(UnplacedStruct_t const &halfspace,
0051 Vector3D<Real_v> const &point, bool &inside)
0052 {
0053 inside = SignedDistance(halfspace, point) <= Real_v(kTolerance);
0054 }
0055
0056
0057
0058
0059
0060 template <typename Real_v>
0061 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void Inside(UnplacedStruct_t const &halfspace,
0062 Vector3D<Real_v> const &point, Inside_t &inside)
0063 {
0064 const Real_v signedDistance = SignedDistance(halfspace, point);
0065 inside = EInside::kSurface;
0066 if (signedDistance < Real_v(-kTolerance)) inside = Inside_t(EInside::kInside);
0067 if (signedDistance > Real_v(kTolerance)) inside = Inside_t(EInside::kOutside);
0068 }
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078 template <typename Real_v>
0079 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToIn(UnplacedStruct_t const &halfspace,
0080 Vector3D<Real_v> const &point,
0081 Vector3D<Real_v> const &direction,
0082 Real_v const &stepMax, Real_v &distance)
0083 {
0084 distance = kInfLength;
0085 const Real_v signedDistance = SignedDistance(halfspace, point);
0086 if (signedDistance < Real_v(-kTolerance)) {
0087 distance = Real_v(-1.);
0088 return;
0089 }
0090
0091 const Real_v nDotDir = Vector3D<Real_v>(halfspace.fNormal).Dot(direction);
0092 if (signedDistance <= Real_v(kTolerance)) {
0093 if (nDotDir < Real_v(-kTolerance)) distance = Real_v(0.);
0094 return;
0095 }
0096
0097 if (nDotDir >= Real_v(-kTolerance)) return;
0098 const Real_v candidate = -signedDistance / nDotDir;
0099 if (candidate >= Real_v(0.) && candidate < stepMax) distance = candidate;
0100 }
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112 template <typename Real_v>
0113 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void DistanceToOut(UnplacedStruct_t const &halfspace,
0114 Vector3D<Real_v> const &point,
0115 Vector3D<Real_v> const &direction,
0116 Real_v const &stepMax, Real_v &distance,
0117 SurfaceHitView<Real_v> *hitInfo = nullptr)
0118 {
0119 if (hitInfo) hitInfo->Clear();
0120 distance = kInfLength;
0121 const Real_v signedDistance = SignedDistance(halfspace, point);
0122 if (signedDistance > Real_v(kTolerance)) {
0123 distance = Real_v(-1.);
0124 return;
0125 }
0126
0127 const Real_v nDotDir = Vector3D<Real_v>(halfspace.fNormal).Dot(direction);
0128 if (signedDistance >= Real_v(-kTolerance)) {
0129 if (nDotDir > Real_v(kTolerance)) {
0130 distance = Real_v(0.);
0131 if (hitInfo) {
0132 hitInfo->SetLeftBehind(true);
0133 hitInfo->SetNormal(Vector3D<Real_v>(halfspace.fNormal));
0134 }
0135 }
0136 return;
0137 }
0138
0139 if (nDotDir <= Real_v(kTolerance)) return;
0140 const Real_v candidate = -signedDistance / nDotDir;
0141 if (candidate >= Real_v(0.) && candidate < stepMax) {
0142 distance = candidate;
0143 if (hitInfo) {
0144 hitInfo->SetLeftBehind(true);
0145 hitInfo->SetNormal(Vector3D<Real_v>(halfspace.fNormal));
0146 }
0147 }
0148 }
0149
0150
0151
0152
0153
0154 template <typename Real_v>
0155 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToIn(UnplacedStruct_t const &halfspace,
0156 Vector3D<Real_v> const &point, Real_v &safety)
0157 {
0158 const Real_v signedDistance = SignedDistance(halfspace, point);
0159 safety = signedDistance;
0160 if (signedDistance < Real_v(-kTolerance)) {
0161 safety = Real_v(-1.);
0162 return;
0163 }
0164 if (signedDistance <= Real_v(kTolerance)) safety = Real_v(0.);
0165 }
0166
0167
0168
0169
0170
0171 template <typename Real_v>
0172 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static void SafetyToOut(UnplacedStruct_t const &halfspace,
0173 Vector3D<Real_v> const &point, Real_v &safety)
0174 {
0175 const Real_v signedDistance = SignedDistance(halfspace, point);
0176 safety = -signedDistance;
0177 if (signedDistance > Real_v(kTolerance)) {
0178 safety = Real_v(-1.);
0179 return;
0180 }
0181 if (signedDistance >= Real_v(-kTolerance)) safety = Real_v(0.);
0182 }
0183
0184
0185
0186
0187
0188
0189 template <typename Real_v>
0190 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE static Vector3D<Real_v> NormalKernel(UnplacedStruct_t const &halfspace,
0191 Vector3D<Real_v> const &point,
0192 bool &valid)
0193 {
0194 valid = Abs(SignedDistance(halfspace, point)) <= Real_v(kTolerance);
0195 return Vector3D<Real_v>(halfspace.fNormal);
0196 }
0197 };
0198
0199 }
0200 }
0201
0202 #endif