16 if (m_confinedLayers !=
nullptr) {
17 return (m_confinedLayers->object(position).get());
24 template <
typename options_t>
25 std::vector<LayerIntersection> TrackingVolume::compatibleLayers(
27 const Vector3D& direction,
const options_t& options)
const {
29 std::vector<LayerIntersection> lIntersections;
32 if (m_confinedLayers !=
nullptr) {
34 const Layer* tLayer = options.startObject !=
nullptr
36 : associatedLayer(gctx, position);
37 while (tLayer !=
nullptr) {
43 if (tLayer != options.startObject && tLayer->
resolve(options)) {
50 (path * path <= options.pathLimit * options.pathLimit);
53 (atIntersection.object != options.targetSurface) && withinLimit) {
56 atIntersection.intersection, tLayer, atIntersection.object));
61 (tLayer == options.endObject)
63 : tLayer->
nextLayer(gctx, position, options.navDir * direction);
66 if (options.navDir ==
forward) {
67 std::sort(lIntersections.begin(), lIntersections.end());
69 std::sort(lIntersections.begin(), lIntersections.end(), std::greater<>());
73 return lIntersections;
77 template <
typename options_t>
78 std::vector<BoundaryIntersection> TrackingVolume::compatibleBoundaries(
80 const Vector3D& direction,
const options_t& options)
const {
82 auto excludeObject = options.startObject;
83 std::vector<BoundaryIntersection> bIntersections;
86 auto sDirection = options.navDir * direction;
89 double pLimit = options.pathLimit;
90 double oLimit = options.overstepLimit;
93 auto checkIntersection =
108 std::copysign(1., options.navDir);
116 withinLimit = (cLimit > oLimit and
120 std::copysign(1., options.navDir);
130 auto processBoundaries =
133 for (
auto& bsIter : bSurfaces) {
135 const auto& bSurfaceRep = bsIter->surfaceRepresentation();
137 if (excludeObject != &bSurfaceRep) {
138 auto bCandidate = bSurfaceRep.intersect(gctx, position, sDirection,
139 options.boundaryCheck);
141 auto bIntersection = checkIntersection(bCandidate, bsIter.get());
143 bIntersections.push_back(bIntersection);
150 auto& bSurfaces = boundarySurfaces();
151 processBoundaries(bSurfaces);
154 auto confinedDenseVolumes = denseVolumes();
155 for (
const auto& dv : confinedDenseVolumes) {
156 auto& bSurfacesConfined = dv->boundarySurfaces();
157 processBoundaries(bSurfacesConfined);
161 if (options.navDir ==
forward) {
162 std::sort(bIntersections.begin(), bIntersections.end());
164 std::sort(bIntersections.begin(), bIntersections.end(), std::greater<>());
166 return bIntersections;
169 template <
typename options_t>
170 std::vector<SurfaceIntersection>
171 TrackingVolume::compatibleSurfacesFromHierarchy(
173 const Vector3D& direction,
double angle,
const options_t& options)
const {
174 std::vector<SurfaceIntersection> sIntersections;
175 sIntersections.reserve(20);
178 double pLimit = options.pathLimit;
179 double oLimit = options.overstepLimit;
181 if (m_bvhTop ==
nullptr || !options.navDir) {
182 return sIntersections;
186 Vector3D sdir = options.navDir * direction;
188 std::vector<const Volume*>
hits;
191 Ray3D obj(position, sdir);
192 hits = intersectSearchHierarchy(std::move(obj), m_bvhTop);
195 hits = intersectSearchHierarchy(std::move(obj), m_bvhTop);
199 for (
const Volume* vol : hits) {
201 const std::vector<std::shared_ptr<const BoundarySurfaceT<AbstractVolume>>>&
203 for (
const auto& bs : boundarySurfaces) {
204 const Surface& srf = bs->surfaceRepresentation();
208 if (sfi and sfi.intersection.pathLength > oLimit and
209 sfi.intersection.pathLength <= pLimit) {
210 sIntersections.push_back(std::move(sfi));
216 if (options.navDir ==
forward) {
217 std::sort(sIntersections.begin(), sIntersections.end());
219 std::sort(sIntersections.begin(), sIntersections.end(), std::greater<>());
222 return sIntersections;
225 template <
typename T>
226 std::vector<const Volume*> TrackingVolume::intersectSearchHierarchy(
228 std::vector<const Volume*>
hits;
237 if (obb.intersect(obj.transformed(vol->
itransform()))) {
249 }
while (lnode !=
nullptr);