diff --git a/data/assets/customization/globebrowsing.asset b/data/assets/customization/globebrowsing.asset index e7dad3f248..726ac0bce9 100644 --- a/data/assets/customization/globebrowsing.asset +++ b/data/assets/customization/globebrowsing.asset @@ -1,6 +1,9 @@ -- Add require statements for assets exporting the neccessary globes -- example: --- asset.require('../scene/solarsystem/planets/mars/mars') +asset.require('../scene/solarsystem/planets/mars/mars') +asset.require('../scene/solarsystem/planets/earth/moon/moon') +asset.require('../scene/solarsystem/planets/mercury/mercury') + local CreateFocusNodes = false @@ -14,11 +17,12 @@ local vrt_folders = { -- Add folders here whose contents will be automatically added to the Mars globe -- If multiple folders are added, the results will be added sequentially, meaning that -- if areas overlap (for example CTX and HiRISE) and CTX is specified *after* HiRISE, - -- CTX will stomp over the HiRISE - -- + -- CTX will stomp over the HiRISE. + -- tl;dr: Specify CTX folders first, then HiRISE -- example: 'C:/OpenSpace/GlobeBrowsingData/Mars/CTX' - '', + openspace.absPath('${BASE}/../OpenSpaceData/Mars/CTX'), + openspace.absPath('${BASE}/../OpenSpaceData/Mars/HiRISE'), '', }, Moon = { @@ -27,6 +31,16 @@ local vrt_folders = { -- if areas overlap, images from the lower results will overwrite the images from former -- results -- example: 'C:/OpenSpace/GlobeBrowsingData/Moon' + openspace.absPath('${BASE}/../OpenSpaceData/Moon'), + '' + }, + Mercury = { + -- Add folders here whose contents will be automatically added to the Mercury globe + -- If multiple folders are added, the results will be added sequentially, meaning that + -- if areas overlap, images from the lower results will overwrite the images from former + -- results + -- example: 'C:/OpenSpace/GlobeBrowsingData/Mercury' + openspace.absPath('${BASE}/../OpenSpaceData/Mercury'), '' } } diff --git a/data/assets/scene/digitaluniverse/grids.asset b/data/assets/scene/digitaluniverse/grids.asset index 50f6319833..94bcbc062c 100644 --- a/data/assets/scene/digitaluniverse/grids.asset +++ b/data/assets/scene/digitaluniverse/grids.asset @@ -9,15 +9,46 @@ local speck = asset.syncedResource({ Version = 1 }) +local radio = { + Identifier = "RadioSphere", + Parent = transforms.SolarSystemBarycenter.Name, + Transform = { + Scale = { + Type = "TimeDependentScale", + ReferenceDate = "1901 DEC 12", -- Marconi's first atlantic transmission + Speed = 299792458 -- c + } + }, + Renderable = { + Type = "RenderableSphericalGrid", + Enabled = false, + GridColor = { 1.0, 1.0, 0.3, 0.75}, + LineWidth = 2.0, + GridMatrix = { -0.05487554, 0.4941095, -0.8676661 , 0.0, + -0.9938214 , -0.1109906, -0.0003515167, 0.0, + -0.09647644, 0.8622859, 0.4971472 , 0.0, + 0.0 , 0.0 , 0.0 , 1.0 } + }, + GUI = { + Name = "Radio Sphere", + Path = "/Other/Grids" + } +} + local ecliptic = { Identifier = "EclipticSphere", Parent = transforms.SolarSystemBarycenter.Name, + Transform = { + Scale = { + Type = "StaticScale", + Scale = 9.46377307652E17; + } + }, Renderable = { Type = "RenderableSphericalGrid", Enabled = false, GridColor = { 0.7, 0.0, 0.0, 0.5}, LineWidth = 2.0, - Radius = 9.46377307652E17; GridMatrix = { -0.05487554, 0.4941095, -0.8676661 , 0.0, -0.9938214 , -0.1109906, -0.0003515167, 0.0, -0.09647644, 0.8622859, 0.4971472 , 0.0, @@ -38,9 +69,11 @@ local eclipticLabels = { Color = { 1.0, 1.0, 1.0 }, Transparency = 0.65, LabelFile = speck .. "/eclip.label", + DrawLabels = true, TextColor = { 0.5, 0.5, 0.5, 1.0 }, TextSize = 15.4, TextMinSize = 5.0, + TextMaxSize = 18.0, Unit = "pc", TransformationMatrix = { -0.05487554, 0.4941095, -0.8676661, 0.0, @@ -58,12 +91,17 @@ local eclipticLabels = { local equatorial = { Identifier = "EquatorialSphere", Parent = transforms.SolarSystemBarycenter.Name, + Transform = { + Scale = { + Type = "StaticScale", + Scale = 6.2440846E17; + } + }, Renderable = { Type = "RenderableSphericalGrid", Enabled = false, GridColor = { 0.0, 0.0, 1.0, 0.8}, LineWidth = 2.0, - Radius = 6.2440846E17, GridMatrix = { -0.05487554, 0.4941095, -0.8676661, 0.0, -0.8734371 , -0.4448296, -0.1980764, 0.0, -0.483835 , 0.7469823, 0.4559838, 0.0, @@ -84,9 +122,11 @@ local equatorialLabels = { Color = { 1.0, 1.0, 1.0 }, Transparency = 0.65, LabelFile = speck .. "/radec.label", + DrawLabels = true, TextColor = { 0.5, 0.5, 0.5, 1.0 }, TextSize = 15.3, TextMinSize = 5.0, + TextMaxSize = 18.0, Unit = "pc", TransformationMatrix = { -0.05487554, 0.4941095, -0.8676661, 0.0, @@ -104,11 +144,16 @@ local equatorialLabels = { local galactic = { Identifier = "GalacticSphere", Parent = transforms.SolarSystemBarycenter.Name, + Transform = { + Scale = { + Type = "StaticScale", + Scale = 9.46377307652E18; + } + }, Renderable = { Type = "RenderableSphericalGrid", Enabled = false, LineWidth = 2.0, - Radius = 9.46377307652E18; GridColor = { 0.0, 0.6, 0.6, 0.6} }, GUI = { @@ -126,9 +171,11 @@ local galacticLabels = { Color = { 1.0, 1.0, 1.0 }, Transparency = 0.65, LabelFile = speck .. "/galac.label", + DrawLabels = true, TextColor = { 0.5, 0.5, 0.5, 1.0 }, TextSize = 16.25, TextMinSize = 5.0, + TextMaxSize = 18.0, Unit = "pc" }, GUI = { @@ -150,7 +197,8 @@ local plane100kly = { LabelFile = speck .. "/100kly.label", TextColor = { 0.0, 0.2, 0.5, 1.0 }, TextSize = 18.6, - TextMinSize = 7.0, + TextMinSize = 0.5, + TextMaxSize = 30.0, Unit = "Mpc" }, GUI = { @@ -172,7 +220,8 @@ local plane1Mly = { LabelFile = speck .. "/1Mly.label", TextColor = { 0.0, 0.2, 0.5, 1.0 }, TextSize = 19.6, - TextMinSize = 7.0, + TextMinSize = 0.5, + TextMaxSize = 30.0, Unit = "Mpc" }, GUI = { @@ -194,7 +243,8 @@ local plane10Mly = { LabelFile = speck .. "/10Mly.label", TextColor = { 0.0, 0.2, 0.5, 1.0 }, TextSize = 20.6, - TextMinSize = 7.0, + TextMinSize = 0.5, + TextMaxSize = 30.0, Unit = "Mpc" }, GUI = { @@ -216,7 +266,8 @@ local plane100Mly = { LabelFile = speck .. "/100Mly.label", TextColor = { 0.0, 0.2, 0.5, 1.0 }, TextSize = 21.6, - TextMinSize = 7.0, + TextMinSize = 0.5, + TextMaxSize = 30.0, Unit = "Mpc" }, GUI = { @@ -238,7 +289,8 @@ local plane20Gly = { LabelFile = speck .. "/20Gly.label", TextColor = { 0.0, 0.2, 0.5, 1.0 }, TextSize = 23.6, - TextMinSize = 7.0, + TextMinSize = 0.5, + TextMaxSize = 30.0, Unit = "Mpc" }, GUI = { @@ -248,6 +300,6 @@ local plane20Gly = { } assetHelper.registerSceneGraphNodesAndExport(asset, { - ecliptic, eclipticLabels, equatorial, equatorialLabels, galactic, galacticLabels, - plane100kly, plane1Mly, plane10Mly, plane100Mly, plane20Gly + radio, ecliptic, eclipticLabels, equatorial, equatorialLabels, galactic, + galacticLabels, plane100kly, plane1Mly, plane10Mly, plane100Mly, plane20Gly }) diff --git a/include/openspace/engine/globals.h b/include/openspace/engine/globals.h index b5b82d6c5e..8bb19ff8d6 100644 --- a/include/openspace/engine/globals.h +++ b/include/openspace/engine/globals.h @@ -54,6 +54,7 @@ namespace interaction { struct JoystickInputStates; class KeybindingManager; class NavigationHandler; + class ShortcutManager; } // namespace interaction namespace performance { class PerformanceManager; } namespace properties { class PropertyOwner; } @@ -87,6 +88,7 @@ configuration::Configuration& gConfiguration(); interaction::JoystickInputStates& gJoystickInputStates(); interaction::KeybindingManager& gKeybindingManager(); interaction::NavigationHandler& gNavigationHandler(); +interaction::ShortcutManager& gShortcutManager(); performance::PerformanceManager& gPerformanceManager(); properties::PropertyOwner& gRootPropertyOwner(); properties::PropertyOwner& gScreenSpaceRootPropertyOwner(); @@ -118,6 +120,7 @@ static interaction::JoystickInputStates& joystickInputStates = detail::gJoystickInputStates(); static interaction::KeybindingManager& keybindingManager = detail::gKeybindingManager(); static interaction::NavigationHandler& navigationHandler = detail::gNavigationHandler(); +static interaction::ShortcutManager& shortcutManager = detail::gShortcutManager(); static performance::PerformanceManager& performanceManager = detail::gPerformanceManager(); static properties::PropertyOwner& rootPropertyOwner = detail::gRootPropertyOwner(); diff --git a/include/openspace/interaction/keybindingmanager.h b/include/openspace/interaction/keybindingmanager.h index 7ddcc2312a..ce95c7fd36 100644 --- a/include/openspace/interaction/keybindingmanager.h +++ b/include/openspace/interaction/keybindingmanager.h @@ -41,7 +41,6 @@ namespace openspace::interaction { class KeybindingManager : public DocumentationGenerator { public: - BooleanType(IsLocalBind); BooleanType(IsSynchronized); struct KeyInformation { @@ -69,6 +68,8 @@ public: void keyboardCallback(Key key, KeyModifier modifier, KeyAction action); + const std::multimap& keyBindings() const; + private: std::string generateJson() const override; diff --git a/include/openspace/interaction/shortcutmanager.h b/include/openspace/interaction/shortcutmanager.h new file mode 100644 index 0000000000..caab550807 --- /dev/null +++ b/include/openspace/interaction/shortcutmanager.h @@ -0,0 +1,59 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_CORE___SHORTCUTSMANAGER___H__ +#define __OPENSPACE_CORE___SHORTCUTSMANAGER___H__ + +#include +#include +#include + +namespace openspace::scripting { struct LuaLibrary; } + +namespace openspace::interaction { + +class ShortcutManager { +public: + BooleanType(IsSynchronized); + + struct ShortcutInformation { + std::string name; + std::string script; + IsSynchronized synchronization; + std::string documentation; + }; + + void resetShortcuts(); + void addShortcut(ShortcutInformation info); + const std::vector& shortcuts() const; + + static scripting::LuaLibrary luaLibrary(); + +private: + std::vector _shortcuts; +}; + +} // namespace openspace::interaction + +#endif // __OPENSPACE_CORE___SHORTCUTSMANAGER___H__ diff --git a/include/openspace/scene/scene.h b/include/openspace/scene/scene.h index 63ccb15b59..784567ef6c 100644 --- a/include/openspace/scene/scene.h +++ b/include/openspace/scene/scene.h @@ -62,6 +62,13 @@ public: const std::string& comp = ""); }; + /// This struct describes a time that has some intrinsic interesting-ness to this + /// scene. + struct InterestingTime { + std::string name; + std::string time; + }; + // constructors & destructor Scene(std::unique_ptr initializer); ~Scene(); @@ -209,6 +216,24 @@ public: */ void updateInterpolations(); + /** + * Adds the provided \p time as an interesting time to this scene. The same time can + * be added multiple times. + * + * \param The time that should be added + * + * \pre \p time.time must not be empty + * \pre \p time.name must not be empty + */ + void addInterestingTime(InterestingTime time); + + /** + * Returns the list of all interesting times that are defined for this scene. + * + * \return The list of all interesting times that are defined for this scene + */ + const std::vector& interestingTimes() const; + /** * Returns the Lua library that contains all Lua functions available to change the * scene graph. The functions contained are @@ -235,6 +260,8 @@ private: SceneGraphNode _rootDummy; std::unique_ptr _initializer; + std::vector _interestingTimes; + std::vector _licenses; std::mutex _programUpdateLock; diff --git a/modules/base/CMakeLists.txt b/modules/base/CMakeLists.txt index f59393c8c8..ad38bfb017 100644 --- a/modules/base/CMakeLists.txt +++ b/modules/base/CMakeLists.txt @@ -34,6 +34,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditempropertyvalue.h ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemsimulationincrement.h ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemspacing.h + ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemvelocity.h ${CMAKE_CURRENT_SOURCE_DIR}/lightsource/cameralightsource.h ${CMAKE_CURRENT_SOURCE_DIR}/lightsource/scenegraphlightsource.h ${CMAKE_CURRENT_SOURCE_DIR}/rendering/modelgeometry.h @@ -59,6 +60,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.h ${CMAKE_CURRENT_SOURCE_DIR}/scale/luascale.h ${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.h + ${CMAKE_CURRENT_SOURCE_DIR}/scale/timedependentscale.h ${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.h ${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.h ) @@ -74,6 +76,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditempropertyvalue.cpp ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemsimulationincrement.cpp ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemspacing.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboarditemvelocity.cpp ${CMAKE_CURRENT_SOURCE_DIR}/lightsource/cameralightsource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/lightsource/scenegraphlightsource.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rendering/modelgeometry.cpp @@ -99,6 +102,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/rotation/staticrotation.cpp ${CMAKE_CURRENT_SOURCE_DIR}/scale/luascale.cpp ${CMAKE_CURRENT_SOURCE_DIR}/scale/staticscale.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/scale/timedependentscale.cpp ${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeinterval.cpp ${CMAKE_CURRENT_SOURCE_DIR}/timeframe/timeframeunion.cpp ) diff --git a/modules/base/basemodule.cpp b/modules/base/basemodule.cpp index 2c7e56e187..ca6c8e1baa 100644 --- a/modules/base/basemodule.cpp +++ b/modules/base/basemodule.cpp @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include #include #include @@ -109,6 +111,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { "DashboardItemSimulationIncrement" ); fDashboard->registerClass("DashboardItemSpacing"); + fDashboard->registerClass("DashboardItemVelocity"); auto fRenderable = FactoryManager::ref().factory(); ghoul_assert(fRenderable, "Renderable factory was not created"); @@ -140,6 +143,7 @@ void BaseModule::internalInitialize(const ghoul::Dictionary&) { fScale->registerClass("LuaScale"); fScale->registerClass("StaticScale"); + fScale->registerClass("TimeDependentScale"); auto fTimeFrame = FactoryManager::ref().factory(); ghoul_assert(fTimeFrame, "Scale factory was not created"); @@ -173,6 +177,7 @@ std::vector BaseModule::documentations() const { DashboardItemParallelConnection::Documentation(), DashboardItemSimulationIncrement::Documentation(), DashboardItemSpacing::Documentation(), + DashboardItemVelocity::Documentation(), RenderableModel::Documentation(), RenderablePlane::Documentation(), @@ -191,6 +196,7 @@ std::vector BaseModule::documentations() const { LuaScale::Documentation(), StaticScale::Documentation(), + TimeDependentScale::Documentation(), LuaTranslation::Documentation(), StaticTranslation::Documentation(), diff --git a/modules/base/dashboard/dashboarditemdistance.cpp b/modules/base/dashboard/dashboarditemdistance.cpp index 3a3b484404..71b83ce7f0 100644 --- a/modules/base/dashboard/dashboarditemdistance.cpp +++ b/modules/base/dashboard/dashboarditemdistance.cpp @@ -53,7 +53,7 @@ namespace { constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = { "FontSize", "Font Size", - "This value determines the size of the font that is used to render the date." + "This value determines the size of the font that is used to render the distance." }; constexpr openspace::properties::Property::PropertyInfo SourceTypeInfo = { @@ -87,9 +87,9 @@ namespace { constexpr openspace::properties::Property::PropertyInfo SimplificationInfo = { "Simplification", "Simplification", - "If this value is enabled, the distace is displayed in nuanced units, such as " - "km, AU, light years, parsecs, etc. If this value is disabled, it is always " - "displayed in meters." + "If this value is enabled, the distance is displayed in nuanced units, such as " + "km, AU, light years, parsecs, etc. If this value is disabled, the unit can be " + "explicitly requested." }; constexpr openspace::properties::Property::PropertyInfo RequestedUnitInfo = { diff --git a/modules/base/dashboard/dashboarditemvelocity.cpp b/modules/base/dashboard/dashboarditemvelocity.cpp new file mode 100644 index 0000000000..e6d225b321 --- /dev/null +++ b/modules/base/dashboard/dashboarditemvelocity.cpp @@ -0,0 +1,238 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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 +#include + +namespace { + constexpr const char* KeyFontMono = "Mono"; + + constexpr const float DefaultFontSize = 10.f; + + constexpr openspace::properties::Property::PropertyInfo FontNameInfo = { + "FontName", + "Font Name", + "This value is the name of the font that is used. It can either refer to an " + "internal name registered previously, or it can refer to a path that is used." + }; + + constexpr openspace::properties::Property::PropertyInfo FontSizeInfo = { + "FontSize", + "Font Size", + "This value determines the size of the font that is used to render the velocity." + }; + + constexpr openspace::properties::Property::PropertyInfo SimplificationInfo = { + "Simplification", + "Simplification", + "If this value is enabled, the velocity is displayed in nuanced units, such as " + "m/s, AU/s, light years / s etc. If this value is disabled, the unit can be " + "explicitly requested." + }; + + constexpr openspace::properties::Property::PropertyInfo RequestedUnitInfo = { + "RequestedUnit", + "Requested Unit", + "If the simplification is disabled, this distance unit is used for the velocity " + "display." + }; + + std::vector unitList() { + std::vector res(openspace::DistanceUnits.size()); + std::transform( + openspace::DistanceUnits.begin(), + openspace::DistanceUnits.end(), + res.begin(), + [](openspace::DistanceUnit unit) -> std::string { + return nameForDistanceUnit(unit); + } + ); + return res; + } +} // namespace + +namespace openspace { + +documentation::Documentation DashboardItemVelocity::Documentation() { + using namespace documentation; + return { + "DashboardItem Velocity", + "base_dashboarditem_velocity", + { + { + "Type", + new StringEqualVerifier("DashboardItemVelocity"), + Optional::No + }, + { + FontNameInfo.identifier, + new StringVerifier, + Optional::Yes, + FontNameInfo.description + }, + { + FontSizeInfo.identifier, + new IntVerifier, + Optional::Yes, + FontSizeInfo.description + }, + { + SimplificationInfo.identifier, + new BoolVerifier, + Optional::Yes, + SimplificationInfo.description + }, + { + RequestedUnitInfo.identifier, + new StringInListVerifier(unitList()), + Optional::Yes, + RequestedUnitInfo.description + } + } + }; +} + +DashboardItemVelocity::DashboardItemVelocity(const ghoul::Dictionary& dictionary) + : DashboardItem(dictionary) + , _fontName(FontNameInfo, KeyFontMono) + , _fontSize(FontSizeInfo, DefaultFontSize, 6.f, 144.f, 1.f) + , _doSimplification(SimplificationInfo, true) + , _requestedUnit(RequestedUnitInfo, properties::OptionProperty::DisplayType::Dropdown) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "DashboardItemVelocity" + ); + + if (dictionary.hasKey(FontNameInfo.identifier)) { + _fontName = dictionary.value(FontNameInfo.identifier); + } + if (dictionary.hasKey(FontSizeInfo.identifier)) { + _fontSize = static_cast(dictionary.value(FontSizeInfo.identifier)); + } + + _fontName.onChange([this]() { + _font = global::fontManager.font(_fontName, _fontSize); + }); + addProperty(_fontName); + + _fontSize.onChange([this]() { + _font = global::fontManager.font(_fontName, _fontSize); + }); + addProperty(_fontSize); + + if (dictionary.hasKey(SimplificationInfo.identifier)) { + _doSimplification = dictionary.value(SimplificationInfo.identifier); + } + _doSimplification.onChange([this]() { + _requestedUnit.setVisibility( + _doSimplification ? + properties::Property::Visibility::Hidden : + properties::Property::Visibility::User + ); + }); + addProperty(_doSimplification); + + for (DistanceUnit u : DistanceUnits) { + _requestedUnit.addOption(static_cast(u), nameForDistanceUnit(u)); + } + _requestedUnit = static_cast(DistanceUnit::Meter); + if (dictionary.hasKey(RequestedUnitInfo.identifier)) { + const std::string& value = dictionary.value( + RequestedUnitInfo.identifier + ); + DistanceUnit unit = distanceUnitFromString(value.c_str()); + _requestedUnit = static_cast(unit); + } + _requestedUnit.setVisibility(properties::Property::Visibility::Hidden); + addProperty(_requestedUnit); + + _font = global::fontManager.font(_fontName, _fontSize); +} + +void DashboardItemVelocity::render(glm::vec2& penPosition) { + const glm::dvec3 currentPos = global::renderEngine.scene()->camera()->positionVec3(); + const glm::dvec3 dt = currentPos - _prevPosition; + const double speedPerFrame = glm::length(dt); + + const double secondsPerFrame = global::windowDelegate.averageDeltaTime(); + + const double speedPerSecond = speedPerFrame / secondsPerFrame; + + std::pair dist; + if (_doSimplification) { + dist = simplifyDistance(speedPerSecond); + } + else { + const DistanceUnit unit = static_cast(_requestedUnit.value()); + const double convertedD = convertDistance(speedPerSecond, unit); + dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) }; + } + + penPosition.y -= _font->height(); + RenderFont( + *_font, + penPosition, + fmt::format( + "Camera velocity: {} {}/s", dist.first, dist.second + ) + ); + + _prevPosition = currentPos; +} + +glm::vec2 DashboardItemVelocity::size() const { + const double d = glm::length(1e20); + std::pair dist; + if (_doSimplification) { + dist = simplifyDistance(d); + } + else { + DistanceUnit unit = static_cast(_requestedUnit.value()); + double convertedD = convertDistance(d, unit); + dist = { convertedD, nameForDistanceUnit(unit, convertedD != 1.0) }; + } + + return ghoul::fontrendering::FontRenderer::defaultRenderer().boundingBox( + *_font, + fmt::format("Camera velocity: {} {}/s", dist.first, dist.second) + ).boundingBox; +} + +} // namespace openspace diff --git a/modules/base/dashboard/dashboarditemvelocity.h b/modules/base/dashboard/dashboarditemvelocity.h new file mode 100644 index 0000000000..b36f1a8a69 --- /dev/null +++ b/modules/base/dashboard/dashboarditemvelocity.h @@ -0,0 +1,68 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___DASHBOARDITEMVELOCITY___H__ +#define __OPENSPACE_MODULE_BASE___DASHBOARDITEMVELOCITY___H__ + +#include + +#include +#include +#include +#include +#include + +namespace ghoul::fontrendering { class Font; } + +namespace openspace { + +class SceneGraphNode; + +namespace documentation { struct Documentation; } + +class DashboardItemVelocity : public DashboardItem { +public: + DashboardItemVelocity(const ghoul::Dictionary& dictionary); + virtual ~DashboardItemVelocity() = default; + + void render(glm::vec2& penPosition) override; + + glm::vec2 size() const override; + + static documentation::Documentation Documentation(); + +private: + properties::StringProperty _fontName; + properties::FloatProperty _fontSize; + properties::BoolProperty _doSimplification; + properties::OptionProperty _requestedUnit; + + glm::dvec3 _prevPosition; + + std::shared_ptr _font; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___DASHBOARDITEMVELOCITY___H__ diff --git a/modules/base/rendering/renderablesphericalgrid.cpp b/modules/base/rendering/renderablesphericalgrid.cpp index 2394b10feb..b09741e43b 100644 --- a/modules/base/rendering/renderablesphericalgrid.cpp +++ b/modules/base/rendering/renderablesphericalgrid.cpp @@ -62,12 +62,6 @@ namespace { "Line Width", "This value specifies the line width of the spherical grid." }; - - constexpr openspace::properties::Property::PropertyInfo RadiusInfo = { - "Radius", - "Radius", - "This value specifies the radius of the grid." - }; } // namespace namespace openspace { @@ -101,12 +95,6 @@ documentation::Documentation RenderableSphericalGrid::Documentation() { new DoubleVerifier, Optional::Yes, LineWidthInfo.description - }, - { - RadiusInfo.identifier, - new DoubleVerifier, - Optional::Yes, - RadiusInfo.description } } }; @@ -125,7 +113,6 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio ) , _segments(SegmentsInfo, 36, 4, 200) , _lineWidth(LineWidthInfo, 0.5f, 0.f, 20.f) - , _radius(RadiusInfo, 1e20f, 1.f, 1e35f) { documentation::testSpecificationAndThrow( Documentation(), @@ -159,14 +146,6 @@ RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictio ); } addProperty(_lineWidth); - - if (dictionary.hasKey(RadiusInfo.identifier)) { - _radius = static_cast( - dictionary.value(RadiusInfo.identifier) - ); - } - _radius.onChange([&]() { _gridIsDirty = true; }); - addProperty(_radius); } bool RenderableSphericalGrid::isReady() const { @@ -257,7 +236,6 @@ void RenderableSphericalGrid::update(const UpdateData&) { int nr = 0; const float fsegments = static_cast(_segments); - const float r = _radius; for (int nSegment = 0; nSegment <= _segments; ++nSegment) { // define an extra vertex around the y-axis due to texture mapping @@ -271,9 +249,9 @@ void RenderableSphericalGrid::update(const UpdateData&) { // azimuth angle (east to west) const float phi = fj * glm::pi() * 2.0f / fsegments; // 0 -> 2*PI - const float x = r * sin(phi) * sin(theta); // - const float y = r * cos(theta); // up - const float z = r * cos(phi) * sin(theta); // + const float x = sin(phi) * sin(theta); // + const float y = cos(theta); // up + const float z = cos(phi) * sin(theta); // glm::vec3 normal = glm::vec3(x, y, z); if (!(x == 0.f && y == 0.f && z == 0.f)) { diff --git a/modules/base/rendering/renderablesphericalgrid.h b/modules/base/rendering/renderablesphericalgrid.h index ee071031a3..71c0a79ddb 100644 --- a/modules/base/rendering/renderablesphericalgrid.h +++ b/modules/base/rendering/renderablesphericalgrid.h @@ -66,7 +66,6 @@ protected: properties::Vec4Property _gridColor; properties::IntProperty _segments; properties::FloatProperty _lineWidth; - properties::FloatProperty _radius; bool _gridIsDirty = true; diff --git a/modules/base/scale/timedependentscale.cpp b/modules/base/scale/timedependentscale.cpp new file mode 100644 index 0000000000..e2b481160e --- /dev/null +++ b/modules/base/scale/timedependentscale.cpp @@ -0,0 +1,105 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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 + +namespace { + constexpr openspace::properties::Property::PropertyInfo ReferenceDateInfo = { + "ReferenceDate", + "Reference Date", + "The date at which this scale will be 0. The current value of the scale is " + "computed by taking the difference between the current time and the reference " + "date and multiplying it by the speed. This field must be formatted as: " + "YYYY-MM-DDThh:mm:ss.uuu where h is a 24h clock and u microseconds." + }; + + constexpr openspace::properties::Property::PropertyInfo SpeedInfo = { + "Speed", + "Speed", + "The speed at which the value grows or shrinks. The units for this are meters " + "per second. The default value is 1 m/s." + }; +} // namespace + +namespace openspace { + +documentation::Documentation TimeDependentScale::Documentation() { + using namespace openspace::documentation; + return { + "Timedependent Scaling", + "base_scale_timedependent", + { + { + ReferenceDateInfo.identifier, + new StringVerifier, + Optional::No, + ReferenceDateInfo.description + }, + { + SpeedInfo.identifier, + new DoubleVerifier, + Optional::Yes, + SpeedInfo.description + } + } + }; +} + +TimeDependentScale::TimeDependentScale(const ghoul::Dictionary& dictionary) + : _referenceDate(ReferenceDateInfo, "") + , _speed(SpeedInfo, 1.0, 0.0, 1e12) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "TimeDependentScale" + ); + + _referenceDate = dictionary.value(ReferenceDateInfo.identifier); + _referenceDate.onChange([this]() { _cachedReferenceDirty = true; }); + addProperty(_referenceDate); + + if (dictionary.value(SpeedInfo.identifier)) { + _speed = dictionary.value(SpeedInfo.identifier); + } + addProperty(_speed); +} + +double TimeDependentScale::scaleValue(const UpdateData& data) const { + if (_cachedReferenceDirty) { + _cachedReference = Time::convertTime(_referenceDate); + _cachedReferenceDirty = false; + } + + const double now = data.time.j2000Seconds(); + const double dt = now - _cachedReference; + return dt * _speed; +} + +} // namespace openspace diff --git a/modules/base/scale/timedependentscale.h b/modules/base/scale/timedependentscale.h new file mode 100644 index 0000000000..f5aa44b945 --- /dev/null +++ b/modules/base/scale/timedependentscale.h @@ -0,0 +1,54 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_BASE___TIMEDEPENDENTSCALE___H__ +#define __OPENSPACE_MODULE_BASE___TIMEDEPENDENTSCALE___H__ + +#include + +#include +#include + +namespace openspace { + +namespace documentation { struct Documentation; } + +class TimeDependentScale : public Scale { +public: + TimeDependentScale(const ghoul::Dictionary& dictionary); + double scaleValue(const UpdateData& data) const override; + + static documentation::Documentation Documentation(); + +private: + properties::StringProperty _referenceDate; + properties::DoubleProperty _speed; + + mutable bool _cachedReferenceDirty = true; + mutable double _cachedReference = 0.0; // in seconds past the J2000 epoch +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_BASE___TIMEDEPENDENTSCALE___H__ diff --git a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp index 9c0a405c01..ca900ec1ca 100644 --- a/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp +++ b/modules/digitaluniverse/rendering/renderablebillboardscloud.cpp @@ -395,8 +395,8 @@ RenderableBillboardsCloud::RenderableBillboardsCloud(const ghoul::Dictionary& di glm::vec4(1.f) ) , _textSize(TextSizeInfo, 8.0, 0.5, 24.0) - , _textMinSize(LabelMinSizeInfo, 8.0, 0.5, 24.0) - , _textMaxSize(LabelMaxSizeInfo, 500.0, 0.0, 1000.0) + , _textMinSize(LabelMinSizeInfo, 8.f, 0.5f, 24.f) + , _textMaxSize(LabelMaxSizeInfo, 20.f, 0.5f, 100.f) , _drawElements(DrawElementsInfo, true) , _drawLabels(DrawLabelInfo, false) , _pixelSizeControl(PixelSizeControlInfo, false) diff --git a/modules/digitaluniverse/rendering/renderabledumeshes.cpp b/modules/digitaluniverse/rendering/renderabledumeshes.cpp index 3c2987d323..18cefd9ed2 100644 --- a/modules/digitaluniverse/rendering/renderabledumeshes.cpp +++ b/modules/digitaluniverse/rendering/renderabledumeshes.cpp @@ -215,13 +215,13 @@ documentation::Documentation RenderableDUMeshes::Documentation() { }, { LabelMinSizeInfo.identifier, - new IntVerifier, + new DoubleVerifier, Optional::Yes, LabelMinSizeInfo.description }, { LabelMaxSizeInfo.identifier, - new IntVerifier, + new DoubleVerifier, Optional::Yes, LabelMaxSizeInfo.description }, diff --git a/modules/imgui/CMakeLists.txt b/modules/imgui/CMakeLists.txt index 01a5cf9ccf..2e92065fc2 100644 --- a/modules/imgui/CMakeLists.txt +++ b/modules/imgui/CMakeLists.txt @@ -38,6 +38,7 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/guiperformancecomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/guiparallelcomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/guipropertycomponent.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/guishortcutscomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/guispacetimecomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/guiiswacomponent.h ${CMAKE_CURRENT_SOURCE_DIR}/include/imgui_include.h @@ -57,6 +58,7 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/src/guiperformancecomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guiparallelcomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guipropertycomponent.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/guishortcutscomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guispacetimecomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/guiiswacomponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/renderproperties.cpp diff --git a/modules/imgui/include/gui.h b/modules/imgui/include/gui.h index 509bf4facd..6653f16523 100644 --- a/modules/imgui/include/gui.h +++ b/modules/imgui/include/gui.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +62,7 @@ namespace openspace::gui { namespace detail { constexpr int nComponents() { - const int nRegularComponents = 14; + const int nRegularComponents = 15; int totalComponents = nRegularComponents; #ifdef GLOBEBROWSING_USE_GDAL ++totalComponents; @@ -118,6 +119,7 @@ public: #ifdef OPENSPACE_MODULE_ISWA_ENABLED GuiIswaComponent _iswa; #endif // OPENSPACE_MODULE_ISWA_ENABLED + GuiShortcutsComponent _shortcuts; GuiJoystickComponent _joystick; GuiParallelComponent _parallel; GuiPropertyComponent _featuredProperties; @@ -149,6 +151,7 @@ private: #endif &_asset, + &_shortcuts, &_joystick, &_filePath, diff --git a/modules/imgui/include/guishortcutscomponent.h b/modules/imgui/include/guishortcutscomponent.h new file mode 100644 index 0000000000..6eb2840819 --- /dev/null +++ b/modules/imgui/include/guishortcutscomponent.h @@ -0,0 +1,41 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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. * + ****************************************************************************************/ + +#ifndef __OPENSPACE_MODULE_IMGUI___GUISHORTCUTSCOMPONENT___H__ +#define __OPENSPACE_MODULE_IMGUI___GUISHORTCUTSCOMPONENT___H__ + +#include + +namespace openspace::gui { + +class GuiShortcutsComponent : public GuiComponent { +public: + GuiShortcutsComponent(); + + void render() override; +}; + +} // namespace openspace::gui + +#endif // __OPENSPACE_MODULE_IMGUI___GUISHORTCUTSCOMPONENT___H__ diff --git a/modules/imgui/src/guishortcutscomponent.cpp b/modules/imgui/src/guishortcutscomponent.cpp new file mode 100644 index 0000000000..8b717209f4 --- /dev/null +++ b/modules/imgui/src/guishortcutscomponent.cpp @@ -0,0 +1,109 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2018 * + * * + * 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 + +namespace openspace::gui { + +GuiShortcutsComponent::GuiShortcutsComponent() + : GuiComponent("Shortcuts", "Shortcuts") +{} + +void GuiShortcutsComponent::render() { + ImGui::SetNextWindowCollapsed(_isCollapsed); + + bool v = _isEnabled; + ImGui::Begin("Shortcuts", &v); + _isEnabled = v; + _isCollapsed = ImGui::IsWindowCollapsed(); + + + + // First the actual shortcuts + CaptionText("Shortcuts"); + const std::vector& shortcuts = + global::shortcutManager.shortcuts(); + + for (size_t i = 0; i < shortcuts.size(); ++i) { + const interaction::ShortcutManager::ShortcutInformation& info = shortcuts[i]; + + if (ImGui::Button(info.name.c_str())) { + global::scriptEngine.queueScript( + info.script, + scripting::ScriptEngine::RemoteScripting(info.synchronization) + ); + } + ImGui::SameLine(); + + // Poor mans table layout + ImGui::SetCursorPosX(125.f); + + ImGui::Text("%s", info.documentation.c_str()); + if (!info.synchronization) { + ImGui::SameLine(); + ImGui::Text("(%s)", "local"); + } + } + + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 25.f); + + + + // Then display all the keybinds as buttons as well, for good measure + CaptionText("Keybindings"); + using K = KeyWithModifier; + using V = interaction::KeybindingManager::KeyInformation; + const std::multimap& binds = global::keybindingManager.keyBindings(); + + for (const std::pair& p : binds) { + if (ImGui::Button(ghoul::to_string(p.first).c_str())) { + global::scriptEngine.queueScript( + p.second.command, + scripting::ScriptEngine::RemoteScripting(p.second.synchronization) + ); + } + ImGui::SameLine(); + + // Poor mans table layout + ImGui::SetCursorPosX(125.f); + + ImGui::Text("%s", p.second.documentation.c_str()); + if (!p.second.synchronization) { + ImGui::SameLine(); + ImGui::Text("(%s)", "local"); + } + + } +} + +} // namespace openspace::gui diff --git a/modules/imgui/src/guispacetimecomponent.cpp b/modules/imgui/src/guispacetimecomponent.cpp index e975dda0a3..84568775f5 100644 --- a/modules/imgui/src/guispacetimecomponent.cpp +++ b/modules/imgui/src/guispacetimecomponent.cpp @@ -177,6 +177,28 @@ void GuiSpaceTimeComponent::render() { CaptionText("Time Controls"); ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.f); + const std::vector& interestingTimes = + global::renderEngine.scene()->interestingTimes(); + if (!interestingTimes.empty()) { + ImGui::Text("%s", "Interesting Times"); + + for (size_t i = 0; i < interestingTimes.size(); ++i) { + const Scene::InterestingTime& t = interestingTimes[i]; + if (ImGui::Button(t.name.c_str())) { + global::scriptEngine.queueScript( + "openspace.time.setTime(\"" + t.time + "\")", + scripting::ScriptEngine::RemoteScripting::No + ); + } + + if (i != interestingTimes.size() - 1) { + ImGui::SameLine(); + } + } + } + + ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 10.f); + ImGui::Text("Current Date: %s", global::timeManager.time().UTC().c_str()); constexpr int BufferSize = 256; diff --git a/scripts/core_scripts.lua b/scripts/core_scripts.lua index e07db48ad0..073e7d3c7e 100644 --- a/scripts/core_scripts.lua +++ b/scripts/core_scripts.lua @@ -6,6 +6,12 @@ openspace.documentation = { "as interesting, which will provide shortcut access to focus buttons and " .. "featured properties." }, + { + Name = "markInterestingTimes", + Arguments = "List of { Name = '...', Time = '...' } or { '', '