From 77e14edec345b913f2c135055f7e2bfd9d1eb32f Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Fri, 29 Jun 2018 12:19:23 -0400 Subject: [PATCH] Add DashboardItem to show the current camera location on a globe --- data/assets/util/default_dashboard.asset | 5 + modules/globebrowsing/CMakeLists.txt | 4 + .../dashboard/dashboardglobelocation.cpp | 199 ++++++++++++++++++ .../dashboard/dashboardglobelocation.h | 59 ++++++ modules/globebrowsing/globebrowsingmodule.cpp | 7 + 5 files changed, 274 insertions(+) create mode 100644 modules/globebrowsing/dashboard/dashboardglobelocation.cpp create mode 100644 modules/globebrowsing/dashboard/dashboardglobelocation.h diff --git a/data/assets/util/default_dashboard.asset b/data/assets/util/default_dashboard.asset index dcc4191c70..935aae0956 100644 --- a/data/assets/util/default_dashboard.asset +++ b/data/assets/util/default_dashboard.asset @@ -25,5 +25,10 @@ assetHelper.registerDashboardItems(asset, { Type = "DashboardItemParallelConnection", Identifier = "ParallelConnection", GuiName = "Parallel Connection" + }, + { + Type = "DashboardItemGlobeLocation", + Identifier = "GlobeLocation", + GuiName = "Globe Location" } }) diff --git a/modules/globebrowsing/CMakeLists.txt b/modules/globebrowsing/CMakeLists.txt index 2be90e197f..bf0b1a95f4 100644 --- a/modules/globebrowsing/CMakeLists.txt +++ b/modules/globebrowsing/CMakeLists.txt @@ -42,6 +42,8 @@ set(HEADER_FILES ${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/frustumculler.h ${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/horizonculler.h + ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboardglobelocation.h + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.h ${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.h ${CMAKE_CURRENT_SOURCE_DIR}/geometry/angle.inl @@ -136,6 +138,8 @@ set(SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/frustumculler.cpp ${CMAKE_CURRENT_SOURCE_DIR}/chunk/culling/horizonculler.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/dashboard/dashboardglobelocation.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/geometry/aabb.cpp ${CMAKE_CURRENT_SOURCE_DIR}/geometry/ellipsoid.cpp ${CMAKE_CURRENT_SOURCE_DIR}/geometry/geodetic2.cpp diff --git a/modules/globebrowsing/dashboard/dashboardglobelocation.cpp b/modules/globebrowsing/dashboard/dashboardglobelocation.cpp new file mode 100644 index 0000000000..01ab242a53 --- /dev/null +++ b/modules/globebrowsing/dashboard/dashboardglobelocation.cpp @@ -0,0 +1,199 @@ +/***************************************************************************************** + * * + * 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 + +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 date." + }; + + constexpr openspace::properties::Property::PropertyInfo ActiveColorInfo = { + "ActiveColor", + "Active Color", + "This value determines the color that the active instrument is rendered in. " + "Shortly after activation, the used color is mixture of this and the flash " + "color. The default value is (0.6, 1.0, 0.0)." + }; + + constexpr openspace::properties::Property::PropertyInfo FlashColorInfo = { + "FlashColor", + "Flash Color", + "This value determines the color that is used shortly after an instrument " + "activation. The default value is (0.9, 1.0, 0.75)" + }; +} // namespace + +namespace openspace { + +documentation::Documentation DashboardItemGlobeLocation::Documentation() { + using namespace documentation; + return { + "DashboardItem Globe Location", + "globebrowsing_dashboarditem_globelocation", + { + { + "Type", + new StringEqualVerifier("DashboardItemGlobeLocation"), + Optional::No + }, + { + FontNameInfo.identifier, + new StringVerifier, + Optional::Yes, + FontNameInfo.description + }, + { + FontSizeInfo.identifier, + new IntVerifier, + Optional::Yes, + FontSizeInfo.description + }, + { + ActiveColorInfo.identifier, + new DoubleVector3Verifier, + Optional::Yes, + ActiveColorInfo.description + }, + { + FlashColorInfo.identifier, + new DoubleVector3Verifier, + Optional::Yes, + FlashColorInfo.description + } + } + }; +} + +DashboardItemGlobeLocation::DashboardItemGlobeLocation(const ghoul::Dictionary& dictionary) + : DashboardItem(dictionary) + , _fontName(FontNameInfo, KeyFontMono) + , _fontSize(FontSizeInfo, DefaultFontSize, 6.f, 144.f, 1.f) + , _font(OsEng.fontManager().font(KeyFontMono, 10)) +{ + documentation::testSpecificationAndThrow( + Documentation(), + dictionary, + "DashboardItemGlobeLocation" + ); + + 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 = OsEng.fontManager().font(_fontName, _fontSize); + }); + addProperty(_fontName); + + _fontSize.onChange([this]() { + _font = OsEng.fontManager().font(_fontName, _fontSize); + }); + addProperty(_fontSize); + + _font = OsEng.fontManager().font(_fontName, _fontSize); +} + +void DashboardItemGlobeLocation::render(glm::vec2& penPosition) { + using namespace globebrowsing; + + SceneGraphNode* n = OsEng.navigationHandler().focusNode(); + const RenderableGlobe* globe = dynamic_cast(n->renderable()); + if (!globe) { + return; + } + + const glm::dvec3 cameraPosition = OsEng.navigationHandler().camera()->positionVec3(); + const glm::dmat4 inverseModelTransform = + OsEng.navigationHandler().focusNode()->inverseModelTransform(); + const glm::dvec3 cameraPositionModelSpace = + glm::dvec3(inverseModelTransform * glm::dvec4(cameraPosition, 1.0)); + const SurfacePositionHandle posHandle = globe->calculateSurfacePositionHandle( + cameraPositionModelSpace + ); + + const Geodetic2 geo2 = globe->ellipsoid().cartesianToGeodetic2( + posHandle.centerToReferenceSurface + ); + + double lat = glm::degrees(geo2.lat); + double lon = glm::degrees(geo2.lon); + + bool isNorth = lat > 0.0; + lat = std::abs(lat); + + bool isEast = lon > 0.0; + lon = std::abs(lon); + + const double altitude = glm::length(cameraPositionModelSpace - + posHandle.centerToReferenceSurface); + std::pair dist = simplifyDistance(altitude); + + penPosition.y -= _font->height(); + RenderFont( + *_font, + penPosition, + fmt::format( + "Position: {:03.2f}{}, {:03.2f}{} Altitude: {} {}", + lat, isNorth ? "N" : "S", + lon, isEast ? "E" : "W", + dist.first, dist.second) + ); +} +glm::vec2 DashboardItemGlobeLocation::size() const { + return ghoul::fontrendering::FontRenderer::defaultRenderer().boundingBox( + *_font, + fmt::format("Position: {}, {} Altitude: {}", 1.f, 1.f, 1.f) + ).boundingBox; +} + +} // namespace openspace diff --git a/modules/globebrowsing/dashboard/dashboardglobelocation.h b/modules/globebrowsing/dashboard/dashboardglobelocation.h new file mode 100644 index 0000000000..e62cc6f207 --- /dev/null +++ b/modules/globebrowsing/dashboard/dashboardglobelocation.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_MODULE_GLOBEBROWSING___DASHBOARDITEMGLOBELOCATION___H__ +#define __OPENSPACE_MDOULE_GLOBEBROWSING___DASHBOARDITEMGLOBELOCATION___H__ + +#include + +#include +#include + +namespace ghoul::fontrendering { class Font; } + +namespace openspace { + +namespace documentation { struct Documentation; } + +class DashboardItemGlobeLocation : public DashboardItem { +public: + DashboardItemGlobeLocation(const ghoul::Dictionary& dictionary); + ~DashboardItemGlobeLocation() = default; + + void render(glm::vec2& penPosition) override; + + glm::vec2 size() const override; + + static documentation::Documentation Documentation(); + +private: + properties::StringProperty _fontName; + properties::FloatProperty _fontSize; + + std::shared_ptr _font; +}; + +} // namespace openspace + +#endif // __OPENSPACE_MODULE_GLOBEBROWSING___DASHBOARDITEMGLOBELOCATION___H__ diff --git a/modules/globebrowsing/globebrowsingmodule.cpp b/modules/globebrowsing/globebrowsingmodule.cpp index c8f29356e3..55e878b52f 100644 --- a/modules/globebrowsing/globebrowsingmodule.cpp +++ b/modules/globebrowsing/globebrowsingmodule.cpp @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -217,6 +218,12 @@ void GlobeBrowsingModule::internalInitialize(const ghoul::Dictionary&) { )]); FactoryManager::ref().addFactory(std::move(fTileProvider)); + + auto fDashboard = FactoryManager::ref().factory(); + ghoul_assert(fDashboard, "Dashboard factory was not created"); + + fDashboard->registerClass("DashboardItemGlobeLocation"); + } globebrowsing::cache::MemoryAwareTileCache* GlobeBrowsingModule::tileCache() {