First draft of refactor of skybrowser

This commit is contained in:
Ylva Selling
2024-07-11 12:48:03 +02:00
parent 4e323f42f0
commit e1127709c4
9 changed files with 376 additions and 269 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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;

View File

@@ -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

View File

@@ -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) {

View File

@@ -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();

View File

@@ -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

View File

@@ -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) {

View File

@@ -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