From e1127709c445b67ef87ed13abc7d50a1b2da46a2 Mon Sep 17 00:00:00 2001 From: Ylva Selling Date: Thu, 11 Jul 2024 12:48:03 +0200 Subject: [PATCH] First draft of refactor of skybrowser --- modules/skybrowser/include/browser.h | 15 +- .../include/screenspaceskybrowser.h | 55 +++- .../skybrowser/include/targetbrowserpair.h | 6 +- modules/skybrowser/include/wwtcommunicator.h | 44 +-- modules/skybrowser/skybrowsermodule.cpp | 1 + modules/skybrowser/src/browser.cpp | 19 +- .../skybrowser/src/screenspaceskybrowser.cpp | 267 ++++++++++++++++-- modules/skybrowser/src/targetbrowserpair.cpp | 24 +- modules/skybrowser/src/wwtcommunicator.cpp | 214 ++------------ 9 files changed, 376 insertions(+), 269 deletions(-) diff --git a/modules/skybrowser/include/browser.h b/modules/skybrowser/include/browser.h index 900afc2ae9..82a406e210 100644 --- a/modules/skybrowser/include/browser.h +++ b/modules/skybrowser/include/browser.h @@ -26,6 +26,7 @@ #define __OPENSPACE_MODULE_SKYBROWSER___BROWSER___H__ #include +#include #include #include #include @@ -59,7 +60,7 @@ class BrowserInstance; class RenderHandler; class WebKeyboardHandler; -class Browser { +class Browser : public properties::PropertyOwner { public: explicit Browser(const ghoul::Dictionary& dictionary); virtual ~Browser(); @@ -67,26 +68,28 @@ public: void initializeGL(); void deinitializeGL(); bool isReady() const; - void render(); void update(); - void updateBrowserSize(); void reload(); + void updateBrowserSize(); + void updateBrowserDimensions(); void setRatio(float ratio); float browserRatio() const; + glm::ivec2 browserDimensions() const; + void setBrowserDimensions(glm::ivec2 dimensions); + void bindTexture(); protected: + void executeJavascript(const std::string& script) const; + properties::IVec2Property _browserDimensions; properties::StringProperty _url; properties::TriggerProperty _reload; std::unique_ptr _texture; - void updateBrowserDimensions(); - void executeJavascript(const std::string& script) const; - bool _isUrlDirty = false; bool _isDimensionsDirty = false; bool _shouldReload = false; diff --git a/modules/skybrowser/include/screenspaceskybrowser.h b/modules/skybrowser/include/screenspaceskybrowser.h index acfd47fbd4..13344c80f7 100644 --- a/modules/skybrowser/include/screenspaceskybrowser.h +++ b/modules/skybrowser/include/screenspaceskybrowser.h @@ -34,8 +34,10 @@ #include namespace openspace { +using SelectedImageDeque = std::deque>; + +class ScreenSpaceSkyBrowser : public ScreenSpaceRenderable { -class ScreenSpaceSkyBrowser : public ScreenSpaceRenderable, public WwtCommunicator { public: explicit ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary); ~ScreenSpaceSkyBrowser() override; @@ -45,8 +47,36 @@ public: glm::mat4 scaleMatrix() override; void render(const RenderData& renderData) override; void update() override; - float opacity() const noexcept override; + + double verticalFov() const; + glm::ivec3 borderColor() const; + glm::dvec2 equatorialAim() const; + glm::dvec2 fieldsOfView() const; + float browserRatio() const; + std::vector selectedImages() const; + std::vector opacities() const; + double borderRadius() const; + + void selectImage(const std::string& imageUrl); + void setVerticalFov(double vfov); + void setEquatorialAim(glm::dvec2 equatorial); + void setImageOpacity(const std::string& imageUrl, float opacity); + void setTargetRoll(double roll); + void setBorderColor(glm::ivec3 color); + void removeSelectedImage(const std::string& imageUrl); + + void hideChromeInterface(); + void addImageLayerToWwt(std::string imageUrl); + void reload(); + void setBorderRadius(double radius); + void setRatio(float ratio); + + bool isImageCollectionLoaded() const; + + void setImageCollectionIsLoaded(bool isLoaded); + void setImageOrder(const std::string& imageUrl, int order); + void loadImageCollection(const std::string& collection); glm::dvec2 fineTuneVector(const glm::dvec2& drag); bool isInitialized() const; bool isPointingSpacecraft() const; @@ -58,6 +88,7 @@ public: void setPointSpaceCraft(bool shouldPoint); void updateTextureResolution(); + void updateBorderColor(); // Copies rendered void addDisplayCopy(const glm::vec3& raePosition, int nCopies); @@ -68,14 +99,26 @@ public: static documentation::Documentation Documentation(); private: + SelectedImageDeque::iterator findSelectedImage(const std::string& imageUrl); + static constexpr int RadiusTimeOut = 25; properties::FloatProperty _textureQuality; properties::BoolProperty _isHidden; properties::BoolProperty _isPointingSpacecraft; properties::BoolProperty _updateDuringTargetAnimation; + properties::DoubleProperty _verticalFov; std::vector> _displayCopies; std::vector> _showDisplayCopies; + bool _borderColorIsDirty = false; + bool _equatorialAimIsDirty = false; + bool _isImageCollectionLoaded = false; + double _borderRadius = 0.0; + glm::ivec3 _wwtBorderColor = glm::ivec3(70); + glm::dvec2 _equatorialAim = glm::dvec2(0.0); + double _targetRoll = 0.0; + SelectedImageDeque _selectedImages; + void bindTexture() override; // Flags @@ -84,6 +127,14 @@ private: int _borderRadiusTimer = -1; float _lastTextureQuality = 1.f; + + WwtCommunicator _wwtCommunicator; + + // Time variables + // For capping the message passing to WWT + static constexpr std::chrono::milliseconds TimeUpdateInterval = + std::chrono::milliseconds(10); + std::chrono::system_clock::time_point _lastUpdateTime; }; } // namespace openspace diff --git a/modules/skybrowser/include/targetbrowserpair.h b/modules/skybrowser/include/targetbrowserpair.h index 34ec31dd71..8167434faa 100644 --- a/modules/skybrowser/include/targetbrowserpair.h +++ b/modules/skybrowser/include/targetbrowserpair.h @@ -25,8 +25,10 @@ #ifndef __OPENSPACE_MODULE_SKYBROWSER___TARGETBROWSERPAIR___H__ #define __OPENSPACE_MODULE_SKYBROWSER___TARGETBROWSERPAIR___H__ +#include #include #include +#include namespace ghoul { class Dictionary; } @@ -38,7 +40,7 @@ class ScreenSpaceSkyBrowser; class RenderableSkyTarget; class ScreenSpaceRenderable; -class TargetBrowserPair { +class TargetBrowserPair : public properties::PropertyOwner { public: TargetBrowserPair(SceneGraphNode* target, ScreenSpaceSkyBrowser* browser); @@ -104,6 +106,8 @@ public: void hideChromeInterface(); private: + properties::FloatProperty _lineWidth; + // Target and browser RenderableSkyTarget* _targetRenderable = nullptr; ScreenSpaceSkyBrowser* _browser = nullptr; diff --git a/modules/skybrowser/include/wwtcommunicator.h b/modules/skybrowser/include/wwtcommunicator.h index 082486bf09..62a4f7357a 100644 --- a/modules/skybrowser/include/wwtcommunicator.h +++ b/modules/skybrowser/include/wwtcommunicator.h @@ -31,17 +31,12 @@ #include namespace openspace { -using SelectedImageDeque = std::deque>; class WwtCommunicator : public Browser { public: explicit WwtCommunicator(const ghoul::Dictionary& dictionary); ~WwtCommunicator() override = default; - void update(); - - // WorldWide Telescope communication - void selectImage(const std::string& imageUrl); void addImageLayerToWwt(const std::string& imageUrl); void removeSelectedImage(const std::string& imageUrl); void setImageOrder(const std::string& imageUrl, int order); @@ -49,50 +44,13 @@ public: void setImageOpacity(const std::string& imageUrl, float opacity); void hideChromeInterface() const; - bool isImageCollectionLoaded() const; - - double verticalFov() const; - glm::ivec3 borderColor() const; - glm::dvec2 equatorialAim() const; - glm::dvec2 fieldsOfView() const; - std::vector selectedImages() const; - std::vector opacities() const; - double borderRadius() const; - - void setImageCollectionIsLoaded(bool isLoaded); - void setVerticalFov(double vfov); - void setEquatorialAim(glm::dvec2 equatorial); void setBorderColor(glm::ivec3 color); void setBorderRadius(double radius); - void setTargetRoll(double roll); - - void updateBorderColor() const; - void updateAim() const; - -protected: + void setAim(glm::dvec2 aim, double vfov, double roll); void setIdInBrowser(const std::string& id) const; - SelectedImageDeque::iterator findSelectedImage(const std::string& imageUrl); - - properties::DoubleProperty _verticalFov; - - double _borderRadius = 0.0; - glm::ivec3 _wwtBorderColor = glm::ivec3(70); - glm::dvec2 _equatorialAim = glm::dvec2(0.0); - double _targetRoll = 0.0; - bool _isImageCollectionLoaded = false; - SelectedImageDeque _selectedImages; private: void sendMessageToWwt(const ghoul::Dictionary& msg) const; - - bool _borderColorIsDirty = false; - bool _equatorialAimIsDirty = false; - - // Time variables - // For capping the message passing to WWT - static constexpr std::chrono::milliseconds TimeUpdateInterval = - std::chrono::milliseconds(10); - std::chrono::system_clock::time_point _lastUpdateTime; }; } // namespace openspace diff --git a/modules/skybrowser/skybrowsermodule.cpp b/modules/skybrowser/skybrowsermodule.cpp index 0a33037dd2..909ec022f3 100644 --- a/modules/skybrowser/skybrowsermodule.cpp +++ b/modules/skybrowser/skybrowsermodule.cpp @@ -295,6 +295,7 @@ void SkyBrowserModule::addTargetBrowserPair(const std::string& targetId, _targetsBrowsers.push_back(std::make_unique(target, browser)); } _uniqueIdentifierCounter++; + addPropertySubOwner(_targetsBrowsers.back().get()); } void SkyBrowserModule::removeTargetBrowserPair(const std::string& id) { diff --git a/modules/skybrowser/src/browser.cpp b/modules/skybrowser/src/browser.cpp index 7cd47925cc..da23d93d86 100644 --- a/modules/skybrowser/src/browser.cpp +++ b/modules/skybrowser/src/browser.cpp @@ -82,7 +82,8 @@ void Browser::RenderHandler::setTexture(GLuint t) { } Browser::Browser(const ghoul::Dictionary& dictionary) - : _browserDimensions( + : properties::PropertyOwner({ "Browser" }) + , _browserDimensions( DimensionsInfo, glm::vec2(1000.f), glm::vec2(10.f), @@ -106,6 +107,10 @@ Browser::Browser(const ghoul::Dictionary& dictionary) _reload.onChange([this]() { _shouldReload = true; }); + addProperty(_url); + addProperty(_browserDimensions); + addProperty(_reload); + // Create browser and render handler _browserInstance = std::make_unique( _renderHandler.get(), @@ -204,6 +209,10 @@ float Browser::browserRatio() const { static_cast(_texture->dimensions().y); } +void Browser::bindTexture() { + _texture->bind(); +} + void Browser::updateBrowserDimensions() { const glm::ivec2 dim = _browserDimensions; if (dim.x > 0 && dim.y > 0) { @@ -213,6 +222,14 @@ void Browser::updateBrowserDimensions() { } } +glm::ivec2 Browser::browserDimensions() const { + return _browserDimensions; +} + +void Browser::setBrowserDimensions(glm::ivec2 dimensions) { + _browserDimensions = dimensions; +} + void Browser::executeJavascript(const std::string& script) const { // Make sure that the browser has a main frame const bool browserExists = _browserInstance && _browserInstance->getBrowser(); diff --git a/modules/skybrowser/src/screenspaceskybrowser.cpp b/modules/skybrowser/src/screenspaceskybrowser.cpp index 388fe3fb6f..071ad1e8fc 100644 --- a/modules/skybrowser/src/screenspaceskybrowser.cpp +++ b/modules/skybrowser/src/screenspaceskybrowser.cpp @@ -88,6 +88,13 @@ namespace { openspace::properties::Property::Visibility::User }; + constexpr openspace::properties::Property::PropertyInfo VerticalFovInfo = { + "VerticalFov", + "Vertical Field Of View", + "The vertical field of view of the target.", + openspace::properties::Property::Visibility::AdvancedUser + }; + // This `ScreenSpaceRenderable` is used to display a screen space window showing the // integrated World Wide Telescope view. The view will be dynamically updated when // interacting with the view or with images in the SkyBrowser panel. @@ -107,6 +114,9 @@ namespace { // [[codegen::verbatim(UpdateDuringAnimationInfo.description)]] std::optional updateDuringTargetAnimation; + + // [[codegen::verbatim(VerticalFovInfo.description)]] + std::optional verticalFov; }; #include "screenspaceskybrowser_codegen.cpp" @@ -134,7 +144,8 @@ documentation::Documentation ScreenSpaceSkyBrowser::Documentation() { ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary) : ScreenSpaceRenderable(dictionary) - , WwtCommunicator(dictionary) + , _wwtCommunicator(dictionary) + , _verticalFov(VerticalFovInfo, 10.0, 0.00000000001, 70.0) , _textureQuality(TextureQualityInfo, 1.f, 0.25f, 1.f) , _isHidden(IsHiddenInfo, true) , _isPointingSpacecraft(PointSpacecraftInfo, false) @@ -151,17 +162,19 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary _updateDuringTargetAnimation = p.updateDuringTargetAnimation.value_or( _updateDuringTargetAnimation ); + // Handle target dimension property + _verticalFov = p.verticalFov.value_or(_verticalFov); + _verticalFov.setReadOnly(true); addProperty(_isHidden); - addProperty(_url); - addProperty(_browserDimensions); - addProperty(_reload); addProperty(_textureQuality); addProperty(_verticalFov); addProperty(_isPointingSpacecraft); addProperty(_updateDuringTargetAnimation); - _textureQuality.onChange([this]() { _isDimensionsDirty = true; }); + _textureQuality.onChange([this]() { + _wwtCommunicator.updateBrowserDimensions(); + }); if (global::windowDelegate->isMaster()) { _wwtBorderColor = randomBorderColor(); @@ -182,6 +195,19 @@ ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary } }); }); + + addPropertySubOwner(_wwtCommunicator); + _wwtCommunicator.property("Reload")->onChange([this]() { + _isImageCollectionLoaded = false; + _isInitialized = false; + }); + + _wwtCommunicator.property("Dimensions")->onChange([this]() { + updateTextureResolution(); + }); + + _lastUpdateTime = std::chrono::system_clock::now(); + _objectSize = glm::ivec3(_wwtCommunicator.browserDimensions(), 1); } ScreenSpaceSkyBrowser::~ScreenSpaceSkyBrowser() { @@ -192,7 +218,7 @@ ScreenSpaceSkyBrowser::~ScreenSpaceSkyBrowser() { } bool ScreenSpaceSkyBrowser::initializeGL() { - WwtCommunicator::initializeGL(); + _wwtCommunicator.initializeGL(); ScreenSpaceRenderable::initializeGL(); return true; } @@ -226,7 +252,7 @@ bool ScreenSpaceSkyBrowser::shouldUpdateWhileTargetAnimates() const { void ScreenSpaceSkyBrowser::setIdInBrowser() const { int currentNode = global::windowDelegate->currentNode(); - WwtCommunicator::setIdInBrowser(std::format("{}_{}", identifier(), currentNode)); + _wwtCommunicator.setIdInBrowser(std::format("{}_{}", identifier(), currentNode)); } void ScreenSpaceSkyBrowser::setIsInitialized(bool isInitialized) { @@ -241,17 +267,21 @@ void ScreenSpaceSkyBrowser::updateTextureResolution() { // Check if texture quality has changed. If it has, adjust accordingly if (std::abs(_textureQuality.value() - _lastTextureQuality) > glm::epsilon()) { const float diffTextureQuality = _textureQuality / _lastTextureQuality; - const glm::vec2 res = glm::vec2(_browserDimensions.value()) * diffTextureQuality; - _browserDimensions = glm::ivec2(res); + const glm::vec2 res = glm::vec2(_wwtCommunicator.browserDimensions()) * diffTextureQuality; + _wwtCommunicator.setBrowserDimensions(glm::ivec2(res)); _lastTextureQuality = _textureQuality.value(); } - _objectSize = glm::ivec3(_browserDimensions.value(), 1); + _objectSize = glm::ivec3(_wwtCommunicator.browserDimensions(), 1); // The radius has to be updated when the texture resolution has changed _radiusIsDirty = true; _borderRadiusTimer = 0; } +void ScreenSpaceSkyBrowser::updateBorderColor() { + _wwtCommunicator.setBorderColor(glm::ivec3(_borderColor.value())); +} + void ScreenSpaceSkyBrowser::addDisplayCopy(const glm::vec3& raePosition, int nCopies) { const size_t start = _displayCopies.size(); for (int i = 0; i < nCopies; i++) { @@ -283,6 +313,25 @@ void ScreenSpaceSkyBrowser::addDisplayCopy(const glm::vec3& raePosition, int nCo } } +std::vector ScreenSpaceSkyBrowser::selectedImages() const { + std::vector selectedImagesVector; + selectedImagesVector.resize(_selectedImages.size()); + std::transform( + _selectedImages.cbegin(), + _selectedImages.cend(), + selectedImagesVector.begin(), + [](const std::pair& image) { return image.first; } + ); + return selectedImagesVector; +} + + +void ScreenSpaceSkyBrowser::setBorderColor(glm::ivec3 color) { + _wwtBorderColor = std::move(color); + _borderColorIsDirty = true; + _borderColor = color; +} + void ScreenSpaceSkyBrowser::removeDisplayCopy() { if (!_displayCopies.empty()) { removeProperty(_displayCopies.back().get()); @@ -316,12 +365,12 @@ ScreenSpaceSkyBrowser::showDisplayCopies() const bool ScreenSpaceSkyBrowser::deinitializeGL() { ScreenSpaceRenderable::deinitializeGL(); - WwtCommunicator::deinitializeGL(); + _wwtCommunicator.deinitializeGL(); return true; } void ScreenSpaceSkyBrowser::render(const RenderData& renderData) { - WwtCommunicator::render(); + _wwtCommunicator.render(); if (!_isHidden) { const glm::mat4 mat = @@ -358,25 +407,60 @@ void ScreenSpaceSkyBrowser::render(const RenderData& renderData) { } } +glm::dvec2 ScreenSpaceSkyBrowser::fieldsOfView() const { + const double vFov = _verticalFov; + const double hFov = vFov * _wwtCommunicator.browserRatio(); + return glm::dvec2(hFov, vFov); +} + +float ScreenSpaceSkyBrowser::browserRatio() const { + return _wwtCommunicator.browserRatio(); +} + +void ScreenSpaceSkyBrowser::selectImage(const std::string& url) { + // Ensure there are no duplicates + auto it = findSelectedImage(url); + + if (it == _selectedImages.end()) { + // Push newly selected image to front + _selectedImages.emplace_front(url, 1.0); + + // If wwt has not loaded the collection yet, wait with passing the message + if (_isImageCollectionLoaded) { + _wwtCommunicator.addImageLayerToWwt(url); + } + } +} + void ScreenSpaceSkyBrowser::update() { - // Check for dirty flags - if (_isDimensionsDirty) { - updateTextureResolution(); - } - if (_shouldReload) { - _isInitialized = false; - } // After the texture has been updated, wait a little bit before updating the border // radius so the browser has time to update its size if (_radiusIsDirty && _isInitialized && _borderRadiusTimer == RadiusTimeOut) { - setBorderRadius(_borderRadius); + _wwtCommunicator.setBorderRadius(_borderRadius); _radiusIsDirty = false; _borderRadiusTimer = -1; } _borderRadiusTimer++; + // Cap how messages are passed + const std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); + const std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime; + + if (timeSinceLastUpdate > TimeUpdateInterval) { + if (_equatorialAimIsDirty) { + _wwtCommunicator.setAim(_equatorialAim, _verticalFov, _targetRoll); + _equatorialAimIsDirty = false; + } + if (_borderColorIsDirty) { + _wwtCommunicator.setBorderColor(glm::ivec3(_borderColor.value())); + _borderColorIsDirty = false; + } + _lastUpdateTime = std::chrono::system_clock::now(); + } + _wwtCommunicator.update(); + ScreenSpaceRenderable::update(); - WwtCommunicator::update(); + } double ScreenSpaceSkyBrowser::setVerticalFovWithScroll(float scroll) { @@ -391,7 +475,7 @@ double ScreenSpaceSkyBrowser::setVerticalFovWithScroll(float scroll) { } void ScreenSpaceSkyBrowser::bindTexture() { - _texture->bind(); + _wwtCommunicator.bindTexture(); } glm::mat4 ScreenSpaceSkyBrowser::scaleMatrix() { @@ -401,7 +485,7 @@ glm::mat4 ScreenSpaceSkyBrowser::scaleMatrix() { glm::mat4 scale = glm::scale( glm::mat4(1.f), - glm::vec3(browserRatio() * _scale, _scale, 1.f) + glm::vec3(_wwtCommunicator.browserRatio() * _scale, _scale, 1.f) ); return scale; } @@ -410,4 +494,141 @@ float ScreenSpaceSkyBrowser::opacity() const noexcept { return _opacity; } +glm::ivec3 ScreenSpaceSkyBrowser::borderColor() const { + return _wwtBorderColor; +} + +void ScreenSpaceSkyBrowser::removeSelectedImage(const std::string& imageUrl) { + // Remove from selected list + auto it = findSelectedImage(imageUrl); + if (it != _selectedImages.end()) { + _selectedImages.erase(it); + _wwtCommunicator.removeSelectedImage(imageUrl); + } +} + +void ScreenSpaceSkyBrowser::hideChromeInterface() { + _wwtCommunicator.hideChromeInterface(); +} + +void ScreenSpaceSkyBrowser::addImageLayerToWwt(std::string imageUrl) { + _wwtCommunicator.addImageLayerToWwt(imageUrl); +} + +void ScreenSpaceSkyBrowser::reload() { + _wwtCommunicator.reload(); +} + +void ScreenSpaceSkyBrowser::setBorderRadius(double radius) { + _wwtCommunicator.setBorderRadius(radius); +} + +void ScreenSpaceSkyBrowser::setRatio(float ratio) { + _wwtCommunicator.setRatio(ratio); +} + +std::vector ScreenSpaceSkyBrowser::opacities() const { + std::vector opacities; + opacities.resize(_selectedImages.size()); + std::transform( + _selectedImages.cbegin(), + _selectedImages.cend(), + opacities.begin(), + [](const std::pair& image) { return image.second; } + ); + return opacities; +} + +double ScreenSpaceSkyBrowser::borderRadius() const { + return _borderRadius; +} + +void ScreenSpaceSkyBrowser::setTargetRoll(double roll) { + _targetRoll = roll; +} + +void ScreenSpaceSkyBrowser::setVerticalFov(double vfov) { + _verticalFov = vfov; + _equatorialAimIsDirty = true; +} + +void ScreenSpaceSkyBrowser::setEquatorialAim(glm::dvec2 equatorial) { + _equatorialAim = std::move(equatorial); + _equatorialAimIsDirty = true; +} + +void ScreenSpaceSkyBrowser::loadImageCollection(const std::string& collection) { + if (!_isImageCollectionLoaded) { + _wwtCommunicator.loadImageCollection(collection); + } +} + +SelectedImageDeque::iterator ScreenSpaceSkyBrowser::findSelectedImage( + const std::string& imageUrl) +{ + auto it = std::find_if( + _selectedImages.begin(), + _selectedImages.end(), + [imageUrl](const std::pair& pair) { + return pair.first == imageUrl; + } + ); + return it; +} + +glm::dvec2 ScreenSpaceSkyBrowser::equatorialAim() const { + return _equatorialAim; +} + +bool ScreenSpaceSkyBrowser::isImageCollectionLoaded() const { + return _isImageCollectionLoaded; +} + +void ScreenSpaceSkyBrowser::setImageOpacity(const std::string& imageUrl, float opacity) { + auto it = findSelectedImage(imageUrl); + it->second = opacity; + _wwtCommunicator.setImageOpacity(imageUrl, opacity); +} + +void ScreenSpaceSkyBrowser::setImageCollectionIsLoaded(bool isLoaded) { + _isImageCollectionLoaded = isLoaded; +} + +double ScreenSpaceSkyBrowser::verticalFov() const { + return _verticalFov; +} + +void ScreenSpaceSkyBrowser::setImageOrder(const std::string& imageUrl, int order) { + // Find in selected images list + auto current = findSelectedImage(imageUrl); + const int currentIndex = static_cast( + std::distance(_selectedImages.begin(), current) + ); + + std::deque> newDeque; + + for (int i = 0; i < static_cast(_selectedImages.size()); i++) { + if (i == currentIndex) { + continue; + } + else if (i == order) { + if (order < currentIndex) { + newDeque.push_back(*current); + newDeque.push_back(_selectedImages[i]); + } + else { + newDeque.push_back(_selectedImages[i]); + newDeque.push_back(*current); + } + } + else { + newDeque.push_back(_selectedImages[i]); + } + } + + _selectedImages = newDeque; + const int reverseOrder = static_cast(_selectedImages.size()) - order - 1; + _wwtCommunicator.setImageOrder(imageUrl, reverseOrder); +} + } // namespace openspace diff --git a/modules/skybrowser/src/targetbrowserpair.cpp b/modules/skybrowser/src/targetbrowserpair.cpp index 4cab3a16c1..7d0dbbcdda 100644 --- a/modules/skybrowser/src/targetbrowserpair.cpp +++ b/modules/skybrowser/src/targetbrowserpair.cpp @@ -43,6 +43,8 @@ using nlohmann::json; namespace { + constexpr std::string_view _loggerCat = "TargetBrowserPair"; + void aimTargetGalactic(std::string_view id, const glm::dvec3& direction) { const glm::dvec3 positionCelestial = glm::normalize(direction) * openspace::skybrowser::CelestialSphereRadius; @@ -57,19 +59,39 @@ namespace { openspace::scripting::ScriptEngine::ShouldSendToRemote::Yes ); } + + constexpr openspace::properties::Property::PropertyInfo LineWidthInfo = { + "LineWidth", + "Line Width", + "The thickness of the line of the target. The larger number, the thicker line.", + openspace::properties::Property::Visibility::NoviceUser + }; + + struct [[codegen::Dictionary(TargetBrowserPair)]] Parameters { + // [[codegen::verbatim(LineWidthInfo.description)]] + std::optional lineWidth; + }; +#include "targetbrowserpair_codegen.cpp" } // namespace namespace openspace { TargetBrowserPair::TargetBrowserPair(SceneGraphNode* targetNode, ScreenSpaceSkyBrowser* browser) - : _browser(browser) + : properties::PropertyOwner({ "Guacamole" }) + , _browser(browser) , _targetNode(targetNode) + , _lineWidth(LineWidthInfo) { ghoul_assert(browser, "Sky browser is null pointer"); ghoul_assert(targetNode, "Sky target is null pointer"); _targetRenderable = dynamic_cast(_targetNode->renderable()); + addProperty(_lineWidth); + _lineWidth.onChange([this]() { + _targetRenderable->property("LineWidth")->set(_lineWidth.value()); + }); + LINFO(uri()); } void TargetBrowserPair::setImageOrder(const std::string& imageUrl, int order) { diff --git a/modules/skybrowser/src/wwtcommunicator.cpp b/modules/skybrowser/src/wwtcommunicator.cpp index 3507f2f513..192dfa69a3 100644 --- a/modules/skybrowser/src/wwtcommunicator.cpp +++ b/modules/skybrowser/src/wwtcommunicator.cpp @@ -107,68 +107,22 @@ namespace { return msg; } - constexpr openspace::properties::Property::PropertyInfo VerticalFovInfo = { - "VerticalFov", - "Vertical Field Of View", - "The vertical field of view of the target.", - openspace::properties::Property::Visibility::AdvancedUser - }; + ghoul::Dictionary hideChromeInterfaceMessage() { + using namespace std::string_literals; - struct [[codegen::Dictionary(WwtCommunicator)]] Parameters { - // [[codegen::verbatim(VerticalFovInfo.description)]] - std::optional verticalFov; - }; - #include "wwtcommunicator_codegen.cpp" + ghoul::Dictionary msg; + msg.setValue("event", "modify_settings"s); + msg.setValue("settings", "[[\"hideAllChrome\", true]]"s); + msg.setValue("target", "app"s); + return msg; + } } // namespace namespace openspace { WwtCommunicator::WwtCommunicator(const ghoul::Dictionary& dictionary) : Browser(dictionary) - , _verticalFov(VerticalFovInfo, 10.0, 0.00000000001, 70.0) -{ - // Handle target dimension property - const Parameters p = codegen::bake(dictionary); - _verticalFov = p.verticalFov.value_or(_verticalFov); - _verticalFov.setReadOnly(true); -} - -void WwtCommunicator::update() { - // Cap how messages are passed - const std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); - const std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime; - - if (timeSinceLastUpdate > TimeUpdateInterval) { - if (_equatorialAimIsDirty) { - updateAim(); - _equatorialAimIsDirty = false; - } - if (_borderColorIsDirty) { - updateBorderColor(); - _borderColorIsDirty = false; - } - _lastUpdateTime = std::chrono::system_clock::now(); - } - if (_shouldReload) { - _isImageCollectionLoaded = false; - } - Browser::update(); -} - -void WwtCommunicator::selectImage(const std::string& url) { - // Ensure there are no duplicates - auto it = findSelectedImage(url); - - if (it == _selectedImages.end()) { - // Push newly selected image to front - _selectedImages.emplace_front(url, 1.0); - - // If wwt has not loaded the collection yet, wait with passing the message - if (_isImageCollectionLoaded) { - addImageLayerToWwt(url); - } - } -} +{} void WwtCommunicator::addImageLayerToWwt(const std::string& imageUrl) { // Index of image is used as layer ID as it is unique in the image data set @@ -177,12 +131,7 @@ void WwtCommunicator::addImageLayerToWwt(const std::string& imageUrl) { } void WwtCommunicator::removeSelectedImage(const std::string& imageUrl) { - // Remove from selected list - auto it = findSelectedImage(imageUrl); - if (it != _selectedImages.end()) { - _selectedImages.erase(it); - sendMessageToWwt(removeImageMessage(imageUrl)); - } + sendMessageToWwt(removeImageMessage(imageUrl)); } void WwtCommunicator::sendMessageToWwt(const ghoul::Dictionary& msg) const { @@ -190,160 +139,49 @@ void WwtCommunicator::sendMessageToWwt(const ghoul::Dictionary& msg) const { executeJavascript(std::format("sendMessageToWWT({});", m)); } -std::vector WwtCommunicator::selectedImages() const { - std::vector selectedImagesVector; - selectedImagesVector.resize(_selectedImages.size()); - std::transform( - _selectedImages.cbegin(), - _selectedImages.cend(), - selectedImagesVector.begin(), - [](const std::pair& image) { return image.first; } - ); - return selectedImagesVector; -} - -std::vector WwtCommunicator::opacities() const { - std::vector opacities; - opacities.resize(_selectedImages.size()); - std::transform( - _selectedImages.cbegin(), - _selectedImages.cend(), - opacities.begin(), - [](const std::pair& image) { return image.second; } - ); - return opacities; -} - -double WwtCommunicator::borderRadius() const { - return _borderRadius; -} - -void WwtCommunicator::setTargetRoll(double roll) { - _targetRoll = roll; -} - -void WwtCommunicator::setVerticalFov(double vfov) { - _verticalFov = vfov; - _equatorialAimIsDirty = true; -} - -void WwtCommunicator::setEquatorialAim(glm::dvec2 equatorial) { - _equatorialAim = std::move(equatorial); - _equatorialAimIsDirty = true; -} - -void WwtCommunicator::setBorderColor(glm::ivec3 color) { - _wwtBorderColor = std::move(color); - _borderColorIsDirty = true; -} - void WwtCommunicator::setBorderRadius(double radius) { - _borderRadius = radius; const std::string scr = std::format("setBorderRadius({});", radius); executeJavascript(scr); } -void WwtCommunicator::updateBorderColor() const { +void WwtCommunicator::setBorderColor(glm::ivec3 borderColor) { const std::string script = std::format( "setBackgroundColor('rgb({},{},{})');", - _wwtBorderColor.x, _wwtBorderColor.y, _wwtBorderColor.z + borderColor.x, borderColor.y, borderColor.z ); executeJavascript(script); } -void WwtCommunicator::updateAim() const { +void WwtCommunicator::setAim(glm::dvec2 aim, double vfov, double roll) { // Message WorldWide Telescope current view const ghoul::Dictionary msg = moveCameraMessage( - _equatorialAim, - _verticalFov, - _targetRoll + aim, + vfov, + roll ); sendMessageToWwt(msg); } -glm::dvec2 WwtCommunicator::fieldsOfView() const { - const double vFov = verticalFov(); - const double hFov = vFov * browserRatio(); - return glm::dvec2(hFov, vFov); -} - -bool WwtCommunicator::isImageCollectionLoaded() const { - return _isImageCollectionLoaded; -} - -SelectedImageDeque::iterator WwtCommunicator::findSelectedImage( - const std::string& imageUrl) -{ - auto it = std::find_if( - _selectedImages.begin(), - _selectedImages.end(), - [imageUrl](const std::pair& pair) { - return pair.first == imageUrl; - } - ); - return it; -} - -glm::dvec2 WwtCommunicator::equatorialAim() const { - return _equatorialAim; -} - -void WwtCommunicator::setImageOrder(const std::string& imageUrl, int order) { - // Find in selected images list - auto current = findSelectedImage(imageUrl); - const int currentIndex = static_cast( - std::distance(_selectedImages.begin(), current) - ); - - std::deque> newDeque; - - for (int i = 0; i < static_cast(_selectedImages.size()); i++) { - if (i == currentIndex) { - continue; - } - else if (i == order) { - if (order < currentIndex) { - newDeque.push_back(*current); - newDeque.push_back(_selectedImages[i]); - } - else { - newDeque.push_back(_selectedImages[i]); - newDeque.push_back(*current); - } - } - else { - newDeque.push_back(_selectedImages[i]); - } - } - - _selectedImages = newDeque; - const int reverseOrder = static_cast(_selectedImages.size()) - order - 1; +void WwtCommunicator::setImageOrder(const std::string& imageUrl, int reverseOrder) { const ghoul::Dictionary message = setLayerOrderMessage(imageUrl, reverseOrder); sendMessageToWwt(message); } void WwtCommunicator::loadImageCollection(const std::string& collection) { - if (!_isImageCollectionLoaded) { - sendMessageToWwt(loadCollectionMessage(collection)); - } + sendMessageToWwt(loadCollectionMessage(collection)); } void WwtCommunicator::setImageOpacity(const std::string& imageUrl, float opacity) { - auto it = findSelectedImage(imageUrl); - it->second = opacity; - const ghoul::Dictionary msg = setImageOpacityMessage(imageUrl, opacity); sendMessageToWwt(msg); } void WwtCommunicator::hideChromeInterface() const { - const std::string script = "sendMessageToWWT({event : \"modify_settings\", " - "settings : [[\"hideAllChrome\", true]], target: \"app\"});"; + const std::string script = "sendMessageToWWT({event : \"modify_settings\", " + "settings : [[\"hideAllChrome\", true]], target: \"app\"});"; executeJavascript(script); -} - -void WwtCommunicator::setImageCollectionIsLoaded(bool isLoaded) { - _isImageCollectionLoaded = isLoaded; + // TODO ylvse 2024-07-10 see if i can get this to work + //sendMessageToWwt(hideChromeInterfaceMessage()); } void WwtCommunicator::setIdInBrowser(const std::string& id) const { @@ -351,12 +189,4 @@ void WwtCommunicator::setIdInBrowser(const std::string& id) const { executeJavascript(std::format("setId('{}')", id)); } -glm::ivec3 WwtCommunicator::borderColor() const { - return _wwtBorderColor; -} - -double WwtCommunicator::verticalFov() const { - return _verticalFov; -} - } // namespace openspace