Merge pull request #2050 from OpenSpace/feature/skybrowser

Feature/skybrowser
This commit is contained in:
Alexander Bock
2022-05-05 14:00:58 -07:00
committed by GitHub
30 changed files with 969 additions and 547 deletions
@@ -1,5 +1,6 @@
asset.onInitialize(function ()
openspace.setPropertyValueSingle("Modules.SkyBrowser.Enabled", true)
openspace.setPropertyValueSingle("Modules.SkyBrowser.ShowTitleInGuiBrowser", false)
-- More settings are available, but for now using the default values
end)
@@ -74,6 +74,7 @@ public:
bool isFacingCamera() const;
void setEnabled(bool isEnabled);
float depth();
float scale() const;
// Screen space functionality in these coords: [-1,1][-ratio,ratio]
glm::vec2 screenSpacePosition();
+2
View File
@@ -43,6 +43,7 @@ set(HEADER_FILES
include/topics/shortcuttopic.h
include/topics/subscriptiontopic.h
include/topics/timetopic.h
include/topics/skybrowsertopic.h
include/topics/topic.h
include/topics/triggerpropertytopic.h
include/topics/versiontopic.h
@@ -67,6 +68,7 @@ set(SOURCE_FILES
src/topics/shortcuttopic.cpp
src/topics/subscriptiontopic.cpp
src/topics/timetopic.cpp
src/topics/skybrowsertopic.cpp
src/topics/topic.cpp
src/topics/triggerpropertytopic.cpp
src/topics/versiontopic.cpp
+4
View File
@@ -1 +1,5 @@
set(DEFAULT_MODULE ON)
set(OPENSPACE_DEPENDENCIES
skybrowser
)
@@ -0,0 +1,56 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef __OPENSPACE_MODULE_SERVER___SKY_BROWSER_TOPIC___H__
#define __OPENSPACE_MODULE_SERVER___SKY_BROWSER_TOPIC___H__
#include <modules/server/include/topics/topic.h>
#include <chrono>
namespace openspace {
class SkyBrowserTopic : public Topic {
public:
SkyBrowserTopic();
virtual ~SkyBrowserTopic();
void handleJson(const nlohmann::json& json) override;
bool isDone() const override;
private:
const int UnsetOnChangeHandle = -1;
void sendBrowserData();
int _targetDataCallbackHandle = UnsetOnChangeHandle;
bool _isDone = false;
std::chrono::system_clock::time_point _lastUpdateTime;
std::string _lastUpdateJsonString;
std::chrono::milliseconds _skyBrowserUpdateTime = std::chrono::milliseconds(100);
};
} // namespace openspace
#endif // __OPENSPACE_MODULE_SERVER___SKY_BROWSER_TOPIC___H__
+9
View File
@@ -72,6 +72,10 @@ ServerInterface* ServerModule::serverInterfaceByIdentifier(const std::string& id
return si->get();
}
int ServerModule::skyBrowserUpdateTime() const {
return _skyBrowserUpdateTime;
}
void ServerModule::internalInitialize(const ghoul::Dictionary& configuration) {
global::callback::preSync->emplace_back([this]() {
ZoneScopedN("ServerModule")
@@ -110,6 +114,11 @@ void ServerModule::internalInitialize(const ghoul::Dictionary& configuration) {
_interfaces.push_back(std::move(serverInterface));
}
}
if (configuration.hasValue<double>("SkyBrowserUpdateTime")) {
_skyBrowserUpdateTime = static_cast<int>(
configuration.value<double>("SkyBrowserUpdateTime")
);
}
}
void ServerModule::preSync() {
+3
View File
@@ -55,6 +55,8 @@ public:
ServerInterface* serverInterfaceByIdentifier(const std::string& identifier);
int skyBrowserUpdateTime() const;
protected:
void internalInitialize(const ghoul::Dictionary& configuration) override;
@@ -76,6 +78,7 @@ private:
std::vector<ConnectionData> _connections;
std::vector<std::unique_ptr<ServerInterface>> _interfaces;
properties::PropertyOwner _interfaceOwner;
int _skyBrowserUpdateTime = 100;
};
} // namespace openspace
+3
View File
@@ -34,6 +34,7 @@
#include <modules/server/include/topics/sessionrecordingtopic.h>
#include <modules/server/include/topics/setpropertytopic.h>
#include <modules/server/include/topics/shortcuttopic.h>
#include <modules/server/include/topics/skybrowsertopic.h>
#include <modules/server/include/topics/subscriptiontopic.h>
#include <modules/server/include/topics/timetopic.h>
#include <modules/server/include/topics/topic.h>
@@ -69,6 +70,7 @@ namespace {
constexpr const char* TriggerPropertyTopicKey = "trigger";
constexpr const char* BounceTopicKey = "bounce";
constexpr const char* FlightControllerTopicKey = "flightcontroller";
constexpr const char* SkyBrowserKey = "skybrowser";
} // namespace
namespace openspace {
@@ -109,6 +111,7 @@ Connection::Connection(std::unique_ptr<ghoul::io::Socket> s,
_topicFactory.registerClass<BounceTopic>(BounceTopicKey);
_topicFactory.registerClass<FlightControllerTopic>(FlightControllerTopicKey);
_topicFactory.registerClass<VersionTopic>(VersionTopicKey);
_topicFactory.registerClass<SkyBrowserTopic>(SkyBrowserKey);
}
void Connection::handleMessage(const std::string& message) {
@@ -0,0 +1,131 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2022 *
* *
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
* software and associated documentation files (the "Software"), to deal in the Software *
* without restriction, including without limitation the rights to use, copy, modify, *
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to the following *
* conditions: *
* *
* The above copyright notice and this permission notice shall be included in all copies *
* or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include "modules/server/include/topics/skybrowsertopic.h"
#include <modules/server/include/connection.h>
#include <modules/server/servermodule.h>
#include <modules/skybrowser/skybrowsermodule.h>
#include <modules/skybrowser/include/targetbrowserpair.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/engine/globals.h>
#include <openspace/properties/property.h>
#include <openspace/query/query.h>
#include <ghoul/logging/logmanager.h>
namespace {
constexpr const char* EventKey = "event";
constexpr const char* SubscribeEvent = "start_subscription";
constexpr const char* UnsubscribeEvent = "stop_subscription";
} // namespace
using nlohmann::json;
namespace openspace {
SkyBrowserTopic::SkyBrowserTopic()
: _lastUpdateTime(std::chrono::system_clock::now())
{
ServerModule* module = global::moduleEngine->module<ServerModule>();
if (module) {
_skyBrowserUpdateTime = std::chrono::milliseconds(module->skyBrowserUpdateTime());
}
}
SkyBrowserTopic::~SkyBrowserTopic() {
if (_targetDataCallbackHandle != UnsetOnChangeHandle) {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module) {
module->removePreSyncCallback(_targetDataCallbackHandle);
}
}
}
bool SkyBrowserTopic::isDone() const {
return _isDone;
}
void SkyBrowserTopic::handleJson(const nlohmann::json& json) {
std::string event = json.at(EventKey).get<std::string>();
if (event == UnsubscribeEvent) {
_isDone = true;
return;
}
if (event != SubscribeEvent) {
_isDone = true;
return;
}
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
_targetDataCallbackHandle = module->addPreSyncCallback(
[this]() {
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
if (now - _lastUpdateTime > _skyBrowserUpdateTime) {
sendBrowserData();
_lastUpdateTime = std::chrono::system_clock::now();
}
}
);
}
void SkyBrowserTopic::sendBrowserData() {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
ghoul::Dictionary data;
// Set general data
data.setValue("selectedBrowserId", module->selectedBrowserId());
data.setValue("cameraInSolarSystem", module->isCameraInSolarSystem());
// Pass data for all the browsers and the corresponding targets
if (module->isCameraInSolarSystem()) {
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
ghoul::Dictionary targets;
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
std::string id = pair->browserId();
ghoul::Dictionary target = pair->dataAsDictionary();
targets.setValue(id, target);
}
data.setValue("browsers", targets);
}
std::string jsonString = ghoul::formatJson(data);
// Only send message if data actually changed
if (jsonString != _lastUpdateJsonString) {
json jsonData = json::parse(jsonString.begin(), jsonString.end());
_connection->sendJson(wrappedPayload(jsonData));
}
// @TODO (2022-04-28, emmbr) The message is still sent very often; every time the
// camera moves or the time is changes, because this changes the "roll" parameter
// of the browser. This is the update that occurs most often. Maybe it could be
// separated into it's own topic?
_lastUpdateJsonString = jsonString;
}
} // namespace openspace
+7 -1
View File
@@ -51,9 +51,15 @@ set(SOURCE_FILES
)
source_group("Source Files" FILES ${SOURCE_FILES})
set(SHADER_FILES
shaders/target_fs.glsl
shaders/target_vs.glsl
)
source_group("Shader Files" FILES ${SHADER_FILES})
create_new_module(
"SkyBrowser"
skybrowser_module
STATIC
${HEADER_FILES} ${SOURCE_FILES}
${HEADER_FILES} ${SOURCE_FILES} ${SHADER_FILES}
)
+4 -4
View File
@@ -86,6 +86,10 @@ protected:
void executeJavascript(const std::string& script) const;
bool _isUrlDirty = false;
bool _isDimensionsDirty = false;
bool _shouldReload = false;
private:
class RenderHandler : public WebRenderHandler {
public:
@@ -98,10 +102,6 @@ private:
std::unique_ptr<BrowserInstance> _browserInstance;
CefRefPtr<RenderHandler> _renderHandler;
CefRefPtr<WebKeyboardHandler> _keyboardHandler;
bool _isUrlDirty = false;
bool _isDimensionsDirty = false;
bool _shouldReload = false;
};
} // namespace openspace
@@ -46,31 +46,27 @@ public:
void bindTexture() override;
glm::ivec3 borderColor() const;
float opacity() const;
double animationSpeed() const;
double stopAnimationThreshold() const;
void setDimensions(glm::vec2 dimensions);
void setRatio(float ratio);
void setColor(glm::ivec3 color);
void setOpacity(float opacity);
void setVerticalFov(double fov);
// Display
void highlight(const glm::ivec3& addition);
void removeHighlight(const glm::ivec3& removal);
static documentation::Documentation Documentation();
private:
// Properties
properties::FloatProperty _crossHairSize;
properties::FloatProperty _showRectangleThreshold;
properties::FloatProperty _lineWidth;
properties::DoubleProperty _stopAnimationThreshold;
properties::DoubleProperty _animationSpeed;
double _verticalFov = 10.0;
glm::ivec3 _borderColor = glm::ivec3(230);
glm::vec2 _dimensions = glm::vec2(1.f);
float _ratio = 1.f;
};
} // namespace openspace
@@ -47,37 +47,40 @@ public:
void update() override;
float opacity() const;
glm::vec2 size() const;
glm::dvec2 fineTuneVector(const glm::dvec2& drag);
bool isInitialized() const;
void setVerticalFovWithScroll(float scroll);
void setOpacity(float opacity);
void setScreenSpaceSize(glm::vec2 newSize);
void updateScreenSpaceSize();
glm::dvec2 fineTuneVector(const glm::dvec2& drag);
void setRatio(float ratio);
void setIdInBrowser() const;
void setIsInitialized(bool isInitialized);
void updateTextureResolution();
// Copies rendered
void addRenderCopy(const glm::vec3& raePosition, int nCopies);
void removeRenderCopy();
std::vector<std::pair<std::string, glm::dvec3>> renderCopies() const;
void moveRenderCopy(int i, glm::vec3 raePosition);
void addDisplayCopy(const glm::vec3& raePosition, int nCopies);
void removeDisplayCopy();
std::vector<std::pair<std::string, glm::dvec3>> displayCopies() const;
std::vector<std::pair<std::string, bool>> showDisplayCopies() const;
static documentation::Documentation Documentation();
private:
properties::FloatProperty _textureQuality;
properties::BoolProperty _renderOnlyOnMaster;
std::vector<std::unique_ptr<properties::Vec3Property>> _renderCopies;
properties::BoolProperty _isHidden;
std::vector<std::unique_ptr<properties::Vec3Property>> _displayCopies;
std::vector<std::unique_ptr<properties::BoolProperty>> _showDisplayCopies;
void bindTexture() override;
// Flags
bool _isSyncedWithWwt = false;
bool _textureDimensionsIsDirty = false;
bool _sizeIsDirty = false;
bool _ratioIsDirty = false;
bool _isInitialized = false;
glm::vec2 _size = glm::vec2(1.f, 1.f);
float _ratio = 1.f;
};
} // namespace openspace
+17 -19
View File
@@ -29,6 +29,8 @@
#include <openspace/documentation/documentation.h>
#include <deque>
namespace ghoul { class Dictionary; }
namespace openspace {
struct ImageData;
@@ -44,14 +46,13 @@ public:
// Target & Browser
void initialize();
// Highlighting
void removeHighlight(const glm::ivec3& color);
void highlight(const glm::ivec3& color);
// Animation
void startAnimation(glm::dvec3 coordsEnd, double fovEnd);
void incrementallyAnimateToCoordinate();
void startFading(float goal, float fadeTime);
void incrementallyFade();
void stopAnimations();
// Mouse interaction
void startFinetuningTarget();
void fineTuneTarget(const glm::vec2& startMouse, const glm::vec2& translation);
@@ -60,25 +61,25 @@ public:
// Browser
void sendIdToBrowser() const;
void updateBrowserSize();
std::vector<std::pair<std::string, glm::dvec3>> renderCopies() const;
std::vector<std::pair<std::string, glm::dvec3>> displayCopies() const;
bool isImageCollectionLoaded();
// Target
void centerTargetOnScreen();
double targetRoll();
double targetRoll() const;
bool hasFinishedFading() const;
bool isFacingCamera() const;
bool isUsingRadiusAzimuthElevation() const;
bool isEnabled() const;
void setEnabled(bool enable);
void setOpacity(float opacity);
void setIsSyncedWithWwt(bool isSynced);
void setVerticalFov(double vfov);
void setEquatorialAim(const glm::dvec2& aim);
void setBorderColor(const glm::ivec3& color);
void setScreenSpaceSize(const glm::vec2& dimensions);
void setBrowserRatio(float ratio);
void setVerticalFovWithScroll(float scroll);
void setImageCollectionIsLoaded(bool isLoaded);
double verticalFov() const;
glm::ivec3 borderColor() const;
@@ -88,19 +89,22 @@ public:
std::string browserId() const;
std::string targetRenderableId() const;
std::string targetNodeId() const;
glm::vec2 size() const;
float browserRatio() const;
SceneGraphNode* targetNode() const;
ScreenSpaceSkyBrowser* browser() const;
const std::deque<int>& selectedImages() const;
std::vector<int> selectedImages() const;
ghoul::Dictionary dataAsDictionary() const;
// WorldWide Telescope image handling
void setImageOrder(int i, int order);
void selectImage(const ImageData& image, int i);
void addImageLayerToWwt(const std::string& url, int i);
void removeSelectedImage(int i);
void loadImageCollection(const std::string& collection);
void setImageOpacity(int i, float opacity);
void hideChromeInterface(bool shouldHide);
void hideChromeInterface();
friend bool operator==(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs);
friend bool operator!=(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs);
@@ -114,19 +118,13 @@ private:
SceneGraphNode* _targetNode = nullptr;
// Animation
skybrowser::Animation<float> _fadeBrowser = skybrowser::Animation(0.f, 0.f, 0.f);
skybrowser::Animation<float> _fadeTarget = skybrowser::Animation(0.f, 0.f, 0.f);
skybrowser::Animation<double> _fovAnimation = skybrowser::Animation(0.0, 0.0, 0.0);
skybrowser::Animation<glm::dvec3> _moveTarget =
skybrowser::Animation<glm::dvec3> _targetAnimation =
skybrowser::Animation(glm::dvec3(0.0), glm::dvec3(0.0), 0.0);
bool _targetIsAnimating = false;
// Dragging
glm::dvec3 _startTargetPosition = glm::dvec3(0.0);
glm::dvec2 _equatorialAim = glm::dvec2(0.0);
glm::ivec3 _borderColor = glm::ivec3(255);
glm::vec2 _dimensions = glm::vec2(0.5f);
};
} // namespace openspace
+5 -14
View File
@@ -207,21 +207,21 @@ public:
{
_animationTime = std::chrono::milliseconds(static_cast<int>(time * 1000));
}
void start() {
_isStarted = true;
_startTime = std::chrono::system_clock::now();
}
void stop() {
_isStarted = false;
}
bool isAnimating() const {
bool timeLeft = timeSpent().count() < _animationTime.count() ? true : false;
return timeLeft && _isStarted;
}
T getNewValue();
glm::dmat4 getRotationMatrix();
@@ -231,20 +231,11 @@ private:
std::chrono::duration<double, std::milli> timeSpent = now - _startTime;
return timeSpent;
}
double percentageSpent() const {
return timeSpent().count() / _animationTime.count();
}
double easeOutExpo(double x) {
double epsilon = std::numeric_limits<double>::epsilon();
return std::abs(x - 1.0) < epsilon ? 1.0 : 1.0 - pow(2.0, -10.0 * x);
}
double easeInOutSine(double x) {
return -(cos(glm::pi<double>() * x) - 1.0) / 2.0;
}
// Animation
bool _isStarted = false;
double _lastPercentage = 0;
+12 -13
View File
@@ -44,42 +44,42 @@ public:
void update();
// WorldWide Telescope communication
void displayImage(const std::string& url, int i);
void selectImage(const std::string& url, int i);
void addImageLayerToWwt(const std::string& url, int i);
void removeSelectedImage(int i);
void setImageOrder(int i, int order);
void loadImageCollection(const std::string& collection);
void setImageOpacity(int i, float opacity) const;
void hideChromeInterface(bool shouldHide) const;
void setImageOpacity(int i, float opacity);
void hideChromeInterface() const;
bool isImageCollectionLoaded() const;
bool hasLoadedImages() const;
double verticalFov() const;
glm::ivec3 borderColor() const;
glm::dvec2 equatorialAim() const;
glm::dvec2 fieldsOfView() const;
const std::deque<int>& getSelectedImages() const;
std::vector<int> selectedImages() const;
std::vector<double> opacities() const;
void setHasLoadedImages(bool isLoaded);
void setImageCollectionIsLoaded(bool isLoaded);
void setVerticalFov(double vfov);
void setIsSyncedWithWwt(bool isSynced);
void setEquatorialAim(glm::dvec2 equatorial);
void setBorderColor(glm::ivec3 color);
void setTargetRoll(double roll);
void highlight(const glm::ivec3& addition) const;
// The removal parameter decides what will be removed from the border color
void removeHighlight(const glm::ivec3& removal) const;
void updateBorderColor() const;
void updateAim() const;
protected:
void setIdInBrowser(const std::string& id) const;
std::deque<std::pair<int, double>>::iterator findSelectedImage(int i);
double _verticalFov = 10.0f;
glm::ivec3 _borderColor = glm::ivec3(70);
glm::dvec2 _equatorialAim = glm::dvec2(0.0);
double _targetRoll = 0.0;
bool _hasLoadedImages = false;
std::deque<int> _selectedImages;
bool _isImageCollectionLoaded = false;
std::deque<std::pair<int, double>> _selectedImages;
private:
void setWebpageBorderColor(glm::ivec3 color) const;
@@ -96,7 +96,6 @@ private:
ghoul::Dictionary setImageOpacityMessage(const std::string& id, double opacity) const;
ghoul::Dictionary setLayerOrderMessage(const std::string& id, int version);
bool _isSyncedWithWwt = false;
bool _borderColorIsDirty = false;
bool _equatorialAimIsDirty = false;
int messageCounter = 0;
+7 -8
View File
@@ -32,12 +32,12 @@ in vec4 vs_position;
uniform float crossHairSize;
uniform bool showRectangle;
uniform float lineWidth;
uniform vec2 dimensions;
uniform float ratio;
uniform vec4 lineColor;
uniform float fov;
uniform bool additiveBlending;
uniform float opacity = 1.0;
uniform float opacity;
uniform vec3 multiplyColor;
// A factor which states how much thicker vertical lines are rendered than horizontal
@@ -67,23 +67,22 @@ float createCrosshair(in float linewidth, in float ratio, in vec2 coord) {
#include "fragment.glsl"
Fragment getFragment() {
float ratio = dimensions.y / dimensions.x;
float rectangle = 0.0;
float maxWwtFov = 70;
float crosshair = createCrosshair(lineWidth, ratio, vs_st);
float crossHairHeight = crossHairSize/maxWwtFov;
float crossHairWidth = crossHairHeight * ratio;
float crossHairBox = createFilledRectangle(crossHairHeight, crossHairWidth, vs_st);
float crossHairBox = createFilledRectangle(crossHairWidth, crossHairHeight, vs_st);
crosshair *= crossHairBox;
if (showRectangle) {
float height = (fov * 0.5)/maxWwtFov;
float width = height * ratio;
float outerEdge = createFilledRectangle(height, width, vs_st);
float lineWidthX = lineWidth * 2 * VerticalThickness;
float lineWidthY = lineWidth * 2;
float innerEdge = createFilledRectangle(height-lineWidthX, width-lineWidthY, vs_st);
float height = ((fov * 0.5)/maxWwtFov)-lineWidthX;
float width = (height * ratio) - lineWidthY;
float outerEdge = createFilledRectangle(width, height, vs_st);
float innerEdge = createFilledRectangle(width-lineWidthY, height-lineWidthX, vs_st);
rectangle = outerEdge - innerEdge;
}
+200 -78
View File
@@ -45,6 +45,15 @@ namespace {
"Decides if the GUI for this module should be enabled."
};
constexpr const openspace::properties::Property::PropertyInfo
ShowTitleInGuiBrowserInfo =
{
"ShowTitleInGuiBrowser",
"Show Title in Gui Browser",
"If true, the name of the currently selected sky browser is shown in the WebGUI "
"browser."
};
constexpr const openspace::properties::Property::PropertyInfo AllowRotationInfo = {
"AllowCameraRotation",
"Allow Camera Rotation",
@@ -67,10 +76,37 @@ namespace {
constexpr const openspace::properties::Property::PropertyInfo BrowserSpeedInfo = {
"BrowserAnimationSpeed",
"Field Of View Animation Speed",
"Field of View Animation Speed",
"This determines the speed of the animation of the field of view in the browser."
};
constexpr const openspace::properties::Property::PropertyInfo HideWithGuiInfo = {
"HideTargetsBrowsersWithGui",
"Hide Targets and Browsers with GUI",
"If checked, the targets and browsers will be disabled when the sky browser "
"panel is minimized."
};
constexpr const openspace::properties::Property::PropertyInfo InverseZoomInfo = {
"InverseZoomDirection",
"Inverse Zoom Direction",
"If checked, the zoom direction of the scroll over the AAS WWT browser will be "
"inversed."
};
constexpr const openspace::properties::Property::PropertyInfo SpaceCraftTimeInfo = {
"SpaceCraftAnimationTime",
"Space Craft Animation Time",
"Sets the duration (in seconds) of the animation of the space craft when it is "
"pointed to where the target is aiming."
};
constexpr const openspace::properties::Property::PropertyInfo ImageCollectionInfo = {
"WwtImageCollectionUrl",
"AAS WorldWide Telescope Image Collection Url",
"The url of the image collection which is loaded into AAS WorldWide Telescope."
};
struct [[codegen::Dictionary(SkyBrowserModule)]] Parameters {
// [[codegen::verbatim(EnabledInfo.description)]]
std::optional<bool> enabled;
@@ -86,6 +122,18 @@ namespace {
// [[codegen::verbatim(BrowserSpeedInfo.description)]]
std::optional<double> browserSpeed;
// [[codegen::verbatim(HideWithGuiInfo.description)]]
std::optional<bool> hideTargetsBrowsersGui;
// [[codegen::verbatim(InverseZoomInfo.description)]]
std::optional<bool> inverseZoomDirection;
// [[codegen::verbatim(SpaceCraftTimeInfo.description)]]
std::optional<double> spaceCraftAnimationTime;
// [[codegen::verbatim(SpaceCraftTimeInfo.description)]]
std::optional<std::string> wwtImageCollectionUrl;
};
#include "skybrowsermodule_codegen.cpp"
@@ -96,16 +144,28 @@ namespace openspace {
SkyBrowserModule::SkyBrowserModule()
: OpenSpaceModule(SkyBrowserModule::Name)
, _enabled(EnabledInfo)
, _showTitleInGuiBrowser(ShowTitleInGuiBrowserInfo, true)
, _allowCameraRotation(AllowRotationInfo, true)
, _cameraRotationSpeed(CameraRotSpeedInfo, 0.5, 0.0, 1.0)
, _targetAnimationSpeed(TargetSpeedInfo, 0.2, 0.0, 1.0)
, _browserAnimationSpeed(BrowserSpeedInfo, 5.0, 0.0, 10.0)
, _hideTargetsBrowsersWithGui(HideWithGuiInfo, false)
, _inverseZoomDirection(InverseZoomInfo, false)
, _spaceCraftAnimationTime(SpaceCraftTimeInfo, 2.0, 0.0, 10.0)
, _wwtImageCollectionUrl(ImageCollectionInfo,
"https://data.openspaceproject.com/wwt/1/imagecollection.wtml")
{
addProperty(_enabled);
addProperty(_showTitleInGuiBrowser);
addProperty(_allowCameraRotation);
addProperty(_cameraRotationSpeed);
addProperty(_targetAnimationSpeed);
addProperty(_browserAnimationSpeed);
addProperty(_hideTargetsBrowsersWithGui);
addProperty(_inverseZoomDirection);
addProperty(_spaceCraftAnimationTime);
addProperty(_wwtImageCollectionUrl);
_wwtImageCollectionUrl.setReadOnly(true);
// Set callback functions
global::callback::mouseButton->emplace(global::callback::mouseButton->begin(),
@@ -126,45 +186,41 @@ SkyBrowserModule::SkyBrowserModule()
_isCameraInSolarSystem = glm::length(cameraPos) < SolarSystemRadius;
bool vizModeChanged = _isCameraInSolarSystem != camWasInSolarSystem;
// Visualization mode changed. Start fading
if (vizModeChanged && !_isCameraInSolarSystem) {
// Camera moved into the solar system
_isFading = true;
_goal = Transparency::Transparent;
// Visualization mode changed. Start fading in/out
if (vizModeChanged) {
constexpr float FadeDuration = 2.f;
float transparency = [](Transparency goal) {
switch (goal) {
case Transparency::Transparent: return 0.f;
case Transparency::Opaque: return 1.f;
default: throw ghoul::MissingCaseException();
if (camWasInSolarSystem) { // Camera moved out of the solar system => fade out
for (const std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
pair->startFading(0.f, FadeDuration);
}
}(_goal);
std::for_each(
_targetsBrowsers.begin(),
_targetsBrowsers.end(),
[&](const std::unique_ptr<TargetBrowserPair>& pair) {
pair->startFading(transparency, 2.f);
// Also hide the hover circle
disableHoverCircle();
}
else { // Camera moved into the solar system => fade in
for (const std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
pair->startFading(1.f, FadeDuration);
}
);
}
// Fade pairs if the camera moved in or out the solar system
if (_isFading) {
incrementallyFadeBrowserTargets(_goal);
}
}
if (_isCameraInSolarSystem) {
std::for_each(
_targetsBrowsers.begin(),
_targetsBrowsers.end(),
[&](const std::unique_ptr<TargetBrowserPair>& pair) {
pair->synchronizeAim();
}
);
for (const std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
pair->synchronizeAim();
}
incrementallyAnimateTargets();
}
if (_cameraRotation.isAnimating() && _allowCameraRotation) {
incrementallyRotateCamera();
}
// Trigger callbacks (should maybe have a check to see if update is needed)
using K = CallbackHandle;
using V = CallbackFunction;
for (const std::pair<const K, V>& it : _preSyncCallbacks) {
it.second(); // call function
}
});
}
@@ -172,6 +228,18 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
const Parameters p = codegen::bake<Parameters>(dict);
_enabled = p.enabled.value_or(true);
_allowCameraRotation = p.allowCameraRotation.value_or(_allowCameraRotation);
_cameraRotationSpeed = p.cameraRotSpeed.value_or(_cameraRotationSpeed);
_targetAnimationSpeed = p.targetSpeed.value_or(_targetAnimationSpeed);
_browserAnimationSpeed = p.browserSpeed.value_or(_browserAnimationSpeed);
_inverseZoomDirection = p.inverseZoomDirection.value_or(_inverseZoomDirection);
_wwtImageCollectionUrl = p.wwtImageCollectionUrl.value_or(_wwtImageCollectionUrl);
_hideTargetsBrowsersWithGui = p.hideTargetsBrowsersGui.value_or(
_hideTargetsBrowsersWithGui
);
_spaceCraftAnimationTime = p.spaceCraftAnimationTime.value_or(
_spaceCraftAnimationTime
);
ghoul::TemplateFactory<ScreenSpaceRenderable>* fScreenSpaceRenderable =
FactoryManager::ref().factory<ScreenSpaceRenderable>();
@@ -208,10 +276,11 @@ void SkyBrowserModule::addTargetBrowserPair(const std::string& targetId,
if (browser && target) {
_targetsBrowsers.push_back(std::make_unique<TargetBrowserPair>(target, browser));
}
_uniqueIdentifierCounter++;
}
void SkyBrowserModule::removeTargetBrowserPair(const std::string& id) {
TargetBrowserPair* found = getPair(id);
TargetBrowserPair* found = pair(id);
if (!found) {
return;
}
@@ -222,18 +291,17 @@ void SkyBrowserModule::removeTargetBrowserPair(const std::string& id) {
[&](const std::unique_ptr<TargetBrowserPair>& pair) {
// should this be?
// found == pair.get()
return *found == *(pair.get());
return found == pair.get();
}
);
_targetsBrowsers.erase(it, _targetsBrowsers.end());
_mouseOnPair = nullptr;
}
void SkyBrowserModule::lookAtTarget(const std::string& id) {
TargetBrowserPair* pair = getPair(id);
if (pair) {
startRotatingCamera(pair->targetDirectionGalactic());
TargetBrowserPair* found = pair(id);
if (found) {
startRotatingCamera(found->targetDirectionGalactic());
}
}
@@ -241,23 +309,39 @@ void SkyBrowserModule::setHoverCircle(SceneGraphNode* circle) {
_hoverCircle = circle;
}
void SkyBrowserModule::moveHoverCircle(int i) {
void SkyBrowserModule::moveHoverCircle(int i, bool useScript) {
const ImageData& image = _dataHandler->getImage(i);
// Only move and show circle if the image has coordinates
if (_hoverCircle && image.hasCelestialCoords && _isCameraInSolarSystem) {
// Make circle visible
_hoverCircle->renderable()->property("Enabled")->set(true);
const std::string id = _hoverCircle->identifier();
// Show the circle
if (useScript) {
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Renderable.Fade', 1.0);",
id
);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
else {
Renderable* renderable = _hoverCircle->renderable();
if (renderable) {
renderable->property("Fade")->set(1.f);
}
}
// Set the exact target position
// Move it slightly outside of the celestial sphere so it doesn't overlap with
// the target
glm::dvec3 pos = skybrowser::equatorialToGalactic(image.equatorialCartesian);
pos *= skybrowser::CelestialSphereRadius * 1.1;
// Uris for properties
std::string id = _hoverCircle->identifier();
std::string script = fmt::format(
// Note that the position can only be set through the script engine
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Translation.Position', {});",
id, ghoul::to_string(pos)
);
@@ -268,9 +352,21 @@ void SkyBrowserModule::moveHoverCircle(int i) {
}
}
void SkyBrowserModule::disableHoverCircle() {
void SkyBrowserModule::disableHoverCircle(bool useScript) {
if (_hoverCircle && _hoverCircle->renderable()) {
_hoverCircle->renderable()->property("Enabled")->set(false);
if (useScript) {
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{}.Renderable.Fade', 0.0);",
_hoverCircle->identifier()
);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
else {
_hoverCircle->renderable()->property("Fade")->set(0.f);
}
}
}
@@ -296,7 +392,7 @@ int SkyBrowserModule::nPairs() const {
return static_cast<int>(_targetsBrowsers.size());
}
TargetBrowserPair* SkyBrowserModule::getPair(const std::string& id) const {
TargetBrowserPair* SkyBrowserModule::pair(const std::string& id) const {
auto it = std::find_if(
_targetsBrowsers.begin(),
_targetsBrowsers.end(),
@@ -307,7 +403,11 @@ TargetBrowserPair* SkyBrowserModule::getPair(const std::string& id) const {
return foundBrowser || foundTarget || foundTargetNode;
}
);
return it != _targetsBrowsers.end() ? it->get() : nullptr;
TargetBrowserPair* found = it != _targetsBrowsers.end() ? it->get() : nullptr;
if (found == nullptr) {
LINFO(fmt::format("Identifier '{}' not found", id));
}
return found;
}
void SkyBrowserModule::startRotatingCamera(glm::dvec3 endAnimation) {
@@ -326,29 +426,6 @@ void SkyBrowserModule::incrementallyRotateCamera() {
}
}
void SkyBrowserModule::incrementallyFadeBrowserTargets(Transparency goal) {
bool isAllFinished = true;
for (std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
if (pair->isEnabled()) {
bool isPairFinished = pair->hasFinishedFading();
if (!isPairFinished) {
pair->incrementallyFade();
}
else if (isPairFinished && goal == Transparency::Transparent) {
pair->setEnabled(false);
pair->setOpacity(1.0);
}
isAllFinished &= isPairFinished;
}
}
// The transition is over when the fade is finished
if (isAllFinished) {
_isFading = false;
}
}
void SkyBrowserModule::incrementallyAnimateTargets() {
for (std::unique_ptr<TargetBrowserPair>& pair : _targetsBrowsers) {
if (pair->isEnabled()) {
@@ -365,8 +442,16 @@ double SkyBrowserModule::browserAnimationSpeed() const {
return _browserAnimationSpeed;
}
double SkyBrowserModule::spaceCraftAnimationTime() const {
return _spaceCraftAnimationTime;
}
std::string SkyBrowserModule::wwtImageCollectionUrl() const {
return _wwtImageCollectionUrl;
}
void SkyBrowserModule::setSelectedBrowser(const std::string& id) {
TargetBrowserPair* found = getPair(id);
TargetBrowserPair* found = pair(id);
if (found) {
_selectedBrowser = id;
}
@@ -377,12 +462,12 @@ std::string SkyBrowserModule::selectedBrowserId() const {
}
std::string SkyBrowserModule::selectedTargetId() const {
TargetBrowserPair* found = getPair(_selectedBrowser);
TargetBrowserPair* found = pair(_selectedBrowser);
return found ? found->targetRenderableId() : "";
}
glm::ivec3 SkyBrowserModule::highlight() const {
return _highlightAddition;
int SkyBrowserModule::uniqueIdentifierCounter() const {
return _uniqueIdentifierCounter;
}
bool SkyBrowserModule::isCameraInSolarSystem() const {
@@ -390,15 +475,47 @@ bool SkyBrowserModule::isCameraInSolarSystem() const {
}
bool SkyBrowserModule::isSelectedPairUsingRae() const {
TargetBrowserPair* found = getPair(_selectedBrowser);
TargetBrowserPair* found = pair(_selectedBrowser);
return found ? found->isUsingRadiusAzimuthElevation() : false;
}
bool SkyBrowserModule::isSelectedPairFacingCamera() const {
TargetBrowserPair* found = getPair(_selectedBrowser);
TargetBrowserPair* found = pair(_selectedBrowser);
return found ? found->isFacingCamera() : false;
}
SkyBrowserModule::CallbackHandle SkyBrowserModule::addPreSyncCallback(
CallbackFunction cb)
{
CallbackHandle handle = _nextCallbackHandle++;
_preSyncCallbacks.emplace_back(handle, std::move(cb));
return handle;
}
void SkyBrowserModule::removePreSyncCallback(CallbackHandle handle) {
const auto it = std::find_if(
_preSyncCallbacks.begin(),
_preSyncCallbacks.end(),
[handle](const std::pair<CallbackHandle, CallbackFunction>& cb) {
return cb.first == handle;
}
);
ghoul_assert(
it != _preSyncCallbacks.end(),
"handle must be a valid callback handle"
);
_preSyncCallbacks.erase(it);
}
std::vector<documentation::Documentation> SkyBrowserModule::documentations() const {
return {
RenderableSkyTarget::Documentation(),
ScreenSpaceSkyBrowser::Documentation()
};
}
scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
return {
"skybrowser",
@@ -426,12 +543,17 @@ scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
codegen::lua::SetVerticalFov,
codegen::lua::SetBorderColor,
codegen::lua::TranslateScreenSpaceRenderable,
codegen::lua::AddRenderCopy,
codegen::lua::SetScreenSpaceSize,
codegen::lua::RemoveRenderCopy,
codegen::lua::AddDisplayCopy,
codegen::lua::SetBrowserRatio,
codegen::lua::RemoveDisplayCopy,
codegen::lua::StartFinetuningTarget,
codegen::lua::FinetuneTargetPosition,
codegen::lua::ScrollOverBrowser
codegen::lua::ScrollOverBrowser,
codegen::lua::LoadingImageCollectionComplete,
codegen::lua::ShowAllTargetsAndBrowsers,
codegen::lua::PointSpaceCraft,
codegen::lua::GetWwtImageCollectionUrl,
codegen::lua::StopAnimations
}
};
}
+23 -29
View File
@@ -33,6 +33,7 @@
#include <openspace/util/mouse.h>
#include <openspace/properties/scalar/boolproperty.h>
#include <openspace/properties/scalar/doubleproperty.h>
#include <openspace/properties/stringproperty.h>
#include <fstream>
namespace openspace {
@@ -43,30 +44,21 @@ class TargetBrowserPair;
class SceneGraphNode;
struct ImageData;
enum class Transparency {
Transparent,
Opaque
};
enum class MouseInteraction {
Hover,
Drag,
FineTune
};
class SkyBrowserModule : public OpenSpaceModule {
public:
constexpr static const char* Name = "SkyBrowser";
using CallbackHandle = int;
using CallbackFunction = std::function<void()>;
SkyBrowserModule();
std::vector<std::unique_ptr<TargetBrowserPair>>& getPairs();
int nPairs() const;
TargetBrowserPair* getPair(const std::string& id) const;
TargetBrowserPair* pair(const std::string& id) const;
const std::unique_ptr<WwtDataHandler>& getWwtDataHandler() const;
std::string selectedBrowserId() const;
std::string selectedTargetId() const;
glm::ivec3 highlight() const;
int uniqueIdentifierCounter() const;
void setSelectedBrowser(const std::string& id);
void setHoverCircle(SceneGraphNode* circle);
@@ -75,10 +67,11 @@ public:
void lookAtTarget(const std::string& id);
void startRotatingCamera(glm::dvec3 endAnimation); // Pass in galactic coordinate
void incrementallyRotateCamera();
void incrementallyFadeBrowserTargets(Transparency goal);
void incrementallyAnimateTargets();
double targetAnimationSpeed() const;
double browserAnimationSpeed() const;
double spaceCraftAnimationTime() const;
std::string wwtImageCollectionUrl() const;
bool isCameraInSolarSystem() const;
bool isSelectedPairFacingCamera() const;
@@ -89,45 +82,42 @@ public:
void addTargetBrowserPair(const std::string& targetId, const std::string& browserId);
// Hover circle
void moveHoverCircle(int i);
void disableHoverCircle();
void moveHoverCircle(int i, bool useScript = true);
void disableHoverCircle(bool useScript = true);
// Image collection handling
void loadImages(const std::string& root, const std::filesystem::path& directory);
int nLoadedImages() const;
CallbackHandle addPreSyncCallback(CallbackFunction cb);
void removePreSyncCallback(CallbackHandle handle);
scripting::LuaLibrary luaLibrary() const override;
//std::vector<documentation::Documentation> documentations() const override;
std::vector<documentation::Documentation> documentations() const override;
protected:
void internalInitialize(const ghoul::Dictionary& dict) override;
private:
properties::BoolProperty _enabled;
properties::BoolProperty _showTitleInGuiBrowser;
properties::BoolProperty _allowCameraRotation;
properties::BoolProperty _hideTargetsBrowsersWithGui;
properties::BoolProperty _inverseZoomDirection;
properties::DoubleProperty _cameraRotationSpeed;
properties::DoubleProperty _targetAnimationSpeed;
properties::DoubleProperty _browserAnimationSpeed;
glm::ivec3 _highlightAddition = glm::ivec3(35); // Highlight object when mouse hovers
properties::DoubleProperty _spaceCraftAnimationTime;
properties::StringProperty _wwtImageCollectionUrl;
// The browsers and targets
std::vector<std::unique_ptr<TargetBrowserPair>> _targetsBrowsers;
TargetBrowserPair* _mouseOnPair = nullptr;
SceneGraphNode* _hoverCircle = nullptr;
std::string _selectedBrowser = ""; // Currently selected browser
// Fading
Transparency _goal = Transparency::Opaque;
int _uniqueIdentifierCounter = 0;
// Flags
bool _isCameraInSolarSystem = true; // Visualization modes
bool _isFading = false;
// Mouse interaction
glm::vec2 _mousePosition; // Current mouse position in screen space coordinates
glm::vec2 _startMousePosition;
glm::vec2 _startDragPosition;
glm::dvec3 _startTargetPosition;
// Animation of rotation of camera to look at coordinate galactic coordinates
skybrowser::Animation<glm::dvec3> _cameraRotation =
@@ -135,6 +125,10 @@ private:
// Data handler for the image collections
std::unique_ptr<WwtDataHandler> _dataHandler;
// Callbacks for tiggering topic
int _nextCallbackHandle = 0;
std::vector<std::pair<CallbackHandle, CallbackFunction>> _preSyncCallbacks;
};
} // namespace openspace
+157 -101
View File
@@ -27,6 +27,7 @@
#include <modules/skybrowser/include/utility.h>
#include <modules/skybrowser/include/targetbrowserpair.h>
#include <modules/skybrowser/include/wwtdatahandler.h>
#include <openspace/events/eventengine.h>
#include <openspace/engine/globals.h>
#include <openspace/engine/moduleengine.h>
#include <openspace/engine/windowdelegate.h>
@@ -44,21 +45,21 @@ namespace {
*/
[[codegen::luawrap]] void selectImage(int imageIndex) {
using namespace openspace;
// Load image
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->isCameraInSolarSystem()) {
TargetBrowserPair* selected = module->getPair(module->selectedBrowserId());
TargetBrowserPair* selected = module->pair(module->selectedBrowserId());
if (selected) {
const ImageData& image = module->getWwtDataHandler()->getImage(imageIndex);
// Load image into browser
std::string str = image.name;
// Check if character is ASCII - if it isn't, remove
str.erase(
std::remove_if(
str.begin(), str.end(),
[](char c) {
// Check if character is ASCII - if it isn't, remove
return c < 0 || c >= 128;
}
),
@@ -84,7 +85,7 @@ namespace {
*/
[[codegen::luawrap]] void setHoverCircle(std::string identifier) {
using namespace openspace;
SceneGraphNode* circle = global::renderEngine->scene()->sceneGraphNode(identifier);
global::moduleEngine->module<SkyBrowserModule>()->setHoverCircle(circle);
}
@@ -94,8 +95,8 @@ namespace {
*/
[[codegen::luawrap]] void moveCircleToHoverImage(int imageIndex) {
using namespace openspace;
global::moduleEngine->module<SkyBrowserModule>()->moveHoverCircle(imageIndex);
global::moduleEngine->module<SkyBrowserModule>()->moveHoverCircle(imageIndex, false);
}
/**
@@ -103,17 +104,14 @@ namespace {
*/
[[codegen::luawrap]] void disableHoverCircle() {
using namespace openspace;
global::moduleEngine->module<SkyBrowserModule>()->disableHoverCircle();
global::moduleEngine->module<SkyBrowserModule>()->disableHoverCircle(false);
}
/**
* Takes an identifier to a sky browser or a sky target, an image index and the order
* which it should have in the selected image list. The image is then changed to have this
* order.
* \param id Identifier
* \param i Image index
* \param order Order of image
*/
[[codegen::luawrap]] void setImageLayerOrder(std::string identifier, int imageIndex,
int imageOrder)
@@ -121,7 +119,7 @@ namespace {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setImageOrder(imageIndex, imageOrder);
}
@@ -133,20 +131,17 @@ namespace {
*/
[[codegen::luawrap]] void loadImagesToWWT(std::string identifier) {
using namespace openspace;
// Load images from url
LINFO("Connection established to WorldWide Telescope application in " + identifier);
LINFO("Loading image collections to " + identifier);
// Load the collections here because we know that the browser can execute javascript
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
"wwt-web-client/master/assets/webclient-explore-root.wtml";
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->hideChromeInterface(true);
pair->loadImageCollection(root);
pair->hideChromeInterface();
pair->loadImageCollection(module->wwtImageCollectionUrl());
}
}
@@ -156,7 +151,7 @@ namespace {
*/
[[codegen::luawrap]] void startSetup() {
using namespace openspace;
// This is called when the sky_browser website is connected to OpenSpace
// Set all border colors to the border color in the master node
if (global::windowDelegate->isMaster()) {
@@ -189,7 +184,7 @@ namespace {
*/
[[codegen::luawrap]] void sendOutIdsToBrowsers() {
using namespace openspace;
// This is called when the sky_browser website is connected to OpenSpace
// Send out identifiers to the browsers
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
@@ -207,13 +202,12 @@ namespace {
*/
[[codegen::luawrap]] void initializeBrowser(std::string identifier) {
using namespace openspace;
// Initialize browser with ID and its corresponding target
LINFO("Initializing sky browser " + identifier);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setIsSyncedWithWwt(true);
pair->initialize();
}
}
@@ -234,6 +228,17 @@ namespace {
module->addTargetBrowserPair(targetId, browserId);
}
/**
* Returns the AAS WorldWide Telescope image collection url.
*/
[[codegen::luawrap]] ghoul::Dictionary getWwtImageCollectionUrl() {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
ghoul::Dictionary url;
url.setValue("url", module->wwtImageCollectionUrl());
return url;
}
/**
* Returns a list of all the loaded AAS WorldWide Telescope images that have been loaded.
* Each image has a name, thumbnail url, equatorial spherical coordinates RA and Dec,
@@ -242,17 +247,14 @@ namespace {
*/
[[codegen::luawrap]] ghoul::Dictionary getListOfImages() {
using namespace openspace;
// Send image list to GUI
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
std::string url = module->wwtImageCollectionUrl();
// If no data has been loaded yet, download the data from the web!
if (module->nLoadedImages() == 0) {
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
"wwt-web-client/master/assets/webclient-explore-root.wtml";
std::filesystem::path directory = absPath("${MODULE_SKYBROWSER}/wwtimagedata/");
module->loadImages(root, directory);
module->loadImages(url, directory);
}
// Create Lua table to send to the GUI
@@ -285,11 +287,11 @@ namespace {
/**
* Returns a table of data regarding the current view and the sky browsers and targets.
* \return Dictionary of data regarding the current targets
* returns a table of data regarding the current targets.
*/
[[codegen::luawrap]] ghoul::Dictionary getTargetData() {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
ghoul::Dictionary data;
@@ -323,16 +325,6 @@ namespace {
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
std::string id = pair->browserId();
// Convert deque to vector so ghoul can read it
std::vector<int> selectedImagesVector;
const std::deque<int> selectedImages = pair->selectedImages();
std::for_each(
selectedImages.begin(),
selectedImages.end(),
[&](int i) {
selectedImagesVector.push_back(i);
}
);
glm::dvec2 spherical = pair->targetDirectionEquatorial();
glm::dvec3 cartesian = skybrowser::sphericalToCartesian(spherical);
@@ -342,20 +334,19 @@ namespace {
target.setValue("id", id);
target.setValue("name", pair->browserGuiName());
target.setValue("FOV", static_cast<double>(pair->verticalFov()));
target.setValue("selectedImages", selectedImagesVector);
target.setValue("selectedImages", pair->selectedImages());
target.setValue("cartesianDirection", cartesian);
target.setValue("ra", spherical.x);
target.setValue("dec", spherical.y);
target.setValue("roll", pair->targetRoll());
target.setValue("color", pair->borderColor());
target.setValue("size", glm::dvec2(pair->size()));
std::vector<std::pair<std::string, glm::dvec3>> copies = pair->renderCopies();
std::vector<std::pair<std::string, glm::dvec3>> copies = pair->displayCopies();
ghoul::Dictionary copiesData;
for (size_t i = 0; i < copies.size(); i++) {
copiesData.setValue(copies[i].first, copies[i].second);
}
// Set table for the current target
target.setValue("renderCopies", copiesData);
target.setValue("displayCopies", copiesData);
data.setValue(id, target);
}
}
@@ -369,7 +360,7 @@ namespace {
*/
[[codegen::luawrap]] void adjustCamera(std::string id) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->isCameraInSolarSystem()) {
module->lookAtTarget(id);
@@ -384,9 +375,9 @@ namespace {
float opacity)
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setImageOpacity(imageIndex, opacity);
}
@@ -398,9 +389,9 @@ namespace {
*/
[[codegen::luawrap]] void centerTargetOnScreen(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->centerTargetOnScreen();
}
@@ -412,7 +403,7 @@ namespace {
*/
[[codegen::luawrap]] void setSelectedBrowser(std::string identifier) {
using namespace openspace;
global::moduleEngine->module<SkyBrowserModule>()->setSelectedBrowser(identifier);
}
@@ -421,20 +412,20 @@ namespace {
*/
[[codegen::luawrap]] void createTargetBrowserPair() {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
int noOfPairs = module->nPairs();
std::string nameBrowser = "Sky Browser " + std::to_string(noOfPairs);
std::string nameTarget = "Sky Target " + std::to_string(noOfPairs);
std::string idBrowser = "SkyBrowser" + std::to_string(noOfPairs);
std::string idTarget = "SkyTarget" + std::to_string(noOfPairs);
int uniqueIdentifier = module->uniqueIdentifierCounter();
std::string nameBrowser = "Sky Browser " + std::to_string(uniqueIdentifier);
std::string nameTarget = "Sky Target " + std::to_string(uniqueIdentifier);
std::string idBrowser = "SkyBrowser" + std::to_string(uniqueIdentifier);
std::string idTarget = "SkyTarget" + std::to_string(uniqueIdentifier);
// Determine starting point on screen for the target
glm::vec3 positionBrowser = glm::vec3(-3.f, -3.f, -2.1f);
glm::vec3 positionBrowser = glm::vec3(0.f, 0.f, -2.1f);
glm::vec3 positionTarget = glm::vec3(0.9f, 0.4f, -2.1f);
glm::dvec3 galacticTarget = skybrowser::localCameraToGalactic(positionTarget);
std::string guiPath = "/Sky Browser";
std::string url = "https://data.openspaceproject.com/dist/skybrowser/page/";
std::string url = "http://wwt.openspaceproject.com/1/openspace/";
double fov = 70.0;
double size = skybrowser::sizeFromFov(fov, galacticTarget);
@@ -445,7 +436,7 @@ namespace {
"Url = '" + url + "',"
"FaceCamera = false,"
"CartesianPosition = " + ghoul::to_string(positionBrowser) +
"}";
"}";
const std::string target = "{"
"Identifier = '" + idTarget + "',"
@@ -454,10 +445,10 @@ namespace {
"Transform = {"
"Translation = {"
"Type = 'StaticTranslation',"
"Position = {"
+ std::to_string(galacticTarget.x) + ", "
+ std::to_string(galacticTarget.y) + ", "
+ std::to_string(galacticTarget.z) + ", "
"Position = {" +
std::to_string(galacticTarget.x) + ", " +
std::to_string(galacticTarget.y) + ", " +
std::to_string(galacticTarget.z) + ", " +
"},"
"},"
"Rotation = {"
@@ -475,7 +466,7 @@ namespace {
"Opacity = 0.99"
"},"
"GUI = {"
"Name = 'Sky Target', "
"Name = '" + nameTarget + "', "
"Path = '/SkyBrowser', "
"}"
"}";
@@ -507,9 +498,9 @@ namespace {
*/
[[codegen::luawrap]] void removeTargetBrowserPair(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* found = module->getPair(identifier);
TargetBrowserPair* found = module->pair(identifier);
if (found) {
std::string browser = found->browserId();
std::string target = found->targetNodeId();
@@ -540,7 +531,7 @@ namespace {
float translationY)
{
using namespace openspace;
ScreenSpaceRenderable* renderable =
global::renderEngine->screenSpaceRenderable(identifier);
@@ -559,11 +550,11 @@ namespace {
int imageIndex)
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const ImageData& image = module->getWwtDataHandler()->getImage(imageIndex);
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->removeSelectedImage(imageIndex);
}
@@ -578,9 +569,9 @@ namespace {
double declination)
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setEquatorialAim(glm::dvec2(rightAscension, declination));
}
@@ -594,9 +585,9 @@ namespace {
float verticalFieldOfView)
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setVerticalFov(verticalFieldOfView);
}
@@ -608,9 +599,9 @@ namespace {
*/
[[codegen::luawrap]] void scrollOverBrowser(std::string identifier, float scroll) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setVerticalFovWithScroll(scroll);
}
@@ -624,9 +615,9 @@ namespace {
int blue)
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setBorderColor(glm::ivec3(red, green, blue));
}
@@ -636,46 +627,45 @@ namespace {
* Sets the screen space size of the sky browser to the numbers specified by the input
* [x, y].
*/
[[codegen::luawrap]] void setScreenSpaceSize(std::string identifier, float sizeX,
float sizeY)
[[codegen::luawrap]] void setBrowserRatio(std::string identifier, float ratio)
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->setScreenSpaceSize(glm::vec2(sizeX, sizeY));
pair->setBrowserRatio(ratio);
}
}
/**
* Takes an identifier to a sky browser and adds a rendered copy to it.
* \param raePosition Position in radius, azimuth, elevation coordinates
* \param nCopies Number of copies
* Takes an identifier to a sky browser and adds a rendered copy to it. The first argument
* is the position of the first copy. The position is in RAE or Cartesian coordinates,
* depending on if 'Use Radius Azimuth Elevation' is checked. The second argument is the
* number of copies. If RAE is used, they will be evenly spread out on the azimuth.
*/
[[codegen::luawrap]] void addRenderCopy(std::string identifier,
int numberOfCopies = 1,
glm::vec3 radiusAzimuthElevationPosition = glm::vec3(2.1f, 0.f, 0.f))
[[codegen::luawrap]] void addDisplayCopy(std::string identifier, int numberOfCopies = 1,
glm::vec3 position = glm::vec3(2.1f, 0.f, 0.f))
{
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->browser()->addRenderCopy(radiusAzimuthElevationPosition, numberOfCopies);
pair->browser()->addDisplayCopy(position, numberOfCopies);
}
}
/**
* Takes an identifier to a sky browser and removes the latest added rendered copy to it.
*/
[[codegen::luawrap]] void removeRenderCopy(std::string identifier) {
[[codegen::luawrap]] void removeDisplayCopy(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->browser()->removeRenderCopy();
pair->browser()->removeDisplayCopy();
}
}
@@ -684,16 +674,18 @@ namespace {
*/
[[codegen::luawrap]] void startFinetuningTarget(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
pair->startFinetuningTarget();
}
}
/**
* Finetunes the target depending on a mouse drag. rendered copy to it.
* Finetunes the target depending on a mouse drag. rendered copy to it. First argument
* is the identifier of the sky browser, second is the start position of the drag
* and third is the end position of the drag.
*/
[[codegen::luawrap]] void finetuneTargetPosition(std::string identifier,
glm::vec2 startPosition,
@@ -702,7 +694,7 @@ namespace {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->getPair(identifier);
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
glm::vec2 startScreenSpace = skybrowser::pixelToScreenSpace2d(startPosition);
glm::vec2 endScreenSpace = skybrowser::pixelToScreenSpace2d(endPosition);
@@ -711,6 +703,70 @@ namespace {
}
}
/**
* Sets the image collection as loaded in the sky browser. Takes an identifier to the sky
* browser.
*/
[[codegen::luawrap]] void loadingImageCollectionComplete(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->pair(identifier);
if (pair) {
LINFO("Image collection is loaded in Screen Space Sky Browser " + identifier);
pair->setImageCollectionIsLoaded(true);
// Add all selected images to WorldWide Telescope
const std::vector<int>& images = pair->selectedImages();
std::for_each(
images.rbegin(), images.rend(),
[&](int index) {
const ImageData& image = module->getWwtDataHandler()->getImage(index);
// Index of image is used as layer ID as it is unique in the image data set
pair->browser()->addImageLayerToWwt(image.imageUrl, index);
}
);
}
}
/**
* Show or hide all targets and browsers. Takes a boolean that sets it to either be shown
* or not.
*/
[[codegen::luawrap]] void showAllTargetsAndBrowsers(bool show) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const std::vector<std::unique_ptr<TargetBrowserPair>>& pairs = module->getPairs();
for (const std::unique_ptr<TargetBrowserPair>& pair : pairs) {
pair->setEnabled(show);
}
}
/**
* Point spacecraft to the equatorial coordinates the target points to. Takes an
* identifier to a sky browser.
*/
[[codegen::luawrap]] void pointSpaceCraft(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->pair(identifier);
glm::dvec2 equatorial = pair->targetDirectionEquatorial();
global::eventEngine->publishEvent<events::EventPointSpacecraft>(
equatorial.x,
equatorial.y,
module->spaceCraftAnimationTime()
);
}
/**
* Stop animations. Takes an identifier to a sky browser.
*/
[[codegen::luawrap]] void stopAnimations(std::string identifier) {
using namespace openspace;
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
TargetBrowserPair* pair = module->pair(identifier);
pair->stopAnimations();
}
#include "skybrowsermodule_lua_codegen.cpp"
} // namespace
+1 -1
View File
@@ -92,7 +92,7 @@ Browser::Browser(const ghoul::Dictionary& dictionary)
if (dictionary.hasValue<std::string>(UrlInfo.identifier)) {
_url = dictionary.value<std::string>(UrlInfo.identifier);
}
// Handle target dimension property
const Parameters p = codegen::bake<Parameters>(dictionary);
_url = p.url.value_or(_url);
+11 -52
View File
@@ -63,21 +63,6 @@ namespace {
"be rendered in the target."
};
constexpr const openspace::properties::Property::PropertyInfo AnimationSpeedInfo = {
"AnimationSpeed",
"Animation Speed",
"The factor which is multiplied with the animation speed of the target."
};
constexpr const openspace::properties::Property::PropertyInfo AnimationThresholdInfo =
{
"AnimationThreshold",
"Animation Threshold",
"The threshold for when the target is determined to have appeared at its "
"destination. Angle in radians between the destination and the target position "
"in equatorial Cartesian coordinate system."
};
constexpr const openspace::properties::Property::PropertyInfo LineWidthInfo = {
"LineWidth",
"Line Width",
@@ -91,12 +76,6 @@ namespace {
// [[codegen::verbatim(RectangleThresholdInfo.description)]]
std::optional<float> rectangleThreshold;
// [[codegen::verbatim(AnimationSpeedInfo.description)]]
std::optional<double> animationSpeed;
// [[codegen::verbatim(AnimationThresholdInfo.description)]]
std::optional<float> animationThreshold;
// [[codegen::verbatim(LineWidthInfo.description)]]
std::optional<float> lineWidth;
};
@@ -106,29 +85,25 @@ namespace {
namespace openspace {
documentation::Documentation RenderableSkyTarget::Documentation() {
return codegen::doc<Parameters>("skybrowser_renderableskytarget");
}
RenderableSkyTarget::RenderableSkyTarget(const ghoul::Dictionary& dictionary)
: RenderablePlane(dictionary)
, _crossHairSize(crossHairSizeInfo, 2.f, 1.f, 10.f)
, _showRectangleThreshold(RectangleThresholdInfo, 5.f, 0.1f, 70.f)
, _stopAnimationThreshold(AnimationThresholdInfo, 5.0f, 1.f, 10.f)
, _animationSpeed(AnimationSpeedInfo, 5.0, 0.1, 10.0)
, _lineWidth(LineWidthInfo, 13.f, 1.f, 100.f)
, _borderColor(220, 220, 220)
{
// Handle target dimension property
const Parameters p = codegen::bake<Parameters>(dictionary);
_crossHairSize = p.crossHairSize.value_or(_crossHairSize);
addProperty(_crossHairSize);
_showRectangleThreshold = p.rectangleThreshold.value_or(_showRectangleThreshold);
addProperty(_showRectangleThreshold);
_stopAnimationThreshold = p.crossHairSize.value_or(_stopAnimationThreshold);
addProperty(_stopAnimationThreshold);
_animationSpeed = p.animationSpeed.value_or(_animationSpeed);
addProperty(_animationSpeed);
addProperty(_lineWidth);
}
@@ -166,15 +141,15 @@ void RenderableSkyTarget::render(const RenderData& data, RendererTasks&) {
ZoneScoped
const bool showRectangle = _verticalFov > _showRectangleThreshold;
glm::vec4 color = { glm::vec3(_borderColor) / 255.f, _opacity.value() };
glm::vec4 color = { glm::vec3(_borderColor) / 255.f, 1.0 };
_shader->activate();
_shader->setUniform("opacity", _opacity);
_shader->setUniform("opacity", opacity());
_shader->setUniform("crossHairSize", _crossHairSize);
_shader->setUniform("showRectangle", showRectangle);
_shader->setUniform("lineWidth", _lineWidth * 0.0001f);
_shader->setUniform("dimensions", _dimensions);
_shader->setUniform("ratio", _ratio);
_shader->setUniform("lineColor", color);
_shader->setUniform("fov", static_cast<float>(_verticalFov));
@@ -239,10 +214,10 @@ void RenderableSkyTarget::render(const RenderData& data, RendererTasks&) {
_shader->deactivate();
}
void RenderableSkyTarget::setDimensions(glm::vec2 dimensions) {
void RenderableSkyTarget::setRatio(float ratio) {
// To avoid flooring of the size of the target, multiply by factor of 100
// Object size is really the pixel size so this calculation is not exact
_dimensions = glm::ivec2(dimensions * 100.f);
_ratio = ratio;
}
void RenderableSkyTarget::highlight(const glm::ivec3& addition) {
@@ -253,22 +228,6 @@ void RenderableSkyTarget::removeHighlight(const glm::ivec3& removal) {
_borderColor -= removal;
}
float RenderableSkyTarget::opacity() const {
return _opacity;
}
double RenderableSkyTarget::animationSpeed() const {
return _animationSpeed;
}
double RenderableSkyTarget::stopAnimationThreshold() const {
return _stopAnimationThreshold * 0.0001;
}
void RenderableSkyTarget::setOpacity(float opacity) {
_opacity = opacity;
}
void RenderableSkyTarget::setVerticalFov(double fov) {
_verticalFov = fov;
}
+127 -97
View File
@@ -48,32 +48,38 @@ namespace {
"frame rate."
};
constexpr const openspace::properties::Property::PropertyInfo RenderCopyInfo = {
"RenderCopy",
"RAE Position Of A Copy Of The Sky Browser",
"Render a copy of this sky browser at an additional position. This copy will not "
"be interactive. The position is in RAE (Radius, Azimuth, Elevation) coordinates."
constexpr const openspace::properties::Property::PropertyInfo DisplayCopyInfo = {
"DisplayCopy",
"Display Copy Position",
"Display a copy of this sky browser at an additional position. This copy will not "
"be interactive. The position is in RAE (Radius, Azimuth, Elevation) coordinates "
"or Cartesian, depending on if the browser uses RAE or Cartesian coordinates."
};
constexpr const openspace::properties::Property::PropertyInfo RenderOnMasterInfo = {
"RenderOnlyOnMaster",
"Render Only On Master",
"Render the interactive sky browser only on the master node (this setting won't "
"affect the copies). This setting allows mouse interactions in a dome "
"environment."
constexpr const openspace::properties::Property::PropertyInfo DisplayCopyShowInfo = {
"ShowDisplayCopy",
"Show Display Copy",
"Show the display copy."
};
constexpr const openspace::properties::Property::PropertyInfo IsHiddenInfo = {
"IsHidden",
"Is Hidden",
"If checked, the browser will be not be displayed. If it is not checked, it will "
"be."
};
struct [[codegen::Dictionary(ScreenSpaceSkyBrowser)]] Parameters {
// [[codegen::verbatim(TextureQualityInfo.description)]]
std::optional<float> textureQuality;
// [[codegen::verbatim(RenderOnMasterInfo.description)]]
std::optional<bool> renderOnlyOnMaster;
// [[codegen::verbatim(IsHiddenInfo.description)]]
std::optional<bool> isHidden;
};
#include "screenspaceskybrowser_codegen.cpp"
glm::ivec3 randomBorderColor(glm::ivec3 highlight) {
glm::ivec3 randomBorderColor() {
// Generate a random border color with sufficient lightness and a n
std::random_device rd;
// Hue is in the unit degrees [0, 360]
@@ -82,13 +88,8 @@ namespace {
// Value in saturation are in the unit percent [0,1]
float value = 0.9f; // Brightness
float saturation = 0.5f;
glm::ivec3 rgbColor;
glm::ivec3 highlighted;
do {
glm::vec3 hsvColor = glm::vec3(hue(rd), saturation, value);
rgbColor = glm::ivec3(glm::rgbColor(hsvColor) * 255.f);
highlighted = rgbColor + highlight;
} while (highlighted.x < 255 && highlighted.y < 255 && highlighted.z < 255);
glm::vec3 hsvColor = glm::vec3(hue(rd), saturation, value);
glm::ivec3 rgbColor = glm::ivec3(glm::rgbColor(hsvColor) * 255.f);
return rgbColor;
}
@@ -96,41 +97,60 @@ namespace {
namespace openspace {
documentation::Documentation ScreenSpaceSkyBrowser::Documentation() {
return codegen::doc<Parameters>("skybrowser_screenspaceskybrowser");
}
ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary)
: ScreenSpaceRenderable(dictionary)
, WwtCommunicator(dictionary)
, _textureQuality(TextureQualityInfo, 0.5f, 0.25f, 1.f)
, _renderOnlyOnMaster(RenderOnMasterInfo, false)
, _isHidden(IsHiddenInfo, true)
{
_identifier = makeUniqueIdentifier(_identifier);
// Handle target dimension property
const Parameters p = codegen::bake<Parameters>(dictionary);
_textureQuality = p.textureQuality.value_or(_textureQuality);
_renderOnlyOnMaster = p.renderOnlyOnMaster.value_or(_renderOnlyOnMaster);
_isHidden = p.isHidden.value_or(_isHidden);
addProperty(_isHidden);
addProperty(_url);
addProperty(_browserPixeldimensions);
addProperty(_reload);
addProperty(_textureQuality);
addProperty(_renderOnlyOnMaster);
_textureQuality.onChange([this]() { _textureDimensionsIsDirty = true; });
// Ensure that the browser is placed at the z-coordinate of the screen space plane
glm::vec2 screenPosition = _cartesianPosition.value();
_cartesianPosition = glm::vec3(screenPosition, skybrowser::ScreenSpaceZ);
if (global::windowDelegate->isMaster()) {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
_borderColor = randomBorderColor(module->highlight());
_borderColor = randomBorderColor();
}
_scale = _size.y * 0.5f;
_scale.onChange([this]() {
updateTextureResolution();
});
_useRadiusAzimuthElevation.onChange(
[this]() {
std::for_each(
_displayCopies.begin(),
_displayCopies.end(),
[this](std::unique_ptr<properties::Vec3Property>& copy) {
if (_useRadiusAzimuthElevation) {
*copy = sphericalToRae(cartesianToSpherical(copy->value()));
}
else {
*copy = sphericalToCartesian(raeToSpherical(copy->value()));
}
});
});
}
ScreenSpaceSkyBrowser::~ScreenSpaceSkyBrowser() {
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module && module->getPair(identifier())) {
if (module && module->pair(identifier())) {
module->removeTargetBrowserPair(identifier());
}
}
@@ -157,10 +177,18 @@ glm::dvec2 ScreenSpaceSkyBrowser::fineTuneVector(const glm::dvec2& drag) {
return result;
}
bool ScreenSpaceSkyBrowser::isInitialized() const {
return _isInitialized;
}
void ScreenSpaceSkyBrowser::setIdInBrowser() const {
WwtCommunicator::setIdInBrowser(identifier());
}
void ScreenSpaceSkyBrowser::setIsInitialized(bool isInitialized) {
_isInitialized = isInitialized;
}
void ScreenSpaceSkyBrowser::updateTextureResolution() {
// Scale texture depending on the height of the window
// Set texture size to the actual pixel size it covers
@@ -168,8 +196,7 @@ void ScreenSpaceSkyBrowser::updateTextureResolution() {
// If the scale is 1, it covers half the window. Hence multiplication with 2
float newResY = pixels.y * 2.f * _scale;
float ratio = _size.x / _size.y;
float newResX = newResY * ratio;
float newResX = newResY * _ratio;
glm::vec2 newSize = glm::vec2(newResX , newResY) * _textureQuality.value();
_browserPixeldimensions = glm::ivec2(newSize);
@@ -177,55 +204,63 @@ void ScreenSpaceSkyBrowser::updateTextureResolution() {
_objectSize = glm::ivec3(_texture->dimensions());
}
void ScreenSpaceSkyBrowser::addRenderCopy(const glm::vec3& raePosition, int nCopies) {
size_t start = _renderCopies.size();
void ScreenSpaceSkyBrowser::addDisplayCopy(const glm::vec3& raePosition, int nCopies) {
size_t start = _displayCopies.size();
for (int i = 0; i < nCopies; i++) {
openspace::properties::Property::PropertyInfo info = RenderCopyInfo;
openspace::properties::Property::PropertyInfo info = DisplayCopyInfo;
float azimuth = i * glm::two_pi<float>() / nCopies;
glm::vec3 position = raePosition + glm::vec3(0.f, azimuth, 0.f);
std::string id = "RenderCopy" + std::to_string(start + i);
info.identifier = id.c_str();
_renderCopies.push_back(
std::string idDisplayCopy = "DisplayCopy" + std::to_string(start + i);
info.identifier = idDisplayCopy.c_str();
_displayCopies.push_back(
std::make_unique<properties::Vec3Property>(
info,
position,
glm::vec3(0.f, -glm::pi<float>(), -glm::half_pi<float>()),
glm::vec3(10.f, glm::pi<float>(), glm::half_pi<float>())
glm::vec3(-4.f, -4.f, -10.f),
glm::vec3(4.f, 4.f, glm::half_pi<float>())
)
);
addProperty(_renderCopies.back().get());
openspace::properties::Property::PropertyInfo showInfo = DisplayCopyShowInfo;
std::string idDisplayCopyVisible = "ShowDisplayCopy" + std::to_string(start + i);
showInfo.identifier = idDisplayCopyVisible.c_str();
_showDisplayCopies.push_back(
std::make_unique<properties::BoolProperty>(
showInfo,
true
)
);
addProperty(_displayCopies.back().get());
addProperty(_showDisplayCopies.back().get());
}
}
void ScreenSpaceSkyBrowser::removeRenderCopy() {
if (!_renderCopies.empty()) {
removeProperty(_renderCopies.back().get());
_renderCopies.pop_back();
void ScreenSpaceSkyBrowser::removeDisplayCopy() {
if (!_displayCopies.empty()) {
removeProperty(_displayCopies.back().get());
_displayCopies.pop_back();
}
}
std::vector<std::pair<std::string, glm::dvec3>>
ScreenSpaceSkyBrowser::renderCopies() const
ScreenSpaceSkyBrowser::displayCopies() const
{
std::vector<std::pair<std::string, glm::dvec3>> vec;
std::for_each(
_renderCopies.begin(),
_renderCopies.end(),
[&](const std::unique_ptr<properties::Vec3Property>& copy) {
std::pair<std::string, glm::dvec3> pair = {
copy.get()->identifier(),
glm::dvec3(copy.get()->value())
};
vec.push_back(pair);
}
);
using vec3Property = std::unique_ptr<properties::Vec3Property>;
for (const vec3Property& copy : _displayCopies) {
vec.push_back({ copy->identifier(), copy->value() });
}
return vec;
}
void ScreenSpaceSkyBrowser::moveRenderCopy(int i, glm::vec3 raePosition) {
if (i < static_cast<int>(_renderCopies.size()) && i >= 0) {
*_renderCopies[i].get() = raePosition;
std::vector<std::pair<std::string, bool>>
ScreenSpaceSkyBrowser::showDisplayCopies() const
{
std::vector<std::pair<std::string, bool>> vec;
using boolProperty = std::unique_ptr<properties::BoolProperty>;
for (const boolProperty& copy : _showDisplayCopies) {
vec.push_back({copy->identifier(), copy->value()});
}
return vec;
}
bool ScreenSpaceSkyBrowser::deinitializeGL() {
@@ -237,12 +272,7 @@ bool ScreenSpaceSkyBrowser::deinitializeGL() {
void ScreenSpaceSkyBrowser::render() {
WwtCommunicator::render();
// If the sky browser only should be rendered on master, don't use the
// global rotation
if (_renderOnlyOnMaster && global::windowDelegate->isMaster()) {
draw(translationMatrix() * localRotationMatrix() * scaleMatrix());
}
else if (!_renderOnlyOnMaster) {
if (!_isHidden) {
draw(
globalRotationMatrix() *
translationMatrix() *
@@ -251,20 +281,29 @@ void ScreenSpaceSkyBrowser::render() {
);
}
// Render a copy that is not interactive
for (const std::unique_ptr<properties::Vec3Property>& copy : _renderCopies) {
glm::vec3 spherical = sphericalToCartesian(raeToSpherical(copy.get()->value()));
glm::mat4 localRotation = glm::inverse(glm::lookAt(
glm::vec3(0.f),
glm::normalize(spherical),
glm::vec3(0.f, 1.f, 0.f)
));
draw(
globalRotationMatrix() *
glm::translate(glm::mat4(1.f), spherical) *
localRotation *
scaleMatrix()
);
// Render the display copies
for (size_t i = 0; i < _displayCopies.size(); i++) {
if (_showDisplayCopies[i]->value()) {
glm::vec3 coordinates = _displayCopies[i]->value();
if (_useRadiusAzimuthElevation) {
coordinates = sphericalToCartesian(raeToSpherical(coordinates));
}
glm::mat4 localRotation = glm::mat4(1.f);
if (_faceCamera) {
localRotation = glm::inverse(glm::lookAt(
glm::vec3(0.f),
glm::normalize(coordinates),
glm::vec3(0.f, 1.f, 0.f)
));
}
draw(
globalRotationMatrix() *
glm::translate(glm::mat4(1.f), coordinates) *
localRotation *
scaleMatrix()
);
}
}
}
@@ -276,9 +315,9 @@ void ScreenSpaceSkyBrowser::update() {
updateTextureResolution();
_textureDimensionsIsDirty = false;
}
if (_sizeIsDirty) {
updateScreenSpaceSize();
_sizeIsDirty = false;
if (_ratioIsDirty) {
updateTextureResolution();
_ratioIsDirty = false;
}
WwtCommunicator::update();
@@ -289,7 +328,7 @@ void ScreenSpaceSkyBrowser::setVerticalFovWithScroll(float scroll) {
// Make scroll more sensitive the smaller the FOV
double x = _verticalFov;
double zoomFactor = atan(x / 50.0) + exp(x / 40.0) - 0.99999999999999999999999999999;
double zoom = scroll > 0.0 ? -zoomFactor : zoomFactor;
double zoom = scroll > 0.0 ? zoomFactor : -zoomFactor;
_verticalFov = std::clamp(_verticalFov + zoom, 0.0, 70.0);
}
@@ -313,22 +352,13 @@ void ScreenSpaceSkyBrowser::setOpacity(float opacity) {
_opacity = opacity;
}
void ScreenSpaceSkyBrowser::setScreenSpaceSize(glm::vec2 newSize) {
_size = std::move(newSize);
_sizeIsDirty = true;
}
void ScreenSpaceSkyBrowser::updateScreenSpaceSize() {
_scale = abs(_size.y) * 0.5f;
updateTextureResolution();
void ScreenSpaceSkyBrowser::setRatio(float ratio) {
_ratio = ratio;
_ratioIsDirty = true;
}
float ScreenSpaceSkyBrowser::opacity() const {
return _opacity;
}
glm::vec2 ScreenSpaceSkyBrowser::size() const {
return _size;
}
} // namespace openspace
+87 -55
View File
@@ -63,16 +63,6 @@ void TargetBrowserPair::setImageOrder(int i, int order) {
_browser->setImageOrder(i, order);
}
void TargetBrowserPair::removeHighlight(const glm::ivec3& color) {
_targetRenderable->removeHighlight(color);
_browser->removeHighlight(color);
}
void TargetBrowserPair::highlight(const glm::ivec3& color) {
_browser->highlight(color);
_targetRenderable->highlight(color);
}
void TargetBrowserPair::aimTargetGalactic(glm::dvec3 direction) {
std::string id = _targetNode->identifier();
glm::dvec3 positionCelestial = glm::normalize(direction) *
@@ -114,7 +104,7 @@ void TargetBrowserPair::fineTuneTarget(const glm::vec2& startMouse,
}
void TargetBrowserPair::synchronizeAim() {
if (!_moveTarget.isAnimating()) {
if (!_targetAnimation.isAnimating() && _browser->isInitialized()) {
_browser->setEquatorialAim(targetDirectionEquatorial());
_browser->setTargetRoll(targetRoll());
_targetRenderable->setVerticalFov(_browser->verticalFov());
@@ -123,7 +113,7 @@ void TargetBrowserPair::synchronizeAim() {
void TargetBrowserPair::setEnabled(bool enable) {
_browser->setEnabled(enable);
_targetRenderable->property("Enabled")->set(false);
_targetRenderable->property("Enabled")->set(enable);
}
void TargetBrowserPair::setOpacity(float opacity) {
@@ -137,8 +127,11 @@ bool TargetBrowserPair::isEnabled() const {
void TargetBrowserPair::initialize() {
_targetRenderable->setColor(_browser->borderColor());
_targetRenderable->setDimensions(_browser->screenSpaceDimensions());
glm::vec2 dim = _browser->screenSpaceDimensions();
_targetRenderable->setRatio(dim.x / dim.y);
_browser->updateBorderColor();
_browser->hideChromeInterface();
_browser->setIsInitialized(true);
}
glm::ivec3 TargetBrowserPair::borderColor() const {
@@ -172,31 +165,70 @@ std::string TargetBrowserPair::targetNodeId() const {
return _targetNode->identifier();
}
glm::vec2 TargetBrowserPair::size() const {
return _browser->size();
float TargetBrowserPair::browserRatio() const {
return _browser->browserRatio();
}
double TargetBrowserPair::verticalFov() const {
return _browser->verticalFov();
}
const std::deque<int>& TargetBrowserPair::selectedImages() const {
return _browser->getSelectedImages();
std::vector<int> TargetBrowserPair::selectedImages() const {
return _browser->selectedImages();
}
ghoul::Dictionary TargetBrowserPair::dataAsDictionary() const {
glm::dvec2 spherical = targetDirectionEquatorial();
glm::dvec3 cartesian = skybrowser::sphericalToCartesian(spherical);
ghoul::Dictionary res;
res.setValue("id", browserId());
res.setValue("name", browserGuiName());
res.setValue("fov", static_cast<double>(verticalFov()));
res.setValue("ra", spherical.x);
res.setValue("dec", spherical.y);
res.setValue("roll", targetRoll());
res.setValue("color", borderColor());
res.setValue("cartesianDirection", cartesian);
res.setValue("ratio", static_cast<double>(browserRatio()));
res.setValue("isFacingCamera", isFacingCamera());
res.setValue("isUsingRae", isUsingRadiusAzimuthElevation());
res.setValue("selectedImages", selectedImages());
res.setValue("scale", static_cast<double>(_browser->scale()));
res.setValue("opacities", _browser->opacities());
std::vector<std::pair<std::string, glm::dvec3>> copies = displayCopies();
std::vector<std::pair<std::string, bool>> showCopies = _browser->showDisplayCopies();
ghoul::Dictionary copiesData;
for (size_t i = 0; i < copies.size(); i++) {
ghoul::Dictionary copy;
copy.setValue("position", copies[i].second);
copy.setValue("show", showCopies[i].second);
copy.setValue("idShowProperty", showCopies[i].first);
copiesData.setValue(copies[i].first, copy);
}
// Set table for the current target
res.setValue("displayCopies", copiesData);
return res;
}
void TargetBrowserPair::selectImage(const ImageData& image, int i) {
// Load image into browser
_browser->displayImage(image.imageUrl, i);
_browser->selectImage(image.imageUrl, i);
// If the image has coordinates, move the target
if (image.hasCelestialCoords) {
// Animate the target to the image coordinate position
// unlock();
glm::dvec3 galactic = skybrowser::equatorialToGalactic(image.equatorialCartesian);
startAnimation(galactic * skybrowser::CelestialSphereRadius, image.fov);
}
}
void TargetBrowserPair::addImageLayerToWwt(const std::string& url, int i) {
_browser->addImageLayerToWwt(url, i);
}
void TargetBrowserPair::removeSelectedImage(int i) {
_browser->removeSelectedImage(i);
}
@@ -209,8 +241,8 @@ void TargetBrowserPair::setImageOpacity(int i, float opacity) {
_browser->setImageOpacity(i, opacity);
}
void TargetBrowserPair::hideChromeInterface(bool shouldHide) {
_browser->hideChromeInterface(shouldHide);
void TargetBrowserPair::hideChromeInterface() {
_browser->hideChromeInterface();
}
void TargetBrowserPair::sendIdToBrowser() const {
@@ -221,12 +253,12 @@ void TargetBrowserPair::updateBrowserSize() {
_browser->updateBrowserSize();
}
std::vector<std::pair<std::string, glm::dvec3>> TargetBrowserPair::renderCopies() const {
return _browser->renderCopies();
std::vector<std::pair<std::string, glm::dvec3>> TargetBrowserPair::displayCopies() const {
return _browser->displayCopies();
}
void TargetBrowserPair::setIsSyncedWithWwt(bool isSynced) {
_browser->setIsSyncedWithWwt(isSynced);
bool TargetBrowserPair::isImageCollectionLoaded() {
return _browser->isImageCollectionLoaded();
}
void TargetBrowserPair::setVerticalFov(double vfov) {
@@ -235,7 +267,6 @@ void TargetBrowserPair::setVerticalFov(double vfov) {
}
void TargetBrowserPair::setEquatorialAim(const glm::dvec2& aim) {
_equatorialAim = aim;
aimTargetGalactic(
skybrowser::equatorialToGalactic(skybrowser::sphericalToCartesian(aim))
);
@@ -243,28 +274,31 @@ void TargetBrowserPair::setEquatorialAim(const glm::dvec2& aim) {
}
void TargetBrowserPair::setBorderColor(const glm::ivec3& color) {
_borderColor = color;
_targetRenderable->setColor(color);
_browser->setBorderColor(color);
}
void TargetBrowserPair::setScreenSpaceSize(const glm::vec2& dimensions) {
_browser->setScreenSpaceSize(dimensions);
_targetRenderable->setDimensions(dimensions);
void TargetBrowserPair::setBrowserRatio(float ratio) {
_browser->setRatio(ratio);
_targetRenderable->setRatio(ratio);
}
void TargetBrowserPair::setVerticalFovWithScroll(float scroll) {
_browser->setVerticalFovWithScroll(scroll);
}
void TargetBrowserPair::setImageCollectionIsLoaded(bool isLoaded) {
_browser->setImageCollectionIsLoaded(isLoaded);
}
void TargetBrowserPair::incrementallyAnimateToCoordinate() {
// Animate the target before the field of view starts to animate
if (_moveTarget.isAnimating()) {
aimTargetGalactic(_moveTarget.getNewValue());
if (_targetAnimation.isAnimating()) {
aimTargetGalactic(_targetAnimation.getNewValue());
}
else if (!_moveTarget.isAnimating() && _targetIsAnimating) {
else if (!_targetAnimation.isAnimating() && _targetIsAnimating) {
// Set the finished position
aimTargetGalactic(_moveTarget.getNewValue());
aimTargetGalactic(_targetAnimation.getNewValue());
_fovAnimation.start();
_targetIsAnimating = false;
}
@@ -275,10 +309,21 @@ void TargetBrowserPair::incrementallyAnimateToCoordinate() {
}
void TargetBrowserPair::startFading(float goal, float fadeTime) {
_fadeTarget = skybrowser::Animation(_targetRenderable->opacity(), goal, fadeTime);
_fadeBrowser = skybrowser::Animation(_browser->opacity(), goal, fadeTime);
_fadeTarget.start();
_fadeBrowser.start();
const std::string script = fmt::format(
"openspace.setPropertyValueSingle('Scene.{0}.Renderable.Fade', {2}, {3});"
"openspace.setPropertyValueSingle('ScreenSpace.{1}.Fade', {2}, {3});",
_targetNode->identifier(), _browser->identifier(), goal, fadeTime
);
global::scriptEngine->queueScript(
script,
scripting::ScriptEngine::RemoteScripting::Yes
);
}
void TargetBrowserPair::stopAnimations() {
_fovAnimation.stop();
_targetAnimation.stop();
}
void TargetBrowserPair::startAnimation(glm::dvec3 galacticCoords, double fovEnd) {
@@ -294,8 +339,8 @@ void TargetBrowserPair::startAnimation(glm::dvec3 galacticCoords, double fovEnd)
skybrowser::CelestialSphereRadius;
double targetSpeed = module->targetAnimationSpeed();
double angle = skybrowser::angleBetweenVectors(start, galacticCoords);
_moveTarget = skybrowser::Animation(start, galacticCoords, angle / targetSpeed);
_moveTarget.start();
_targetAnimation = skybrowser::Animation(start, galacticCoords, angle / targetSpeed);
_targetAnimation.start();
_targetIsAnimating = true;
}
@@ -307,9 +352,9 @@ void TargetBrowserPair::centerTargetOnScreen() {
startAnimation(viewDirection, currentFov);
}
double TargetBrowserPair::targetRoll() {
double TargetBrowserPair::targetRoll() const {
// To remove the lag effect when moving the camera while having a locked
// target, send the locked coordinates to wwt
// target, send the locked coordinates to wwt
glm::dvec3 normal = glm::normalize(
_targetNode->worldPosition() -
global::navigationHandler->camera()->positionVec3()
@@ -324,10 +369,6 @@ double TargetBrowserPair::targetRoll() {
return skybrowser::targetRoll(up, normal);
}
bool TargetBrowserPair::hasFinishedFading() const {
return !_fadeBrowser.isAnimating() && !_fadeTarget.isAnimating();
}
bool TargetBrowserPair::isFacingCamera() const {
return _browser->isFacingCamera();
}
@@ -344,15 +385,6 @@ ScreenSpaceSkyBrowser* TargetBrowserPair::browser() const {
return _browser;
}
void TargetBrowserPair::incrementallyFade() {
if (_fadeBrowser.isAnimating()) {
_browser->setOpacity(_fadeBrowser.getNewValue());
}
if (_fadeTarget.isAnimating()) {
_targetRenderable->setOpacity(_fadeTarget.getNewValue());
}
}
bool operator==(const TargetBrowserPair& lhs, const TargetBrowserPair& rhs) {
return lhs._targetNode == rhs._targetNode && lhs._browser == rhs._browser;
}
+6 -5
View File
@@ -28,6 +28,7 @@
#include <openspace/engine/globals.h>
#include <openspace/engine/windowdelegate.h>
#include <openspace/navigation/navigationhandler.h>
#include <ghoul/misc/easing.h>
#include <glm/gtx/vector_angle.hpp>
#include <cmath>
@@ -216,7 +217,7 @@ float Animation<float>::getNewValue() {
}
else {
float percentage = static_cast<float>(percentageSpent());
float diff = static_cast<float>((_goal - _start) * easeOutExpo(percentage));
float diff = static_cast<float>((_goal - _start) * ghoul::exponentialEaseOut(percentage));
return _start + diff;
}
}
@@ -227,7 +228,7 @@ double Animation<double>::getNewValue() {
}
else {
double percentage = percentageSpent();
double diff = (_goal - _start) * easeOutExpo(percentage);
double diff = (_goal - _start) * ghoul::exponentialEaseOut(percentage);
return _start + diff;
}
}
@@ -236,8 +237,8 @@ glm::dmat4 Animation<glm::dvec3>::getRotationMatrix() {
if (!isAnimating()) {
return glm::dmat4(1.0);
}
double percentage = easeInOutSine(percentageSpent());
double percentage = ghoul::sineEaseInOut(percentageSpent());
double increment = percentage - _lastPercentage;
_lastPercentage = percentage;
@@ -256,7 +257,7 @@ glm::dvec3 Animation<glm::dvec3>::getNewValue() {
glm::dmat4 rotMat = skybrowser::incrementalAnimationMatrix(
glm::normalize(_start),
glm::normalize(_goal),
easeOutExpo(percentageSpent())
ghoul::exponentialEaseOut(percentageSpent())
);
// Rotate direction
return glm::dvec3(rotMat * glm::dvec4(_start, 1.0));;
+62 -38
View File
@@ -42,21 +42,30 @@ WwtCommunicator::WwtCommunicator(const ghoul::Dictionary& dictionary)
WwtCommunicator::~WwtCommunicator() {}
void WwtCommunicator::displayImage(const std::string& url, int i) {
void WwtCommunicator::selectImage(const std::string& url, int i) {
// Ensure there are no duplicates
auto it = std::find(_selectedImages.begin(), _selectedImages.end(), i);
auto it = findSelectedImage(i);
if (it == _selectedImages.end()) {
// Push newly selected image to front
_selectedImages.push_front(i);
// Index of image is used as layer ID as it is unique in the image data set
sendMessageToWwt(addImageMessage(std::to_string(i), url));
sendMessageToWwt(setImageOpacityMessage(std::to_string(i), 1.0));
_selectedImages.push_front(std::pair<int, double>(i, 1.0));
// If wwt has not loaded the collection yet, wait with passing the message
if (_isImageCollectionLoaded) {
addImageLayerToWwt(url, i);
}
}
}
void WwtCommunicator::addImageLayerToWwt(const std::string& url, int i) {
// Index of image is used as layer ID as it is unique in the image data set
sendMessageToWwt(addImageMessage(std::to_string(i), url));
sendMessageToWwt(setImageOpacityMessage(std::to_string(i), 1.0));
}
void WwtCommunicator::removeSelectedImage(int i) {
// Remove from selected list
auto it = std::find(_selectedImages.begin(), _selectedImages.end(), i);
auto it = findSelectedImage(i);
if (it != _selectedImages.end()) {
_selectedImages.erase(it);
@@ -69,8 +78,20 @@ void WwtCommunicator::sendMessageToWwt(const ghoul::Dictionary& msg) const {
executeJavascript(script);
}
const std::deque<int>& WwtCommunicator::getSelectedImages() const {
return _selectedImages;
std::vector<int> WwtCommunicator::selectedImages() const {
std::vector<int> selectedImagesVector;
for (const std::pair<int, double>& image : _selectedImages) {
selectedImagesVector.push_back(image.first);
}
return selectedImagesVector;
}
std::vector<double> WwtCommunicator::opacities() const {
std::vector<double> opacities;
for (const std::pair<int, double>& image : _selectedImages) {
opacities.push_back(image.second);
}
return opacities;
}
void WwtCommunicator::setTargetRoll(double roll) {
@@ -88,10 +109,6 @@ void WwtCommunicator::setWebpageBorderColor(glm::ivec3 color) const {
executeJavascript(scr);
}
void WwtCommunicator::setIsSyncedWithWwt(bool isSynced) {
_isSyncedWithWwt = isSynced;
}
void WwtCommunicator::setEquatorialAim(glm::dvec2 equatorial) {
_equatorialAim = std::move(equatorial);
_equatorialAimIsDirty = true;
@@ -102,14 +119,6 @@ void WwtCommunicator::setBorderColor(glm::ivec3 color) {
_borderColorIsDirty = true;
}
void WwtCommunicator::highlight(const glm::ivec3& addition) const {
setWebpageBorderColor(_borderColor + addition);
}
void WwtCommunicator::removeHighlight(const glm::ivec3& removal) const {
setWebpageBorderColor(_borderColor - removal);
}
void WwtCommunicator::updateBorderColor() const {
setWebpageBorderColor(_borderColor);
}
@@ -125,8 +134,16 @@ glm::dvec2 WwtCommunicator::fieldsOfView() const {
return browserFov;
}
bool WwtCommunicator::hasLoadedImages() const {
return _hasLoadedImages;
bool WwtCommunicator::isImageCollectionLoaded() const {
return _isImageCollectionLoaded;
}
std::deque<std::pair<int, double>>::iterator WwtCommunicator::findSelectedImage(int i) {
auto it = std::find_if(_selectedImages.begin(), _selectedImages.end(),
[i](std::pair<int, double>& pair) {
return (pair.first == i);
});
return it;
}
glm::dvec2 WwtCommunicator::equatorialAim() const {
@@ -135,7 +152,7 @@ glm::dvec2 WwtCommunicator::equatorialAim() const {
void WwtCommunicator::setImageOrder(int i, int order) {
// Find in selected images list
auto current = std::find(_selectedImages.begin(), _selectedImages.end(), i);
auto current = findSelectedImage(i);
auto target = _selectedImages.begin() + order;
// Make sure the image was found in the list
@@ -150,23 +167,26 @@ void WwtCommunicator::setImageOrder(int i, int order) {
}
void WwtCommunicator::loadImageCollection(const std::string& collection) {
sendMessageToWwt(loadCollectionMessage(collection));
_hasLoadedImages = true;
if (!_isImageCollectionLoaded) {
sendMessageToWwt(loadCollectionMessage(collection));
}
}
void WwtCommunicator::setImageOpacity(int i, float opacity) const {
void WwtCommunicator::setImageOpacity(int i, float opacity) {
auto it = findSelectedImage(i);
it->second = opacity;
ghoul::Dictionary msg = setImageOpacityMessage(std::to_string(i), opacity);
sendMessageToWwt(msg);
}
void WwtCommunicator::hideChromeInterface(bool shouldHide) const {
void WwtCommunicator::hideChromeInterface() const {
std::string script = "sendMessageToWWT({event : \"modify_settings\", "
"settings : [[\"hideAllChrome\", true]], target: \"app\"});";
executeJavascript(script);
}
void WwtCommunicator::update() {
Browser::update();
// Cap how messages are passed
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime;
@@ -180,12 +200,16 @@ void WwtCommunicator::update() {
updateBorderColor();
_borderColorIsDirty = false;
}
if (_shouldReload) {
_isImageCollectionLoaded = false;
}
_lastUpdateTime = std::chrono::system_clock::now();
}
Browser::update();
}
void WwtCommunicator::setHasLoadedImages(bool isLoaded) {
_hasLoadedImages = isLoaded;
void WwtCommunicator::setImageCollectionIsLoaded(bool isLoaded) {
_isImageCollectionLoaded = isLoaded;
}
void WwtCommunicator::setIdInBrowser(const std::string& id) const {
@@ -207,7 +231,7 @@ ghoul::Dictionary WwtCommunicator::moveCameraMessage(const glm::dvec2& celestCoo
bool shouldMoveInstantly) const
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "center_on_coordinates"s);
msg.setValue("ra", celestCoords.x);
@@ -220,7 +244,7 @@ ghoul::Dictionary WwtCommunicator::moveCameraMessage(const glm::dvec2& celestCoo
ghoul::Dictionary WwtCommunicator::loadCollectionMessage(const std::string& url) const {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "load_image_collection"s);
msg.setValue("url", url);
@@ -230,7 +254,7 @@ ghoul::Dictionary WwtCommunicator::loadCollectionMessage(const std::string& url)
ghoul::Dictionary WwtCommunicator::setForegroundMessage(const std::string& name) const {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "set_foreground_by_name"s);
msg.setValue("name", name);
@@ -241,7 +265,7 @@ ghoul::Dictionary WwtCommunicator::addImageMessage(const std::string& id,
const std::string& url) const
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_create"s);
msg.setValue("id", id);
@@ -253,7 +277,7 @@ ghoul::Dictionary WwtCommunicator::addImageMessage(const std::string& id,
ghoul::Dictionary WwtCommunicator::removeImageMessage(const std::string& imageId) const {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_remove"s);
msg.setValue("id", imageId);
@@ -264,7 +288,7 @@ ghoul::Dictionary WwtCommunicator::setImageOpacityMessage(const std::string& ima
double opacity) const
{
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_set"s);
msg.setValue("id", imageId);
@@ -278,7 +302,7 @@ ghoul::Dictionary WwtCommunicator::setLayerOrderMessage(const std::string& id, i
// The lower the layer order, the more towards the back the image is placed
// 0 is the background
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_order"s);
msg.setValue("id", id);
+4 -2
View File
@@ -42,8 +42,10 @@ void WebBrowserApp::OnContextCreated(CefRefPtr<CefBrowser>, CefRefPtr<CefFrame>,
void WebBrowserApp::OnBeforeCommandLineProcessing(const CefString&,
CefRefPtr<CefCommandLine> commandLine)
{
commandLine->AppendSwitch("use-gl=desktop");
commandLine->AppendSwitch("ignore-gpu-blacklist");
commandLine->AppendSwitch("--enable-gpu-rasterization");
commandLine->AppendSwitch("--use-gl=desktop");
commandLine->AppendSwitch("--enable-webgl2-compute-context");
commandLine->AppendSwitch("ignore-gpu-blocklist");
commandLine->AppendSwitch("log-gpu-control-list-decisions");
commandLine->AppendSwitch("use-mock-keychain");
commandLine->AppendSwitch("enable-begin-frame-scheduling");
-5
View File
@@ -140,11 +140,6 @@ void WebBrowserModule::internalInitialize(const ghoul::Dictionary& dictionary) {
_enabled = dictionary.value<bool>("Enabled");
}
const bool isMaster = global::windowDelegate->isMaster();
if (!_enabled || (!isMaster)) {
return;
}
LDEBUG(fmt::format("CEF using web helper executable: {}", _webHelperLocation));
_cefHost = std::make_unique<CefHost>(_webHelperLocation.string());
LDEBUG("Starting CEF... done!");
+2 -1
View File
@@ -151,6 +151,7 @@ ModuleConfigurations = {
},
Server = {
AllowAddresses = { "127.0.0.1", "localhost" },
SkyBrowserUpdateTime = 50,
Interfaces = {
{
Type = "TcpSocket",
@@ -188,7 +189,7 @@ ModuleConfigurations = {
Space = {
ShowExceptions = false
}
-- OBS! The settings for the SkyBrowser and Exoplanets modules are
-- OBS! The settings for the SkyBrowser and Exoplanets modules are
-- set in individual assets, see "data/assets/modules". Note that
-- any settings addded here might be overwritten by those assets
}
+7 -3
View File
@@ -73,7 +73,7 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo CartesianPositionInfo = {
"CartesianPosition",
"Cartesian coordinates",
"Cartesian Coordinates",
"This value determines the position of this screen space plane in Cartesian "
"three-dimensional coordinates (meters)."
};
@@ -88,7 +88,7 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo ScaleInfo = {
"Scale",
"Scale value",
"Scale Value",
"This value determines a scale factor for the plane. The default size of a plane "
"is determined by the concrete instance and reflects, for example, the size of "
"the image being displayed."
@@ -96,7 +96,7 @@ namespace {
constexpr openspace::properties::Property::PropertyInfo LocalRotationInfo = {
"Rotation",
"Local rotation",
"Local Rotation",
"An euler rotation (x, y, z) to apply to the plane."
};
@@ -436,6 +436,10 @@ float ScreenSpaceRenderable::depth() {
cartesianToSpherical(_cartesianPosition).x;
}
float ScreenSpaceRenderable::scale() const {
return _scale;
}
void ScreenSpaceRenderable::createShaders() {
ghoul::Dictionary dict = ghoul::Dictionary();