From 6e751585b0bd1300a164c635de36fc3248d40d8f Mon Sep 17 00:00:00 2001 From: Emma Broman Date: Sun, 27 Feb 2022 20:51:26 +0100 Subject: [PATCH] Add a property to change the default arrival distance for camera paths --- include/openspace/navigation/pathnavigator.h | 2 ++ src/navigation/path.cpp | 15 ++++--------- .../pathcurves/avoidcollisioncurve.cpp | 18 ++++++++++----- src/navigation/pathnavigator.cpp | 22 +++++++++++++++---- 4 files changed, 37 insertions(+), 20 deletions(-) diff --git a/include/openspace/navigation/pathnavigator.h b/include/openspace/navigation/pathnavigator.h index 2764e51e2d..082775b7b4 100644 --- a/include/openspace/navigation/pathnavigator.h +++ b/include/openspace/navigation/pathnavigator.h @@ -58,6 +58,7 @@ public: const SceneGraphNode* anchor() const; const Path* currentPath() const; double speedScale() const; + double arrivalDistanceFactor() const; bool hasCurrentPath() const; bool hasFinished() const; @@ -99,6 +100,7 @@ private: properties::BoolProperty _includeRoll; properties::FloatProperty _speedScale; properties::BoolProperty _applyIdleBehaviorOnFinish; + properties::DoubleProperty _arrivalDistanceFactor; properties::DoubleProperty _minValidBoundingSphere; properties::StringListProperty _relevantNodeTags; diff --git a/src/navigation/path.cpp b/src/navigation/path.cpp index b489c2565f..6bf807c5d9 100644 --- a/src/navigation/path.cpp +++ b/src/navigation/path.cpp @@ -346,16 +346,8 @@ double Path::speedAlongPath(double traveledDistance) const { // Dampen at the start and end constexpr const double DampenDistanceFactor = 3.0; - - double startUpDistance = DampenDistanceFactor * _start.node()->boundingSphere(); - if (startUpDistance < LengthEpsilon) { // zero bounding sphere - startUpDistance = glm::distance(_start.position(), startNodePos); - } - - double closeUpDistance = DampenDistanceFactor * _end.node()->boundingSphere(); - if (closeUpDistance < LengthEpsilon) { // zero bounding sphere - closeUpDistance = glm::distance(_end.position(), endNodePos); - } + double startUpDistance = DampenDistanceFactor * _start.validBoundingSphere(); + double closeUpDistance = DampenDistanceFactor * _end.validBoundingSphere(); if (pathLength() < startUpDistance + closeUpDistance) { startUpDistance = 0.49 * pathLength(); // a little less than half @@ -507,7 +499,8 @@ Waypoint computeWaypointFromNodeInfo(const NodeInfo& info, const Waypoint& start } else { const double radius = Waypoint::findValidBoundingSphere(targetNode); - const double defaultHeight = 2.0 * radius; + const double defaultHeight = radius * + global::navigationHandler->pathNavigator().arrivalDistanceFactor(); const double height = info.height.value_or(defaultHeight); const double distanceFromNodeCenter = radius + height; diff --git a/src/navigation/pathcurves/avoidcollisioncurve.cpp b/src/navigation/pathcurves/avoidcollisioncurve.cpp index 1f123d289e..d5365e299f 100644 --- a/src/navigation/pathcurves/avoidcollisioncurve.cpp +++ b/src/navigation/pathcurves/avoidcollisioncurve.cpp @@ -70,10 +70,18 @@ AvoidCollisionCurve::AvoidCollisionCurve(const Waypoint& start, const Waypoint& // Add an extra point to first go backwards if starting close to planet glm::dvec3 nodeToStart = start.position() - startNodeCenter; - double distanceToStartNode = glm::length(nodeToStart); + const double distanceToStartNode = glm::length(nodeToStart); - if (distanceToStartNode < CloseToNodeThresholdRadiusMultiplier * startNodeRadius) { - double distance = startNodeRadius; + // Note that the factor 2.0 is arbitrarily chosen to look ok. + // @TODO: (2022-02-27, emmbr) Should be unified to a "getting close to object sphere" + // that can be used in multiple cases when creating paths more cleverly later on + const double closeToNodeThresholdFactor = glm::max( + CloseToNodeThresholdRadiusMultiplier, + 2.0 * global::navigationHandler->pathNavigator().arrivalDistanceFactor() + ); + + if (distanceToStartNode < closeToNodeThresholdFactor * startNodeRadius) { + const double distance = startNodeRadius; glm::dvec3 newPos = start.position() + distance * glm::normalize(nodeToStart); _points.push_back(newPos); } @@ -104,8 +112,8 @@ AvoidCollisionCurve::AvoidCollisionCurve(const Waypoint& start, const Waypoint& const glm::dvec3 nodeToEnd = end.position() - endNodeCenter; const double distanceToEndNode = glm::length(nodeToEnd); - if (distanceToEndNode < CloseToNodeThresholdRadiusMultiplier * endNodeRadius) { - double distance = endNodeRadius; + if (distanceToEndNode < closeToNodeThresholdFactor * endNodeRadius) { + const double distance = endNodeRadius; glm::dvec3 newPos = end.position() + distance * glm::normalize(nodeToEnd); _points.push_back(newPos); } diff --git a/src/navigation/pathnavigator.cpp b/src/navigation/pathnavigator.cpp index f43d5a42e5..cf2756b054 100644 --- a/src/navigation/pathnavigator.cpp +++ b/src/navigation/pathnavigator.cpp @@ -45,10 +45,9 @@ namespace { constexpr openspace::properties::Property::PropertyInfo DefaultCurveOptionInfo = { "DefaultPathType", "Default Path Type", - "The defualt path type chosen when generating a path. See wiki for alternatives." - " The shape of the generated path will be different depending on the path type." - // TODO (2021-08-15, emmbr) right now there is no way to specify a type for a - // single path instance, only for any created paths + "The default path type chosen when generating a path or flying to a target. " + "See wiki for alternatives. The shape of the generated path will be different " + "depending on the path type." }; constexpr openspace::properties::Property::PropertyInfo IncludeRollInfo = { @@ -72,6 +71,15 @@ namespace { "triggered once the path has reached its target." }; + constexpr openspace::properties::Property::PropertyInfo ArrivalDistanceFactorInfo = { + "ArrivalDistanceFactor", + "Arrival Distance Factor", + "A factor used to compute the default distance from a target scene graph node " + "when creating a camera path. The factor will be multipled with the node's " + "bounding sphere to compute the target height from the bounding sphere of the " + "object." + }; + constexpr const openspace::properties::Property::PropertyInfo MinBoundingSphereInfo = { "MinimalValidBoundingSphere", @@ -102,6 +110,7 @@ PathNavigator::PathNavigator() , _includeRoll(IncludeRollInfo, false) , _speedScale(SpeedScaleInfo, 1.f, 0.01f, 2.f) , _applyIdleBehaviorOnFinish(IdleBehaviorOnFinishInfo, false) + , _arrivalDistanceFactor(ArrivalDistanceFactorInfo, 2.0, 0.1, 20.0) , _minValidBoundingSphere(MinBoundingSphereInfo, 10.0, 1.0, 3e10) , _relevantNodeTags(RelevantNodeTagsInfo) { @@ -116,6 +125,7 @@ PathNavigator::PathNavigator() addProperty(_includeRoll); addProperty(_speedScale); addProperty(_applyIdleBehaviorOnFinish); + addProperty(_arrivalDistanceFactor); addProperty(_minValidBoundingSphere); _relevantNodeTags = std::vector{ @@ -144,6 +154,10 @@ double PathNavigator::speedScale() const { return _speedScale; } +double PathNavigator::arrivalDistanceFactor() const { + return _arrivalDistanceFactor; +} + bool PathNavigator::hasCurrentPath() const { return _currentPath != nullptr; }