mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-04 18:51:17 -06:00
First draft of refactor of skybrowser
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#define __OPENSPACE_MODULE_SKYBROWSER___BROWSER___H__
|
||||
|
||||
#include <modules/webbrowser/include/webrenderhandler.h>
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/properties/stringproperty.h>
|
||||
#include <openspace/properties/triggerproperty.h>
|
||||
@@ -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<ghoul::opengl::Texture> _texture;
|
||||
|
||||
void updateBrowserDimensions();
|
||||
void executeJavascript(const std::string& script) const;
|
||||
|
||||
bool _isUrlDirty = false;
|
||||
bool _isDimensionsDirty = false;
|
||||
bool _shouldReload = false;
|
||||
|
||||
@@ -34,8 +34,10 @@
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
|
||||
namespace openspace {
|
||||
using SelectedImageDeque = std::deque<std::pair<std::string, double>>;
|
||||
|
||||
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<std::string> selectedImages() const;
|
||||
std::vector<double> 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<std::unique_ptr<properties::Vec3Property>> _displayCopies;
|
||||
std::vector<std::unique_ptr<properties::BoolProperty>> _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
|
||||
|
||||
@@ -25,8 +25,10 @@
|
||||
#ifndef __OPENSPACE_MODULE_SKYBROWSER___TARGETBROWSERPAIR___H__
|
||||
#define __OPENSPACE_MODULE_SKYBROWSER___TARGETBROWSERPAIR___H__
|
||||
|
||||
#include <openspace/properties/propertyowner.h>
|
||||
#include <modules/skybrowser/include/utility.h>
|
||||
#include <openspace/json.h>
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -31,17 +31,12 @@
|
||||
#include <deque>
|
||||
|
||||
namespace openspace {
|
||||
using SelectedImageDeque = std::deque<std::pair<std::string, double>>;
|
||||
|
||||
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<std::string> selectedImages() const;
|
||||
std::vector<double> 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
|
||||
|
||||
|
||||
@@ -295,6 +295,7 @@ void SkyBrowserModule::addTargetBrowserPair(const std::string& targetId,
|
||||
_targetsBrowsers.push_back(std::make_unique<TargetBrowserPair>(target, browser));
|
||||
}
|
||||
_uniqueIdentifierCounter++;
|
||||
addPropertySubOwner(_targetsBrowsers.back().get());
|
||||
}
|
||||
|
||||
void SkyBrowserModule::removeTargetBrowserPair(const std::string& id) {
|
||||
|
||||
@@ -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<BrowserInstance>(
|
||||
_renderHandler.get(),
|
||||
@@ -204,6 +209,10 @@ float Browser::browserRatio() const {
|
||||
static_cast<float>(_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();
|
||||
|
||||
@@ -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<bool> updateDuringTargetAnimation;
|
||||
|
||||
// [[codegen::verbatim(VerticalFovInfo.description)]]
|
||||
std::optional<double> 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<float>()) {
|
||||
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<std::string> ScreenSpaceSkyBrowser::selectedImages() const {
|
||||
std::vector<std::string> selectedImagesVector;
|
||||
selectedImagesVector.resize(_selectedImages.size());
|
||||
std::transform(
|
||||
_selectedImages.cbegin(),
|
||||
_selectedImages.cend(),
|
||||
selectedImagesVector.begin(),
|
||||
[](const std::pair<std::string, double>& 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<double> ScreenSpaceSkyBrowser::opacities() const {
|
||||
std::vector<double> opacities;
|
||||
opacities.resize(_selectedImages.size());
|
||||
std::transform(
|
||||
_selectedImages.cbegin(),
|
||||
_selectedImages.cend(),
|
||||
opacities.begin(),
|
||||
[](const std::pair<std::string, double>& 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<std::string, double>& 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<int>(
|
||||
std::distance(_selectedImages.begin(), current)
|
||||
);
|
||||
|
||||
std::deque<std::pair<std::string, double>> newDeque;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(_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<int>(_selectedImages.size()) - order - 1;
|
||||
_wwtCommunicator.setImageOrder(imageUrl, reverseOrder);
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -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<float> 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<RenderableSkyTarget*>(_targetNode->renderable());
|
||||
addProperty(_lineWidth);
|
||||
_lineWidth.onChange([this]() {
|
||||
_targetRenderable->property("LineWidth")->set(_lineWidth.value());
|
||||
});
|
||||
LINFO(uri());
|
||||
}
|
||||
|
||||
void TargetBrowserPair::setImageOrder(const std::string& imageUrl, int order) {
|
||||
|
||||
@@ -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<double> 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<Parameters>(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<std::string> WwtCommunicator::selectedImages() const {
|
||||
std::vector<std::string> selectedImagesVector;
|
||||
selectedImagesVector.resize(_selectedImages.size());
|
||||
std::transform(
|
||||
_selectedImages.cbegin(),
|
||||
_selectedImages.cend(),
|
||||
selectedImagesVector.begin(),
|
||||
[](const std::pair<std::string, double>& image) { return image.first; }
|
||||
);
|
||||
return selectedImagesVector;
|
||||
}
|
||||
|
||||
std::vector<double> WwtCommunicator::opacities() const {
|
||||
std::vector<double> opacities;
|
||||
opacities.resize(_selectedImages.size());
|
||||
std::transform(
|
||||
_selectedImages.cbegin(),
|
||||
_selectedImages.cend(),
|
||||
opacities.begin(),
|
||||
[](const std::pair<std::string, double>& 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<std::string, double>& 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<int>(
|
||||
std::distance(_selectedImages.begin(), current)
|
||||
);
|
||||
|
||||
std::deque<std::pair<std::string, double>> newDeque;
|
||||
|
||||
for (int i = 0; i < static_cast<int>(_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<int>(_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
|
||||
|
||||
Reference in New Issue
Block a user