diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index 576282ee3d..6eeb092db7 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -29,6 +29,7 @@ #include #include +#include #include #include #include @@ -176,12 +177,16 @@ public: * \param prop The property that should be called to update itself every frame until * \p durationSeconds seconds have passed * \param durationSeconds The number of seconds that the interpolation will run for + * \param postScript A Lua script that will be executed when the interpolation + * finishes + * \param easingFunction A function that determines who the interpolation occurs * * \pre \p prop must not be \c nullptr * \pre \p durationSeconds must be positive and not 0 * \post A new interpolation record exists for \p that is not expired */ void addPropertyInterpolation(properties::Property* prop, float durationSeconds, + std::string postScript = "", ghoul::EasingFunction easingFunction = ghoul::EasingFunction::Linear); /** @@ -340,6 +345,8 @@ private: properties::Property* prop; std::chrono::time_point beginTime; float durationSeconds; + std::string postScript; + ghoul::EasingFunc easingFunction; bool isExpired = false; }; diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index ed8654f588..be4c8fa0fc 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -439,6 +439,7 @@ std::chrono::steady_clock::time_point Scene::currentTimeForInterpolation() { } void Scene::addPropertyInterpolation(properties::Property* prop, float durationSeconds, + std::string postScript, ghoul::EasingFunction easingFunction) { ghoul_precondition(prop != nullptr, "prop must not be nullptr"); @@ -465,6 +466,7 @@ void Scene::addPropertyInterpolation(properties::Property* prop, float durationS if (info.prop == prop) { info.beginTime = now; info.durationSeconds = durationSeconds; + info.postScript = std::move(postScript), info.easingFunction = func; // If we found it, we can break since we make sure that each property is only // represented once in this @@ -473,12 +475,12 @@ void Scene::addPropertyInterpolation(properties::Property* prop, float durationS } PropertyInterpolationInfo i = { - prop, - now, - durationSeconds, - func + .prop = prop, + .beginTime = now, + .durationSeconds = durationSeconds, + .postScript = std::move(postScript), + .easingFunction = func }; - _propertyInterpolationInfos.push_back(std::move(i)); } @@ -513,13 +515,12 @@ void Scene::updateInterpolations() { steady_clock::time_point now = currentTimeForInterpolation(); // First, let's update the properties for (PropertyInterpolationInfo& i : _propertyInterpolationInfos) { - long long usPassed = duration_cast( - now - i.beginTime - ).count(); + long long us = + duration_cast(now - i.beginTime).count(); const float t = glm::clamp( static_cast( - static_cast(usPassed) / + static_cast(us) / static_cast(i.durationSeconds * 1000000) ), 0.f, @@ -537,6 +538,13 @@ void Scene::updateInterpolations() { i.isExpired = (t == 1.f); if (i.isExpired) { + if (!i.postScript.empty()) { + global::scriptEngine->queueScript( + std::move(i.postScript), + scripting::ScriptEngine::RemoteScripting::No + ); + } + global::eventEngine->publishEvent(i.prop); } } @@ -584,7 +592,8 @@ void Scene::setPropertiesFromProfile(const Profile& p) { allProperties(), 0.0, groupName, - ghoul::EasingFunction::Linear + ghoul::EasingFunction::Linear, + "" ); // Clear lua state stack lua_settop(L, 0); diff --git a/src/scene/scene_lua.inl b/src/scene/scene_lua.inl index 5fdb397bcf..20cd7848a3 100644 --- a/src/scene/scene_lua.inl +++ b/src/scene/scene_lua.inl @@ -196,7 +196,8 @@ void applyRegularExpression(lua_State* L, const std::string& regex, const std::vector& properties, double interpolationDuration, const std::string& groupName, - ghoul::EasingFunction easingFunction) + ghoul::EasingFunction easingFunction, + std::string postScript) { using namespace openspace; using ghoul::lua::errorLocation; @@ -244,6 +245,7 @@ void applyRegularExpression(lua_State* L, const std::string& regex, global::renderEngine->scene()->addPropertyInterpolation( prop, static_cast(interpolationDuration), + std::move(postScript), easingFunction ); } @@ -283,7 +285,7 @@ namespace openspace::luascriptfunctions { int setPropertyCallSingle(properties::Property& prop, const std::string& uri, lua_State* L, double duration, - ghoul::EasingFunction easingFunction) + ghoul::EasingFunction easingFunction, std::string postScript) { using ghoul::lua::errorLocation; using ghoul::lua::luaTypeToString; @@ -313,6 +315,7 @@ int setPropertyCallSingle(properties::Property& prop, const std::string& uri, global::renderEngine->scene()->addPropertyInterpolation( &prop, static_cast(duration), + std::move(postScript), easingFunction ); } @@ -321,7 +324,7 @@ int setPropertyCallSingle(properties::Property& prop, const std::string& uri, } int propertySetValue(lua_State* L) { - ghoul::lua::checkArgumentsAndThrow(L, { 2, 5 }, "lua::property_setValue"); + ghoul::lua::checkArgumentsAndThrow(L, { 2, 6 }, "lua::property_setValue"); defer { lua_settop(L, 0); }; std::string uriOrRegex = @@ -330,6 +333,7 @@ int propertySetValue(lua_State* L) { double interpolationDuration = 0.0; std::string easingMethodName; ghoul::EasingFunction easingMethod = ghoul::EasingFunction::Linear; + std::string postScript; if (lua_gettop(L) >= 3) { if (ghoul::lua::hasValue(L, 3)) { @@ -351,8 +355,12 @@ int propertySetValue(lua_State* L) { } } - if (lua_gettop(L) == 5) { - optimization = ghoul::lua::value(L, 5, ghoul::lua::PopValue::No); + if (lua_gettop(L) >= 5) { + postScript = ghoul::lua::value(L, 5, ghoul::lua::PopValue::No); + } + + if (lua_gettop(L) == 6) { + optimization = ghoul::lua::value(L, 6, ghoul::lua::PopValue::No); } // Later functions expect the value to be at the last position on the stack @@ -392,9 +400,9 @@ int propertySetValue(lua_State* L) { allProperties(), interpolationDuration, groupName, - easingMethod + easingMethod, + std::move(postScript) ); - return 0; } else if (optimization == "regex") { applyRegularExpression( @@ -403,7 +411,8 @@ int propertySetValue(lua_State* L) { allProperties(), interpolationDuration, "", - easingMethod + easingMethod, + std::move(postScript) ); } else if (optimization == "single") { @@ -423,7 +432,8 @@ int propertySetValue(lua_State* L) { uriOrRegex, L, interpolationDuration, - easingMethod + easingMethod, + std::move(postScript) ); } else {