54 bool resolvePassive)
const {
61 if (resolveMaterial &&
69 template <
typename options_t>
72 const Vector3D& direction,
const options_t& options)
const {
74 std::vector<SurfaceIntersection> sIntersections;
76 std::map<const Surface*, bool> accepted;
80 return sIntersections;
84 sIntersections.reserve(20);
89 double pathLimit = options.pathLimit;
90 double overstepLimit = options.overstepLimit;
91 if (options.endObject) {
95 gctx, position, options.navDir * direction,
BoundaryCheck(
true));
103 return sIntersections;
112 pathLimit = 1.5 *
thickness() * pCorrection * options.navDir;
116 auto acceptSurface = [&options, &accepted](
const Surface& sf,
117 bool sensitive =
false) ->
bool {
119 if (accepted.find(&sf) != accepted.end()) {
123 if (sensitive && options.resolveSensitive) {
127 if (options.resolveMaterial && sf.surfaceMaterial()) {
131 return options.resolvePassive;
136 auto processSurface = [&](
const Surface& sf,
bool sensitive =
false) {
138 if (options.startObject == &sf || options.endObject == &sf) {
142 if (!acceptSurface(sf, sensitive)) {
147 gctx, position, options.navDir * direction, options.boundaryCheck);
151 if (sfi && sifPath > overstepLimit &&
152 sifPath * sifPath <= pathLimit * pathLimit) {
155 sIntersections.push_back(sfi);
156 accepted[&sf] =
true;
167 (options.resolveMaterial || options.resolvePassive)) {
169 const std::vector<const Surface*>& approachSurfaces =
174 for (
auto& aSurface : approachSurfaces) {
175 processSurface(*aSurface);
182 if (
m_surfaceArray && (options.resolveMaterial || options.resolvePassive ||
183 options.resolveSensitive)) {
185 const std::vector<const Surface*>& sensitiveSurfaces =
190 for (
auto& sSurface : sensitiveSurfaces) {
191 processSurface(*sSurface,
true);
199 processSurface(*layerSurface);
202 if (options.navDir ==
forward) {
203 std::sort(sIntersections.begin(), sIntersections.end());
205 std::sort(sIntersections.begin(), sIntersections.end(), std::greater<>());
208 return sIntersections;
211 template <
typename options_t>
214 const Vector3D& direction,
const options_t& options)
const {
220 bool resolvePS = options.resolveSensitive || options.resolvePassive;
221 bool resolveMS = options.resolveMaterial &&
226 auto sDirection = options.navDir * direction;
229 double pLimit = options.pathLimit;
230 double oLimit = options.overstepLimit;
233 auto checkIntersection =
236 if (!sIntersection) {
237 return sIntersection;
246 sIntersection.intersection.pathLength *=
247 std::copysign(1., options.navDir);
248 return sIntersection;
249 }
else if (sIntersection.alternative.status >=
250 Intersection::Status::reachable) {
252 cLimit = sIntersection.alternative.pathLength;
253 withinLimit = (cLimit > oLimit and
255 if (sIntersection.alternative and withinLimit) {
257 sIntersection.alternative.pathLength *=
258 std::copysign(1., options.navDir);
260 sIntersection.object);
270 gctx, position, sDirection, options.boundaryCheck);
271 return checkIntersection(aSurface);
277 rSurface.
intersect(gctx, position, sDirection, options.boundaryCheck);
278 return checkIntersection(sIntersection);
288 .isOnSurface(gctx, position,
s_origin, bcheck);