53 const G4double proposedStepLength, G4double& newSafety)
56 mLastDirection = direction;
57 mHaveNextState =
false;
59 auto const*
top = mCurState.Top();
61 mWouldEnter = mWouldExit =
false;
64 auto const* navigator =
top->GetLogicalVolume()->GetNavigator();
66 double limit = proposedStepLength *
kG4ToVG;
67 if (!(limit < vecgeom::kInfLength)) {
68 limit = vecgeom::kInfLength;
77 const bool block = mExitBlockPending && globalPoint.diff2(mLocatedPoint) < 1.e-20 &&
79 mExitBlockPending =
false;
81 mCurState.SetLastExited(mEmptyState.GetLastExitedState());
85 const double vgStep = navigator->ComputeStepAndSafetyAndPropagatedState(
86 toVG(globalPoint),
toDir(direction), limit, mCurState, mNextState, !mOnBoundary && !mZeroSafety, vgSafety);
88 newSafety = (vgSafety > 0. && !mZeroSafety) ? vgSafety *
kVGToG4 : 0.;
90 G4double step = vgStep *
kVGToG4;
91 if (mNextState.IsOnBoundary()) {
94 mWouldEnter = mNextState.GetCurrentLevel() > mCurState.GetCurrentLevel();
95 mWouldExit = !mWouldEnter;
96 mNextPoint = globalPoint + step * direction;
97 mHaveNextState =
true;
99 mWouldEnter = mWouldExit =
false;
107 mHaveNextState =
false;
113 if (++mZeroSteps > 4) {
115 mHaveNextState =
false;
120 mForceReInit =
false;
147 const G4ThreeVector*,
148 const G4bool relativeSearch,
const G4bool)
150 bool onBoundary = fWasLimitedByGeometry;
151 if (mHaveNextState && point.diff2(mNextPoint) < 1.e-16) {
155 mPrevState = mCurState;
156 mLocatedPoint = point;
157 mExitBlockPending =
false;
160 if (!mForceReInit && relativeSearch && onBoundary && mHaveNextState) {
163 mCurState = mNextState;
164 mExitBlockPending = mWouldExit;
165 }
else if (mForceReInit || !relativeSearch || onBoundary) {
167 vecgeom::GlobalLocator::LocateGlobalPoint(vecgeom::GeoManager::Instance().GetWorld(),
toVG(point), mCurState,
true);
168 mForceReInit =
false;
174 mCrossed = onBoundary;
176 fExitedMother = mWouldExit;
177 fEnteredDaughter = mWouldEnter;
180 mHaveNextState =
false;
199 if (mZeroSafety || mOnBoundary || mCrossed || fEnteredDaughter || fExitedMother || mWouldEnter || mWouldExit) {
202 if (mCurState.Top() ==
nullptr) {
207 const double rest = mLastSafety - std::sqrt(globalPoint.diff2(mSafetyOrig));
208 if (rest >= proposedMaxLength) {
211 mSafetyOrig = globalPoint;
212 mLastSafety = std::max(
boundedSafety(mCurState, globalPoint, proposedMaxLength), 0.);
220 auto const&
state = mWouldExit ? mPrevState : mCurState;
221 auto const* volume =
state.Top();
222 if (volume ==
nullptr) {
224 return G4ThreeVector(0., 0., 1.);
227 vecgeom::Transformation3D
m;
230 volume->Normal(
m.Transform(
toVG(point)), normal);
231 V3 global =
m.InverseTransformDirection(normal);
234 const V3 dir =
toDir(mLastDirection);
235 if (global.Dot(dir) < 0.) {
240 const double mag2 = global.Mag2();
241 *
valid = std::isfinite(mag2) && mag2 > 0.25;
242 return G4ThreeVector(global[0], global[1], global[2]);