From 8ed9d083cba07f745b43d1c8b79fc0da5ab7a2a4 Mon Sep 17 00:00:00 2001 From: Malin E Date: Thu, 12 Jan 2023 11:01:32 +0100 Subject: [PATCH] Adjust camera position if outside the max distance limit --- .../openspace/navigation/orbitalnavigator.h | 10 +++- src/navigation/orbitalnavigator.cpp | 56 ++++++++++++++++--- 2 files changed, 56 insertions(+), 10 deletions(-) diff --git a/include/openspace/navigation/orbitalnavigator.h b/include/openspace/navigation/orbitalnavigator.h index 60c7d46908..438c23c0cd 100644 --- a/include/openspace/navigation/orbitalnavigator.h +++ b/include/openspace/navigation/orbitalnavigator.h @@ -112,7 +112,10 @@ public: float retargetInterpolationTime() const; void setRetargetInterpolationTime(float durationInSeconds); void updatePreviousStateVariables(); - void setMinimumAllowedDistance(double distance); + + void setMinimumAllowedDistance(float distance); + void setMaximumAllowedDistance(double distance); + void setEnableZoomOutLimit(bool value); JoystickCameraStates& joystickStates(); const JoystickCameraStates& joystickStates() const; @@ -191,7 +194,7 @@ private: LimitZoomOut(); properties::BoolProperty isEnabled; - properties::FloatProperty maximumAllowedDistance; + properties::DoubleProperty maximumAllowedDistance; }; LimitZoomOut _limitZoomOut; @@ -351,7 +354,8 @@ private: */ glm::dvec3 pushToSurface(double minHeightAboveGround, const glm::dvec3& cameraPosition, const glm::dvec3& objectPosition, - const SurfacePositionHandle& positionHandle) const; + const SurfacePositionHandle& positionHandle, + std::optional maxHeightAboveGround) const; /** * Interpolates between rotationDiff and a 0 rotation. diff --git a/src/navigation/orbitalnavigator.cpp b/src/navigation/orbitalnavigator.cpp index b1da79dc1f..3c8d331ece 100644 --- a/src/navigation/orbitalnavigator.cpp +++ b/src/navigation/orbitalnavigator.cpp @@ -344,7 +344,12 @@ OrbitalNavigator::IdleBehavior::IdleBehavior() OrbitalNavigator::LimitZoomOut::LimitZoomOut() : properties::PropertyOwner({ "LimitZoomOut" }) , isEnabled(EnabledMaximumDistanceInfo, false) - , maximumAllowedDistance(MaximumDistanceInfo, 0.f, 0.f) + , maximumAllowedDistance( + MaximumDistanceInfo, + std::numeric_limits::max(), + 0.f, + std::numeric_limits::max() + ) { addProperty(isEnabled); addProperty(maximumAllowedDistance); @@ -728,11 +733,14 @@ void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) { // Perform the vertical movements based on user input pose.position = translateVertically(deltaTime, pose.position, anchorPos, posHandle); + std::optional maxHeight = _limitZoomOut.isEnabled ? + _limitZoomOut.maximumAllowedDistance : std::optional(); pose.position = pushToSurface( - _minimumAllowedDistance, + static_cast(_minimumAllowedDistance), pose.position, anchorPos, - posHandle + posHandle, + maxHeight ); pose.rotation = composeCameraRotation(camRot); @@ -915,10 +923,28 @@ void OrbitalNavigator::updatePreviousStateVariables() { updatePreviousAimState(); } -void OrbitalNavigator::setMinimumAllowedDistance(double distance) { +void OrbitalNavigator::setMinimumAllowedDistance(float distance) { + if (_limitZoomOut.isEnabled && distance > _limitZoomOut.maximumAllowedDistance) { + LWARNING("Setting minumum allowed distance larger than maximum allowed distance"); + } + _minimumAllowedDistance = distance; } +void OrbitalNavigator::setMaximumAllowedDistance(double distance) { + if (_minimumAllowedDistance > distance) { + LWARNING( + "Setting maximum allowed distance smaller than minumum allowed distance" + ); + } + + _limitZoomOut.maximumAllowedDistance = distance; +} + +void OrbitalNavigator::setEnableZoomOutLimit(bool value) { + _limitZoomOut.isEnabled = value; +} + void OrbitalNavigator::startRetargetAnchor() { if (!_anchorNode) { return; @@ -1506,8 +1532,14 @@ glm::dquat OrbitalNavigator::rotateHorizontally(double deltaTime, glm::dvec3 OrbitalNavigator::pushToSurface(double minHeightAboveGround, const glm::dvec3& cameraPosition, const glm::dvec3& objectPosition, - const SurfacePositionHandle& positionHandle) const + const SurfacePositionHandle& positionHandle, + std::optional maxHeightAboveGround) const { + if (maxHeightAboveGround.has_value() && minHeightAboveGround > *maxHeightAboveGround) + { + LWARNING("Minimum allowed distance is larger than maximum allowed distance"); + } + const glm::dmat4 modelTransform = _anchorNode->modelTransform(); const glm::dvec3 posDiff = cameraPosition - objectPosition; @@ -1524,8 +1556,18 @@ glm::dvec3 OrbitalNavigator::pushToSurface(double minHeightAboveGround, const double surfaceToCameraSigned = glm::length(actualSurfaceToCamera) * glm::sign(dot(actualSurfaceToCamera, referenceSurfaceOutDirection)); - return cameraPosition + referenceSurfaceOutDirection * - glm::max(minHeightAboveGround - surfaceToCameraSigned, 0.0); + // Adjustment for if the camera is inside the min distance + double adjustment = glm::max(minHeightAboveGround - surfaceToCameraSigned, 0.0); + + // Adjustment for if the camera is outside the max distance + // Only apply if the min adjustment not already applied + if (maxHeightAboveGround.has_value() && + adjustment < std::numeric_limits::epsilon()) + { + adjustment = glm::min(*maxHeightAboveGround - surfaceToCameraSigned, 0.0); + } + + return cameraPosition + referenceSurfaceOutDirection * adjustment; } glm::dquat OrbitalNavigator::interpolateRotationDifferential(double deltaTime,