/***************************************************************************************** * * * OpenSpace * * * * Copyright (c) 2014-2021 * * * * Permission is hereby granted, free of charge, to any person obtaining a copy of this * * software and associated documentation files (the "Software"), to deal in the Software * * without restriction, including without limitation the rights to use, copy, modify, * * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * * permit persons to whom the Software is furnished to do so, subject to the following * * conditions: * * * * The above copyright notice and this permission notice shall be included in all copies * * or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * ****************************************************************************************/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "time_lua.inl" namespace openspace { double Time::convertTime(const std::string& time) { ghoul_assert(!time.empty(), "timeString must not be empty"); return SpiceManager::ref().ephemerisTimeFromDate(time); } double Time::convertTime(const char* time) { return SpiceManager::ref().ephemerisTimeFromDate(time); } Time::Time(double secondsJ2000) : _time(secondsJ2000) {} Time::Time(const std::string& time) : _time(SpiceManager::ref().ephemerisTimeFromDate(time)) {} Time Time::now() { Time now; time_t secondsSince1970; secondsSince1970 = time(nullptr); const time_t secondsInAYear = static_cast(365.25 * 24 * 60 * 60); const double secondsSince2000 = static_cast( secondsSince1970 - 30 * secondsInAYear ); now.setTime(secondsSince2000); return now; } void Time::setTime(double value) { _time = value; } double Time::j2000Seconds() const { return _time; } double Time::advanceTime(double delta) { _time += delta; return _time; } void Time::setTime(const std::string& time) { _time = SpiceManager::ref().ephemerisTimeFromDate(time); } void Time::setTime(const char* time) { _time = SpiceManager::ref().ephemerisTimeFromDate(time); } std::string_view Time::UTC() const { constexpr const char Format[] = "YYYY MON DDTHR:MN:SC.### ::RND"; char* b = reinterpret_cast( global::memoryManager->TemporaryMemory.allocate(32) ); std::memset(b, 0, 32); SpiceManager::ref().dateFromEphemerisTime(_time, b, 32, Format); return std::string_view(b); } std::string_view Time::ISO8601() const { ZoneScoped constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SC.###"; constexpr const int S = sizeof(Format); char* b = reinterpret_cast( global::memoryManager->TemporaryMemory.allocate(S) ); std::memset(b, 0, S); SpiceManager::ref().dateFromEphemerisTime(_time, b, S, Format); return std::string_view(b, S - 1); } void Time::ISO8601(char* buffer) const { constexpr const char Format[] = "YYYY-MM-DDTHR:MN:SC.###"; constexpr const int S = sizeof(Format) + 1; std::memset(buffer, 0, S); SpiceManager::ref().dateFromEphemerisTime(_time, buffer, S, Format); } void Time::setTimeRelativeFromProfile(const std::string& setTime) { ghoul::lua::LuaState L(ghoul::lua::LuaState::IncludeStandardLibrary::Yes); luascriptfunctions::time_currentWallTime(L); ghoul::lua::push(L, setTime); luascriptfunctions::time_advancedTime(L); luascriptfunctions::time_setTime(L); } void Time::setTimeAbsoluteFromProfile(const std::string& setTime) { ghoul::lua::LuaState L(ghoul::lua::LuaState::IncludeStandardLibrary::Yes); ghoul::lua::push(L, setTime); luascriptfunctions::time_setTime(L); } scripting::LuaLibrary Time::luaLibrary() { return { "time", { { "setTime", &luascriptfunctions::time_setTime, "{number, string}", "Sets the current simulation time to the " "specified value. If the parameter is a number, the value is the number " "of seconds past the J2000 epoch. If it is a string, it has to be a " "valid ISO 8601-like date string of the format YYYY-MM-DDTHH:MN:SS. " "Note: providing time zone using the Z format is not supported. UTC is " "assumed." }, { "setDeltaTime", &luascriptfunctions::time_setDeltaTime, "number", "Sets the amount of simulation time that happens " "in one second of real time" }, { "setDeltaTimeSteps", &luascriptfunctions::time_setDeltaTimeSteps, "List of numbers", "Sets the list of discrete delta time steps for the simulation speed " "that can be quickly jumped between. The list will be sorted to be in " "increasing order. A negative verison of each specified time step will " "be added per default as well." }, { "deltaTime", &luascriptfunctions::time_deltaTime, "", "Returns the amount of simulated time that passes in one " "second of real time" }, { "setPause", &luascriptfunctions::time_setPause, "bool", "Pauses the simulation time or restores the delta time" }, { "togglePause", &luascriptfunctions::time_togglePause, "", "Toggles the pause function, i.e. temporarily setting the delta time to " "0 and restoring it afterwards" }, { "interpolateTime", &luascriptfunctions::time_interpolateTime, "{number, string} [, number]", "Sets the current simulation time to the specified value. " "If the first parameter is a number, the target is the number " "of seconds past the J2000 epoch. If it is a string, it has to be a " "valid ISO 8601-like date string of the format YYYY-MM-DDTHH:MN:SS " "(Note: providing time zone using the Z format is not supported. UTC is " "assumed). If a second input value is given, the interpolation is done " "over the specified number of seconds." }, { "interpolateTimeRelative", &luascriptfunctions::time_interpolateTimeRelative, "number [, number]", "Increments the current simulation time by the specified number of " "seconds. If a second input value is given, the interpolation is done " "over the specified number of seconds." }, { "interpolateDeltaTime", &luascriptfunctions::time_interpolateDeltaTime, "number [, number]", "Sets the amount of simulation time that happens in one second of real " "time. If a second input value is given, the interpolation is done " "over the specified number of seconds." }, { "setNextDeltaTimeStep", &luascriptfunctions::time_setNextDeltaTimeStep, "", "Immediately set the simulation speed to the first delta time step in " "the list that is larger than the current choice of simulation speed, " "if any." }, { "setPreviousDeltaTimeStep", &luascriptfunctions::time_setPreviousDeltaTimeStep, "", "Immediately set the simulation speed to the first delta time step in " "the list that is smaller than the current choice of simulation speed. " "if any." }, { "interpolateNextDeltaTimeStep", &luascriptfunctions::time_interpolateNextDeltaTimeStep, "[number]", "Interpolate the simulation speed to the first delta time step in the " "list that is larger than the current simulation speed, if any. If an " "input value is given, the interpolation is done over the specified " "number of seconds." }, { "interpolatePreviousDeltaTimeStep", &luascriptfunctions::time_interpolatePreviousDeltaTimeStep, "[number]", "Interpolate the simulation speed to the first delta time step in the " "list that is smaller than the current simulation speed, if any. If an " "input value is given, the interpolation is done over the specified " "number of seconds." }, { "interpolatePause", &luascriptfunctions::time_interpolatePause, "bool [, number]", "Pauses the simulation time or restores the delta time. If a second " "input value is given, the interpolation is done over the specified " "number of seconds." }, { "interpolateTogglePause", &luascriptfunctions::time_interpolateTogglePause, "[number]", "Toggles the pause function, i.e. temporarily setting the delta time to 0" " and restoring it afterwards. If an input value is given, the " "interpolation is done over the specified number of seconds." }, { "pauseToggleViaKeyboard", &luascriptfunctions::time_pauseToggleViaKeyboard, "", "Toggles the pause function from a keypress. This function behaves like" " interpolateTogglePause during normal mode, and behaves like" " sessionRecording.pausePlayback when playing-back a recording." }, { "currentTime", &luascriptfunctions::time_currentTime, "", "Returns the current time as the number of seconds since " "the J2000 epoch" }, { "UTC", &luascriptfunctions::time_currentTimeUTC, "", "Returns the current time as an ISO 8601 date string " "(YYYY-MM-DDTHH:MN:SS)" }, { "currentWallTime", &luascriptfunctions::time_currentWallTime, "", "Returns the current wall time as an ISO 8601 date string " "(YYYY-MM-DDTHH-MN-SS) in the UTC timezone" }, { "currentApplicationTime", &luascriptfunctions::time_currentApplicationTime, "", "Returns the current application time as the number of seconds " "since the OpenSpace application started" }, { "advancedTime", &luascriptfunctions::time_advancedTime, "string or number, string or number", "Modifies the passed time (first argument) by the delta time (second " "argument). The first argument can either be an ISO 8601 date string or " "the number of seconds past the J2000 epoch. The second argument can " "either be a string of the form [-]XX(s,m,h,d,M,y] with (s)econds, " "(m)inutes, (h)ours, (d)ays, (M)onths, and (y)ears as units and an " "optional - sign to move backwards in time. If the second argument is a " "number, it is interpreted as a number of seconds. The return value is " "of the same type as the first argument." } } }; } } // namespace openspace