Issue/3016 - Settings for jumpTo (#3080)

* Add script for jumpTo scene graph node and navigation state

* Add property to control how long the fading takes (navigation handler)

* Update GUI hash

---------

Co-authored-by: Alexander Bock <alexander.bock@liu.se>
This commit is contained in:
Emma Broman
2024-04-04 10:20:24 +02:00
committed by GitHub
parent c47eb8fc7a
commit a82af895d7
6 changed files with 134 additions and 2 deletions

View File

@@ -4,7 +4,7 @@ local guiCustomization = asset.require("customization/gui")
-- Select which commit hashes to use for the frontend and backend
local frontendHash = "e1ebc90f79f10bafe46aea72eb91fdf0e86876ad"
local frontendHash = "0f745d1672eb63c37eaa9164f1e5f991f6c7795c"
local frontend = asset.resource({
Identifier = "WebGuiFrontend",

View File

@@ -85,7 +85,9 @@ public:
OrbitalNavigator& orbitalNavigator();
KeyframeNavigator& keyframeNavigator();
PathNavigator& pathNavigator();
bool isKeyFrameInteractionEnabled() const;
float jumpToFadeDuration() const;
float interpolationTime() const;
// Callback functions
@@ -165,6 +167,18 @@ public:
*/
void setCameraFromNodeSpecNextFrame(NodeCameraStateSpec spec);
/**
* Trigger a transition script after first fading out the rendering, and fading in
* the rendering when the script is finished. One example use case could be to fade
* out, move the camera to another focus node, and then fade in
*
* \param transitionScript The Lua script to handle the transition. Can be anything
* \param fadeDuration An optional duration for the fading. If unspecified, use the
* JumpToFadeDuration property
*/
void triggerFadeToTransition(const std::string& transitionScript,
std::optional<float> fadeDuration = std::nullopt);
/**
* \return The Lua library that contains all Lua functions available to affect the
* interaction
@@ -195,6 +209,7 @@ private:
properties::BoolProperty _disableMouseInputs;
properties::BoolProperty _disableJoystickInputs;
properties::BoolProperty _useKeyFrameInteraction;
properties::FloatProperty _jumpToFadeDuration;
};
} // namespace openspace::interaction

View File

@@ -90,6 +90,15 @@ namespace {
"than using the mouse interaction",
openspace::properties::Property::Visibility::Developer
};
constexpr openspace::properties::Property::PropertyInfo JumpToFadeDurationInfo = {
"JumpToFadeDuration",
"JumpTo Fade Duration",
"The number of seconds the fading of the rendering should take per default when "
"navigating through a 'jump' transition. This is when the rendering is first "
"faded to black, then the camera is moved, and then the rendering fades in again",
openspace::properties::Property::Visibility::User
};
} // namespace
namespace openspace::interaction {
@@ -100,6 +109,7 @@ NavigationHandler::NavigationHandler()
, _disableMouseInputs(DisableMouseInputInfo, false)
, _disableJoystickInputs(DisableJoystickInputInfo, false)
, _useKeyFrameInteraction(FrameInfo, false)
, _jumpToFadeDuration(JumpToFadeDurationInfo, 1.f, 0.f, 10.f)
{
addPropertySubOwner(_orbitalNavigator);
addPropertySubOwner(_pathNavigator);
@@ -108,6 +118,7 @@ NavigationHandler::NavigationHandler()
addProperty(_disableMouseInputs);
addProperty(_disableJoystickInputs);
addProperty(_useKeyFrameInteraction);
addProperty(_jumpToFadeDuration);
}
NavigationHandler::~NavigationHandler() {}
@@ -170,6 +181,10 @@ bool NavigationHandler::isKeyFrameInteractionEnabled() const {
return _useKeyFrameInteraction;
}
float NavigationHandler::jumpToFadeDuration() const {
return _jumpToFadeDuration;
}
float NavigationHandler::interpolationTime() const {
return _orbitalNavigator.retargetInterpolationTime();
}
@@ -178,6 +193,30 @@ void NavigationHandler::setInterpolationTime(float durationInSeconds) {
_orbitalNavigator.setRetargetInterpolationTime(durationInSeconds);
}
void NavigationHandler::triggerFadeToTransition(const std::string& transitionScript,
std::optional<float> fadeDuration)
{
const float duration = fadeDuration.value_or(_jumpToFadeDuration);
const std::string onArrivalScript = std::format(
"{} "
"openspace.setPropertyValueSingle("
"'RenderEngine.BlackoutFactor', 1, {}, 'QuadraticEaseIn'"
")", transitionScript, duration
);
const std::string script = std::format(
"openspace.setPropertyValueSingle("
"'RenderEngine.BlackoutFactor', 0, {}, 'QuadraticEaseOut', [[{}]]"
")", duration, onArrivalScript
);
// No syncing, as this was called from a script that should have been synced already
global::scriptEngine->queueScript(
std::move(script),
scripting::ScriptEngine::ShouldBeSynchronized::No,
scripting::ScriptEngine::ShouldSendToRemote::No
);
}
void NavigationHandler::updateCamera(double deltaTime) {
ghoul_assert(_camera != nullptr, "Camera must not be nullptr");

View File

@@ -44,6 +44,7 @@
#include <ghoul/filesystem/file.h>
#include <ghoul/filesystem/filesystem.h>
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionaryluaformatter.h>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/vector_angle.hpp>
#include <vector>
@@ -600,6 +601,8 @@ scripting::LuaLibrary PathNavigator::luaLibrary() {
codegen::lua::ZoomToFocus,
codegen::lua::ZoomToDistance,
codegen::lua::ZoomToDistanceRelative,
codegen::lua::JumpTo,
codegen::lua::JumpToNavigationState,
codegen::lua::CreatePath
}
};

View File

@@ -307,6 +307,81 @@ namespace {
}
}
/**
* Fade rendering to black, jump to the specified node, and then fade in. This is done by
* triggering another script that handles the logic.
*
* If no fade duration is specified, use the property from Navigation Handler
*/
[[codegen::luawrap]] void jumpToNavigationState(ghoul::Dictionary navigationState,
std::optional<double> fadeDuration)
{
using namespace openspace;
try {
documentation::testSpecificationAndThrow(
interaction::NavigationState::Documentation(),
navigationState,
"NavigationState"
);
}
catch (const documentation::SpecificationError& e) {
logError(e, "jumpToNavigationState");
throw ghoul::lua::LuaError(std::format(
"Unable to jump to navigation state: {}", e.what()
));
}
// When copy pasting a printed navigation state from the console, the formatting of
// the navigation state dictionary won't be completely correct if using the
// dictionary directly, due to the number keys for arrays. We solve this by first
// creating an object of the correct datatype
// (@TODO emmbr 2024-04-03, This formatting problem should probably be fixed)
interaction::NavigationState ns = interaction::NavigationState(navigationState);
const std::string script = std::format(
"openspace.navigation.setNavigationState({})", ghoul::formatLua(ns.dictionary())
);
if (fadeDuration.has_value()) {
global::navigationHandler->triggerFadeToTransition(
std::move(script),
static_cast<float>(*fadeDuration)
);
}
else {
global::navigationHandler->triggerFadeToTransition(script);
}
}
/**
* Fade rendering to black, jump to the specified navigation state, and then fade in.
* This is done by triggering another script that handles the logic.
*
* If no fade duration is specified, use the property from Navigation Handler
*/
[[codegen::luawrap]] void jumpTo(std::string nodeIdentifier,
std::optional<double> fadeDuration)
{
using namespace openspace;
if (SceneGraphNode* n = sceneGraphNode(nodeIdentifier); !n) {
throw ghoul::lua::LuaError("Unknown node name: " + nodeIdentifier);
}
const std::string script = std::format(
"openspace.pathnavigation.flyTo('{}', 0)", nodeIdentifier
);
if (fadeDuration.has_value()) {
global::navigationHandler->triggerFadeToTransition(
std::move(script),
static_cast<float>(*fadeDuration)
);
}
else {
global::navigationHandler->triggerFadeToTransition(script);
}
}
// Create a camera path as described by the lua table input argument.
[[codegen::luawrap]] void createPath(ghoul::Dictionary path) {
using namespace openspace;