diff --git a/include/openspace/navigation/navigationstate.h b/include/openspace/navigation/navigationstate.h index 3c7cb795f0..915f5b1b93 100644 --- a/include/openspace/navigation/navigationstate.h +++ b/include/openspace/navigation/navigationstate.h @@ -36,7 +36,7 @@ namespace openspace::interaction { struct NavigationState { NavigationState() = default; - NavigationState(const ghoul::Dictionary& dictionary); + explicit NavigationState(const ghoul::Dictionary& dictionary); NavigationState(std::string anchor, std::string aim, std::string referenceFrame, glm::dvec3 position, std::optional up = std::nullopt, double yaw = 0.0, double pitch = 0.0); diff --git a/include/openspace/navigation/path.h b/include/openspace/navigation/path.h index d3060e5c09..8689d9943c 100644 --- a/include/openspace/navigation/path.h +++ b/include/openspace/navigation/path.h @@ -57,49 +57,49 @@ public: Waypoint startPoint() const; Waypoint endPoint() const; - /* + /** * Return the specified duration for the path, in seconds. Note that the time it * takes to actually traverse the path will not exactly match the provided duration */ double duration() const; - /* + /** * Return the total length of the the curve for the path, in meters */ double pathLength() const; - /* + /** * Return a vector of positions corresponding to the control points of the path's * spline curve */ std::vector controlPoints() const; - /* + /** * Take a step along the current path, corresponding to the delta time step \p dt, and * return the resulting camera pose. The \p speedScale is a factor that will be * multiplied with the traversal speed */ CameraPose traversePath(double dt, float speedScale = 1.f); - /* + /** * Return the identifer of the node that is the current appropriate anchor node, of * the start and end waypoint's reference node. Dtermined based on how far along the * path we have traveled */ std::string currentAnchor() const; - /* + /** * Return wether the path has reached its end point or not */ bool hasReachedEnd() const; - /* + /** * Compute the interpolated camera pose at a certain distance along the path */ CameraPose interpolatedPose(double distance) const; private: - /* + /** * Interpolate between the paths start and end rotation using the approach that * corresponds to the path's curve type. The interpolation parameter \p t is the * same as for the position interpolation, i.e. the relative traveled in distance @@ -107,24 +107,24 @@ private: */ glm::dquat interpolateRotation(double t) const; - /* + /** * Compute the interpolated rotation quaternion using an eased SLERP approach */ glm::dquat easedSlerpRotation(double t) const; - /* + /** * Compute the interpolated rotation quaternion using an approach that first * interpolates to look at the start node, and then the end node, before * interpolating to the end rotation */ glm::dquat lookAtTargetsRotation(double t) const; - /* + /** * Evaluate the current traversal speed along the path, based on the currently * traveled distance. The final speed will be scaled to match the desired duration * for the path (which might have been specified by the user) */ - double speedAlongPath(double traveledDistance); + double speedAlongPath(double traveledDistance) const; Waypoint _start; Waypoint _end; diff --git a/include/openspace/navigation/pathcurve.h b/include/openspace/navigation/pathcurve.h index 3917577024..e00da37583 100644 --- a/include/openspace/navigation/pathcurve.h +++ b/include/openspace/navigation/pathcurve.h @@ -36,43 +36,45 @@ class PathCurve { public: virtual ~PathCurve() = 0; - const double length() const; + double length() const; - /* - * Compute and rteturn the position along the path at the specified relative + /** + * Compute and return the position along the path at the specified relative * distance. The input parameter should be in range [0, 1], where 1 correspond to * the full length of the path */ - glm::dvec3 positionAt(double relativeDistance); + glm::dvec3 positionAt(double relativeDistance) const; - /* - * Compute curve parameter u that matches the input arc length s + /** + * Get the intorlatied position along the spline, based on the given curve parameter + * u in range [0, 1]. A curve parameter of 0 returns the start position and 1 the end + * position. Note that u does not correspond to the relatively traveled distance. */ - virtual glm::dvec3 interpolate(double u); + virtual glm::dvec3 interpolate(double u) const; - /* + /** * Return the positions defining the control points for the spline interpolation */ - std::vector points(); + std::vector points() const; protected: - /* + /** * Precompute information related to the spline parameters, that are * needed for arc length reparameterization. Must be called after * control point creation */ void initializeParameterData(); - /* + /** * Compute curve parameter u that matches the input arc length s. * Input s is a length value, in the range [0, _totalLength]. The returned curve * parameter u is in range [0, 1] */ - double curveParameter(double s); + double curveParameter(double s) const; - double approximatedDerivative(double u, double h = 0.0001); - double arcLength(double limit = 1.0); - double arcLength(double lowerLimit, double upperLimit); + double approximatedDerivative(double u, double h = 0.0001) const; + double arcLength(double limit = 1.0) const; + double arcLength(double lowerLimit, double upperLimit) const; std::vector _points; unsigned int _nSegments = 0; diff --git a/include/openspace/navigation/waypoint.h b/include/openspace/navigation/waypoint.h index ada5ff7437..79506318e5 100644 --- a/include/openspace/navigation/waypoint.h +++ b/include/openspace/navigation/waypoint.h @@ -39,7 +39,7 @@ class Waypoint { public: Waypoint() = default; Waypoint(const glm::dvec3& pos, const glm::dquat& rot, const std::string& ref); - Waypoint(const NavigationState& ns); + explicit Waypoint(const NavigationState& ns); static double findValidBoundingSphere(const SceneGraphNode* node); diff --git a/modules/debugging/debuggingmodule_lua.inl b/modules/debugging/debuggingmodule_lua.inl index dfe3d00c3c..36c9928b05 100644 --- a/modules/debugging/debuggingmodule_lua.inl +++ b/modules/debugging/debuggingmodule_lua.inl @@ -245,7 +245,7 @@ int renderPathControlPoints(lua_State* L) { "openspace.createSingleColorImage('point_color', { 0.0, 1.0, 0.0 })" ")"; - for (int i = 0; i < points.size(); i++) { + for (size_t i = 0; i < points.size(); i++) { const std::string& node = "{" "Identifier = 'ControlPoint_" + std::to_string(i) + "'," "Parent = '" + RenderedPointsIdentifier + "'," diff --git a/src/navigation/navigationhandler.cpp b/src/navigation/navigationhandler.cpp index 1d4b018802..fcae0c1e47 100644 --- a/src/navigation/navigationhandler.cpp +++ b/src/navigation/navigationhandler.cpp @@ -325,10 +325,10 @@ void NavigationHandler::saveNavigationState(const std::string& filepath, )); return; } - state = navigationState(*referenceFrame).dictionary(); + state = navigationState(*referenceFrame); } else { - state = navigationState().dictionary(); + state = navigationState(); } if (!filepath.empty()) { diff --git a/src/navigation/navigationhandler_lua.inl b/src/navigation/navigationhandler_lua.inl index edd3204c4d..c0fd722b09 100644 --- a/src/navigation/navigationhandler_lua.inl +++ b/src/navigation/navigationhandler_lua.inl @@ -136,7 +136,9 @@ int setNavigationState(lua_State* L) { ); } - global::navigationHandler->setNavigationStateNextFrame(navigationStateDictionary); + global::navigationHandler->setNavigationStateNextFrame( + interaction::NavigationState(navigationStateDictionary) + ); // @CLEANUP: When luaDictionaryFromState doesn't leak space anymore, remove the next // line ---abock(2018-02-15) diff --git a/src/navigation/orbitalnavigator.cpp b/src/navigation/orbitalnavigator.cpp index 9fdbbcda3b..a33bf4bfa4 100644 --- a/src/navigation/orbitalnavigator.cpp +++ b/src/navigation/orbitalnavigator.cpp @@ -771,7 +771,7 @@ void OrbitalNavigator::updateOnCameraInteraction() { } glm::dquat OrbitalNavigator::composeCameraRotation( - const CameraRotationDecomposition& decomposition) + const CameraRotationDecomposition& decomposition) { return decomposition.globalRotation * decomposition.localRotation; } diff --git a/src/navigation/path.cpp b/src/navigation/path.cpp index ffe3ddc8a2..1749315a2b 100644 --- a/src/navigation/path.cpp +++ b/src/navigation/path.cpp @@ -107,11 +107,7 @@ Path::Path(Waypoint start, Waypoint end, CurveType type, throw ghoul::MissingCaseException(); } - const auto defaultDuration = [](double pathlength) { - return std::log(pathlength); - }; - - _duration = duration.value_or(defaultDuration(pathLength())); + _duration = duration.value_or(std::log(pathLength())); // Compute speed factor to match the generated path length and duration, by // traversing the path and computing how much faster/slower it should be @@ -233,7 +229,7 @@ glm::dquat Path::lookAtTargetsRotation(double t) const { return ghoul::lookAtQuaternion(_curve->positionAt(t), lookAtPos, up); } -double Path::speedAlongPath(double traveledDistance) { +double Path::speedAlongPath(double traveledDistance) const { const glm::dvec3 endNodePos = _end.node()->worldPosition(); const glm::dvec3 startNodePos = _start.node()->worldPosition(); @@ -323,7 +319,7 @@ SceneGraphNode* findNodeNearTarget(const SceneGraphNode* node) { // Compute a target position close to the specified target node, using knowledge of // the start point and a desired distance from the node's center glm::dvec3 computeGoodStepDirection(const SceneGraphNode* targetNode, - const Waypoint& startPoint) + const Waypoint& startPoint) { const glm::dvec3 nodePos = targetNode->worldPosition(); const SceneGraphNode* closeNode = findNodeNearTarget(targetNode); @@ -363,7 +359,7 @@ glm::dvec3 computeGoodStepDirection(const SceneGraphNode* targetNode, return glm::normalize(offsetRotation * targetToSun); } -}; +} struct NodeInfo { std::string identifier; @@ -415,10 +411,12 @@ Path createPathFromDictionary(const ghoul::Dictionary& dictionary, { const Parameters p = codegen::bake(dictionary); - std::optional duration = p.duration; + const std::optional duration = p.duration; bool hasStart = p.startState.has_value(); - Waypoint startPoint = hasStart ? Waypoint(p.startState.value()) : waypointFromCamera(); + const Waypoint startPoint = hasStart ? + Waypoint(NavigationState(p.startState.value())) : + waypointFromCamera(); // TODO: also handle curve type here @@ -466,7 +464,7 @@ Path createPathFromDictionary(const ghoul::Dictionary& dictionary, } // @TODO (emmbr) Allow for an instruction to represent a list of multiple waypoints - Waypoint waypointToAdd = waypoints[0]; + const Waypoint waypointToAdd = waypoints[0]; return Path(startPoint, waypointToAdd, curveType, duration); } diff --git a/src/navigation/pathcurve.cpp b/src/navigation/pathcurve.cpp index 4b59f6cea4..031af73e95 100644 --- a/src/navigation/pathcurve.cpp +++ b/src/navigation/pathcurve.cpp @@ -43,16 +43,16 @@ namespace openspace::interaction { PathCurve::~PathCurve() {} -const double PathCurve::length() const { +double PathCurve::length() const { return _totalLength; } -glm::dvec3 PathCurve::positionAt(double relativeDistance) { +glm::dvec3 PathCurve::positionAt(double relativeDistance) const { const double u = curveParameter(relativeDistance * _totalLength); return interpolate(u); } -std::vector PathCurve::points() { +std::vector PathCurve::points() const { return _points; } @@ -105,7 +105,7 @@ void PathCurve::initializeParameterData() { // https://www.geometrictools.com/Documentation/MovingAlongCurveSpecifiedSpeed.pdf // Input s is a length value, in the range [0, _totalLength] // Returns curve parameter in range [0, 1] -double PathCurve::curveParameter(double s) { +double PathCurve::curveParameter(double s) const { if (s <= 0.0) return 0.0; if (s >= _totalLength) return 1.0; @@ -127,7 +127,7 @@ double PathCurve::curveParameter(double s) { _parameterSamples.begin() + startIndex, _parameterSamples.begin() + endIndex, ParameterPair{ 0.0 , s }, // 0.0 is a dummy value for u - [](ParameterPair lhs, ParameterPair rhs) { + [](const ParameterPair& lhs,const ParameterPair& rhs) { return lhs.s < rhs.s; } ); @@ -174,7 +174,7 @@ double PathCurve::curveParameter(double s) { return u; } -double PathCurve::approximatedDerivative(double u, double h) { +double PathCurve::approximatedDerivative(double u, double h) const { if (u <= h) { return (1.0 / h) * glm::length(interpolate(0.0 + h) - interpolate(0.0)); } @@ -184,11 +184,11 @@ double PathCurve::approximatedDerivative(double u, double h) { return (0.5 / h) * glm::length(interpolate(u + h) - interpolate(u - h)); } -double PathCurve::arcLength(double limit) { +double PathCurve::arcLength(double limit) const { return arcLength(0.0, limit); } -double PathCurve::arcLength(double lowerLimit, double upperLimit) { +double PathCurve::arcLength(double lowerLimit, double upperLimit) const { return ghoul::integrateGaussianQuadrature( lowerLimit, upperLimit, @@ -196,7 +196,7 @@ double PathCurve::arcLength(double lowerLimit, double upperLimit) { ); } -glm::dvec3 PathCurve::interpolate(double u) { +glm::dvec3 PathCurve::interpolate(double u) const { ghoul_assert(u >= 0 && u <= 1.0, "Interpolation variable must be in range [0,1]"); if (u < 0.0) { @@ -206,7 +206,7 @@ glm::dvec3 PathCurve::interpolate(double u) { return *(_points.end() - 2); } - std::vector::iterator segmentEndIt = + std::vector::const_iterator segmentEndIt = std::lower_bound(_curveParameterSteps.begin(), _curveParameterSteps.end(), u); const int index = diff --git a/src/navigation/pathcurves/avoidcollisioncurve.cpp b/src/navigation/pathcurves/avoidcollisioncurve.cpp index 3920eca2cc..2acd4f744d 100644 --- a/src/navigation/pathcurves/avoidcollisioncurve.cpp +++ b/src/navigation/pathcurves/avoidcollisioncurve.cpp @@ -152,43 +152,45 @@ void AvoidCollisionCurve::removeCollisions(int step) { intersectionPointModelCoords ); - if (collision) { - glm::dvec3 collisionPoint = modelTransform * - glm::dvec4(intersectionPointModelCoords, 1.0); + if (!collision) { + continue; + } - // before collision response, make sure none of the points are inside the node - bool isStartInsideNode = collision::isPointInsideSphere(p1, center, radius); - bool isEndInsideNode = collision::isPointInsideSphere(p2, center, radius); - if (isStartInsideNode || isEndInsideNode) { - LWARNING(fmt::format( - "Something went wrong! " - "At least one point in the path is inside node: {}", - node->identifier() - )); - break; - } + glm::dvec3 collisionPoint = modelTransform * + glm::dvec4(intersectionPointModelCoords, 1.0); - // To avoid collision, take a step in an orhtogonal direction of the - // collision point and add a new point - const glm::dvec3 lineDirection = glm::normalize(lineEnd - lineStart); - const glm::dvec3 nodeCenter = node->worldPosition(); - const glm::dvec3 collisionPointToCenter = nodeCenter - collisionPoint; - - const glm::dvec3 parallell = glm::proj(collisionPointToCenter, lineDirection); - const glm::dvec3 orthogonal = collisionPointToCenter - parallell; - - const double avoidCollisionDistance = - AvoidCollisionDistanceRadiusMultiplier * radius; - - glm::dvec3 extraKnot = collisionPoint - - avoidCollisionDistance * glm::normalize(orthogonal); - - _points.insert(_points.begin() + i + 2, extraKnot); - - step++; - removeCollisions(step); + // before collision response, make sure none of the points are inside the node + bool isStartInsideNode = collision::isPointInsideSphere(p1, center, radius); + bool isEndInsideNode = collision::isPointInsideSphere(p2, center, radius); + if (isStartInsideNode || isEndInsideNode) { + LWARNING(fmt::format( + "Something went wrong! " + "At least one point in the path is inside node: {}", + node->identifier() + )); break; } + + // To avoid collision, take a step in an orhtogonal direction of the + // collision point and add a new point + const glm::dvec3 lineDirection = glm::normalize(lineEnd - lineStart); + const glm::dvec3 nodeCenter = node->worldPosition(); + const glm::dvec3 collisionPointToCenter = nodeCenter - collisionPoint; + + const glm::dvec3 parallell = glm::proj(collisionPointToCenter, lineDirection); + const glm::dvec3 orthogonal = collisionPointToCenter - parallell; + + const double avoidCollisionDistance = + AvoidCollisionDistanceRadiusMultiplier * radius; + + glm::dvec3 extraKnot = collisionPoint - + avoidCollisionDistance * glm::normalize(orthogonal); + + _points.insert(_points.begin() + i + 2, extraKnot); + + step++; + removeCollisions(step); + break; } } } diff --git a/src/navigation/pathnavigator.cpp b/src/navigation/pathnavigator.cpp index faa1ef0793..d0a6cc30a2 100644 --- a/src/navigation/pathnavigator.cpp +++ b/src/navigation/pathnavigator.cpp @@ -46,7 +46,8 @@ namespace { "DefaultCurveOption", "Default Curve Option", "The defualt curve type chosen when generating a path, if none is specified" - // TODO: right now there is no way to specify a type for a single path + // 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 }; constexpr openspace::properties::Property::PropertyInfo IncludeRollInfo = { @@ -118,7 +119,7 @@ PathNavigator::PathNavigator() _relevantNodeTags = std::vector{ "planet_solarSystem", "moon_solarSystem" - };; + }; _relevantNodeTags.onChange([this]() { findRelevantNodes(); }); addProperty(_relevantNodeTags); } @@ -159,11 +160,7 @@ bool PathNavigator::isPlayingPath() const { void PathNavigator::updateCamera(double deltaTime) { ghoul_assert(camera() != nullptr, "Camera must not be nullptr"); - if (!hasCurrentPath()) { - return; - } - - if (!_isPlaying) { + if (!hasCurrentPath() || !_isPlaying) { return; } @@ -242,7 +239,7 @@ void PathNavigator::createPath(const ghoul::Dictionary& dictionary) { } void PathNavigator::clearPath() { - LINFO("Clearing path..."); + LINFO("Clearing path"); _currentPath = nullptr; } @@ -258,7 +255,7 @@ void PathNavigator::startPath() { return; } - LINFO("Starting path..."); + LINFO("Starting path"); _isPlaying = true; global::navigationHandler->orbitalNavigator().updateOnCameraInteraction(); @@ -277,7 +274,7 @@ void PathNavigator::abortPath() { void PathNavigator::pausePath() { if (hasFinished()) { - LERROR("No path to pause (path is empty or has finished)."); + LERROR("No path to pause (path is empty or has finished)"); return; } @@ -292,7 +289,7 @@ void PathNavigator::pausePath() { void PathNavigator::continuePath() { if (hasFinished()) { - LERROR("No path to resume (path is empty or has finished)."); + LERROR("No path to resume (path is empty or has finished)"); return; } @@ -301,7 +298,7 @@ void PathNavigator::continuePath() { return; } - LINFO("Continuing path..."); + LINFO("Continuing path"); _isPlaying = true; } diff --git a/src/util/collisionhelper.cpp b/src/util/collisionhelper.cpp index eaa0c2450b..411db611ef 100644 --- a/src/util/collisionhelper.cpp +++ b/src/util/collisionhelper.cpp @@ -30,7 +30,7 @@ namespace openspace::collision { bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center, double r, glm::dvec3& intersectionPoint) { - long double a, b, c; + double a, b, c; const glm::dvec3 diffp = p2 - p1; a = diffp.x * diffp.x + diffp.y * diffp.y + diffp.z * diffp.z; @@ -41,7 +41,7 @@ bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center, c -= 2.0 * (center.x * p1.x + center.y * p1.y + center.z * p1.z); c -= r * r; - long double intersectionTest = b * b - 4.0 * a * c; + double intersectionTest = b * b - 4.0 * a * c; // No intersection if (std::abs(a) < 0 || intersectionTest < 0.0) { @@ -66,8 +66,8 @@ bool lineSphereIntersection(glm::dvec3 p1, glm::dvec3 p2, glm::dvec3 center, bool isPointInsideSphere(const glm::dvec3& p, const glm::dvec3& c, double r) { const glm::dvec3 v = c - p; - const long double squaredDistance = v.x * v.x + v.y * v.y + v.z * v.z; - const long double squaredRadius = r * r; + const double squaredDistance = v.x * v.x + v.y * v.y + v.z * v.z; + const double squaredRadius = r * r; return (squaredDistance <= squaredRadius); }