Skip to content

Commit

Permalink
frustum nav
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Harris committed Jun 18, 2024
1 parent eb8848f commit ae09a51
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 1 deletion.
5 changes: 4 additions & 1 deletion Core/include/Acts/Navigation/DetectorNavigator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ class DetectorNavigator {
struct Config {
/// Detector for this Navigation
const Detector* detector = nullptr;

/// The octree for the world
const BoundingBox* topBox = nullptr;
/// The current frustum
std::shared_ptr<Frustum3> frustum = nullptr;
/// Configuration for this Navigator
/// stop at every sensitive surface (whether it has material or not)
bool resolveSensitive = true;
Expand Down
68 changes: 68 additions & 0 deletions Core/include/Acts/Navigation/InternalNavigation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,64 @@ struct AllPortalsAndSurfacesNavigation : public IInternalNavigation {
}
};

struct FrustumNavigation : public IInternalNavigation {
/// The frustum navigation
///
/// @param gctx is the Geometry context of this call
/// @param nState is the navigation state to be updated
///
/// @note that the intersections are ordered, such that the
/// smallest intersection pathlength >= overstep tolerance is the lowest
///
/// @return an ordered list of portal and surface candidates
inline void update(const GeometryContext& gctx,
NavigationState& nState) const {
if (nState.currentDetector == nullptr) {
throw std::runtime_error(
"FrustumNavigation: no detector volume set to navigation state.");
}
// Create the frustum if it's not set
if (nState.frustum == nullptr) {
nState.frustum = std::make_shared<Frustum3>(nState.position, nState.direction, M_PI/4);
}
//Check if we leave the frustum, reset candidates if so
const auto& normals = nState.frustum->normals();
const bool outside = std::any_of(normals.begin(), normals.end(), [&nState](const auto& normal){
return (nState.position - nState.frustum->origin()).dot(normal) >= 0;});
if(outside){
nState.surfaceCandidates.clear();
nState.frustum = std::make_shared<Frustum3>(nState.position, nState.direction, M_PI/4);
}
// A volume switch has happened, or we left the frustum, update list of portals & surfaces
if (nState.surfaceCandidates.empty()) {
// Fill internal portals if existing
auto topBoxCopy = nState.topBox;
while(topBoxCopy){
if(topBoxCopy->intersect(*nState.frustum)){
if(topBoxCopy->hasEntity()){
const auto& portals = topBoxCopy->entity()->portals();
const auto& surfaces = topBoxCopy->entity()->surfaces();
PortalsFiller::fill(nState, portals);
SurfacesFiller::fill(nState, surfaces);
topBoxCopy = topBoxCopy->getSkip();
} else {
topBoxCopy = topBoxCopy->getLeftChild();
}
} else {
topBoxCopy = topBoxCopy->getSkip();
}
}
}
// Assign the new volume
const auto& portals = nState.currentVolume->portals();
const auto& surfaces = nState.currentVolume->surfaces();
PortalsFiller::fill(nState, portals);
SurfacesFiller::fill(nState, surfaces);
// Update internal candidates
updateCandidates(gctx, nState);
}
};

/// Generate a provider for all portals
///
/// @return a connected navigationstate updator
Expand All @@ -116,6 +174,16 @@ inline static InternalNavigationDelegate tryAllPortalsAndSurfaces() {
return nStateUpdater;
}

/// Generate a provider for portals and surfaces inside a frustum
///
/// @return a connected navigationstate updator
inline static InternalNavigationDelegate tryFrustumPortalsAndSurfaces() {
auto fr = std::make_unique<const FrustumNavigation>();
InternalNavigationDelegate nStateUpdater;
nStateUpdater.connect<&FrustumNavigation::update>(std::move(fr));
return nStateUpdater;
}

/// @brief This holds and extracts a collection of surfaces without much
/// checking, this could be e.g. support surfaces for layer structures,
/// e.g.
Expand Down
5 changes: 5 additions & 0 deletions Core/include/Acts/Navigation/NavigationState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,11 @@ struct NavigationState {
/// The current portal, i.e the position is on portal
const Portal* currentPortal = nullptr;

/// The octree for the world
const BoundingBox* topBox = nullptr;
/// The current frustum
std::shared_ptr<Frustum3> frustum = nullptr;

/// That are the candidate surfaces to process
SurfaceCandidates surfaceCandidates = {};
std::size_t surfaceCandidateIndex = 0;
Expand Down

0 comments on commit ae09a51

Please sign in to comment.