From c895f249896f801c204bd750ffd6508abf650380 Mon Sep 17 00:00:00 2001 From: sylvass Date: Mon, 25 Oct 2021 09:38:09 -0400 Subject: [PATCH] Cleanup --- data/assets/skyBrowserTargetPair.asset | 2 +- .../rendering/screenspacerenderable.h | 8 +- .../skybrowser/include/renderableskybrowser.h | 49 +-- .../include/screenspaceskybrowser.h | 105 +++--- .../skybrowser/include/screenspaceskytarget.h | 67 ++-- modules/skybrowser/include/utility.h | 56 ++-- modules/skybrowser/include/wwtdatahandler.h | 50 +-- modules/skybrowser/shaders/target_fs.glsl | 48 +-- modules/skybrowser/skybrowsermodule.cpp | 264 ++++++++------- modules/skybrowser/skybrowsermodule.h | 109 ++++--- modules/skybrowser/skybrowsermodule_lua.inl | 105 +++--- .../skybrowser/src/renderableskybrowser.cpp | 38 +-- .../skybrowser/src/screenspaceskybrowser.cpp | 304 ++++++++++-------- .../skybrowser/src/screenspaceskytarget.cpp | 143 ++++---- modules/skybrowser/src/utility.cpp | 137 ++++---- modules/skybrowser/src/wwtdatahandler.cpp | 161 ++++++---- src/rendering/screenspacerenderable.cpp | 16 +- 17 files changed, 910 insertions(+), 752 deletions(-) diff --git a/data/assets/skyBrowserTargetPair.asset b/data/assets/skyBrowserTargetPair.asset index 6c0d6e33eb..5fde6352b3 100644 --- a/data/assets/skyBrowserTargetPair.asset +++ b/data/assets/skyBrowserTargetPair.asset @@ -11,7 +11,7 @@ local browser = { Name = "Sky Browser", Url = serverUrl, FaceCamera = false, - TargetID = targetId, + TargetId = targetId, CartesianPosition = {-1.0, -0.5, -2.1}, }; diff --git a/include/openspace/rendering/screenspacerenderable.h b/include/openspace/rendering/screenspacerenderable.h index 5e79c90c74..a27de28b34 100644 --- a/include/openspace/rendering/screenspacerenderable.h +++ b/include/openspace/rendering/screenspacerenderable.h @@ -73,10 +73,10 @@ public: // Added by skybrowser team // Screen space functionality in these coords: [-1,1][-ratio,ratio] - glm::vec2 getScreenSpacePosition(); - glm::vec2 getScreenSpaceDimensions(); - glm::vec2 getUpperRightCornerScreenSpace(); - glm::vec2 getLowerLeftCornerScreenSpace(); + glm::vec2 screenSpacePosition(); + glm::vec2 screenSpaceDimensions(); + glm::vec2 upperRightCornerScreenSpace(); + glm::vec2 lowerLeftCornerScreenSpace(); bool coordIsInsideCornersScreenSpace(glm::vec2 coord); void translate(glm::vec2 translation, glm::vec2 position); friend bool operator<(const ScreenSpaceRenderable& lhs, const ScreenSpaceRenderable& rhs); diff --git a/modules/skybrowser/include/renderableskybrowser.h b/modules/skybrowser/include/renderableskybrowser.h index d1fabcd9f0..85daa90142 100644 --- a/modules/skybrowser/include/renderableskybrowser.h +++ b/modules/skybrowser/include/renderableskybrowser.h @@ -47,30 +47,35 @@ namespace openspace { RenderableSkyBrowser(const ghoul::Dictionary& dictionary); virtual ~RenderableSkyBrowser() = default; + // Inherited from RenderablePlane void initializeGL() override; void deinitializeGL() override; - void update(const UpdateData& data) override; + // Web page communication void executeJavascript(std::string script) const; - bool sendMessageToWWT(const ghoul::Dictionary& msg); - void connectToWwt(); - void stopConnectingToWwt(); + void setIdInBrowser(std::string id); + + // WorldWide Telescope communication void displayImage(ImageData& image, int i); void removeSelectedImage(ImageData& image, int i); - void setIdInBrowser(std::string id); - float fieldOfView() const; - std::deque& selectedImages(); + bool sendMessageToWwt(const ghoul::Dictionary& msg); + void syncWwtView(); + void stopSyncingWwtView(); + + // Getters + float verticalFov() const; + std::deque& getSelectedImages(); + + // Setters void setImageLayerOrder(int i, int order, int version); - protected: - - properties::Vec2Property _dimensions; - std::unique_ptr _browserInstance; - std::unique_ptr _texture; - - private: + // Properties + properties::Vec2Property _dimensions; + properties::StringProperty _url; + properties::TriggerProperty _reload; + class ScreenSpaceRenderHandler : public WebRenderHandler { public: void draw() override; @@ -79,23 +84,21 @@ namespace openspace { void setTexture(GLuint t); }; - CefRefPtr _renderHandler; - void bindTexture() override; - properties::StringProperty _url; - - properties::TriggerProperty _reload; - + // Browser variables + std::unique_ptr _browserInstance; + std::unique_ptr _texture; + CefRefPtr _renderHandler; CefRefPtr _keyboardHandler; + // Flags bool _isUrlDirty = false; bool _isDimensionsDirty = false; + bool _syncViewWithWwt; - float _fov; - bool _connectToWwt; + float _verticalFov; std::thread _threadWwtMessages; - std::deque _selectedImages; }; } diff --git a/modules/skybrowser/include/screenspaceskybrowser.h b/modules/skybrowser/include/screenspaceskybrowser.h index 1d7c54ae98..52d716787b 100644 --- a/modules/skybrowser/include/screenspaceskybrowser.h +++ b/modules/skybrowser/include/screenspaceskybrowser.h @@ -13,63 +13,88 @@ namespace openspace { class ScreenSpaceSkyBrowser : public ScreenSpaceBrowser { public: + // Constructor and destructor ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary); virtual ~ScreenSpaceSkyBrowser(); + // Inherited functions bool initializeGL() override; bool deinitializeGL() override; - bool setConnectedTarget(); + glm::mat4 scaleMatrix() override; + + // Target - browser connection + bool connectToSkyTarget(); void initializeBrowser(); - void setIdInBrowser(); + + // Getters returning values + bool hasLoadedImages() const; + glm::vec2 browserPixelDimensions() const; + glm::ivec3 borderColor() const; + float verticalFov() const; - // Communication with the webpage and WWT - void executeJavascript(std::string script) const; - bool sendMessageToWWT(const ghoul::Dictionary& msg); - void WWTfollowCamera(); - float fieldOfView() const; - void setVerticalFieldOfView(float fov); - void scrollZoom(float scroll); + // Getters returning references ScreenSpaceSkyTarget* getSkyTarget(); - bool hasLoadedCollections(); - void setHasLoadedCollections(bool isLoaded); + std::deque& getSelectedImages(); properties::FloatProperty& getOpacity(); - std::deque& selectedImages(); + + // Setters + void setHasLoadedImages(bool isLoaded); + void setVerticalFov(float vfov); + void setVerticalFovWithScroll(float scroll); + void setScale(glm::vec2 scalingFactor); + void setScale(float scalingFactor); + void setWebpageBorderColor(glm::ivec3 color); + + // Communication with the web page + void executeJavascript(std::string script); + void sendIdToBrowser(); + + // Communication with WorldWide Telescope void addSelectedImage(ImageData& image, int i); void removeSelectedImage(ImageData& image, int i); - void setImageLayerOrder(int i, int order, int version); + void setImageOrder(int i, int order, int version); + void sendMessageToWwt(const ghoul::Dictionary& msg); + void syncWwtView(); + + // Mouse interaction with the browser. Returns 1 or -1 at the coordinate in + // image if the mouse is on a side of the browser + // __1__ + // y| -1 |_____|1 + // |__x -1 + glm::vec2 isOnResizeArea(glm::vec2 screenSpaceCoord); + + // Resize functions + void saveResizeStartSize(); + void updateBrowserSize(); // Translation //void translate(glm::vec2 translation); - - // Position and dimension and corners - glm::vec2 getBrowserPixelDimensions(); - glm::vec2 coordIsOnResizeArea(glm::vec2 coord); - // Scaling - void scale(glm::vec2 scalingFactor); - void scale(float scalingFactor); - glm::mat4 scaleMatrix() override; - // Resizing - void saveResizeStartSize(); - void updateBrowserSize(); - void setBorderColor(glm::ivec3 addColor); - glm::ivec3 getColor(); - // Flag for dimensions - bool _browserDimIsDirty; - properties::FloatProperty _vfieldOfView; - properties::StringProperty _skyTargetID; - properties::Vec3Property _borderColor; + private: - glm::vec2 _startDimensionsSize; - float _startScale; + // Properties + properties::FloatProperty _verticalFov; + properties::StringProperty _skyTargetId; properties::Vec2Property _browserDimensions; - bool _camIsSyncedWWT; - ScreenSpaceSkyTarget* _skyTarget; - std::thread _threadWWTMessages; - // For capping the calls to change the zoom from scrolling - constexpr static const std::chrono::milliseconds TimeUpdateInterval{ 10 }; - std::chrono::system_clock::time_point _lastUpdateTime; - bool _hasLoadedCollections{ false }; + properties::Vec3Property _borderColor; + + // Flags + bool _hasLoadedImages{ false }; + bool _syncViewWithWwt{ false }; + + // Resizing of browser + glm::vec2 _originalDimensions; + float _originalScale; + float _resizeAreaPercentage{ 0.1f }; + + // Target & images + ScreenSpaceSkyTarget* _skyTarget{ nullptr }; + std::thread _threadWwtMessages; std::deque _selectedImages; + + // Time variables + // For capping the calls to change the zoom from scrolling + constexpr static const std::chrono::milliseconds _timeUpdateInterval{ 10 }; + std::chrono::system_clock::time_point _lastUpdateTime; }; } diff --git a/modules/skybrowser/include/screenspaceskytarget.h b/modules/skybrowser/include/screenspaceskytarget.h index feac775cb3..49fd66e66f 100644 --- a/modules/skybrowser/include/screenspaceskytarget.h +++ b/modules/skybrowser/include/screenspaceskytarget.h @@ -19,64 +19,77 @@ namespace openspace { class ScreenSpaceSkyTarget : public ScreenSpaceRenderable { public: + // Constructor & destructor ScreenSpaceSkyTarget(const ghoul::Dictionary& dictionary); virtual ~ScreenSpaceSkyTarget(); + // ScreenSpaceRenderable inherited functions bool initializeGL() override; bool isReady() const override; void render() override; glm::mat4 scaleMatrix() override; void bindTexture() override; // Empty function but has to be defined - void createShaders(); - void initializeWithBrowser(); + + // Sky browser functionality + bool findSkyBrowser(); + void matchAppearanceToSkyBrowser(); + + // Getters ScreenSpaceSkyBrowser* getSkyBrowser(); - - void setVerticalFOV(float VFOV); + glm::ivec3 borderColor() const; + float opacity() const; + + // Setters + void setScale(float verticalFov); void setDimensions(glm::vec2 dimensions); void setColor(glm::ivec3 color); - glm::ivec3 getColor(); - properties::FloatProperty& getOpacity(); + void setOpacity(float opacity); // Target directions - glm::dvec3 getTargetDirectionGalactic(); - glm::dvec2 getTargetDirectionCelestial(); + glm::dvec3 targetDirectionGalactic() const; + glm::dvec3 targetDirectionEquatorial() const; // Locking functionality - void unlock(); void lock(); + void unlock(); bool isLocked(); // Animations - void startAnimation(glm::dvec2 coordsEnd, float FOVEnd, bool lockAfterwards = true); - void animateToCoord(double deltaTime); - bool animateToFOV(float endFOV, float deltaTime); + void startAnimation(glm::dvec3 coordsEnd, float FOVEnd, bool lockAfter = true); + void animateToCoordinate(double deltaTime); + bool animateToFov(float endFOV, float deltaTime); - properties::StringProperty _skyBrowserID; + private: + // Properties + properties::StringProperty _skyBrowserId; properties::FloatProperty _showCrosshairThreshold; properties::FloatProperty _showRectangleThreshold; - private: + // Flags + bool _isAnimated{ false }; + bool _lockAfterAnimation{ false }; + bool _isLocked{ false }; + // Shader UniformCache(modelTransform, viewProj, showCrosshair, showRectangle, lineWidth, dimensions, lineColor) _uniformCache; GLuint _vertexArray = 0; GLuint _vertexBuffer = 0; - glm::ivec3 _color; - float _verticalFOV = 100.f; - ScreenSpaceSkyBrowser* _skyBrowser; - // Locking target to a coordinate on the sky - bool _isLocked; - glm::dvec2 _lockedCoords; // Spherical celestial coords - std::thread _lockTargetThread; + // Sky browser + ScreenSpaceSkyBrowser* _skyBrowser; + glm::ivec3 _color; + + // Lock target to a coordinate on the sky + glm::dvec3 _lockedCoordinates; // Spherical celestial coordinates + std::thread _lockTarget; - // Animating the target - bool _isAnimated = false; - glm::dvec3 _coordsEndAnimation; // Cartesian celestial coords - glm::dvec3 _coordsStartAnimation; // Cartesian celestial coords + // Animation of target + glm::dvec3 _animationEnd; // Cartesian celestial coordinates + glm::dvec3 _animationStart; // Cartesian celestial coordinates double _animationTime = 1.0; - float _FOVEndAnimation; - bool _lockAfterAnimation; + float _vfovEndAnimation; + }; } diff --git a/modules/skybrowser/include/utility.h b/modules/skybrowser/include/utility.h index f12998a09d..32069a701f 100644 --- a/modules/skybrowser/include/utility.h +++ b/modules/skybrowser/include/utility.h @@ -10,45 +10,49 @@ namespace openspace { namespace skybrowser { - const double SCREENSPACE_Z = -2.1; - const double RAD_TO_DEG = 180.0 / M_PI; - const double DEG_TO_RAD = M_PI / 180.0; - const glm::dvec3 NORTH_POLE = { 0.0 , 0.0 , 1.0 }; - constexpr double infinity = std::numeric_limits::max(); + // Constants + constexpr const double ScreenSpaceZ = -2.1; + constexpr const glm::dvec3 NorthPole = { 0.0 , 0.0 , 1.0 }; + constexpr const double CelestialSphereRadius = std::numeric_limits::max(); - // Conversion matrix from this paper: https://arxiv.org/abs/1010.3773v1 + // Conversion matrix - J2000 equatorial <-> galactic + // https://arxiv.org/abs/1010.3773v1 const glm::dmat3 conversionMatrix = glm::dmat3({ -0.054875539390, 0.494109453633, -0.867666135681, // col 0 -0.873437104725, -0.444829594298, -0.198076389622, // col 1 -0.483834991775, 0.746982248696, 0.455983794523 // col 2 }); - // J2000 to galactic conversion and vice versa - glm::dvec2 cartesianToSpherical(glm::dvec3 cartesianCoords); - glm::dvec3 sphericalToCartesian(glm::dvec2 sphericalCoords); - glm::dvec3 galacticCartesianToJ2000Cartesian(glm::dvec3 rGal); - glm::dvec2 galacticCartesianToJ2000Spherical(glm::dvec3 rGal); - glm::dvec3 galacticCartesianToCameraLocalCartesian(glm::dvec3 galCoords); - glm::dvec3 J2000SphericalToGalacticCartesian(glm::dvec2 coords, - double distance = infinity); - glm::dvec3 J2000CartesianToGalacticCartesian(glm::dvec3 coords, - double distance = infinity); - // Convert J2000, spherical or Cartesian, to screen space - glm::dvec3 J2000SphericalToScreenSpace(glm::dvec2 coords); - glm::dvec3 J2000CartesianToScreenSpace(glm::dvec3 coords); - glm::dvec3 galacticToScreenSpace(glm::dvec3 galacticCoord); - double calculateRoll(glm::dvec3 upWorld, glm::dvec3 forwardWorld); - glm::dvec3 cameraDirectionJ2000Cartesian(); + // Conversion spherical <-> Cartesian + glm::dvec2 cartesianToSpherical(glm::dvec3 coords); + glm::dvec3 sphericalToCartesian(glm::dvec2 coords); + + // Conversion J2000 equatorial <-> galactic + glm::dvec3 galacticToEquatorial(glm::dvec3 coords); + glm::dvec3 galacticToCameraLocal(glm::dvec3 coords); + glm::dvec3 equatorialToGalactic(glm::dvec3 coords); + + // Conversion J2000 equatorial / galactic <-> screen space + glm::dvec3 equatorialToScreenSpace(glm::dvec3 coords); + glm::dvec3 galacticToScreenSpace(glm::dvec3 coords); + glm::dvec3 screenSpaceToGalactic(glm::dvec3 coords); + glm::dvec3 screenSpaceToEquatorial(glm::dvec3 coords); + + // Camera roll and direction + // Camera roll is with respect to the equatorial North Pole + double cameraRoll(); + glm::dvec3 cameraDirectionGalactic(); + glm::dvec3 cameraDirectionEquatorial(); } + // WorldWide Telescope messages namespace wwtmessage { - // WWT messages ghoul::Dictionary moveCamera(const glm::dvec2 celestCoords, const double fov, const double roll, const bool moveInstantly = true); ghoul::Dictionary loadCollection(const std::string& url); ghoul::Dictionary setForeground(const std::string& name); - ghoul::Dictionary createImageLayer(const std::string& id, const std::string& url); - ghoul::Dictionary removeImageLayer(const std::string& id); - ghoul::Dictionary setLayerOpacity(const std::string& id, double opacity); + ghoul::Dictionary addImage(const std::string& id, const std::string& url); + ghoul::Dictionary removeImage(const std::string& id); + ghoul::Dictionary setImageOpacity(const std::string& id, double opacity); ghoul::Dictionary setForegroundOpacity(double val); ghoul::Dictionary setLayerOrder(const std::string& id, int order, int version); } diff --git a/modules/skybrowser/include/wwtdatahandler.h b/modules/skybrowser/include/wwtdatahandler.h index 8d078cd804..45ab0a7a6e 100644 --- a/modules/skybrowser/include/wwtdatahandler.h +++ b/modules/skybrowser/include/wwtdatahandler.h @@ -57,12 +57,12 @@ namespace openspace { std::string name; std::string thumbnailUrl; std::string imageUrl; - std::string credits; std::string creditsUrl; - glm::dvec2 celestCoords; + std::string credits; + glm::dvec2 celestialCoords; std::string collection; float fov; - bool hasCelestCoords{ false }; + bool hasCelestialCoords{ false }; bool has3dCoords{ false }; glm::dvec3 position3d; }; @@ -73,24 +73,31 @@ namespace openspace { bool loaded = false; }; - class WWTDataHandler { + class WwtDataHandler { public: - WWTDataHandler() = default; - ~WWTDataHandler(); - // Image downloading and xml parsing - bool downloadFile(std::string& url, std::string& fileDestination); - void loadWTMLCollectionsFromURL(std::string directory, std::string url, std::string fileName); - bool loadWTMLCollectionsFromDirectory(std::string directory); - int loadImagesFromLoadedXMLs(); + // Constructor and destructor + WwtDataHandler() = default; + ~WwtDataHandler(); + // Image downloading and xml parsing + bool loadWtmlCollectionsFromUrl(std::string directory, std::string url, + std::string fileName); + bool loadWtmlCollectionsFromDirectory(std::string directory); + int loadImagesFromLoadedXmls(); + + // Loading speck files + void loadSpeckData(speck::Dataset& dataset); + + // Getters const std::vector& getAllImageCollectionUrls() const; std::vector& getLoadedImages(); - void loadSpeckData(speck::Dataset& dataset); - std::string createSearchableString(std::string name); private: - void loadImagesFromXML(tinyxml2::XMLElement* node, + + // Parsing and downloading of wtml files + bool downloadFile(std::string& url, std::string& fileDestination); + void loadImagesFromXml(tinyxml2::XMLElement* node, std::string collectionName); int loadImageFromXmlNode(tinyxml2::XMLElement* imageSet, std::string collectionName); @@ -105,17 +112,22 @@ namespace openspace { std::string getChildNodeContentFromImageSet(tinyxml2::XMLElement* imageSet, std::string elementName); - std::string getURLFromPlace(tinyxml2::XMLElement* place); + std::string getUrlFromPlace(tinyxml2::XMLElement* place); tinyxml2::XMLElement* getDirectChildNode(tinyxml2::XMLElement* node, std::string name); tinyxml2::XMLElement* getChildNode(tinyxml2::XMLElement* node, std::string name); - std::vector images; - std::vector imageUrls; - std::vector xmls; + // Used for matching names + std::string createSearchableString(std::string name); + + // Images + std::vector _images; + std::vector _imageUrls; + std::vector _xmls; + // 3D position data loaded from speck files std::unordered_map _3dPositions; - int nImagesWith3dPositions = 0; + int _nImagesWith3dPositions = 0; }; } diff --git a/modules/skybrowser/shaders/target_fs.glsl b/modules/skybrowser/shaders/target_fs.glsl index fea8daa875..ee7d042cd6 100644 --- a/modules/skybrowser/shaders/target_fs.glsl +++ b/modules/skybrowser/shaders/target_fs.glsl @@ -11,45 +11,45 @@ in vec4 vs_position; // This compensates for the optical illusion that vertical lines appear thinner #define VERTICAL_THICKNESS 1.15f -float line(in float _lineCenter, in float _lineWidth, in float _coord) { +float createLine(in float lineCenter, in float lineWidth, in float coord) { // Calculate edges of line - float start_edge = _lineCenter - (_lineWidth * 0.5f); - float end_edge = _lineCenter + (_lineWidth * 0.5f); + float start_edge = lineCenter - (lineWidth * 0.5f); + float end_edge = lineCenter + (lineWidth * 0.5f); // Create line - float line = step(start_edge, _coord) - step(end_edge, _coord); + float line = step(start_edge, coord) - step(end_edge, coord); return line; } -float rectangle(in float _linewidth_y, in float _ratio, in vec2 _coord) { +float createRectangle(in float linewidth_y, in float ratio, in vec2 coord) { // Calculate the widths and centers for the lines - float linewidth_x = _linewidth_y * _ratio * VERTICAL_THICKNESS; + float linewidth_x = linewidth_y * ratio * VERTICAL_THICKNESS; float linecenter_x = linewidth_x * 0.5f; - float linecenter_y = _linewidth_y * 0.5f; + float linecenter_y = linewidth_y * 0.5f; // Create the four lines for the rectangle - float l = line(linecenter_x, linewidth_x, _coord.x); - float r = line(1.0f - linecenter_x, linewidth_x, _coord.x); - float b = line(linecenter_y, _linewidth_y, _coord.y); - float t = line(1.0f - linecenter_y, _linewidth_y, _coord.y); + float l = createLine(linecenter_x, linewidth_x, coord.x); + float r = createLine(1.0f - linecenter_x, linewidth_x, coord.x); + float b = createLine(linecenter_y, linewidth_y, coord.y); + float t = createLine(1.0f - linecenter_y, linewidth_y, coord.y); // Add all lines together return l + r + b + t; } -float crosshair(in float _linewidth, in float _ratio, in vec2 _coord) { +float createCrosshair(in float linewidth, in float ratio, in vec2 coord) { float center = 0.5f; - float crosshair_vertical = line(center, _linewidth * _ratio * VERTICAL_THICKNESS, _coord.x); - float crosshair_horizontal = line(center, _linewidth, _coord.y); + float crosshair_vertical = createLine(center, linewidth * ratio * VERTICAL_THICKNESS, coord.x); + float crosshair_horizontal = createLine(center, linewidth, coord.y); return crosshair_horizontal + crosshair_vertical; } -float filledRectangle(in float _size, in float _ratio, in vec2 _coord) { +float createFilledRectangle(in float size, in float ratio, in vec2 coord) { float center = 0.5f; - float horizontal = line(center, _size, _coord.y); - float vertical = line(center, _size, _coord.x); + float horizontal = createLine(center, size, coord.y); + float vertical = createLine(center, size, coord.x); return horizontal * vertical; } @@ -57,24 +57,24 @@ float filledRectangle(in float _size, in float _ratio, in vec2 _coord) { #include "fragment.glsl" Fragment getFragment() { - float _ratio = dimensions.y / dimensions.x; - float _crosshair = 0.0f; - float _rectangle = 0.0f; + float ratio = dimensions.y / dimensions.x; + float crosshair = 0.0f; + float rectangle = 0.0f; if(showCrosshair) { - _crosshair = crosshair(lineWidth, _ratio, vs_st); + crosshair = createCrosshair(lineWidth, ratio, vs_st); } if(showRectangle) { - _rectangle = rectangle(lineWidth, _ratio, vs_st); + rectangle = createRectangle(lineWidth, ratio, vs_st); } // If both rectangle and crosshair are displayed, draw crosshair a bit smaller if(showCrosshair && showRectangle) { - _crosshair *= filledRectangle(lineWidth * 7.0f, _ratio, vs_st); + crosshair *= createFilledRectangle(lineWidth * 7.0f, ratio, vs_st); } - float result = clamp(_crosshair + _rectangle, 0.0, 1.0); + float result = clamp(crosshair + rectangle, 0.0, 1.0); Fragment frag; frag.color = lineColor; diff --git a/modules/skybrowser/skybrowsermodule.cpp b/modules/skybrowser/skybrowsermodule.cpp index 051279182a..4c3bf15d95 100644 --- a/modules/skybrowser/skybrowsermodule.cpp +++ b/modules/skybrowser/skybrowsermodule.cpp @@ -247,34 +247,37 @@ namespace openspace { return res; } +// Transforms a pixel coordinate to a screen space coordinate +glm::vec2 pixelToScreenSpace(glm::vec2& mouseCoordinate) { + glm::vec2 size = global::windowDelegate->currentWindowSize(); + // Change origin to middle of the window + glm::vec2 screenSpacePos = glm::vec2((mouseCoordinate - (size / 2.0f))); + // Ensure the upper right corner is positive on the y axis + screenSpacePos *= glm::vec2(1.0f, -1.0f); + // Transform pixel coordinates to screen space coordinates [-1,1][-ratio, ratio] + screenSpacePos /= (0.5f * size.y); + return screenSpacePos; +} + SkyBrowserModule::SkyBrowserModule() : OpenSpaceModule(SkyBrowserModule::Name) - , _mouseOnObject(nullptr) - , currentlyResizingBrowser(false) - , currentlyDraggingObject(false) - , resizeVector(0.f, 0.f) - , changeViewWithinBrowser(false) - , _browser3d(nullptr) - , _layerOrderCounter(0) - , _cameraInSolarSystem(true) - , highlightAddition(35, 35, 35) { global::callback::mousePosition->emplace_back( [&](double x, double y) { - glm::vec2 pos = glm::vec2(static_cast(x), static_cast(y)); - _mousePosition = getMousePositionInScreenSpaceCoords(pos); + glm::vec2 pixel = glm::vec2(static_cast(x), static_cast(y)); + _mousePosition = pixelToScreenSpace(pixel); - if (currentlyDraggingObject) { + if (_isDragging) { - glm::dvec2 move = _mousePosition - startDragMousePos; + glm::dvec2 move = _mousePosition - _startMousePosition; - // Change view within the browser and move target accordingly to mousedrag movement - if (changeViewWithinBrowser) { + // Change view within the browser and move target accordingly to mouse drag movement + if (_fineTuneMode) { // WWT FOV - double WWTVerticalFOV = to_browser(_mouseOnObject)->fieldOfView(); - glm::dvec2 browserDim = to_browser(_mouseOnObject)->getScreenSpaceDimensions(); + double WWTVerticalFOV = toBrowser(_mouseOnObject)->verticalFov(); + glm::dvec2 browserDim = toBrowser(_mouseOnObject)->screenSpaceDimensions(); double browserRatio = browserDim.x / browserDim.y; glm::dvec2 WWTFOV = glm::dvec2(WWTVerticalFOV * browserRatio, WWTVerticalFOV); @@ -291,24 +294,24 @@ SkyBrowserModule::SkyBrowserModule() glm::dvec2 screenSpaceCoord{ (2 / windowRatio), 2.f }; glm::dvec2 result = screenSpaceCoord * OSresult; - to_browser(_mouseOnObject)->getSkyTarget()->translate(-result, startDragObjectPos); + toBrowser(_mouseOnObject)->getSkyTarget()->translate(-result, _startDragPosition); } // Move browser or target - else _mouseOnObject->translate(move, startDragObjectPos); + else _mouseOnObject->translate(move, _startDragPosition); } - else if (currentlyResizingBrowser) { + else if (_isResizing) { // Calculate scaling factor - glm::vec2 mouseDragVector = (_mousePosition - startDragMousePos); - glm::vec2 scalingVector = mouseDragVector * resizeVector; - glm::vec2 newSizeRelToOld = (startResizeBrowserSize + (scalingVector)) / startResizeBrowserSize; + glm::vec2 mouseDragVector = (_mousePosition - _startMousePosition); + glm::vec2 scalingVector = mouseDragVector * _resizeDirection; + glm::vec2 newSizeRelToOld = (_startBrowserSize + (scalingVector)) / _startBrowserSize; // Scale the browser - to_browser(_mouseOnObject)->scale(newSizeRelToOld); + toBrowser(_mouseOnObject)->setScale(newSizeRelToOld); // For dragging functionality, translate so it looks like the browser isn't moving // Make sure the browser doesn't move in directions it's not supposed to - _mouseOnObject->translate(mouseDragVector * abs(resizeVector) / 2.f, startDragObjectPos); + _mouseOnObject->translate(mouseDragVector * abs(_resizeDirection) / 2.f, _startDragPosition); } // If there is no dragging or resizing, look for new objects else { @@ -316,27 +319,27 @@ SkyBrowserModule::SkyBrowserModule() ScreenSpaceRenderable* lastObj = _mouseOnObject; // Find and save what mouse is currently hovering on - auto currentlyOnObject = std::find_if(renderables.begin(), renderables.end(), [&](ScreenSpaceRenderable* obj) { + auto currentlyOnObject = std::find_if(_renderables.begin(), _renderables.end(), [&](ScreenSpaceRenderable* obj) { return obj && (obj->coordIsInsideCornersScreenSpace(_mousePosition) && obj->isEnabled()); }); - _mouseOnObject = currentlyOnObject != renderables.end() ? *currentlyOnObject : nullptr; + _mouseOnObject = currentlyOnObject != _renderables.end() ? *currentlyOnObject : nullptr; // Selection has changed if (lastObj != _mouseOnObject) { // Remove highlight - if (to_browser(lastObj)) { - to_browser(lastObj)->setBorderColor(to_browser(lastObj)->getColor() - highlightAddition); + if (toBrowser(lastObj)) { + toBrowser(lastObj)->setWebpageBorderColor(toBrowser(lastObj)->borderColor() - _highlightAddition); } - else if (to_target(lastObj)) { - to_target(lastObj)->setColor(to_target(lastObj)->getColor() - highlightAddition); + else if (toTarget(lastObj)) { + toTarget(lastObj)->setColor(toTarget(lastObj)->borderColor() - _highlightAddition); } // Add highlight - if (to_browser(_mouseOnObject)) { - to_browser(_mouseOnObject)->setBorderColor(to_browser(_mouseOnObject)->getColor() + highlightAddition); + if (toBrowser(_mouseOnObject)) { + toBrowser(_mouseOnObject)->setWebpageBorderColor(toBrowser(_mouseOnObject)->borderColor() + _highlightAddition); } - else if (to_target(_mouseOnObject)) { - to_target(_mouseOnObject)->setColor(to_target(_mouseOnObject)->getColor() + highlightAddition); + else if (toTarget(_mouseOnObject)) { + toTarget(_mouseOnObject)->setColor(toTarget(_mouseOnObject)->borderColor() + _highlightAddition); } } @@ -348,12 +351,12 @@ SkyBrowserModule::SkyBrowserModule() [&](double, double scroll) -> bool { // If mouse is on browser or target, apply zoom - if (to_browser(_mouseOnObject)) { - to_browser(_mouseOnObject)->scrollZoom(static_cast(scroll)); + if (toBrowser(_mouseOnObject)) { + toBrowser(_mouseOnObject)->setVerticalFovWithScroll(static_cast(scroll)); return true; } - else if (to_target(_mouseOnObject) && to_target(_mouseOnObject)->getSkyBrowser()) { - to_target(_mouseOnObject)->getSkyBrowser()->scrollZoom(static_cast(scroll)); + else if (toTarget(_mouseOnObject) && toTarget(_mouseOnObject)->getSkyBrowser()) { + toTarget(_mouseOnObject)->getSkyBrowser()->setVerticalFovWithScroll(static_cast(scroll)); } return false; @@ -366,62 +369,62 @@ SkyBrowserModule::SkyBrowserModule() if (_mouseOnObject && action == MouseAction::Press) { // Get the currently selected browser - if (to_browser(_mouseOnObject)) { - setSelectedBrowser(to_browser(_mouseOnObject)); + if (toBrowser(_mouseOnObject)) { + setSelectedBrowser(toBrowser(_mouseOnObject)); } - else if (to_target(_mouseOnObject) && - to_target(_mouseOnObject)->getSkyBrowser()) { + else if (toTarget(_mouseOnObject) && + toTarget(_mouseOnObject)->getSkyBrowser()) { - setSelectedBrowser(to_target(_mouseOnObject)->getSkyBrowser()); + setSelectedBrowser(toTarget(_mouseOnObject)->getSkyBrowser()); } if (button == MouseButton::Left) { - isRotating = false; - startDragMousePos = _mousePosition; - startDragObjectPos = _mouseOnObject->getScreenSpacePosition(); + _isRotating = false; + _startMousePosition = _mousePosition; + _startDragPosition = _mouseOnObject->screenSpacePosition(); // If current object is browser, check for resizing - if (to_browser(_mouseOnObject)) { + if (toBrowser(_mouseOnObject)) { // Resize browser if mouse is over resize button - resizeVector = to_browser(_mouseOnObject)->coordIsOnResizeArea(_mousePosition); - if (resizeVector != glm::vec2{ 0 }) { - to_browser(_mouseOnObject)->saveResizeStartSize(); - startResizeBrowserSize = to_browser(_mouseOnObject)->getScreenSpaceDimensions(); - currentlyResizingBrowser = true; + _resizeDirection = toBrowser(_mouseOnObject)->isOnResizeArea(_mousePosition); + if (_resizeDirection != glm::vec2{ 0 }) { + toBrowser(_mouseOnObject)->saveResizeStartSize(); + _startBrowserSize = toBrowser(_mouseOnObject)->screenSpaceDimensions(); + _isResizing = true; return true; } } // If you start dragging around the target, it should unlock - if (to_target(_mouseOnObject)) { - to_target(_mouseOnObject)->unlock(); + if (toTarget(_mouseOnObject)) { + toTarget(_mouseOnObject)->unlock(); } - currentlyDraggingObject = true; + _isDragging = true; return true; } - else if (to_browser(_mouseOnObject) && button == MouseButton::Right) { + else if (toBrowser(_mouseOnObject) && button == MouseButton::Right) { // If you start dragging around on the browser, the target should unlock - if (to_browser(_mouseOnObject) && to_browser(_mouseOnObject)->getSkyTarget()) { - to_browser(_mouseOnObject)->getSkyTarget()->unlock(); + if (toBrowser(_mouseOnObject) && toBrowser(_mouseOnObject)->getSkyTarget()) { + toBrowser(_mouseOnObject)->getSkyTarget()->unlock(); } // Change view (by moving target) within browser if right mouse click on browser - startDragMousePos = _mousePosition; - startDragObjectPos = to_browser(_mouseOnObject)->getSkyTarget()->getScreenSpacePosition(); - changeViewWithinBrowser = true; - currentlyDraggingObject = true; + _startMousePosition = _mousePosition; + _startDragPosition = toBrowser(_mouseOnObject)->getSkyTarget()->screenSpacePosition(); + _fineTuneMode = true; + _isDragging = true; return true; } } else if (action == MouseAction::Release) { - if (currentlyDraggingObject) { - currentlyDraggingObject = false; - changeViewWithinBrowser = false; + if (_isDragging) { + _isDragging = false; + _fineTuneMode = false; return true; } - if (currentlyResizingBrowser) { - currentlyResizingBrowser = false; - to_browser(_mouseOnObject)->updateBrowserSize(); + if (_isResizing) { + _isResizing = false; + toBrowser(_mouseOnObject)->updateBrowserSize(); return true; } } @@ -440,7 +443,7 @@ SkyBrowserModule::SkyBrowserModule() double deltaTime = global::windowDelegate->deltaTime(); // Fade out or in browser & target - for (std::pair pair : browsers) { + for (std::pair pair : _browsers) { ScreenSpaceSkyBrowser* browser = pair.second; // If outside solar system and browser is visible if (!_cameraInSolarSystem && browser->isEnabled()) { @@ -450,7 +453,7 @@ SkyBrowserModule::SkyBrowserModule() browser->property("Enabled")->set(false); // Select the 3D browser when moving out of the solar system if (_browser3d != nullptr) { - selectedBrowser = _browser3d->renderable()->identifier(); + _selectedBrowser = _browser3d->renderable()->identifier(); } } } @@ -458,8 +461,8 @@ SkyBrowserModule::SkyBrowserModule() else if (_cameraInSolarSystem && !browser->isEnabled()) { browser->property("Enabled")->set(true); // Select the first 2D browser when moving into the solar system - if (browsers.size() != 0) { - selectedBrowser = std::begin(browsers)->second->identifier(); + if (_browsers.size() != 0) { + _selectedBrowser = std::begin(_browsers)->second->identifier(); } } // If within solar system and browser is visible @@ -467,18 +470,18 @@ SkyBrowserModule::SkyBrowserModule() fadeBrowserAndTarget(false, fadingTime, deltaTime); if (browser->getSkyTarget()) { - browser->getSkyTarget()->animateToCoord(deltaTime); + browser->getSkyTarget()->animateToCoordinate(deltaTime); } } } - if (isRotating) { + if (_isRotating) { rotateCamera(deltaTime); } }); } SkyBrowserModule::~SkyBrowserModule() { - delete dataHandler; + delete _dataHandler; } void SkyBrowserModule::internalDeinitialize() { @@ -502,37 +505,26 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) { fRenderable->registerClass("RenderableSkyBrowser"); // Create data handler dynamically to avoid the linking error that // came up when including the include file in the module header file - dataHandler = new WWTDataHandler(); + _dataHandler = new WwtDataHandler(); } -glm::vec2 SkyBrowserModule::getMousePositionInScreenSpaceCoords(glm::vec2& mousePos) { - glm::vec2 size = global::windowDelegate->currentWindowSize(); - // Change origin to middle of the window - glm::vec2 screenSpacePos = glm::vec2((mousePos - (size / 2.0f))); - // Ensure the upper right corner is positive on the y axis - screenSpacePos *= glm::vec2(1.0f, -1.0f); - // Transform pixel coordinates to screen space coordinates [-1,1][-ratio, ratio] - screenSpacePos /= (0.5f*size.y); - return screenSpacePos; -} - -int SkyBrowserModule::getAndIncrementLayerOrder() { - return _layerOrderCounter++; +int SkyBrowserModule::getAndIncrementMessageOrder() { + return _messageOrder++; } void SkyBrowserModule::addRenderable(ScreenSpaceRenderable* object) { - renderables.push_back(object); + _renderables.push_back(object); // Sort on z coordinate, objects closer to camera are in beginning of list - std::sort(renderables.begin(), renderables.end()); - ScreenSpaceSkyBrowser* browser = to_browser(object); + std::sort(_renderables.begin(), _renderables.end()); + ScreenSpaceSkyBrowser* browser = toBrowser(object); if (browser) { - browsers[browser->identifier()] = browser; + _browsers[browser->identifier()] = browser; } } bool SkyBrowserModule::browserIdExists(std::string id) { // If the id doesn't exist, return false - if (browsers.find(id) == browsers.end()) { + if (_browsers.find(id) == _browsers.end()) { return false; } return true; @@ -605,7 +597,7 @@ void SkyBrowserModule::createTargetBrowserPair() { void SkyBrowserModule::removeTargetBrowserPair(std::string& browserId) { if (!browserIdExists(browserId)) return; - ScreenSpaceSkyBrowser* browser = browsers[browserId]; + ScreenSpaceSkyBrowser* browser = _browsers[browserId]; // Find corresponding target std::string targetId{ "" }; @@ -614,10 +606,10 @@ void SkyBrowserModule::removeTargetBrowserPair(std::string& browserId) { targetId = browser->getSkyTarget()->identifier(); } // Remove pointer to the renderable from browsers vector - browsers.erase(browserId); + _browsers.erase(browserId); // Remove pointer to the renderable from screenspace renderable vector - renderables.erase(std::remove_if(std::begin(renderables), std::end(renderables), + _renderables.erase(std::remove_if(std::begin(_renderables), std::end(_renderables), [&](ScreenSpaceRenderable* renderable) { if (renderable->identifier() == browserId) { return true; @@ -628,7 +620,7 @@ void SkyBrowserModule::removeTargetBrowserPair(std::string& browserId) { else { return false; } - }), std::end(renderables)); + }), std::end(_renderables)); // Remove from engine openspace::global::scriptEngine->queueScript( "openspace.removeScreenSpaceRenderable('" + browserId + "');", @@ -661,7 +653,7 @@ void SkyBrowserModule::place3dBrowser(ImageData& image) { // /_| Adjacent is the horizontal line, opposite the vertical // \ | Calculate for half the triangle first, then multiply with 2 // \| - glm::dvec3 j2000 = skybrowser::galacticCartesianToJ2000Cartesian(position); + glm::dvec3 j2000 = skybrowser::galacticToEquatorial(position); double adjacent = glm::length(j2000); double opposite = 2 * adjacent * glm::tan(glm::radians(image.fov * 0.5)); @@ -698,23 +690,23 @@ void SkyBrowserModule::set3dBrowser(SceneGraphNode* node) { _browser3d = node; } -ScreenSpaceSkyBrowser* SkyBrowserModule::to_browser(ScreenSpaceRenderable* ptr) { +ScreenSpaceSkyBrowser* SkyBrowserModule::toBrowser(ScreenSpaceRenderable* ptr) { return dynamic_cast(ptr); } -ScreenSpaceSkyTarget* SkyBrowserModule::to_target(ScreenSpaceRenderable* ptr) { +ScreenSpaceSkyTarget* SkyBrowserModule::toTarget(ScreenSpaceRenderable* ptr) { return dynamic_cast(ptr); } -WWTDataHandler* SkyBrowserModule::getWWTDataHandler() { - return dataHandler; +WwtDataHandler* SkyBrowserModule::getWWTDataHandler() { + return _dataHandler; } std::map& SkyBrowserModule::getSkyBrowsers() { - return browsers; + return _browsers; } std::vector& SkyBrowserModule::getBrowsersAndTargets() { - return renderables; + return _renderables; } SceneGraphNode* SkyBrowserModule::get3dBrowser() { @@ -738,35 +730,32 @@ void SkyBrowserModule::lookAt3dBrowser() { ); } -void SkyBrowserModule::startRotation(glm::dvec2 coordsEnd) { - +void SkyBrowserModule::startRotation(glm::dvec3 endAnimation) { // Save coordinates to rotate to in galactic world coordinates - glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); - _coordsToAnimateTo = skybrowser::J2000SphericalToGalacticCartesian(coordsEnd); - _coordsStartAnimation = (global::navigationHandler->camera()->viewDirectionWorldSpace() * skybrowser::infinity) + camPos; - isRotating = true; + _endAnimation = endAnimation; + _startAnimation = skybrowser::cameraDirectionGalactic(); + _isRotating = true; } void SkyBrowserModule::rotateCamera(double deltaTime) { // Find smallest angle between the two vectors - double smallestAngle = std::acos(glm::dot(_coordsStartAnimation, _coordsToAnimateTo) / (glm::length(_coordsStartAnimation) * glm::length(_coordsToAnimateTo))); + double smallestAngle = std::acos(glm::dot(_startAnimation, _endAnimation) / (glm::length(_startAnimation) * glm::length(_endAnimation))); // Only keep animating when target is not at final position if (abs(smallestAngle) > 0.0001) { // Calculate rotation this frame double rotationAngle = smallestAngle * deltaTime; // Create the rotation matrix for local camera space - glm::dvec3 rotationAxis = glm::normalize(glm::cross(_coordsStartAnimation, _coordsToAnimateTo)); + glm::dvec3 rotationAxis = glm::normalize(glm::cross(_startAnimation, _endAnimation)); glm::dmat4 rotmat = glm::rotate(rotationAngle, rotationAxis); // Rotate global::navigationHandler->camera()->rotate(glm::quat_cast(rotmat)); // Update camera direction - glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); - _coordsStartAnimation = (global::navigationHandler->camera()->viewDirectionWorldSpace() * skybrowser::infinity) + camPos; + _startAnimation = skybrowser::cameraDirectionGalactic(); } else { - isRotating = false; + _isRotating = false; } } @@ -780,17 +769,18 @@ bool SkyBrowserModule::fadeBrowserAndTarget(bool makeTransparent, double fadeTim opacityDelta *= -1.f; } bool finished = true; - for (std::pair idAndBrowser : browsers) { + for (std::pair idAndBrowser : _browsers) { ScreenSpaceSkyBrowser* browser = idAndBrowser.second; // If there is a target, fade it as well. Otherwise, skip ScreenSpaceSkyTarget* target = browser->getSkyTarget(); bool targetFinished = true; if (target) { - target->getOpacity() = target->getOpacity().value() + opacityDelta; - float opacityTarget = abs(target->getOpacity().value()); + target->setOpacity(target->opacity() + opacityDelta); + float opacityTarget = abs(target->opacity()); targetFinished = makeTransparent ? opacityTarget < lowThreshold : opacityTarget > highTreshold; if (targetFinished) { - target->getOpacity() = makeTransparent ? transparent : opaque; + float newOpacity = makeTransparent ? transparent : opaque; + target->setOpacity(newOpacity); } } // Keep fading the browsers until all are finished @@ -809,16 +799,16 @@ bool SkyBrowserModule::fadeBrowserAndTarget(bool makeTransparent, double fadeTim void SkyBrowserModule::setSelectedBrowser(ScreenSpaceSkyBrowser* browser) { if (browser) { - selectedBrowser = browser->identifier(); + _selectedBrowser = browser->identifier(); } } void SkyBrowserModule::setSelectedBrowser(std::string id) { - selectedBrowser = id; + _selectedBrowser = id; } std::string SkyBrowserModule::selectedBrowserId() { - return selectedBrowser; + return _selectedBrowser; } int SkyBrowserModule::loadImages(const std::string& root, const std::string& directory) { @@ -830,13 +820,13 @@ int SkyBrowserModule::loadImages(const std::string& root, const std::string& dir speck::Dataset speckGlobularClusters = speck::loadSpeckFile(globularClusters); speck::Dataset speckOpenClusters = speck::loadSpeckFile(openClusters); - dataHandler->loadSpeckData(speckGlobularClusters); - dataHandler->loadSpeckData(speckOpenClusters); + _dataHandler->loadSpeckData(speckGlobularClusters); + _dataHandler->loadSpeckData(speckOpenClusters); int nLoadedImages; // Read from disc - bool loadedImages = dataHandler->loadWTMLCollectionsFromDirectory(directory); + bool loadedImages = _dataHandler->loadWtmlCollectionsFromDirectory(directory); // Reading from url if there is no directory if (loadedImages) { @@ -844,10 +834,10 @@ int SkyBrowserModule::loadImages(const std::string& root, const std::string& dir } else { LINFO("Loading images from url"); - dataHandler->loadWTMLCollectionsFromURL(directory, root, "root"); + _dataHandler->loadWtmlCollectionsFromUrl(directory, root, "root"); } - nLoadedImages = dataHandler->loadImagesFromLoadedXMLs(); + nLoadedImages = _dataHandler->loadImagesFromLoadedXmls(); LINFO("Loaded " + std::to_string(nLoadedImages) + " WorldWide Telescope images."); return nLoadedImages; @@ -856,12 +846,12 @@ int SkyBrowserModule::loadImages(const std::string& root, const std::string& dir bool SkyBrowserModule::cameraInSolarSystem() { return _cameraInSolarSystem; } -/* -std::vector SkyBrowserModule::documentations() const { - return { - ExoplanetsDataPreparationTask::documentation(), - RenderableOrbitDisc::Documentation() - }; -} -*/ + +//std::vector SkyBrowserModule::documentations() const { +// return { +// ExoplanetsDataPreparationTask::documentation(), +// RenderableOrbitDisc::Documentation() +// }; +//} + } // namespace openspace diff --git a/modules/skybrowser/skybrowsermodule.h b/modules/skybrowser/skybrowsermodule.h index a193624bf4..7c41afda01 100644 --- a/modules/skybrowser/skybrowsermodule.h +++ b/modules/skybrowser/skybrowsermodule.h @@ -43,7 +43,7 @@ class ScreenSpaceSkyBrowser; class ScreenSpaceSkyTarget; class RenderableSkyBrowser; class ScreenSpaceRenderable; -class WWTDataHandler; +class WwtDataHandler; class SceneGraphNode; class ImageData; @@ -51,32 +51,42 @@ class ImageData; class SkyBrowserModule : public OpenSpaceModule { public: constexpr static const char* Name = "SkyBrowser"; - constexpr static const int FROM_DIRECTORY = 0; - constexpr static const int FROM_URL = 1; - + + // Constructor & destructor SkyBrowserModule(); virtual ~SkyBrowserModule(); - glm::vec2 getMousePositionInScreenSpaceCoords(glm::vec2& mousePos); - void addRenderable(ScreenSpaceRenderable* object); - WWTDataHandler* getWWTDataHandler(); + + // Getters std::map& getSkyBrowsers(); std::vector& getBrowsersAndTargets(); SceneGraphNode* get3dBrowser(); - void startRotation(glm::dvec2 coordsEnd); - void rotateCamera(double deltaTime); - bool fadeBrowserAndTarget(bool makeTransparent, double fadeTime, double deltaTime); + WwtDataHandler* getWWTDataHandler(); + std::string selectedBrowserId(); + + // Setters void setSelectedBrowser(ScreenSpaceSkyBrowser* ptr); void setSelectedBrowser(std::string id); - bool browserIdExists(std::string id); - std::string selectedBrowserId(); - int loadImages(const std::string& root, const std::string& directory); void set3dBrowser(SceneGraphNode* node); + + // Rotation and animation + void startRotation(glm::dvec3 endAnimation); // Pass in galactic coord + void rotateCamera(double deltaTime); + bool fadeBrowserAndTarget(bool makeTransparent, double fadeTime, double deltaTime); + void lookAt3dBrowser(); + + // Boolean functions + bool browserIdExists(std::string id); bool cameraInSolarSystem(); + + // Managing the browsers void createTargetBrowserPair(); void removeTargetBrowserPair(std::string& browserId); + void addRenderable(ScreenSpaceRenderable* object); void place3dBrowser(ImageData& image); - void lookAt3dBrowser(); - int getAndIncrementLayerOrder(); + + // Image collection handling + int loadImages(const std::string& root, const std::string& directory); + int getAndIncrementMessageOrder(); // For version handling calls to WWT scripting::LuaLibrary luaLibrary() const override; //std::vector documentations() const override; @@ -84,43 +94,42 @@ public: protected: void internalInitialize(const ghoul::Dictionary& dict) override; void internalDeinitialize() override; - - // Using snake case on these casting functions to make them similar to eg std::to_string - ScreenSpaceSkyBrowser* to_browser(ScreenSpaceRenderable* ptr); - ScreenSpaceSkyTarget* to_target(ScreenSpaceRenderable* ptr); + +private: + // Cast screen space renderable to either target or browser + ScreenSpaceSkyBrowser* toBrowser(ScreenSpaceRenderable* ptr); + ScreenSpaceSkyTarget* toTarget(ScreenSpaceRenderable* ptr); // The browsers and targets - std::vector renderables; - // Only the browsers - std::map browsers; - // 3D browser - SceneGraphNode* _browser3d; - // Pointer to what mouse is currently on - ScreenSpaceRenderable* _mouseOnObject; - // Dragging - glm::vec2 startDragMousePos; - glm::vec2 startDragObjectPos; - bool changeViewWithinBrowser; - // Resizing - glm::vec2 startResizeBrowserSize; - glm::vec2 resizeVector; - // The current mouse position in screenspace coordinates - glm::vec2 _mousePosition; - // Current interaction status - bool currentlyResizingBrowser; - bool currentlyDraggingObject; - // Data handler - WWTDataHandler* dataHandler; - // For animating rotation of camera to look at coordinate - glm::dvec3 _coordsToAnimateTo; - glm::dvec3 _coordsStartAnimation; - bool isRotating = false; - // For tracking the currently selected browser - std::string selectedBrowser; - glm::ivec3 highlightAddition; - // Mode of browsing - bool _cameraInSolarSystem; - int _layerOrderCounter; + std::vector _renderables; // 2D browsers and targets + std::map _browsers; // Only the 2D browsers + ScreenSpaceRenderable* _mouseOnObject{ nullptr }; // Pointer to what mouse is currently on + SceneGraphNode* _browser3d{ nullptr }; + std::string _selectedBrowser; // Currently selected browser (2D or 3D) + + // Flags + bool _fineTuneMode{ false }; + bool _isResizing{ false }; + bool _isDragging{ false }; + bool _cameraInSolarSystem{ true }; + bool _isRotating = false; + + // Mouse interaction - dragging and resizing + glm::vec2 _mousePosition; // Current mouse position in screen space coordinates + glm::ivec3 _highlightAddition{ 35 }; // Highlight object when mouse hovers + glm::vec2 _startMousePosition; + glm::vec2 _startDragPosition; + glm::vec2 _startBrowserSize; + glm::vec2 _resizeDirection{ 0.f }; + + // Animation of rotation of camera to look at coordinate galactic coordinates + glm::dvec3 _startAnimation; + glm::dvec3 _endAnimation; + + // Data handler for the image collections + WwtDataHandler* _dataHandler; + int _messageOrder{ 0 }; // Version handler for WorldWide Telescope messages + }; } // namespace openspace diff --git a/modules/skybrowser/skybrowsermodule_lua.inl b/modules/skybrowser/skybrowsermodule_lua.inl index b49a06bddc..02421ca2b6 100644 --- a/modules/skybrowser/skybrowsermodule_lua.inl +++ b/modules/skybrowser/skybrowsermodule_lua.inl @@ -53,12 +53,15 @@ namespace openspace::skybrowser::luascriptfunctions { ScreenSpaceSkyTarget* selectedTarget = selectedBrowser->getSkyTarget(); // If the image has coordinates, move the target - if (image.hasCelestCoords && selectedTarget) { + if (image.hasCelestialCoords && selectedTarget) { + // Animate the target to the image coord position selectedTarget->unlock(); - selectedTarget->startAnimation(image.celestCoords, image.fov); + glm::dvec3 equatorial = skybrowser::sphericalToCartesian(image.celestialCoords); + selectedTarget->startAnimation(equatorial, image.fov); + // Check if image coordinate is within current FOV - glm::dvec3 coordsScreen = J2000SphericalToScreenSpace(image.celestCoords); + glm::dvec3 coordsScreen = equatorialToScreenSpace(equatorial); glm::vec2 windowRatio = global::windowDelegate->currentWindowSize(); float r = windowRatio.x / windowRatio.y; bool coordIsWithinView = (abs(coordsScreen.x) < r && @@ -66,7 +69,8 @@ namespace openspace::skybrowser::luascriptfunctions { bool coordIsBehindCamera = coordsScreen.z > 0; // If the coordinate is not in view, rotate camera if (!coordIsWithinView || coordIsBehindCamera) { - module->startRotation(image.celestCoords); + glm::dvec3 galactic = skybrowser::equatorialToGalactic(equatorial); + module->startRotation(galactic); } } } @@ -95,13 +99,14 @@ namespace openspace::skybrowser::luascriptfunctions { const ImageData& image = module->getWWTDataHandler()->getLoadedImages()[i]; // Only move and show circle if the image has coordinates - if (image.hasCelestCoords && module->cameraInSolarSystem()) { + if (image.hasCelestialCoords && module->cameraInSolarSystem()) { // Make circle visible ScreenSpaceImageLocal* hoverCircle = dynamic_cast( global::renderEngine->screenSpaceRenderable("HoverCircle")); hoverCircle->property("Enabled")->set(true); // Calculate coords for the circle and translate - glm::vec3 coordsScreen = skybrowser::J2000SphericalToScreenSpace(image.celestCoords); + glm::dvec3 equatorialCartesian = skybrowser::sphericalToCartesian(image.celestialCoords); + glm::vec3 coordsScreen = skybrowser::equatorialToScreenSpace(equatorialCartesian); hoverCircle->property("CartesianPosition")->set(coordsScreen); } @@ -152,12 +157,12 @@ namespace openspace::skybrowser::luascriptfunctions { const int i = ghoul::lua::value(L, 2); int order = ghoul::lua::value(L, 3); SkyBrowserModule* module = global::moduleEngine->module(); - int version = module->getAndIncrementLayerOrder(); + int version = module->getAndIncrementMessageOrder(); if (module->browserIdExists(browserId)) { ScreenSpaceSkyBrowser* browser = module->getSkyBrowsers()[browserId]; - browser->setImageLayerOrder(i, order, version); + browser->setImageOrder(i, order, version); } else if (module->get3dBrowser() != nullptr) { RenderableSkyBrowser* browser3d = dynamic_cast( @@ -180,9 +185,9 @@ namespace openspace::skybrowser::luascriptfunctions { ScreenSpaceSkyBrowser* browser = dynamic_cast( global::renderEngine->screenSpaceRenderable(id)); - if (browser && !browser->hasLoadedCollections()) { - browser->sendMessageToWWT(wwtmessage::loadCollection(root)); - browser->setHasLoadedCollections(true); + if (browser && !browser->hasLoadedImages()) { + browser->sendMessageToWwt(wwtmessage::loadCollection(root)); + browser->setHasLoadedImages(true); } else { SceneGraphNode* node = global::renderEngine->scene()->sceneGraphNode(id); @@ -191,9 +196,9 @@ namespace openspace::skybrowser::luascriptfunctions { node->renderable()); if (browser3d) { // Load Image collections - browser3d->stopConnectingToWwt(); + browser3d->stopSyncingWwtView(); LINFO("Load images to " + browser3d->identifier()); - browser3d->sendMessageToWWT(wwtmessage::loadCollection(root)); + browser3d->sendMessageToWwt(wwtmessage::loadCollection(root)); LINFO("Image collection loaded in " + browser3d->identifier()); } } @@ -210,7 +215,7 @@ namespace openspace::skybrowser::luascriptfunctions { SkyBrowserModule* module = global::moduleEngine->module(); std::map browsers = module->getSkyBrowsers(); for (std::pair pair : browsers) { - pair.second->setIdInBrowser(); + pair.second->sendIdToBrowser(); } SceneGraphNode* node = module->get3dBrowser(); if(node) { @@ -228,15 +233,17 @@ namespace openspace::skybrowser::luascriptfunctions { // Find the ScreenSpaceRenderable that has the id ScreenSpaceRenderable* found = global::renderEngine->screenSpaceRenderable(id); + ScreenSpaceSkyBrowser* browser = dynamic_cast(found); + ScreenSpaceSkyTarget* target = dynamic_cast(found); // Connect it to its corresponding target / browser - if (dynamic_cast(found)) { - ScreenSpaceSkyBrowser* browser = dynamic_cast(found); - browser->setConnectedTarget(); + if (browser) { + + browser->connectToSkyTarget(); } - else if (dynamic_cast(found)) { - ScreenSpaceSkyTarget* target = dynamic_cast(found); - target->initializeWithBrowser(); + else if (target) { + + target->findSkyBrowser(); } return 0; } @@ -247,12 +254,12 @@ namespace openspace::skybrowser::luascriptfunctions { const std::string id = ghoul::lua::value(L, 1); ScreenSpaceSkyBrowser* browser = dynamic_cast( global::renderEngine->screenSpaceRenderable(id)); - LINFO("Initializing sky browsers"); + LINFO("Initializing sky browser " + id); if (browser) { browser->initializeBrowser(); ScreenSpaceSkyTarget* target = browser->getSkyTarget(); if (target) { - target->initializeWithBrowser(); + target->findSkyBrowser(); } } else { @@ -263,7 +270,7 @@ namespace openspace::skybrowser::luascriptfunctions { if (browser3d && id == node->identifier()) { // Initialize LINFO("Initializing 3D sky browsers"); - browser3d->connectToWwt(); + browser3d->syncWwtView(); } } } @@ -315,7 +322,7 @@ namespace openspace::skybrowser::luascriptfunctions { for (int i = 0; i < images.size(); i++) { std::string name = images[i].name != "" ? images[i].name : "undefined"; std::string thumbnail = images[i].thumbnailUrl != "" ? images[i].thumbnailUrl : "undefined"; - glm::dvec3 cartCoords = skybrowser::sphericalToCartesian(images[i].celestCoords); + glm::dvec3 cartCoords = skybrowser::sphericalToCartesian(images[i].celestialCoords); std::vector cartCoordsVec = { cartCoords.x, cartCoords.y, cartCoords.z }; glm::dvec3 position = images[i].position3d; std::vector position3d = { position.x, position.y, position.z }; @@ -328,13 +335,13 @@ namespace openspace::skybrowser::luascriptfunctions { lua_settable(L, -3); ghoul::lua::push(L, "thumbnail", thumbnail); lua_settable(L, -3); - ghoul::lua::push(L, "ra", images[i].celestCoords.x); + ghoul::lua::push(L, "ra", images[i].celestialCoords.x); lua_settable(L, -3); - ghoul::lua::push(L, "dec", images[i].celestCoords.y); + ghoul::lua::push(L, "dec", images[i].celestialCoords.y); lua_settable(L, -3); ghoul::lua::push(L, "cartesianDirection", cartCoordsVec); lua_settable(L, -3); - ghoul::lua::push(L, "hasCelestialCoords", images[i].hasCelestCoords); + ghoul::lua::push(L, "hasCelestialCoords", images[i].hasCelestialCoords); lua_settable(L, -3); ghoul::lua::push(L, "credits", images[i].credits); lua_settable(L, -3); @@ -364,7 +371,7 @@ namespace openspace::skybrowser::luascriptfunctions { // Add the window data for OpenSpace ghoul::lua::push(L, "OpenSpace"); lua_newtable(L); - glm::dvec3 cartesianJ2000 = skybrowser::cameraDirectionJ2000Cartesian(); + glm::dvec3 cartesianJ2000 = skybrowser::cameraDirectionEquatorial(); glm::dvec2 sphericalJ2000 = skybrowser::cartesianToSpherical(cartesianJ2000); // Convert to vector so ghoul can read it std::vector viewDirCelestVec = { cartesianJ2000.x, cartesianJ2000.y, cartesianJ2000.z }; @@ -400,18 +407,19 @@ namespace openspace::skybrowser::luascriptfunctions { std::string id = pair.first; // Convert deque to vector so ghoul can read it std::vector selectedImagesVector; - std::deque selectedImages = browser->selectedImages(); - std::for_each(selectedImages.begin(), selectedImages.end(), [&](int index) { - selectedImagesVector.push_back(index); + std::deque selectedImages = browser->getSelectedImages(); + std::for_each(selectedImages.begin(), selectedImages.end(), [&](int i) { + selectedImagesVector.push_back(i); }); // Only add browsers that have an initialized target ScreenSpaceSkyTarget* target = browser->getSkyTarget(); if (target) { - glm::dvec2 celestialSpherical = target->getTargetDirectionCelestial(); - glm::dvec3 celestialCart = skybrowser::sphericalToCartesian(celestialSpherical); + glm::dvec3 celestialCart = target->targetDirectionEquatorial(); + glm::dvec2 celestialSpherical = skybrowser::cartesianToSpherical(celestialCart); + std::vector celestialCartVec = { celestialCart.x, celestialCart.y, celestialCart.z }; // Convert color to vector so ghoul can read it - glm::ivec3 color = browser->_borderColor.value(); + glm::ivec3 color = browser->borderColor(); std::vector colorVec = { color.r, color.g, color.b }; ghoul::lua::push(L, id); @@ -421,7 +429,7 @@ namespace openspace::skybrowser::luascriptfunctions { lua_settable(L, -3); ghoul::lua::push(L, "name", browser->guiName()); lua_settable(L, -3); - ghoul::lua::push(L, "FOV", browser->fieldOfView()); + ghoul::lua::push(L, "FOV", browser->verticalFov()); lua_settable(L, -3); ghoul::lua::push(L, "selectedImages", selectedImagesVector); lua_settable(L, -3); @@ -447,12 +455,12 @@ namespace openspace::skybrowser::luascriptfunctions { node->renderable()); // Convert deque to vector so ghoul can read it std::vector selectedImagesVector; - std::deque selectedImages = browser3d->selectedImages(); + std::deque selectedImages = browser3d->getSelectedImages(); std::for_each(selectedImages.begin(), selectedImages.end(), [&](int index) { selectedImagesVector.push_back(index); }); glm::dvec3 worldPosition = node->position(); - glm::dvec3 celestialCart = skybrowser::galacticCartesianToJ2000Cartesian(worldPosition); + glm::dvec3 celestialCart = skybrowser::galacticToEquatorial(worldPosition); glm::dvec2 celestialSpherical = skybrowser::cartesianToSpherical(celestialCart); std::vector celestialCartVec = { celestialCart.x, celestialCart.y, celestialCart.z }; // Convert color to vector so ghoul can read it @@ -466,7 +474,7 @@ namespace openspace::skybrowser::luascriptfunctions { lua_settable(L, -3); ghoul::lua::push(L, "name", node->guiName()); lua_settable(L, -3); - ghoul::lua::push(L, "FOV", browser3d->fieldOfView()); + ghoul::lua::push(L, "FOV", browser3d->verticalFov()); lua_settable(L, -3); ghoul::lua::push(L, "selectedImages", selectedImagesVector); lua_settable(L, -3); @@ -496,7 +504,8 @@ namespace openspace::skybrowser::luascriptfunctions { if(module->cameraInSolarSystem() && module->browserIdExists(id)) { ScreenSpaceSkyTarget* target = module->getSkyBrowsers()[id]->getSkyTarget(); if (target) { - module->startRotation(target->getTargetDirectionCelestial()); + glm::dvec3 cartesian = target->targetDirectionEquatorial(); + module->startRotation(skybrowser::equatorialToGalactic(cartesian)); } } else if (!module->cameraInSolarSystem() && id3dBrowser == id) { @@ -516,9 +525,9 @@ namespace openspace::skybrowser::luascriptfunctions { RenderableSkyBrowser* browser3d = dynamic_cast( module->get3dBrowser()->renderable()); // Empty 3D browser selection - browser3d->selectedImages().clear(); + browser3d->getSelectedImages().clear(); // Copy 2D selection of images to 3D browser - std::deque images = browser->selectedImages(); + std::deque images = browser->getSelectedImages(); std::for_each(std::begin(images), std::end(images), [&](int index) { ImageData& image = module->getWWTDataHandler()->getLoadedImages()[index]; browser3d->displayImage(image, index); @@ -534,15 +543,15 @@ namespace openspace::skybrowser::luascriptfunctions { const std::string i = std::to_string(ghoul::lua::value(L, 2)); double opacity = ghoul::lua::value(L, 3); SkyBrowserModule* module = global::moduleEngine->module(); - ghoul::Dictionary message = wwtmessage::setLayerOpacity(i, opacity); + ghoul::Dictionary message = wwtmessage::setImageOpacity(i, opacity); if (module->browserIdExists(browserId)) { - module->getSkyBrowsers()[browserId]->sendMessageToWWT(message); + module->getSkyBrowsers()[browserId]->sendMessageToWwt(message); } else if (module->get3dBrowser() != nullptr) { RenderableSkyBrowser* browser3d = dynamic_cast( module->get3dBrowser()->renderable()); - browser3d->sendMessageToWWT(message); + browser3d->sendMessageToWwt(message); } return 0; @@ -558,12 +567,10 @@ namespace openspace::skybrowser::luascriptfunctions { // Animate the target to the center of the screen browser->getSkyTarget()->unlock(); // Get camera direction in celestial spherical coordinates - glm::dvec3 viewDirection = skybrowser::cameraDirectionJ2000Cartesian(); - glm::dvec2 centerOfScreen = skybrowser::cartesianToSpherical( - viewDirection); + glm::dvec3 viewDirection = skybrowser::cameraDirectionEquatorial(); // Keep the current fov - float fov = browser->fieldOfView(); - browser->getSkyTarget()->startAnimation(centerOfScreen, fov, false); + float fov = browser->verticalFov(); + browser->getSkyTarget()->startAnimation(viewDirection, fov, false); browser->getSkyTarget()->unlock(); } } diff --git a/modules/skybrowser/src/renderableskybrowser.cpp b/modules/skybrowser/src/renderableskybrowser.cpp index a284c25a43..4b01031b52 100644 --- a/modules/skybrowser/src/renderableskybrowser.cpp +++ b/modules/skybrowser/src/renderableskybrowser.cpp @@ -68,8 +68,8 @@ namespace openspace { , _url(UrlInfo) , _dimensions(DimensionsInfo, glm::vec2(0.f), glm::vec2(0.f), glm::vec2(3000.f)) , _reload(ReloadInfo) - , _fov(70.f) - , _connectToWwt(false) + , _verticalFov(70.f) + , _syncViewWithWwt(false) { // Handle target dimension property const Parameters p = codegen::bake(dictionary); @@ -182,22 +182,22 @@ namespace openspace { } } - bool RenderableSkyBrowser::sendMessageToWWT(const ghoul::Dictionary& msg) { + bool RenderableSkyBrowser::sendMessageToWwt(const ghoul::Dictionary& msg) { std::string script = "sendMessageToWWT(" + ghoul::formatJson(msg) + ");"; executeJavascript(script); return true; } void RenderableSkyBrowser::displayImage(ImageData& image, int i) { - sendMessageToWWT(wwtmessage::moveCamera(image.celestCoords, image.fov, 0.0)); - _fov = image.fov; + sendMessageToWwt(wwtmessage::moveCamera(image.celestialCoords, image.fov, 0.0)); + _verticalFov = image.fov; // Add to selected images if there are no duplicates auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i); if (it == std::end(_selectedImages)) { // Push newly selected image to front _selectedImages.push_front(i); // Create image layer and center WWT app on the image - sendMessageToWWT(wwtmessage::createImageLayer(std::to_string(i), image.imageUrl)); + sendMessageToWwt(wwtmessage::addImage(std::to_string(i), image.imageUrl)); LINFO("Image has been loaded to " + identifier()); } } @@ -207,7 +207,7 @@ namespace openspace { auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i); if (it != std::end(_selectedImages)) { _selectedImages.erase(it); - sendMessageToWWT(wwtmessage::removeImageLayer(std::to_string(i))); + sendMessageToWwt(wwtmessage::removeImage(std::to_string(i))); } } @@ -216,22 +216,22 @@ namespace openspace { executeJavascript("setId('" + id + "')"); } - float RenderableSkyBrowser::fieldOfView() const { - return _fov; + float RenderableSkyBrowser::verticalFov() const { + return _verticalFov; } - void RenderableSkyBrowser::connectToWwt() { + void RenderableSkyBrowser::syncWwtView() { // If the camera is already synced, the browser is already initialized - if (!_connectToWwt) { - _connectToWwt = true; + if (!_syncViewWithWwt) { + _syncViewWithWwt = true; // Start a thread to enable user interaction while sending the calls to WWT _threadWwtMessages = std::thread([&] { - while (_connectToWwt) { + while (_syncViewWithWwt) { glm::dvec2 aim{ 0.0 }; // Send a message just to establish contact - ghoul::Dictionary message = wwtmessage::moveCamera(aim, _fov, 0.0); - sendMessageToWWT(message); + ghoul::Dictionary message = wwtmessage::moveCamera(aim, _verticalFov, 0.0); + sendMessageToWwt(message); // Sleep so we don't bombard WWT with too many messages std::this_thread::sleep_for(std::chrono::milliseconds(500)); @@ -241,15 +241,15 @@ namespace openspace { } - void RenderableSkyBrowser::stopConnectingToWwt() { - _connectToWwt = false; + void RenderableSkyBrowser::stopSyncingWwtView() { + _syncViewWithWwt = false; if (_threadWwtMessages.joinable()) { _threadWwtMessages.join(); } } - std::deque& RenderableSkyBrowser::selectedImages() { + std::deque& RenderableSkyBrowser::getSelectedImages() { return _selectedImages; } @@ -267,7 +267,7 @@ namespace openspace { int reverseOrder = _selectedImages.size() - order - 1; ghoul::Dictionary message = wwtmessage::setLayerOrder(std::to_string(i), reverseOrder, version); - sendMessageToWWT(message); + sendMessageToWwt(message); } diff --git a/modules/skybrowser/src/screenspaceskybrowser.cpp b/modules/skybrowser/src/screenspaceskybrowser.cpp index 6d42f2fa09..2ebcce44e7 100644 --- a/modules/skybrowser/src/screenspaceskybrowser.cpp +++ b/modules/skybrowser/src/screenspaceskybrowser.cpp @@ -30,26 +30,27 @@ namespace { constexpr const openspace::properties::Property::PropertyInfo BrowserDimensionInfo = { "BrowserDimensions", - "Browser Dimensions Info", - "Set the dimensions of the SkyTarget according to the SkyBrowser ratio " + "Browser Dimensions", + "The pixel dimensions of the sky browser." }; - constexpr const openspace::properties::Property::PropertyInfo ZoomInfo = + constexpr const openspace::properties::Property::PropertyInfo VerticalFovInfo = { - "Zoom", - "Zoom Info", - "tjobidabidobidabidopp plupp" + "VerticalFieldOfView", + "Vertical Field Of View", + "The vertical field of view in degrees." }; - constexpr const openspace::properties::Property::PropertyInfo TargetIDInfo = + constexpr const openspace::properties::Property::PropertyInfo TargetIdInfo = { - "TargetID", - "Target Info", - "tjobidabidobidabidopp plupp" + "TargetId", + "Target Id", + "The identifier of the target. It is used to synchronize the sky browser and the" + "sky target." }; constexpr const openspace::properties::Property::PropertyInfo BorderColorInfo = { "BorderColor", - "Border color Info", - "tjobidabidobidabidopp plupp" + "Border Color", + "The color of the border of the sky browser as well as the sky target." }; @@ -58,14 +59,14 @@ namespace { // [[codegen::verbatim(BrowserDimensionInfo.description)]] std::optional browserDimensions; - // [[codegen::verbatim(ZoomInfo.description)]] - std::optional zoom; + // [[codegen::verbatim(VerticalFovInfo.description)]] + std::optional verticalFov; - // [[codegen::verbatim(TargetIDInfo.description)]] - std::optional targetID; + // [[codegen::verbatim(TargetIdInfo.description)]] + std::optional targetId; // [[codegen::verbatim(BorderColorInfo.description)]] - std::optional borderColor; + std::optional borderColor; }; #include "screenspaceskybrowser_codegen.cpp" @@ -76,47 +77,44 @@ namespace openspace { ScreenSpaceSkyBrowser::ScreenSpaceSkyBrowser(const ghoul::Dictionary& dictionary) : ScreenSpaceBrowser(dictionary) , _browserDimensions(BrowserDimensionInfo, _dimensions, glm::ivec2(0), glm::ivec2(300)) - , _vfieldOfView(ZoomInfo, 10.f, 0.1f, 70.f) - , _borderColor(BorderColorInfo, glm::ivec3(rand() % 256, rand() % 256, rand() % 256)) - , _skyTargetID(TargetIDInfo) - , _camIsSyncedWWT(false) - , _skyTarget(nullptr) + , _verticalFov(VerticalFovInfo, 10.f, 0.1f, 70.f) + , _borderColor(BorderColorInfo, glm::vec3(rand() % 256, rand() % 256, rand() % 256)) + , _skyTargetId(TargetIdInfo) { - // Ensure the color of the border is bright enough. - // Make sure the RGB color at least is 50% brightness - // By making each channel 50% bright in general - // 222 = sqrt(3*(0.5*256)^2) - while (glm::length(_borderColor.value()) < 222) { - _borderColor = glm::ivec3(rand() % 256, rand() % 256, rand() % 256); - } + // Make the color property display a color picker in the GUI + _borderColor.setViewOption("Color", true); // Handle target dimension property const Parameters p = codegen::bake(dictionary); _browserDimensions = p.browserDimensions.value_or(_browserDimensions); - _browserDimensions.onChange([&]() { - if(_skyTarget) { - glm::vec2 dim = getBrowserPixelDimensions(); + _verticalFov = p.verticalFov.value_or(_verticalFov); + _borderColor = p.borderColor.value_or(_borderColor); + _skyTargetId = p.targetId.value_or(_skyTargetId); + + addProperty(_browserDimensions); + addProperty(_verticalFov); + addProperty(_borderColor); + addProperty(_skyTargetId); + + _browserDimensions.onChange([&]() { + if (_skyTarget) { + glm::vec2 dim = browserPixelDimensions(); _skyTarget->setDimensions(dim); } }); - addProperty(_browserDimensions); - - _vfieldOfView = p.zoom.value_or(_vfieldOfView); - addProperty(_vfieldOfView); - - _skyTargetID = p.targetID.value_or(_skyTargetID); - addProperty(_skyTargetID); - - _skyTargetID.onChange([&]() { - setConnectedTarget(); - }); - - _vfieldOfView.onChange([&]() { + _verticalFov.onChange([&]() { if (_skyTarget) { - _skyTarget->setVerticalFOV(_vfieldOfView); + _skyTarget->setScale(_verticalFov); } }); - + _borderColor.onChange([&]() { + setWebpageBorderColor(_borderColor.value()); + }); + _skyTargetId.onChange([&]() { + connectToSkyTarget(); + }); + + // Set a unique identifier std::string identifier; if (dictionary.hasValue(KeyIdentifier)) { identifier = dictionary.value(KeyIdentifier); @@ -127,7 +125,8 @@ namespace openspace { identifier = makeUniqueIdentifier(identifier); setIdentifier(identifier); - _cartesianPosition.setValue(glm::dvec3(_cartesianPosition.value().x, _cartesianPosition.value().y, skybrowser::SCREENSPACE_Z)); + glm::vec2 screenPosition = _cartesianPosition.value(); + _cartesianPosition.setValue(glm::vec3(screenPosition, skybrowser::ScreenSpaceZ)); // Always make sure that the target and browser are visible together _enabled.onChange([&]() { @@ -135,13 +134,21 @@ namespace openspace { _skyTarget->property("Enabled")->set(_enabled.value()); } }); + + // Ensure the color of the border is bright enough. + // Make sure the RGB color at least is 50% brightness + // By making each channel 50% bright in general + // 222 = sqrt(3*(0.5*256)^2) + while (glm::length(_borderColor.value()) < 222) { + _borderColor = glm::vec3(rand() % 256, rand() % 256, rand() % 256); + } } ScreenSpaceSkyBrowser::~ScreenSpaceSkyBrowser() { // Set flag to false so the thread can exit - _camIsSyncedWWT = false; - if (_threadWWTMessages.joinable()) { - _threadWWTMessages.join(); + _syncViewWithWwt = false; + if (_threadWwtMessages.joinable()) { + _threadWwtMessages.join(); LINFO("Joined thread"); } } @@ -150,38 +157,39 @@ namespace openspace { return ScreenSpaceBrowser::initializeGL(); } - void ScreenSpaceSkyBrowser::setIdInBrowser() { + void ScreenSpaceSkyBrowser::sendIdToBrowser() { // Send ID to it's browser executeJavascript("setId('" + identifier() + "')"); } void ScreenSpaceSkyBrowser::initializeBrowser() { // If the camera is already synced, the browser is already initialized - if (!_camIsSyncedWWT) { - _camIsSyncedWWT = true; + if (!_syncViewWithWwt) { + _syncViewWithWwt = true; // Set border color - setBorderColor(_borderColor.value()); + setWebpageBorderColor(_borderColor.value()); // Connect to target if they haven't been connected if (!_skyTarget) { - setConnectedTarget(); + connectToSkyTarget(); } // Track target - WWTfollowCamera(); + syncWwtView(); } } bool ScreenSpaceSkyBrowser::deinitializeGL() { // Set flag to false so the thread can exit - _camIsSyncedWWT = false; - if (_threadWWTMessages.joinable()) { - _threadWWTMessages.join(); + _syncViewWithWwt = false; + if (_threadWwtMessages.joinable()) { + _threadWwtMessages.join(); LINFO("Joined thread"); } return ScreenSpaceBrowser::deinitializeGL(); } - bool ScreenSpaceSkyBrowser::setConnectedTarget() { - _skyTarget = dynamic_cast(global::renderEngine->screenSpaceRenderable(_skyTargetID.value())); + bool ScreenSpaceSkyBrowser::connectToSkyTarget() { + _skyTarget = dynamic_cast( + global::renderEngine->screenSpaceRenderable(_skyTargetId.value())); return _skyTarget; } @@ -189,72 +197,81 @@ namespace openspace { return _skyTarget; } - bool ScreenSpaceSkyBrowser::hasLoadedCollections() { - return _hasLoadedCollections; + bool ScreenSpaceSkyBrowser::hasLoadedImages() const { + return _hasLoadedImages; } - void ScreenSpaceSkyBrowser::setHasLoadedCollections(bool isLoaded) { - _hasLoadedCollections = isLoaded; + void ScreenSpaceSkyBrowser::setHasLoadedImages(bool isLoaded) { + _hasLoadedImages = isLoaded; } - float ScreenSpaceSkyBrowser::fieldOfView() const { - return _vfieldOfView; + void ScreenSpaceSkyBrowser::setVerticalFov(float vfov) { + _verticalFov = vfov; } - void ScreenSpaceSkyBrowser::setVerticalFieldOfView(float fov) { - _vfieldOfView = fov; - } - - void ScreenSpaceSkyBrowser::scrollZoom(float scroll) { + void ScreenSpaceSkyBrowser::setVerticalFovWithScroll(float scroll) { // Cap how often the zoom is allowed to update std::chrono::system_clock::time_point now = std::chrono::system_clock::now(); - if (now - _lastUpdateTime > TimeUpdateInterval) { + std::chrono::system_clock::duration timeSinceLastUpdate = now - _lastUpdateTime; + + if (timeSinceLastUpdate > _timeUpdateInterval) { // Make scroll more sensitive the smaller the FOV - float x = _vfieldOfView; + float x = _verticalFov; float zoomFactor = atan(x / 50.0) + exp(x / 40) - 0.999999; float zoom = scroll > 0.0 ? -zoomFactor : zoomFactor; - _vfieldOfView = std::clamp(_vfieldOfView + zoom, 0.001f, 70.0f); + _verticalFov = std::clamp(_verticalFov + zoom, 0.001f, 70.0f); _lastUpdateTime = std::chrono::system_clock::now(); } } - void ScreenSpaceSkyBrowser::executeJavascript(std::string script) const { - //LINFOC(_loggerCat, "Executing javascript " + script); - if (_browserInstance && _browserInstance->getBrowser() && _browserInstance->getBrowser()->GetMainFrame()) { + void ScreenSpaceSkyBrowser::executeJavascript(std::string script) { + // Make sure that the browser has a main frame + bool browserExists = _browserInstance && _browserInstance->getBrowser(); + bool frameIsLoaded = browserExists && + _browserInstance->getBrowser()->GetMainFrame(); + + if (frameIsLoaded) { CefRefPtr frame = _browserInstance->getBrowser()->GetMainFrame(); frame->ExecuteJavaScript(script, frame->GetURL(), 0); } } - glm::ivec3 ScreenSpaceSkyBrowser::getColor() { + glm::ivec3 ScreenSpaceSkyBrowser::borderColor() const { return _borderColor.value(); } - void ScreenSpaceSkyBrowser::setBorderColor(glm::ivec3 col) { - std::string stringColor = std::to_string(col.x) + "," + std::to_string(col.y) + "," + std::to_string(col.z); - std::string script = "document.body.style.backgroundColor = 'rgb(" + stringColor + ")';"; + float ScreenSpaceSkyBrowser::verticalFov() const { + return _verticalFov.value(); + } + + void ScreenSpaceSkyBrowser::setWebpageBorderColor(glm::ivec3 color) { + std::string stringColor = std::to_string(color.x) + "," + + std::to_string(color.y) + "," + std::to_string(color.z); + std::string script = "document.body.style.backgroundColor = 'rgb(" + + stringColor + ")';"; executeJavascript(script); } - bool ScreenSpaceSkyBrowser::sendMessageToWWT(const ghoul::Dictionary& msg) { + void ScreenSpaceSkyBrowser::sendMessageToWwt(const ghoul::Dictionary& msg) { std::string script = "sendMessageToWWT(" + ghoul::formatJson(msg) + ");"; executeJavascript(script); - return true; } - void ScreenSpaceSkyBrowser::WWTfollowCamera() { + void ScreenSpaceSkyBrowser::syncWwtView() { // Start a thread to enable user interaction while sending the calls to WWT - _threadWWTMessages = std::thread([&] { - while (_camIsSyncedWWT) { - if (_skyTarget) { - glm::dvec2 aim = _skyTarget->getTargetDirectionCelestial(); - // Calculate roll between up vector of camera and J2000 equatorial north - glm::dvec3 upVector = global::navigationHandler->camera()->lookUpVectorWorldSpace(); - glm::dvec3 viewVector = global::navigationHandler->camera()->viewDirectionWorldSpace(); - double roll = skybrowser::calculateRoll(upVector, viewVector); - ghoul::Dictionary message = wwtmessage::moveCamera(aim, _vfieldOfView, roll); - sendMessageToWWT(message); + _threadWwtMessages = std::thread([&] { + while (_syncViewWithWwt) { + if (_skyTarget) { + // Message WorldWide Telescope current view + glm::dvec3 cartesian = _skyTarget->targetDirectionEquatorial(); + + ghoul::Dictionary message = wwtmessage::moveCamera( + skybrowser::cartesianToSpherical(cartesian), + _verticalFov, + skybrowser::cameraRoll() + ); + sendMessageToWwt(message); } // Sleep so we don't bombard WWT with too many messages @@ -264,23 +281,24 @@ namespace openspace { } - /* - void ScreenSpaceSkyBrowser::translate(glm::vec2 translation) { - glm::vec3 position = _cartesianPosition; - _cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, 1.0f); - }*/ + // + //void ScreenSpaceSkyBrowser::translate(glm::vec2 translation) { + // glm::vec3 position = _cartesianPosition; + // _cartesianPosition =glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, 1.0f); + //} - glm::vec2 ScreenSpaceSkyBrowser::coordIsOnResizeArea(glm::vec2 coord) { + glm::vec2 ScreenSpaceSkyBrowser::isOnResizeArea(glm::vec2 screenSpaceCoord) { glm::vec2 resizePosition = glm::vec2{ 0 }; - // Make sure coord is on browser - if (!coordIsInsideCornersScreenSpace(coord)) return resizePosition; + // Make sure coordinate is on browser + if (!coordIsInsideCornersScreenSpace(screenSpaceCoord)) return resizePosition; - float resizeButtonSize = 0.1f; - - bool isOnTop = coord.y > getUpperRightCornerScreenSpace().y - (getScreenSpaceDimensions().y * resizeButtonSize); - bool isOnBottom = coord.y < getLowerLeftCornerScreenSpace().y + (getScreenSpaceDimensions().y * resizeButtonSize); - bool isOnRight = coord.x > getUpperRightCornerScreenSpace().x - (getScreenSpaceDimensions().x * resizeButtonSize); - bool isOnLeft = coord.x < getLowerLeftCornerScreenSpace().x + (getScreenSpaceDimensions().x * resizeButtonSize); + float resizeAreaY = screenSpaceDimensions().y * _resizeAreaPercentage; + float resizeAreaX = screenSpaceDimensions().x * _resizeAreaPercentage; + + bool isOnTop = screenSpaceCoord.y > upperRightCornerScreenSpace().y - resizeAreaY; + bool isOnBottom = screenSpaceCoord.y < lowerLeftCornerScreenSpace().y + resizeAreaY; + bool isOnRight = screenSpaceCoord.x > upperRightCornerScreenSpace().x - resizeAreaX; + bool isOnLeft = screenSpaceCoord.x < lowerLeftCornerScreenSpace().x + resizeAreaX; resizePosition.x = isOnRight ? 1.f : isOnLeft ? -1.f : 0.f; resizePosition.y = isOnTop ? 1.f : isOnBottom ? -1.f : 0.f; @@ -288,13 +306,13 @@ namespace openspace { return resizePosition; } // Scales the ScreenSpaceBrowser to a new ratio - void ScreenSpaceSkyBrowser::scale(glm::vec2 scalingFactor) { + void ScreenSpaceSkyBrowser::setScale(glm::vec2 scalingFactor) { // Scale on the y axis, this is to ensure that _scale = 1 is // equal to the height of the window - scale(abs(scalingFactor.y)); + setScale(abs(scalingFactor.y)); // Resize the dimensions of the texture on the x axis - glm::vec2 newSize = abs(scalingFactor) * _startDimensionsSize; + glm::vec2 newSize = abs(scalingFactor) * _originalDimensions; _texture->setDimensions(glm::ivec3(newSize, 1)); _objectSize = _texture->dimensions(); _browserDimensions = newSize; @@ -303,8 +321,9 @@ namespace openspace { glm::mat4 ScreenSpaceSkyBrowser::scaleMatrix() { // To ensure the plane has the right ratio // The _scale tells us how much of the windows height the - // browser covers: eg a browser that covers 0.25 of the + // browser covers: e.g. a browser that covers 0.25 of the // height of the window will have scale = 0.25 + float textureRatio = static_cast(_texture->dimensions().x) / static_cast(_texture->dimensions().y); @@ -316,19 +335,19 @@ namespace openspace { } void ScreenSpaceSkyBrowser::saveResizeStartSize() { - _startDimensionsSize = glm::vec2(_dimensions.value().x, _dimensions.value().y); - _startScale = _scale.value(); + _originalDimensions = _dimensions.value(); + _originalScale = _scale.value(); } // Updates the browser size to match the size of the texture void ScreenSpaceSkyBrowser::updateBrowserSize() { _dimensions = _texture->dimensions(); } - void ScreenSpaceSkyBrowser::scale(float scalingFactor) { - _scale = _startScale * scalingFactor; + void ScreenSpaceSkyBrowser::setScale(float scalingFactor) { + _scale = _originalScale * scalingFactor; } - glm::vec2 ScreenSpaceSkyBrowser::getBrowserPixelDimensions() { + glm::vec2 ScreenSpaceSkyBrowser::browserPixelDimensions() const { return _browserDimensions.value(); } @@ -336,45 +355,62 @@ namespace openspace { return _opacity; } - std::deque& ScreenSpaceSkyBrowser::selectedImages() { + std::deque& ScreenSpaceSkyBrowser::getSelectedImages() { return _selectedImages; } void ScreenSpaceSkyBrowser::addSelectedImage(ImageData& image, int i) { // Ensure there are no duplicates auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i); - if (it == std::end(_selectedImages)) { + bool found = it != std::end(_selectedImages); + if (!found) { // 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(wwtmessage::createImageLayer(std::to_string(i), image.imageUrl)); - sendMessageToWWT(wwtmessage::setLayerOpacity(std::to_string(i), 1.0)); + sendMessageToWwt(wwtmessage::addImage(std::to_string(i), image.imageUrl)); + sendMessageToWwt(wwtmessage::setImageOpacity(std::to_string(i), 1.0)); } } void ScreenSpaceSkyBrowser::removeSelectedImage(ImageData& image, int i) { // Remove from selected list auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i); - if (it != std::end(_selectedImages)) { + bool found = it != std::end(_selectedImages); + if (found) { _selectedImages.erase(it); - sendMessageToWWT(wwtmessage::removeImageLayer(std::to_string(i))); + sendMessageToWwt(wwtmessage::removeImage(std::to_string(i))); } } - void ScreenSpaceSkyBrowser::setImageLayerOrder(int i, int order, int version) { - // Remove from selected list - auto current = std::find(std::begin(_selectedImages), std::end(_selectedImages), i); + void ScreenSpaceSkyBrowser::setImageOrder(int i, int order, int version) { + + // Find the selected image + auto selected = std::find( + std::begin(_selectedImages), + std::end(_selectedImages), + i + ); + + // Find the target for the swap auto target = std::begin(_selectedImages) + order; - // Make sure the image was found in the list - if (current != std::end(_selectedImages) && target != std::end(_selectedImages)) { + // Make sure the selected and the target placement was found in the list + bool foundSelected = selected != std::end(_selectedImages); + bool foundTarget = target != std::end(_selectedImages); + + if (foundSelected && foundTarget) { // Swap the two images - std::iter_swap(current, target); + std::iter_swap(selected, target); } + // The images in the selected list are displayed in the reverse order from how the + // WorldWide Telescope application sees them int reverseOrder = _selectedImages.size() - order - 1; - ghoul::Dictionary message = wwtmessage::setLayerOrder(std::to_string(i), - reverseOrder, version); - sendMessageToWWT(message); + ghoul::Dictionary message = wwtmessage::setLayerOrder( + std::to_string(i), + reverseOrder, + version + ); + sendMessageToWwt(message); } } diff --git a/modules/skybrowser/src/screenspaceskytarget.cpp b/modules/skybrowser/src/screenspaceskytarget.cpp index 2bb5fa5261..d422b6cbcd 100644 --- a/modules/skybrowser/src/screenspaceskytarget.cpp +++ b/modules/skybrowser/src/screenspaceskytarget.cpp @@ -74,7 +74,7 @@ namespace { namespace openspace { ScreenSpaceSkyTarget::ScreenSpaceSkyTarget(const ghoul::Dictionary& dictionary) : ScreenSpaceRenderable(dictionary) - , _skyBrowserID(BrowserIDInfo) + , _skyBrowserId(BrowserIDInfo) , _skyBrowser(nullptr) , _showCrosshairThreshold(CrosshairThresholdInfo, 2.0f, 0.1f, 70.f) , _showRectangleThreshold(RectangleThresholdInfo, 0.6f, 0.1f, 70.f) @@ -82,17 +82,17 @@ namespace openspace { { // Handle target dimension property const Parameters p = codegen::bake(dictionary); - _skyBrowserID = p.browserID.value_or(_skyBrowserID); + _skyBrowserId = p.browserID.value_or(_skyBrowserId); _showCrosshairThreshold = p.crosshairThreshold.value_or(_showCrosshairThreshold); _showRectangleThreshold = p.rectangleThreshold.value_or(_showRectangleThreshold); - addProperty(_skyBrowserID); + addProperty(_skyBrowserId); addProperty(_showCrosshairThreshold); addProperty(_showRectangleThreshold); // If the ID changes for the corresponding browser, update - _skyBrowserID.onChange([&]() { - initializeWithBrowser(); + _skyBrowserId.onChange([&]() { + findSkyBrowser(); }); // Always make sure that the target and browser are visible together @@ -115,14 +115,14 @@ namespace openspace { // Set the position to screen space z glm::dvec3 startPos{ _cartesianPosition.value().x, _cartesianPosition.value().y, - skybrowser::SCREENSPACE_Z }; + skybrowser::ScreenSpaceZ }; _cartesianPosition.setValue(startPos); } ScreenSpaceSkyTarget::~ScreenSpaceSkyTarget() { - if (_lockTargetThread.joinable()) { - _lockTargetThread.join(); + if (_lockTarget.joinable()) { + _lockTarget.join(); } } @@ -131,13 +131,18 @@ namespace openspace { } - void ScreenSpaceSkyTarget::initializeWithBrowser() { + bool ScreenSpaceSkyTarget::findSkyBrowser() { _skyBrowser = dynamic_cast( - global::renderEngine->screenSpaceRenderable(_skyBrowserID.value())); + global::renderEngine->screenSpaceRenderable(_skyBrowserId.value())); + matchAppearanceToSkyBrowser(); + return _skyBrowser; + } + + void ScreenSpaceSkyTarget::matchAppearanceToSkyBrowser() { if (_skyBrowser) { - _color = _skyBrowser->getColor(); - _objectSize = _skyBrowser->getBrowserPixelDimensions(); - setVerticalFOV(_skyBrowser->_vfieldOfView.value()); + _color = _skyBrowser->borderColor(); + _objectSize = _skyBrowser->browserPixelDimensions(); + setScale(_skyBrowser->verticalFov()); } } @@ -156,10 +161,10 @@ namespace openspace { glm::mat4 ScreenSpaceSkyTarget::scaleMatrix() { // To ensure the plane has the right ratio - // The _scale us how much of the windows height the browser covers: eg a browser + // The _scale us how much of the windows height the browser covers: e.g. a browser // that covers 0.25 of the height of the window will have scale = 0.25 - float ratio = static_cast(_objectSize.x) / - static_cast(_objectSize.y); + glm::vec2 floatObjectSize = glm::abs(_objectSize); + float ratio = floatObjectSize.x / floatObjectSize.y; glm::mat4 scale = glm::scale( glm::mat4(1.f), @@ -186,7 +191,7 @@ namespace openspace { _color = color; } - glm::ivec3 ScreenSpaceSkyTarget::getColor() { + glm::ivec3 ScreenSpaceSkyTarget::borderColor() const { return _color; } @@ -196,20 +201,18 @@ namespace openspace { void ScreenSpaceSkyTarget::render() { - glDisable(GL_CULL_FACE); - + bool showCrosshair = _skyBrowser->verticalFov() < _showCrosshairThreshold; + bool showRectangle = _skyBrowser->verticalFov() > _showRectangleThreshold; + glm::vec4 color = { glm::vec3(_color) / 255.f, _opacity.value() }; glm::mat4 modelTransform = globalRotationMatrix() * translationMatrix() * localRotationMatrix() * scaleMatrix(); float lineWidth = 0.0016f/_scale.value(); - _shader->activate(); + glDisable(GL_CULL_FACE); - bool showCrosshair = _verticalFOV < _showCrosshairThreshold; - bool showRect = _verticalFOV > _showRectangleThreshold; - glm::vec4 color = { glm::vec3(_color) / 255.f, _opacity.value() }; - + _shader->activate(); _shader->setUniform(_uniformCache.showCrosshair, showCrosshair); - _shader->setUniform(_uniformCache.showRectangle, showRect); + _shader->setUniform(_uniformCache.showRectangle, showRectangle); _shader->setUniform(_uniformCache.lineWidth, lineWidth); _shader->setUniform(_uniformCache.dimensions, glm::vec2(_objectSize)); _shader->setUniform(_uniformCache.modelTransform, modelTransform); @@ -231,7 +234,7 @@ namespace openspace { _objectSize = dimensions; } - glm::dvec3 ScreenSpaceSkyTarget::getTargetDirectionGalactic() { + glm::dvec3 ScreenSpaceSkyTarget::targetDirectionGalactic() const { glm::dmat4 rotation = glm::inverse( global::navigationHandler->camera()->viewRotationMatrix()); glm::dvec4 position = glm::dvec4(_cartesianPosition.value(), 1.0); @@ -239,20 +242,26 @@ namespace openspace { return glm::normalize(rotation * position); } - void ScreenSpaceSkyTarget::setVerticalFOV(float VFOV) { - _verticalFOV = VFOV; - - // Update the scale of the target - float horizFOV = global::windowDelegate->getHorizFieldOfView(); - glm::ivec2 windowRatio = global::windowDelegate->currentWindowSize(); - float verticFOV = horizFOV * (static_cast(windowRatio.y) / static_cast(windowRatio.x)); - _scale = std::max((VFOV / verticFOV), (_showRectangleThreshold.value() / verticFOV)); + // Update the scale of the target (the height of the target in relation to the + // OpenSpace window) + void ScreenSpaceSkyTarget::setScale(float verticalFov) { + + // Calculate the vertical field of view of the OpenSpace window + float hFovOs = global::windowDelegate->getHorizFieldOfView(); + glm::vec2 windowRatio = glm::vec2(global::windowDelegate->currentWindowSize()); + float vFovOs = hFovOs * windowRatio.y / windowRatio.x; + + // Cap the scale at small scales so it is still visible + float heightRatio = verticalFov / vFovOs; + float smallestHeightRatio = _showRectangleThreshold.value() / vFovOs; + + _scale = std::max(heightRatio, smallestHeightRatio); } void ScreenSpaceSkyTarget::unlock() { _isLocked = false; - if (_lockTargetThread.joinable()) { - _lockTargetThread.join(); + if (_lockTarget.joinable()) { + _lockTarget.join(); } } @@ -261,13 +270,13 @@ namespace openspace { unlock(); } _isLocked = true; - _lockedCoords = getTargetDirectionCelestial(); + _lockedCoordinates = targetDirectionEquatorial(); // Start a thread to enable user interactions while locking target - _lockTargetThread = std::thread([&] { + _lockTarget = std::thread([&] { while (_isLocked) { - glm::vec3 imageCoordsScreenSpace = skybrowser::J2000SphericalToScreenSpace(_lockedCoords); - _cartesianPosition = imageCoordsScreenSpace; + glm::vec3 coordsScreen = skybrowser::equatorialToScreenSpace(_lockedCoordinates); + _cartesianPosition = coordsScreen; } }); } @@ -276,57 +285,55 @@ namespace openspace { return _isLocked; } - glm::dvec2 ScreenSpaceSkyTarget::getTargetDirectionCelestial() { + glm::dvec3 ScreenSpaceSkyTarget::targetDirectionEquatorial() const { // Calculate the galactic coordinate of the target direction - // with infinite radius - glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); - constexpr double infinity = std::numeric_limits::max(); - glm::dvec3 galCoord = camPos + (infinity * getTargetDirectionGalactic()); - return skybrowser::galacticCartesianToJ2000Spherical(galCoord); + // projected onto the celestial sphere + return skybrowser::screenSpaceToEquatorial(_cartesianPosition.value()); } - void ScreenSpaceSkyTarget::animateToCoord(double deltaTime) { + void ScreenSpaceSkyTarget::animateToCoordinate(double deltaTime) { if (_isAnimated) { // Find smallest angle between the two vectors - double smallestAngle = std::acos(glm::dot(_coordsStartAnimation, _coordsEndAnimation) / (glm::length(_coordsStartAnimation) * glm::length(_coordsEndAnimation))); + double smallestAngle = std::acos(glm::dot(_animationStart, _animationEnd) / (glm::length(_animationStart) * glm::length(_animationEnd))); // Only keep animating when target is not at final position if (abs(smallestAngle) > 0.0005) { // Calculate rotation this frame double rotationAngle = smallestAngle * deltaTime * 5.0; // Create the rotation matrix - glm::dvec3 rotationAxis = glm::normalize(glm::cross(_coordsStartAnimation, _coordsEndAnimation)); + glm::dvec3 rotationAxis = glm::normalize(glm::cross(_animationStart, _animationEnd)); glm::dmat4 rotmat = glm::rotate(rotationAngle, rotationAxis); // Rotate target direction - glm::dvec3 newDir = rotmat * glm::dvec4(_coordsStartAnimation, 1.0); - // Convert to screenspace - _cartesianPosition = skybrowser::J2000CartesianToScreenSpace(newDir); + glm::dvec3 newDir = rotmat * glm::dvec4(_animationStart, 1.0); + // Convert to screen space + _cartesianPosition = skybrowser::equatorialToScreenSpace(newDir); // Update position - _coordsStartAnimation = glm::normalize(newDir); + _animationStart = glm::normalize(newDir); } else { // Set the exact target position - _cartesianPosition = skybrowser::J2000CartesianToScreenSpace(_coordsEndAnimation); + _cartesianPosition = skybrowser::equatorialToScreenSpace(_animationEnd); // Lock target when it first arrives to the position if (!_isLocked && _lockAfterAnimation) { lock(); } // When target is in position, animate the FOV until it has finished - if(animateToFOV(_FOVEndAnimation, deltaTime)) { + if(animateToFov(_vfovEndAnimation, deltaTime)) { _isAnimated = false; } } } } - bool ScreenSpaceSkyTarget::animateToFOV(float endFOV, float deltaTime) { + bool ScreenSpaceSkyTarget::animateToFov(float endFOV, float deltaTime) { if (!_skyBrowser) { - initializeWithBrowser(); + findSkyBrowser(); } if (_skyBrowser) { - double distance = static_cast(_skyBrowser->_vfieldOfView.value()) - endFOV; + double distance = static_cast(_skyBrowser->verticalFov()) - endFOV; + // If distance is too large, keep animating if (abs(distance) > 0.01) { - _skyBrowser->scrollZoom(distance); + _skyBrowser->setVerticalFovWithScroll(distance); return false; } // Animation is finished @@ -339,18 +346,22 @@ namespace openspace { return true; } - void ScreenSpaceSkyTarget::startAnimation(glm::dvec2 coordsEnd, float FOVEnd, + void ScreenSpaceSkyTarget::startAnimation(glm::dvec3 coordsEnd, float FOVEnd, bool lockAfterwards) { // Save the Cartesian celestial coordinates for animation // The coordinates are Cartesian to avoid wrap-around issues - _coordsEndAnimation = glm::normalize(skybrowser::sphericalToCartesian(coordsEnd)); - _coordsStartAnimation = glm::normalize(skybrowser::sphericalToCartesian( - getTargetDirectionCelestial())); - _FOVEndAnimation = FOVEnd; + _animationEnd = glm::normalize(coordsEnd); + _animationStart = glm::normalize(targetDirectionEquatorial()); + _vfovEndAnimation = FOVEnd; _isAnimated = true; _lockAfterAnimation = lockAfterwards; } - properties::FloatProperty& ScreenSpaceSkyTarget::getOpacity() { - return _opacity; + + float ScreenSpaceSkyTarget::opacity() const { + return _opacity.value(); + } + + void ScreenSpaceSkyTarget::setOpacity(float opacity) { + _opacity = opacity; } } diff --git a/modules/skybrowser/src/utility.cpp b/modules/skybrowser/src/utility.cpp index 6849559b0a..b83ba06a44 100644 --- a/modules/skybrowser/src/utility.cpp +++ b/modules/skybrowser/src/utility.cpp @@ -12,103 +12,118 @@ namespace openspace::skybrowser { - glm::dvec3 sphericalToCartesian(glm::dvec2 sphericalCoords) { + glm::dvec3 sphericalToCartesian(glm::dvec2 coords) { + + glm::dvec2 coordsRadians = glm::radians(coords); glm::dvec3 cartesian = glm::dvec3( - cos(sphericalCoords.x * DEG_TO_RAD) * cos(sphericalCoords.y * DEG_TO_RAD), - sin(sphericalCoords.x * DEG_TO_RAD) * cos(sphericalCoords.y * DEG_TO_RAD), - sin(sphericalCoords.y * DEG_TO_RAD) + cos(coordsRadians.x) * cos(coordsRadians.y), + sin(coordsRadians.x) * cos(coordsRadians.y), + sin(coordsRadians.y) ); return cartesian; } - glm::dvec2 cartesianToSpherical(glm::dvec3 cartesianCoords) { - - double ra = atan2(cartesianCoords[1], cartesianCoords[0]); - double dec = atan2(cartesianCoords[2], glm::sqrt((cartesianCoords[0] * cartesianCoords[0]) + (cartesianCoords[1] * cartesianCoords[1]))); + glm::dvec2 cartesianToSpherical(glm::dvec3 coord) { + // Equatorial coordinates RA = right ascension, Dec = declination + double ra = atan2(coord.y, coord.x); + double dec = atan2(coord.z, glm::sqrt((coord.x * coord.x) + (coord.y * coord.y))); ra = ra > 0 ? ra : ra + (2 * M_PI); - return glm::dvec2(RAD_TO_DEG * ra, RAD_TO_DEG * dec); + glm::dvec2 celestialCoords{ ra, dec }; + + return glm::degrees(celestialCoords); } - glm::dvec3 galacticCartesianToJ2000Cartesian(glm::dvec3 rGal) { - return glm::transpose(conversionMatrix) * rGal; - } - - glm::dvec2 galacticCartesianToJ2000Spherical(glm::dvec3 rGal) { - return cartesianToSpherical(galacticCartesianToJ2000Cartesian(rGal)); - } - - glm::dvec3 J2000SphericalToGalacticCartesian(glm::dvec2 coords, double distance) { - glm::dvec3 rGalactic = conversionMatrix * sphericalToCartesian(coords); // on the unit sphere - return distance * rGalactic; + glm::dvec3 galacticToEquatorial(glm::dvec3 coords) { + return glm::transpose(conversionMatrix) * glm::normalize(coords); } - glm::dvec3 J2000CartesianToGalacticCartesian(glm::dvec3 coords, double distance) { - glm::dvec3 rGalactic = conversionMatrix * glm::normalize(coords); // on the unit sphere - return distance * rGalactic; + glm::dvec3 equatorialToGalactic(glm::dvec3 coords) { + // On the unit sphere + glm::dvec3 rGalactic = conversionMatrix * glm::normalize(coords); + return rGalactic * CelestialSphereRadius; } - glm::dvec3 galacticToScreenSpace(glm::dvec3 imageCoordsGalacticCartesian) { + glm::dvec3 galacticToScreenSpace(glm::dvec3 coords) { - glm::dvec3 viewDirectionLocal = galacticCartesianToCameraLocalCartesian(imageCoordsGalacticCartesian); - // Ensure that if the coord is behind the camera, the converted coord will be there too - double zCoord = viewDirectionLocal.z > 0 ? -SCREENSPACE_Z : SCREENSPACE_Z; + glm::dvec3 localCameraSpace = galacticToCameraLocal(coords); + // Ensure that if the coord is behind the camera, + // the converted coordinate will be there too + double zCoord = localCameraSpace.z > 0 ? -ScreenSpaceZ : ScreenSpaceZ; // Calculate screen space coords x and y - long double tan_x = viewDirectionLocal.x / viewDirectionLocal.z; - long double tan_y = viewDirectionLocal.y / viewDirectionLocal.z; + double tan_x = localCameraSpace.x / localCameraSpace.z; + double tan_y = localCameraSpace.y / localCameraSpace.z; - glm::dvec2 angleCoordsLocal = glm::dvec2(std::atanl(tan_x), std::atanl(tan_y)); - glm::dvec3 imageCoordsScreenSpace = glm::dvec3(zCoord * static_cast(std::tanl(angleCoordsLocal.x)), zCoord * static_cast(std::tanl(angleCoordsLocal.y)), zCoord); + glm::dvec3 screenSpace = glm::dvec3(zCoord * tan_x, zCoord * tan_y, zCoord); - return imageCoordsScreenSpace; + return screenSpace; + } + + glm::dvec3 screenSpaceToGalactic(glm::dvec3 coords) { + glm::dmat4 rotation = glm::inverse( + global::navigationHandler->camera()->viewRotationMatrix()); + glm::dvec4 position = glm::dvec4(coords, 1.0); + + return glm::normalize(rotation * position) * skybrowser::CelestialSphereRadius; + } + + glm::dvec3 screenSpaceToEquatorial(glm::dvec3 coords) { + // Calculate the galactic coordinate of the target direction + // projected onto the celestial sphere + glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); + glm::dvec3 galactic = camPos + skybrowser::screenSpaceToGalactic(coords); + + return skybrowser::galacticToEquatorial(galactic); } - glm::dvec3 galacticCartesianToCameraLocalCartesian(glm::dvec3 galCoords) { + glm::dvec3 galacticToCameraLocal(glm::dvec3 coords) { // Transform vector to camera's local coordinate system glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); - glm::dvec3 camToCoordsDir = glm::normalize(galCoords - camPos); glm::dmat4 camMat = global::navigationHandler->camera()->viewRotationMatrix(); - glm::dvec3 viewDirectionLocal = camMat * glm::dvec4(camToCoordsDir, 1.0); - viewDirectionLocal = glm::normalize(viewDirectionLocal); - return viewDirectionLocal; + glm::dvec3 viewDirectionWorld = glm::normalize(coords - camPos); + glm::dvec3 viewDirectionLocal = camMat * glm::dvec4(viewDirectionWorld, 1.0); + + return glm::normalize(viewDirectionLocal); } - glm::dvec3 J2000CartesianToScreenSpace(glm::dvec3 coords) { + glm::dvec3 equatorialToScreenSpace(glm::dvec3 coords) { // Transform equatorial J2000 to galactic coord with infinite radius - glm::dvec3 imageCoordsGalacticCartesian = J2000CartesianToGalacticCartesian(coords, infinity); + glm::dvec3 galactic = equatorialToGalactic(coords); // Transform galactic coord to screen space - return galacticToScreenSpace(imageCoordsGalacticCartesian); + return galacticToScreenSpace(galactic); } - glm::dvec3 J2000SphericalToScreenSpace(glm::dvec2 coords) { - // Transform equatorial J2000 to galactic coord with infinite radius - glm::dvec3 imageCoordsGalacticCartesian = J2000SphericalToGalacticCartesian(coords, infinity); - // Transform galactic coord to screen space - return galacticToScreenSpace(imageCoordsGalacticCartesian); - } + double cameraRoll() { + openspace::Camera* camera = global::navigationHandler->camera(); + glm::dvec3 upWorld = camera->lookUpVectorWorldSpace(); + glm::dvec3 forwardWorld = camera->viewDirectionWorldSpace(); - double calculateRoll(glm::dvec3 upWorld, glm::dvec3 forwardWorld) { - glm::dvec3 camUpJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(upWorld); - glm::dvec3 camForwardJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(forwardWorld); + glm::dvec3 camUpJ2000 = skybrowser::galacticToEquatorial(upWorld); + glm::dvec3 camForwardJ2000 = skybrowser::galacticToEquatorial(forwardWorld); - glm::dvec3 crossUpNorth = glm::cross(camUpJ2000, skybrowser::NORTH_POLE); - double dotNorthUp = glm::dot(skybrowser::NORTH_POLE, camUpJ2000); + glm::dvec3 crossUpNorth = glm::cross(camUpJ2000, skybrowser::NorthPole); + double dotNorthUp = glm::dot(skybrowser::NorthPole, camUpJ2000); double dotCrossUpNorthForward = glm::dot(crossUpNorth, camForwardJ2000); - double roll = glm::degrees(atan2(dotCrossUpNorthForward, dotNorthUp)); - return roll; + + return glm::degrees(atan2(dotCrossUpNorthForward, dotNorthUp)); } - glm::dvec3 cameraDirectionJ2000Cartesian() { + glm::dvec3 cameraDirectionEquatorial() { // Get the view direction of the screen in cartesian J2000 coordinates + return galacticToEquatorial(cameraDirectionGalactic()); + } + + glm::dvec3 cameraDirectionGalactic() { + // Get the view direction of the screen in galactic coordinates glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); - constexpr double infinity = std::numeric_limits::max(); - glm::dvec3 galCoord = camPos + (infinity * global::navigationHandler->camera()->viewDirectionWorldSpace()); - glm::dvec3 cartesianJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(galCoord); - return cartesianJ2000; + glm::dvec3 view = global::navigationHandler->camera()->viewDirectionWorldSpace(); + glm::dvec3 galCoord = camPos + (skybrowser::CelestialSphereRadius * view); + + return galCoord; } } @@ -150,7 +165,7 @@ namespace openspace::wwtmessage { return msg; } - ghoul::Dictionary createImageLayer(const std::string& id, const std::string& url) { + ghoul::Dictionary addImage(const std::string& id, const std::string& url) { using namespace std::string_literals; ghoul::Dictionary msg; msg.setValue("event", "image_layer_create"s); @@ -162,7 +177,7 @@ namespace openspace::wwtmessage { return msg; } - ghoul::Dictionary removeImageLayer(const std::string& imageId) { + ghoul::Dictionary removeImage(const std::string& imageId) { using namespace std::string_literals; ghoul::Dictionary msg; msg.setValue("event", "image_layer_remove"s); @@ -171,7 +186,7 @@ namespace openspace::wwtmessage { return msg; } - ghoul::Dictionary setLayerOpacity(const std::string& imageId, double opacity) { + ghoul::Dictionary setImageOpacity(const std::string& imageId, double opacity) { using namespace std::string_literals; ghoul::Dictionary msg; msg.setValue("event", "image_layer_set"s); diff --git a/modules/skybrowser/src/wwtdatahandler.cpp b/modules/skybrowser/src/wwtdatahandler.cpp index 57abb11be4..f08a4b10bd 100644 --- a/modules/skybrowser/src/wwtdatahandler.cpp +++ b/modules/skybrowser/src/wwtdatahandler.cpp @@ -20,20 +20,37 @@ namespace { namespace openspace { - WWTDataHandler::~WWTDataHandler() { - // Call destructor of all allocated xmls - xmls.clear(); + bool hasAttribute(tinyxml2::XMLElement* element, std::string name) { + return element->FindAttribute(name.c_str()); } - bool WWTDataHandler::downloadFile(std::string& url, std::string& fileDestination) { - // Get the webpage and save to file + std::string getAttribute(tinyxml2::XMLElement* element, std::string name) { + if (hasAttribute(element, name)) { + return element->FindAttribute(name.c_str())->Value(); + } + else { + return ""; + } + } + + WwtDataHandler::~WwtDataHandler() { + // Call destructor of all allocated xmls + _xmls.clear(); + } + + bool WwtDataHandler::downloadFile(std::string& url, std::string& fileDestination) { + // Get the web page and save to file HttpRequest::RequestOptions opt{ 5 }; - SyncHttpFileDownload wtml_root(url, fileDestination, HttpFileDownload::Overwrite::Yes); + SyncHttpFileDownload wtml_root( + url, fileDestination, HttpFileDownload::Overwrite::Yes + ); wtml_root.download(opt); return wtml_root.hasSucceeded(); } - void WWTDataHandler::loadWTMLCollectionsFromURL(std::string directory, std::string url, std::string fileName) { + bool WwtDataHandler::loadWtmlCollectionsFromUrl(std::string directory, + std::string url, std::string fileName) + { // Look for WWT image data folder if (!directoryExists(directory)) { std::string newDir = directory; @@ -46,7 +63,7 @@ namespace openspace { std::string file = directory + fileName + ".aspx"; if (!downloadFile(url, file)) { LINFO("Couldn't download file " + url); - return; + return false; } // Parse to XML using namespace tinyxml2; @@ -55,41 +72,52 @@ namespace openspace { XMLElement* root = doc->RootElement(); XMLElement* element = root->FirstChildElement(std::string("Folder").c_str()); + // If there are no folders, or there are folder but without urls, stop recursion - if (!element || (element && !element->FindAttribute("Url"))) { + bool folderExists = element; + bool folderContainNoUrls = folderExists && !hasAttribute(element, "Url"); + + if (!folderExists || folderContainNoUrls) { // Save the url - std::string collectionName = root->FindAttribute("Name") ? root->FindAttribute("Name")->Value() : ""; - if (collectionName != "") { + if (hasAttribute(root, "Name")) { + std::string collectionName = getAttribute(root, "Name"); ImageCollection newCollection{ collectionName, url }; - imageUrls.push_back(newCollection); + _imageUrls.push_back(newCollection); } - xmls.push_back(doc); + _xmls.push_back(doc); LINFO("Saving " + url); - return; + return true; } // Iterate through all the folders while (element && std::string(element->Value()) == "Folder") { - // Get all attributes for the - std::string subUrl = element->FindAttribute("Url") ? element->FindAttribute("Url")->Value() : ""; - std::string subName = element->FindAttribute("Name") ? element->FindAttribute("Name")->Value() : ""; - if (subUrl != "" && subName != "") { - loadWTMLCollectionsFromURL(directory, subUrl, subName); + + // Get all attributes for the + if (hasAttribute(element, "Url") && hasAttribute(element, "Name")) { + std::string subUrl = getAttribute(element, "Url"); + std::string subName = getAttribute(element, "Name"); + loadWtmlCollectionsFromUrl(directory, subUrl, subName); } element = element->NextSiblingElement(); } } - bool WWTDataHandler::directoryExists(std::string& path) + bool WwtDataHandler::directoryExists(std::string& path) { struct stat info; int statRC = stat(path.c_str(), &info); if (statRC != 0) { - if (errno == ENOENT) { return false; } // something along the path does not exist - if (errno == ENOTDIR) { return false; } // something in path prefix is not a dir + // something along the path does not exist + if (errno == ENOENT) { + return false; + } + // something in path prefix is not a dir + if (errno == ENOTDIR) { + return false; + } return false; } @@ -98,43 +126,49 @@ namespace openspace { return directoryExists; } - bool WWTDataHandler::loadWTMLCollectionsFromDirectory(std::string directory) { + bool WwtDataHandler::loadWtmlCollectionsFromDirectory(std::string directory) { if (!directoryExists(directory)) return false; for (const auto& entry : std::filesystem::directory_iterator(directory)) { - tinyxml2::XMLDocument* doc = new tinyxml2::XMLDocument(); - - if (doc->LoadFile(entry.path().u8string().c_str()) == tinyxml2::XMLError::XML_SUCCESS) { - tinyxml2::XMLElement* root = doc->RootElement(); - std::string collectionName = root->FindAttribute("Name") ? root->FindAttribute("Name")->Value() : ""; - if (collectionName != "") { - ImageCollection newCollection{collectionName, entry.path().u8string()}; - imageUrls.push_back(newCollection); + + tinyxml2::XMLDocument* document = new tinyxml2::XMLDocument(); + std::string path = entry.path().u8string(); + tinyxml2::XMLError successCode = document->LoadFile(path.c_str()); + bool fileIsLoaded = successCode == tinyxml2::XMLError::XML_SUCCESS; + + if (fileIsLoaded) { + tinyxml2::XMLElement* root = document->RootElement(); + + if (hasAttribute(root, "Name")) { + std::string collectionName = getAttribute(root, "Name"); + ImageCollection newCollection{ collectionName, path }; + _imageUrls.push_back(newCollection); } - xmls.push_back(doc); + _xmls.push_back(document); } } return true; } std::ostream& operator<<(std::ostream& os, const ImageData& img) { - os << "Name: " << img.name << " Coords: ra: " << img.celestCoords.x << " dec: " << img.celestCoords.y << std::endl; + os << "Name: " << img.name << " Coords: ra: " << img.celestialCoords.x + << " dec: " << img.celestialCoords.y << std::endl; os << "Thumbnail: " << img.thumbnailUrl << std::endl; os << "Collection: " << img.collection << std::endl << std::endl; return os; } - int WWTDataHandler::loadImagesFromLoadedXMLs() { - for (tinyxml2::XMLDocument* doc : xmls) { + int WwtDataHandler::loadImagesFromLoadedXmls() { + for (tinyxml2::XMLDocument* doc : _xmls) { tinyxml2::XMLElement* root = doc->FirstChildElement(); std::string collectionName = root->FindAttribute("Name") ? root->FindAttribute("Name")->Value() : ""; - loadImagesFromXML(root, collectionName); + loadImagesFromXml(root, collectionName); } - // Sort images in alphabetial order - std::sort(images.begin(), images.end(), [](ImageData a, ImageData b) { - // If the first charachter in the names are lowercase, make it upper case + // Sort images in alphabetical order + std::sort(_images.begin(), _images.end(), [](ImageData a, ImageData b) { + // If the first character in the names are lowercase, make it upper case if (std::islower(a.name[0])) { // convert string to upper case a.name[0] = ::toupper(a.name[0]); @@ -144,16 +178,16 @@ namespace openspace { } return a.name < b.name; }); - LINFO(std::to_string(nImagesWith3dPositions) + " 3D positions were matched in the speck files!"); + LINFO(std::to_string(_nImagesWith3dPositions) + " 3D positions were matched in the speck files!"); - return images.size(); + return _images.size(); } - const std::vector& WWTDataHandler::getAllImageCollectionUrls() const { - return imageUrls; + const std::vector& WwtDataHandler::getAllImageCollectionUrls() const { + return _imageUrls; } - void WWTDataHandler::loadImagesFromXML(tinyxml2::XMLElement* node, std::string collectionName) { + void WwtDataHandler::loadImagesFromXml(tinyxml2::XMLElement* node, std::string collectionName) { // Get direct child of node called "Place" using namespace tinyxml2; XMLElement* ptr = node->FirstChildElement(); @@ -171,7 +205,7 @@ namespace openspace { if (ptr->FindAttribute("Name")) { newCollectionName += std::string(ptr->FindAttribute("Name")->Value()); } - loadImagesFromXML(ptr, newCollectionName); + loadImagesFromXml(ptr, newCollectionName); } ptr = ptr->NextSiblingElement(); @@ -179,7 +213,7 @@ namespace openspace { } - int WWTDataHandler::loadImageFromXmlNode(tinyxml2::XMLElement* node, std::string collectionName) { + int WwtDataHandler::loadImageFromXmlNode(tinyxml2::XMLElement* node, std::string collectionName) { // Only load "Sky" type images if (std::string(node->FindAttribute("DataSetType")->Value()) != "Sky") return -1; @@ -195,7 +229,7 @@ namespace openspace { imageSet = node; } else if (std::string(node->Name()) == "Place") { - thumbnailUrl = getURLFromPlace(node); + thumbnailUrl = getUrlFromPlace(node); imageSet = getChildNode(node, "ImageSet"); } else { @@ -218,19 +252,19 @@ namespace openspace { ImageData image{}; setImageDataValues(node, credits, creditsUrl, thumbnailUrl, collectionName, imageUrl, image); - images.push_back(image); + _images.push_back(image); // Return index of image in vector - return images.size(); + return _images.size(); } - std::string WWTDataHandler::getChildNodeContentFromImageSet(tinyxml2::XMLElement* imageSet, std::string elementName) { + std::string WwtDataHandler::getChildNodeContentFromImageSet(tinyxml2::XMLElement* imageSet, std::string elementName) { // FInd the thumbnail image url // The thumbnail is the last node so traverse backwards for speed tinyxml2::XMLElement* imageSetChild = imageSet->FirstChildElement(elementName.c_str()); return imageSetChild ? imageSetChild->GetText() ? imageSetChild->GetText() : "" : ""; } - std::string WWTDataHandler::getURLFromPlace(tinyxml2::XMLElement* place) { + std::string WwtDataHandler::getUrlFromPlace(tinyxml2::XMLElement* place) { // Get thumbnail attribute, if there is one std::string url = place->FindAttribute("Thumbnail") ? place->FindAttribute("Thumbnail")->Value() : ""; // Url found! Return it @@ -244,14 +278,14 @@ namespace openspace { return imageSet ? getChildNodeContentFromImageSet(imageSet, "ThumbnailUrl") : ""; } - tinyxml2::XMLElement* WWTDataHandler::getDirectChildNode(tinyxml2::XMLElement* node, std::string name) { + tinyxml2::XMLElement* WwtDataHandler::getDirectChildNode(tinyxml2::XMLElement* node, std::string name) { while (node && std::string(node->Name()) != name) { node = node->FirstChildElement(); } return node; } - tinyxml2::XMLElement* WWTDataHandler::getChildNode(tinyxml2::XMLElement* node, std::string name) { + tinyxml2::XMLElement* WwtDataHandler::getChildNode(tinyxml2::XMLElement* node, std::string name) { // Traverse the children and look at all their first child to find ImageSet tinyxml2::XMLElement* child = node->FirstChildElement(); tinyxml2::XMLElement* imageSet = nullptr; @@ -263,7 +297,7 @@ namespace openspace { return imageSet; } - void WWTDataHandler::setImageDataValues(tinyxml2::XMLElement* node, + void WwtDataHandler::setImageDataValues(tinyxml2::XMLElement* node, std::string credits, std::string creditsUrl, std::string thumbnail, @@ -272,11 +306,11 @@ namespace openspace { ImageData& img) { // Get attributes for the image img.name = node->FindAttribute("Name") ? node->FindAttribute("Name")->Value() : ""; - img.hasCelestCoords = node->FindAttribute("RA") && node->FindAttribute("Dec"); - if (img.hasCelestCoords) { + img.hasCelestialCoords = node->FindAttribute("RA") && node->FindAttribute("Dec"); + if (img.hasCelestialCoords) { // The RA from WWT is in the unit hours: to convert to degrees, multiply with 360 (deg) /24 (h) = 15 - img.celestCoords.x = 15.0f * std::stof(node->FindAttribute("RA")->Value()); - img.celestCoords.y = std::stof(node->FindAttribute("Dec")->Value()); + img.celestialCoords.x = 15.0f * std::stof(node->FindAttribute("RA")->Value()); + img.celestialCoords.y = std::stof(node->FindAttribute("Dec")->Value()); } img.collection = collectionName; img.thumbnailUrl = thumbnail; @@ -292,15 +326,15 @@ namespace openspace { if (it != _3dPositions.end()) { img.position3d = it->second; img.has3dCoords = true; - nImagesWith3dPositions++; + _nImagesWith3dPositions++; } } - std::vector& WWTDataHandler::getLoadedImages() { - return images; + std::vector& WwtDataHandler::getLoadedImages() { + return _images; } - void WWTDataHandler::loadSpeckData(speck::Dataset& dataset) { + void WwtDataHandler::loadSpeckData(speck::Dataset& dataset) { for (speck::Dataset::Entry entry : dataset.entries) { if (entry.comment.has_value()) { std::string name = createSearchableString(entry.comment.value()); @@ -310,7 +344,7 @@ namespace openspace { LINFO("Loaded speck file with " + std::to_string(_3dPositions.size()) + " entries!"); } - std::string WWTDataHandler::createSearchableString(std::string str) { + std::string WwtDataHandler::createSearchableString(std::string str) { // Remove white spaces and all special characters str.erase(std::remove_if(str.begin(), str.end(), [](char c) { bool isNumberOrLetter = std::isdigit(c) || std::isalpha(c); @@ -322,7 +356,6 @@ namespace openspace { [](unsigned char c) { return std::tolower(c); }); return str; } - } // Loading of speck files diff --git a/src/rendering/screenspacerenderable.cpp b/src/rendering/screenspacerenderable.cpp index a5e3172ed9..a91dff3d6c 100644 --- a/src/rendering/screenspacerenderable.cpp +++ b/src/rendering/screenspacerenderable.cpp @@ -498,25 +498,25 @@ glm::mat4 ScreenSpaceRenderable::scaleMatrix() { return scale; } -glm::vec2 ScreenSpaceRenderable::getScreenSpacePosition() { +glm::vec2 ScreenSpaceRenderable::screenSpacePosition() { return glm::vec2(_cartesianPosition.value().x, _cartesianPosition.value().y); } -glm::vec2 ScreenSpaceRenderable::getScreenSpaceDimensions() { +glm::vec2 ScreenSpaceRenderable::screenSpaceDimensions() { return glm::vec2(2.f * _scale * static_cast(_objectSize.x) / static_cast(_objectSize.y), 2.f * _scale); } -glm::vec2 ScreenSpaceRenderable::getUpperRightCornerScreenSpace() { - return getScreenSpacePosition() + (getScreenSpaceDimensions() / 2.0f); +glm::vec2 ScreenSpaceRenderable::upperRightCornerScreenSpace() { + return screenSpacePosition() + (screenSpaceDimensions() / 2.0f); } -glm::vec2 ScreenSpaceRenderable::getLowerLeftCornerScreenSpace() { - return getScreenSpacePosition() - (getScreenSpaceDimensions() / 2.0f); +glm::vec2 ScreenSpaceRenderable::lowerLeftCornerScreenSpace() { + return screenSpacePosition() - (screenSpaceDimensions() / 2.0f); } bool ScreenSpaceRenderable::coordIsInsideCornersScreenSpace(glm::vec2 coord) { - bool lessThanUpperRight = coord.x < getUpperRightCornerScreenSpace().x && coord.y < getUpperRightCornerScreenSpace().y; - bool moreThanLowerLeft = coord.x > getLowerLeftCornerScreenSpace().x && coord.y > getLowerLeftCornerScreenSpace().y; + bool lessThanUpperRight = coord.x < upperRightCornerScreenSpace().x && coord.y < upperRightCornerScreenSpace().y; + bool moreThanLowerLeft = coord.x > lowerLeftCornerScreenSpace().x && coord.y > lowerLeftCornerScreenSpace().y; return lessThanUpperRight && moreThanLowerLeft; }