diff --git a/include/openspace/interaction/camerainteractionstates.h b/include/openspace/interaction/camerainteractionstates.h index ba51a74348..e619b1eaaf 100644 --- a/include/openspace/interaction/camerainteractionstates.h +++ b/include/openspace/interaction/camerainteractionstates.h @@ -58,6 +58,12 @@ public: void resetVelocities(); + /* + * Returns true if any of the velocities are larger than zero, + * i.e. wether an interaction happened + */ + bool hasNonZeroVelocities(); + protected: struct InteractionState { InteractionState(double scaleFactor); diff --git a/include/openspace/navigation/orbitalnavigator.h b/include/openspace/navigation/orbitalnavigator.h index 90c364a8af..96e48d2ccf 100644 --- a/include/openspace/navigation/orbitalnavigator.h +++ b/include/openspace/navigation/orbitalnavigator.h @@ -190,6 +190,7 @@ private: properties::BoolProperty apply; properties::OptionProperty chosenBehavior; properties::FloatProperty speedScale; + properties::BoolProperty abortOnCameraInteraction; }; IdleBehavior _idleBehavior; diff --git a/src/interaction/camerainteractionstates.cpp b/src/interaction/camerainteractionstates.cpp index 9164319e7a..69566b459b 100644 --- a/src/interaction/camerainteractionstates.cpp +++ b/src/interaction/camerainteractionstates.cpp @@ -86,6 +86,18 @@ void CameraInteractionStates::resetVelocities() { _globalRollState.velocity.setHard({ 0.0, 0.0 }); } +bool CameraInteractionStates::hasNonZeroVelocities() { + glm::dvec2 sum = globalRotationVelocity(); + sum += localRotationVelocity(); + sum += truckMovementVelocity(); + sum += localRotationVelocity(); + sum += localRollVelocity(); + sum += globalRollVelocity(); + // Epsilon size based on that even if no interaction is happening, + // there might still be some residual velocity in the variables + return glm::length(sum) > 0.001; +} + glm::dvec2 CameraInteractionStates::globalRotationVelocity() const{ return _globalRotationState.velocity.get(); } diff --git a/src/navigation/orbitalnavigator.cpp b/src/navigation/orbitalnavigator.cpp index e347c37039..c574ed8d84 100644 --- a/src/navigation/orbitalnavigator.cpp +++ b/src/navigation/orbitalnavigator.cpp @@ -243,6 +243,14 @@ namespace { "A factor that can eb used to increase or slow down the speed of an applied " "idle behavior." }; + + constexpr openspace::properties::Property::PropertyInfo + AbortOnCameraInteractionInfo = { + "AbortOnCameraInteraction", + "Abort on Camera Interaction", + "If set to true, the idle behavior is aborted on camera interaction. If false, " + "the behavior will be reapplied after the interaction." + }; } // namespace namespace openspace::interaction { @@ -265,6 +273,7 @@ OrbitalNavigator::IdleBehavior::IdleBehavior() , apply(ApplyIdleBehaviorInfo, false) , chosenBehavior(IdleBehaviorInfo) , speedScale(IdleBehaviorSpeedInfo, 1.f, 0.01f, 5.f) + , abortOnCameraInteraction(AbortOnCameraInteractionInfo, true) { addProperty(apply); chosenBehavior.addOptions({ @@ -273,6 +282,7 @@ OrbitalNavigator::IdleBehavior::IdleBehavior() chosenBehavior = IdleBehavior::Behavior::Orbit; addProperty(chosenBehavior); addProperty(speedScale); + addProperty(abortOnCameraInteraction); } OrbitalNavigator::OrbitalNavigator() @@ -413,6 +423,13 @@ OrbitalNavigator::OrbitalNavigator() addPropertySubOwner(_friction); addPropertySubOwner(_idleBehavior); + _idleBehavior.apply.onChange([&]() { + if (_idleBehavior.apply) { + // Reset velocities to ensure that abort on interaction works correctly + resetVelocities(); + } + }); + addProperty(_anchor); addProperty(_aim); addProperty(_retargetAnchor); @@ -483,6 +500,18 @@ void OrbitalNavigator::updateStatesFromInput(const InputState& inputState, _joystickStates.updateStateFromInput(inputState, deltaTime); _websocketStates.updateStateFromInput(inputState, deltaTime); _scriptStates.updateStateFromInput(inputState, deltaTime); + + // Disable idle behavior if camera interaction happened + if (_idleBehavior.apply && _idleBehavior.abortOnCameraInteraction) { + bool interactionHappened = _mouseStates.hasNonZeroVelocities() || + _joystickStates.hasNonZeroVelocities() || + _websocketStates.hasNonZeroVelocities() || + _scriptStates.hasNonZeroVelocities(); + + if (interactionHappened) { + _idleBehavior.apply = false; + } + } } void OrbitalNavigator::updateCameraStateFromStates(double deltaTime) {