Skip to content

Commit ae4db65

Browse files
committed
RayIntersectedFirst() performance improvements
1 parent bc898ae commit ae4db65

File tree

1 file changed

+27
-27
lines changed

1 file changed

+27
-27
lines changed

octree.h

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1891,7 +1891,7 @@ namespace OrthoTree
18911891
struct BoxDistance : ItemDistance
18921892
{
18931893
MortonNodeID NodeKey;
1894-
std::vector<TEntityID> const* Entities;
1894+
Node const* NodePtr;
18951895
};
18961896

18971897

@@ -3273,7 +3273,7 @@ namespace OrthoTree
32733273
auto const nodeMinDistance = IGM::Size(IGM::GetBoxWallDistanceAD(searchPoint, centerPoint, halfSize));
32743274
if (nodeMinDistance < maxDistance)
32753275
{
3276-
nodeMinDistances.push_back({ { nodeMinDistance }, key, &node.Entities });
3276+
nodeMinDistances.push_back({ { nodeMinDistance }, key, &node });
32773277
}
32783278
};
32793279

@@ -3334,7 +3334,7 @@ namespace OrthoTree
33343334
break;
33353335
}
33363336

3337-
CreateEntityDistance(*nodeDistance.Entities, searchPoint, points, neighborEntities, maxDistance);
3337+
CreateEntityDistance(nodeDistance.NodePtr->Entities, searchPoint, points, neighborEntities, maxDistance);
33383338
farestEntityDistance = GetFarestDistance(neighborEntities, neighborNo);
33393339
}
33403340

@@ -4275,48 +4275,48 @@ namespace OrthoTree
42754275

42764276
void GetRayIntersectedFirstRecursive(
42774277
depth_t depthID,
4278-
MortonNodeIDCR parentKey,
4278+
Node const& parentNode,
42794279
TContainer const& boxes,
42804280
TVector const& rayBasePoint,
42814281
TVector const& rayHeading,
42824282
TGeometry tolerance,
4283-
std::multiset<EntityDistance>& foundEntities) const noexcept
4283+
std::optional<EntityDistance>& foundEntity) const noexcept
42844284
{
4285-
auto const& node = this->GetNode(parentKey);
4286-
4287-
auto const maxExaminationDistance =
4288-
foundEntities.empty() ? std::numeric_limits<typename IGM::Geometry>::infinity() : foundEntities.rbegin()->Distance;
4289-
for (auto const entityID : node.Entities)
4285+
for (auto const entityID : parentNode.Entities)
42904286
{
42914287
auto const distance = AD::GetRayBoxDistance(detail::at(boxes, entityID), rayBasePoint, rayHeading, tolerance);
42924288
if (!distance)
42934289
continue;
42944290

4295-
auto const distance_ = IGM_Geometry(*distance);
4296-
if (distance_ > maxExaminationDistance)
4297-
continue;
4298-
4299-
foundEntities.insert({ { distance_ }, entityID });
4291+
if (!foundEntity || foundEntity->Distance > *distance)
4292+
foundEntity = std::optional<EntityDistance>(std::in_place, EntityDistance{ { TGeometry(*distance) }, entityID });
43004293
}
43014294

43024295
++depthID;
4303-
auto nodeDistances = std::multiset<BoxDistance>();
43044296
auto const& halfSize = this->GetNodeSize(depthID + 1);
4305-
for (MortonNodeIDCR childKey : node.GetChildren())
4297+
auto nodeDistances = std::vector<BoxDistance>();
4298+
for (MortonNodeIDCR childKey : parentNode.GetChildren())
43064299
{
43074300
auto const& nodeChild = this->GetNode(childKey);
43084301
auto const distance = IGM::GetRayBoxDistanceAD(GetNodeCenterMacro(this, childKey, nodeChild), halfSize, rayBasePoint, rayHeading, tolerance);
43094302
if (!distance)
43104303
continue;
43114304

4312-
if (*distance > maxExaminationDistance)
4305+
if (foundEntity && *distance > foundEntity->Distance)
43134306
continue;
43144307

4315-
nodeDistances.insert({ { IGM_Geometry(distance.value()) }, childKey, &nodeChild.Entities });
4308+
nodeDistances.push_back({ { IGM_Geometry(distance.value()) }, childKey, &nodeChild });
43164309
}
43174310

4311+
std::sort(nodeDistances.begin(), nodeDistances.end());
4312+
43184313
for (auto const& nodeDistance : nodeDistances)
4319-
GetRayIntersectedFirstRecursive(depthID, nodeDistance.NodeKey, boxes, rayBasePoint, rayHeading, tolerance, foundEntities);
4314+
{
4315+
if (foundEntity && nodeDistance.Distance - tolerance >= foundEntity->Distance)
4316+
break;
4317+
4318+
GetRayIntersectedFirstRecursive(depthID, *nodeDistance.NodePtr, boxes, rayBasePoint, rayHeading, tolerance, foundEntity);
4319+
}
43204320
}
43214321

43224322

@@ -4358,21 +4358,21 @@ namespace OrthoTree
43584358
std::optional<TEntityID> RayIntersectedFirst(
43594359
TVector const& rayBasePoint, TVector const& rayHeading, TContainer const& boxes, TGeometry tolerance = {}) const noexcept
43604360
{
4361-
auto const distance = IGM::GetRayBoxDistanceAD(
4362-
GetNodeCenterMacro(this, SI::GetRootKey(), this->GetNode(SI::GetRootKey())), this->GetNodeSize(1), rayBasePoint, rayHeading, tolerance);
4361+
auto const& rootNode = this->GetNode(SI::GetRootKey());
4362+
auto const distance = IGM::GetRayBoxDistanceAD(GetNodeCenterMacro(this, SI::GetRootKey(), rootNode), this->GetNodeSize(1), rayBasePoint, rayHeading, tolerance);
43634363
if (!distance)
43644364
return std::nullopt;
43654365

4366-
auto foundEntities = std::multiset<EntityDistance>();
4367-
GetRayIntersectedFirstRecursive(0, SI::GetRootKey(), boxes, rayBasePoint, rayHeading, tolerance, foundEntities);
4368-
if (foundEntities.empty())
4366+
auto foundEntity = std::optional<EntityDistance>{};
4367+
GetRayIntersectedFirstRecursive(0, rootNode, boxes, rayBasePoint, rayHeading, tolerance, foundEntity);
4368+
if (!foundEntity)
43694369
return std::nullopt;
43704370

4371-
return foundEntities.begin()->EntityID;
4371+
return foundEntity->EntityID;
43724372
}
43734373

43744374
// Get first box which is intersected by the ray
4375-
inline std::optional<TEntityID> RayIntersectedFirst(TRay const& ray, TContainer const& boxes, TGeometry tolerance) const noexcept
4375+
inline std::optional<TEntityID> RayIntersectedFirst(TRay const& ray, TContainer const& boxes, TGeometry tolerance = {}) const noexcept
43764376
{
43774377
return RayIntersectedFirst(ray.Origin, ray.Direction, boxes, tolerance);
43784378
}

0 commit comments

Comments
 (0)