mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 11:09:37 -06:00
Add functionality for 3D browser: wwt messages and function to create an instance in lua api
This commit is contained in:
@@ -50,6 +50,10 @@ namespace openspace {
|
||||
|
||||
void update(const UpdateData& data) override;
|
||||
|
||||
void executeJavascript(std::string script) const;
|
||||
bool sendMessageToWWT(const ghoul::Dictionary& msg);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
properties::Vec2Property _dimensions;
|
||||
|
||||
@@ -20,17 +20,7 @@ namespace openspace {
|
||||
|
||||
// Communication with the webpage and WWT
|
||||
void executeJavascript(std::string script) const;
|
||||
ghoul::Dictionary createMessageForMovingWWTCamera(const glm::dvec2 celestCoords, const double fov, const bool moveInstantly = true) const;
|
||||
ghoul::Dictionary createMessageForPausingWWTTime() const;
|
||||
ghoul::Dictionary createMessageForLoadingWWTImgColl(const std::string& url) const;
|
||||
ghoul::Dictionary createMessageForSettingForegroundWWT(const std::string& name) const;
|
||||
ghoul::Dictionary createMessageForSettingForegroundOpacityWWT(double val) const;
|
||||
ghoul::Dictionary createMessageForAddingImageLayerWWT(ImageData& url);
|
||||
ghoul::Dictionary createMessageForRemovingImageLayerWWT(const std::string& id) const;
|
||||
ghoul::Dictionary createMessageForSettingOpacityLayerWWT(const ImageData& id, double opacity) const;
|
||||
|
||||
bool sendMessageToWWT(const ghoul::Dictionary& msg);
|
||||
void sendMouseEvent(CefStructBase<CefMouseEventTraits> event, int x, int y) const;
|
||||
void WWTfollowCamera();
|
||||
float fieldOfView() const;
|
||||
void setVerticalFieldOfView(float fov);
|
||||
@@ -38,6 +28,7 @@ namespace openspace {
|
||||
ScreenSpaceSkyTarget* getSkyTarget();
|
||||
bool hasLoadedCollections();
|
||||
void setHasLoadedCollections(bool isLoaded);
|
||||
void addImage(ImageData& image);
|
||||
|
||||
// Translation
|
||||
//void translate(glm::vec2 translation);
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <modules/skybrowser/include/wwtdatahandler.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/util/camera.h>
|
||||
@@ -7,34 +8,51 @@
|
||||
#include <math.h>
|
||||
|
||||
|
||||
namespace openspace::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<float>::max();
|
||||
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<float>::max();
|
||||
|
||||
// Conversion matrix from this paper: 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
|
||||
});
|
||||
// Conversion matrix from this paper: 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);
|
||||
// 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);
|
||||
}
|
||||
namespace wwtmessage {
|
||||
// WWT messages
|
||||
ghoul::Dictionary moveCamera(const glm::dvec2 celestCoords,
|
||||
const double fov, const bool moveInstantly = true);
|
||||
ghoul::Dictionary loadCollection(const std::string& url);
|
||||
ghoul::Dictionary setForeground(const std::string& name);
|
||||
ghoul::Dictionary createImageLayer(ImageData& image, int id = 0);
|
||||
ghoul::Dictionary removeImageLayer(const std::string& id);
|
||||
ghoul::Dictionary setLayerOpacity(const ImageData& image,
|
||||
double opacity);
|
||||
ghoul::Dictionary setForegroundOpacity(double val);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -62,8 +62,9 @@ namespace openspace {
|
||||
std::string creditsUrl;
|
||||
glm::dvec2 celestCoords;
|
||||
std::string collection;
|
||||
float zoomLevel;
|
||||
bool hasCoords;
|
||||
float fov;
|
||||
bool hasCelestCoords{ false };
|
||||
bool has3dCoords{ false };
|
||||
glm::dvec3 position3d;
|
||||
int id{ NO_ID };
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <openspace/util/factorymanager.h>
|
||||
@@ -144,6 +145,14 @@ namespace openspace {
|
||||
"Add one or multiple exoplanet systems to the scene, as specified by the "
|
||||
"input. An input string should be the name of the system host star"
|
||||
},
|
||||
{
|
||||
"create3dSkyBrowser",
|
||||
&skybrowser::luascriptfunctions::create3dSkyBrowser,
|
||||
{},
|
||||
"string or list of strings",
|
||||
"Add one or multiple exoplanet systems to the scene, as specified by the "
|
||||
"input. An input string should be the name of the system host star"
|
||||
},
|
||||
};
|
||||
|
||||
return res;
|
||||
@@ -391,6 +400,10 @@ void SkyBrowserModule::addRenderable(ScreenSpaceRenderable* object) {
|
||||
}
|
||||
}
|
||||
|
||||
void SkyBrowserModule::add3dBrowser(SceneGraphNode* node) {
|
||||
browsers3d.push_back(node);
|
||||
}
|
||||
|
||||
ScreenSpaceSkyBrowser* SkyBrowserModule::to_browser(ScreenSpaceRenderable* ptr) {
|
||||
return dynamic_cast<ScreenSpaceSkyBrowser*>(ptr);
|
||||
}
|
||||
@@ -468,9 +481,10 @@ int SkyBrowserModule::loadImages(const std::string& root, const std::string& dir
|
||||
dataHandler->loadSpeckData(speckOpenClusters);
|
||||
|
||||
int nLoadedImages;
|
||||
|
||||
// Read from disc
|
||||
|
||||
bool loadedImages = dataHandler->loadWTMLCollectionsFromDirectory(directory);
|
||||
|
||||
// Reading from url if there is no directory
|
||||
if (loadedImages) {
|
||||
LINFO("Loading images from directory");
|
||||
|
||||
@@ -44,6 +44,7 @@ class ScreenSpaceSkyTarget;
|
||||
class RenderableSkyBrowser;
|
||||
class ScreenSpaceRenderable;
|
||||
class WWTDataHandler;
|
||||
class SceneGraphNode;
|
||||
|
||||
|
||||
class SkyBrowserModule : public OpenSpaceModule {
|
||||
@@ -64,6 +65,7 @@ public:
|
||||
void setSelectedBrowser(int i);
|
||||
int getSelectedBrowserIndex();
|
||||
int loadImages(const std::string& root, const std::string& directory);
|
||||
void add3dBrowser(SceneGraphNode* node);
|
||||
|
||||
scripting::LuaLibrary luaLibrary() const override;
|
||||
//std::vector<documentation::Documentation> documentations() const override;
|
||||
@@ -81,6 +83,7 @@ protected:
|
||||
// Renderable vector and ptr to where mouse is
|
||||
std::vector<ScreenSpaceRenderable*> renderables;
|
||||
std::vector<ScreenSpaceSkyBrowser*> browsers;
|
||||
std::vector<SceneGraphNode*> browsers3d;
|
||||
ScreenSpaceRenderable* _mouseOnObject;
|
||||
// Dragging
|
||||
glm::vec2 startDragMousePos;
|
||||
|
||||
@@ -2,28 +2,29 @@
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <modules/skybrowser/skybrowsermodule.h>
|
||||
#include <modules/skybrowser/include/utility.h>
|
||||
#include <modules/skybrowser/include/screenspaceskybrowser.h>
|
||||
#include <modules/skybrowser/include/screenspaceskytarget.h>
|
||||
#include <modules/skybrowser/include/renderableskybrowser.h>
|
||||
#include <modules/base/rendering/screenspaceimagelocal.h>
|
||||
#include <modules/base/rendering/renderableplaneimagelocal.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/scripting/scriptengine.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/util/distanceconstants.h>
|
||||
#include <ghoul/misc/dictionaryluaformatter.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/fmt.h>
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <modules/skybrowser/include/screenspaceskybrowser.h>
|
||||
#include <modules/skybrowser/include/screenspaceskytarget.h>
|
||||
#include <modules/skybrowser/include/renderableskybrowser.h>
|
||||
#include <modules/base/rendering/screenspaceimagelocal.h>
|
||||
#include <modules/base/rendering/renderableplaneimagelocal.h>
|
||||
#include <openspace/interaction/navigationhandler.h>
|
||||
#include <openspace/util/camera.h>
|
||||
#include <thread>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <glm/gtx/vector_angle.hpp>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <thread>
|
||||
#include <limits>
|
||||
|
||||
namespace {
|
||||
@@ -39,36 +40,39 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
const int i = ghoul::lua::value<int>(L, 1);
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
ScreenSpaceSkyBrowser* selectedBrowser = module->getSkyBrowsers()[module->getSelectedBrowserIndex()];
|
||||
ScreenSpaceSkyTarget* selectedTarget = selectedBrowser->getSkyTarget();
|
||||
|
||||
ImageData& resultImage = module->getWWTDataHandler()->getLoadedImages()[i];
|
||||
if (selectedBrowser) {
|
||||
ScreenSpaceSkyTarget* selectedTarget = selectedBrowser->getSkyTarget();
|
||||
|
||||
// Load image, if the image has not been loaded yet
|
||||
if (resultImage.id == ImageData::NO_ID) {
|
||||
LINFO("Loading image " + resultImage.name);
|
||||
selectedBrowser->sendMessageToWWT(selectedBrowser->createMessageForAddingImageLayerWWT(resultImage));
|
||||
selectedBrowser->sendMessageToWWT(selectedBrowser->createMessageForSettingOpacityLayerWWT(resultImage, 1.0));
|
||||
}
|
||||
|
||||
// If the image has coordinates, move the target
|
||||
if (resultImage.hasCoords) {
|
||||
// Animate the target to the image coord position
|
||||
// In WWT, the definition of ZoomLevel is: VFOV = ZoomLevel / 6
|
||||
if (selectedTarget) {
|
||||
selectedTarget->unlock();
|
||||
selectedTarget->startAnimation(resultImage.celestCoords, resultImage.zoomLevel / 6);
|
||||
glm::dvec3 imgCoordsOnScreen = J2000SphericalToScreenSpace(resultImage.celestCoords);
|
||||
glm::vec2 windowRatio = global::windowDelegate->currentWindowSize();
|
||||
float r = windowRatio.x / windowRatio.y;
|
||||
// Check if image coordinate is within current FOV
|
||||
bool coordIsWithinView = (abs(imgCoordsOnScreen.x) < r && abs(imgCoordsOnScreen.y) < 1.f && imgCoordsOnScreen.z < 0);
|
||||
bool coordIsBehindCamera = imgCoordsOnScreen.z > 0;
|
||||
// If the coordinate is not in view, rotate camera
|
||||
if (!coordIsWithinView || coordIsBehindCamera) {
|
||||
module->startRotation(resultImage.celestCoords);
|
||||
ImageData& resultImage = module->getWWTDataHandler()->getLoadedImages()[i];
|
||||
|
||||
// Load image, if the image has not been loaded yet
|
||||
if (resultImage.id == ImageData::NO_ID) {
|
||||
LINFO("Loading image " + resultImage.name);
|
||||
selectedBrowser->addImage(resultImage);
|
||||
}
|
||||
|
||||
// If the image has coordinates, move the target
|
||||
if (resultImage.hasCelestCoords) {
|
||||
// Animate the target to the image coord position
|
||||
if (selectedTarget) {
|
||||
selectedTarget->unlock();
|
||||
selectedTarget->startAnimation(resultImage.celestCoords, resultImage.fov);
|
||||
glm::dvec3 imgCoordsOnScreen = J2000SphericalToScreenSpace(resultImage.celestCoords);
|
||||
glm::vec2 windowRatio = global::windowDelegate->currentWindowSize();
|
||||
float r = windowRatio.x / windowRatio.y;
|
||||
// Check if image coordinate is within current FOV
|
||||
bool coordIsWithinView = (abs(imgCoordsOnScreen.x) < r && abs(imgCoordsOnScreen.y) < 1.f && imgCoordsOnScreen.z < 0);
|
||||
bool coordIsBehindCamera = imgCoordsOnScreen.z > 0;
|
||||
// If the coordinate is not in view, rotate camera
|
||||
if (!coordIsWithinView || coordIsBehindCamera) {
|
||||
module->startRotation(resultImage.celestCoords);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
LINFO("No browser selected!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -81,7 +85,7 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
const ImageData& resultImage = module->getWWTDataHandler()->getLoadedImages()[i];
|
||||
|
||||
// Only move and show circle if the image has coordinates
|
||||
if (resultImage.hasCoords) {
|
||||
if (resultImage.hasCelestCoords) {
|
||||
// Make circle visible
|
||||
ScreenSpaceImageLocal* hoverCircle = dynamic_cast<ScreenSpaceImageLocal*>(global::renderEngine->screenSpaceRenderable("HoverCircle"));
|
||||
hoverCircle->property("Enabled")->set(true);
|
||||
@@ -139,7 +143,7 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/wwt-web-client/master/assets/webclient-explore-root.wtml";
|
||||
for (ScreenSpaceSkyBrowser* browser : module->getSkyBrowsers()) {
|
||||
if (!browser->hasLoadedCollections()) {
|
||||
browser->sendMessageToWWT(browser->createMessageForLoadingWWTImgColl(root));
|
||||
browser->sendMessageToWWT(wwtmessage::loadCollection(root));
|
||||
browser->setHasLoadedCollections(true);
|
||||
}
|
||||
}
|
||||
@@ -167,36 +171,42 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
|
||||
for (int i = 0; i < images.size(); i++) {
|
||||
std::string name = images[i].name != "" ? images[i].name : "undefined";
|
||||
std::string url = images[i].thumbnailUrl != "" ? images[i].thumbnailUrl : "undefined";
|
||||
std::string thumbnail = images[i].thumbnailUrl != "" ? images[i].thumbnailUrl : "undefined";
|
||||
glm::dvec3 cartCoords = skybrowser::sphericalToCartesian(images[i].celestCoords);
|
||||
std::vector<double> cartCoordsVec = { cartCoords.x, cartCoords.y, cartCoords.z };
|
||||
glm::dvec3 position = images[i].position3d;
|
||||
std::vector<double> position3d = { position.x, position.y, position.z };
|
||||
|
||||
// Index for current ImageData
|
||||
ghoul::lua::push(L, i + 1);
|
||||
lua_newtable(L);
|
||||
// Push ("Key", value)
|
||||
ghoul::lua::push(L, "Name", name);
|
||||
ghoul::lua::push(L, "name", name);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Thumbnail", url);
|
||||
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].celestCoords.x);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Dec", images[i].celestCoords.y);
|
||||
ghoul::lua::push(L, "dec", images[i].celestCoords.y);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "CartesianDirection", cartCoordsVec);
|
||||
ghoul::lua::push(L, "cartesianDirection", cartCoordsVec);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "HasCoords", images[i].hasCoords);
|
||||
ghoul::lua::push(L, "hasCelestialCoords", images[i].hasCelestCoords);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Credits", images[i].credits);
|
||||
ghoul::lua::push(L, "credits", images[i].credits);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "CreditsUrl", images[i].creditsUrl);
|
||||
ghoul::lua::push(L, "creditsUrl", images[i].creditsUrl);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Index", i);
|
||||
ghoul::lua::push(L, "identifier", std::to_string(i));
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "has3dCoords", images[i].has3dCoords);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "position3d", position3d);
|
||||
lua_settable(L, -3);
|
||||
// Set table for the current ImageData
|
||||
lua_settable(L, -3);
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -229,15 +239,15 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
float VFOV = HFOV * (windowRatio.y / windowRatio.x);
|
||||
double FOV = std::min(HFOV, VFOV);
|
||||
// Push window data
|
||||
ghoul::lua::push(L, "WindowHFOV", FOV);
|
||||
ghoul::lua::push(L, "windowHFOV", FOV);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "CartesianDirection", viewDirCelestVec);
|
||||
ghoul::lua::push(L, "cartesianDirection", viewDirCelestVec);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "RA", sphericalJ2000.x);
|
||||
ghoul::lua::push(L, "ra", sphericalJ2000.x);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Dec", sphericalJ2000.y);
|
||||
ghoul::lua::push(L, "dec", sphericalJ2000.y);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "SelectedBrowserIndex", module->getSelectedBrowserIndex());
|
||||
ghoul::lua::push(L, "selectedBrowserIndex", module->getSelectedBrowserIndex());
|
||||
lua_settable(L, -3);
|
||||
// Set table for the current ImageData
|
||||
lua_settable(L, -3);
|
||||
@@ -262,13 +272,13 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
// Push ("Key", value)
|
||||
ghoul::lua::push(L, "FOV", browser->fieldOfView());
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "CartesianDirection", celestialCartVec);
|
||||
ghoul::lua::push(L, "cartesianDirection", celestialCartVec);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "RA", celestialSpherical.x);
|
||||
ghoul::lua::push(L, "ra", celestialSpherical.x);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Dec", celestialSpherical.y);
|
||||
ghoul::lua::push(L, "dec", celestialSpherical.y);
|
||||
lua_settable(L, -3);
|
||||
ghoul::lua::push(L, "Color", colorVec);
|
||||
ghoul::lua::push(L, "color", colorVec);
|
||||
lua_settable(L, -3);
|
||||
|
||||
// Set table for the current target
|
||||
@@ -299,6 +309,81 @@ namespace openspace::skybrowser::luascriptfunctions {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int create3dSkyBrowser(lua_State* L) {
|
||||
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::create3dSkyBrowser");
|
||||
// Image index to place in 3D
|
||||
const int i = ghoul::lua::value<int>(L, 1);
|
||||
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
|
||||
ImageData image = module->getWWTDataHandler()->getLoadedImages()[i];
|
||||
|
||||
// If the image has a 3D position, add it to the scene graph
|
||||
if (image.has3dCoords) {
|
||||
std::string id = "SkyBrowser" + std::to_string(i);
|
||||
glm::dvec3 position = image.position3d * distanceconstants::Parsec;
|
||||
std::string translation = ghoul::to_string(position);
|
||||
std::string guiPath = "/SkyBrowser";
|
||||
|
||||
// Calculate the size of the plane with trigonometry
|
||||
// Calculate in equatorial coordinate system since the FOV is from Earth
|
||||
// /|
|
||||
// /_| Adjacent is the horizontal line, opposite the vertical
|
||||
// \ | Calculate for half the triangle first, then multiply with 2
|
||||
// \|
|
||||
glm::dvec3 j2000 = skybrowser::galacticCartesianToJ2000Cartesian(position);
|
||||
double adjacent = glm::length(j2000);
|
||||
double opposite = 2 * adjacent * glm::tan(image.fov * 0.5);
|
||||
|
||||
// Calculate rotation to make the plane face the solar system barycenter
|
||||
glm::dvec3 normal = glm::normalize(-position);
|
||||
glm::dvec3 newRight = glm::normalize(
|
||||
glm::cross(glm::dvec3(0.0, 0.0, 1.0), normal)
|
||||
);
|
||||
glm::dvec3 newUp = glm::cross(normal, newRight);
|
||||
|
||||
glm::dmat3 originOrientedRotation = glm::dmat3(1.0);
|
||||
originOrientedRotation[0] = newRight;
|
||||
originOrientedRotation[1] = newUp;
|
||||
originOrientedRotation[2] = normal;
|
||||
|
||||
|
||||
const std::string browser = "{"
|
||||
"Identifier = '" + id + "',"
|
||||
"Parent = 'SolarSystemBarycenter',"
|
||||
"Renderable = {"
|
||||
"Type = 'RenderableSkyBrowser',"
|
||||
"Size = " + std::to_string(opposite) +","
|
||||
"Origin = 'Center',"
|
||||
"Billboard = false,"
|
||||
"Url = 'http://localhost:8000'"
|
||||
"},"
|
||||
"Transform = {"
|
||||
"Translation = {"
|
||||
"Type = 'StaticTranslation',"
|
||||
"Position = " + translation + ""
|
||||
"},"
|
||||
"Rotation = {"
|
||||
"Type = 'StaticRotation',"
|
||||
"Rotation = " + ghoul::to_string(originOrientedRotation) + ""
|
||||
"}"
|
||||
"},"
|
||||
"GUI = {"
|
||||
"Name = '" + image.name + "',"
|
||||
"Path = '" + guiPath + "'"
|
||||
"}"
|
||||
"}";
|
||||
LINFO(browser);
|
||||
openspace::global::scriptEngine->queueScript(
|
||||
"openspace.addSceneGraphNode(" + browser + ");",
|
||||
scripting::ScriptEngine::RemoteScripting::Yes
|
||||
);
|
||||
}
|
||||
else {
|
||||
LINFO("Image has no 3D coordinate!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -6,12 +6,14 @@
|
||||
#include <openspace/engine/windowdelegate.h>
|
||||
#include <openspace/engine/moduleengine.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <ghoul/misc/dictionaryjsonformatter.h> // formatJson
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -112,6 +114,7 @@ namespace openspace {
|
||||
|
||||
_browserInstance->initialize();
|
||||
_browserInstance->loadUrl(_url);
|
||||
_dimensions = _texture->dimensions();
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::deinitializeGL() {
|
||||
@@ -153,7 +156,6 @@ namespace openspace {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RenderableSkyBrowser::bindTexture() {
|
||||
if (_texture) {
|
||||
_texture->bind();
|
||||
@@ -162,4 +164,18 @@ namespace openspace {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderableSkyBrowser::executeJavascript(std::string script) const {
|
||||
//LINFOC(_loggerCat, "Executing javascript " + script);
|
||||
if (_browserInstance && _browserInstance->getBrowser() && _browserInstance->getBrowser()->GetMainFrame()) {
|
||||
CefRefPtr<CefFrame> frame = _browserInstance->getBrowser()->GetMainFrame();
|
||||
frame->ExecuteJavaScript(script, frame->GetURL(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderableSkyBrowser::sendMessageToWWT(const ghoul::Dictionary& msg) {
|
||||
std::string script = "sendMessageToWWT(" + ghoul::formatJson(msg) + ");";
|
||||
executeJavascript(script);
|
||||
return true;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
@@ -230,113 +230,14 @@ namespace openspace {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForMovingWWTCamera(const glm::dvec2 celestCoords, const double fov, const bool moveInstantly) const {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
|
||||
glm::dvec3 camUpJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(global::navigationHandler->camera()->lookUpVectorWorldSpace());
|
||||
glm::dvec3 camForwardJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(global::navigationHandler->camera()->viewDirectionWorldSpace());
|
||||
double angle = glm::degrees(atan2(glm::dot(glm::cross(camUpJ2000, skybrowser::NORTH_POLE), camForwardJ2000), glm::dot(skybrowser::NORTH_POLE, camUpJ2000)));
|
||||
|
||||
msg.setValue("event", "center_on_coordinates"s);
|
||||
msg.setValue("ra", celestCoords.x);
|
||||
msg.setValue("dec", celestCoords.y);
|
||||
msg.setValue("fov", fov);
|
||||
msg.setValue("roll", angle);
|
||||
msg.setValue("instant", moveInstantly);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForLoadingWWTImgColl(const std::string& url) const {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "load_image_collection"s);
|
||||
msg.setValue("url", url);
|
||||
msg.setValue("loadChildFolders", true);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForSettingForegroundWWT(const std::string& name) const {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "set_foreground_by_name"s);
|
||||
msg.setValue("name", name);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForAddingImageLayerWWT(ImageData& image) {
|
||||
std::string idString = std::to_string(_imageId);
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
image.id = _imageId;
|
||||
msg.setValue("event", "image_layer_create"s);
|
||||
msg.setValue("id", idString);
|
||||
msg.setValue("url", image.imageUrl);
|
||||
_imageId++;
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForRemovingImageLayerWWT(const std::string& id) const {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "image_layer_remove"s);
|
||||
msg.setValue("id", id);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForSettingOpacityLayerWWT(const ImageData& image, double opacity) const {
|
||||
std::string idString = std::to_string(image.id);
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "image_layer_set"s);
|
||||
msg.setValue("id", idString);
|
||||
msg.setValue("setting", "opacity"s);
|
||||
msg.setValue("value", opacity);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForSettingForegroundOpacityWWT(double val) const {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "set_foreground_opacity"s);
|
||||
msg.setValue("value", val);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary ScreenSpaceSkyBrowser::createMessageForPausingWWTTime() const {
|
||||
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "pause_time"s);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::sendMouseEvent(CefStructBase<CefMouseEventTraits> event, int x, int y) const {
|
||||
//LINFOC(_loggerCat, "Executing javascript " + script);
|
||||
LINFO(std::to_string(_objectSize.x) + " " + std::to_string(_objectSize.y));
|
||||
if (_browserInstance && _browserInstance->getBrowser() && _browserInstance->getBrowser()->GetHost()) {
|
||||
|
||||
//_browserInstance->getBrowser()->GetHost()->SendMouseWheelEvent(event, x, y);
|
||||
//LINFOC(_loggerCat, "Sending scroll");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::WWTfollowCamera() {
|
||||
|
||||
// Start a thread to enable user interaction while sending the calls to WWT
|
||||
_threadWWTMessages = std::thread([&] {
|
||||
while (_camIsSyncedWWT) {
|
||||
if (_skyTarget) {
|
||||
ghoul::Dictionary message = createMessageForMovingWWTCamera(_skyTarget->getTargetDirectionCelestial(), _vfieldOfView);
|
||||
glm::dvec2 aim = _skyTarget->getTargetDirectionCelestial();
|
||||
ghoul::Dictionary message = wwtmessage::moveCamera(aim, _vfieldOfView);
|
||||
sendMessageToWWT(message);
|
||||
}
|
||||
|
||||
@@ -414,4 +315,10 @@ namespace openspace {
|
||||
glm::vec2 ScreenSpaceSkyBrowser::getBrowserPixelDimensions() {
|
||||
return _browserDimensions.value();
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::addImage(ImageData& image) {
|
||||
sendMessageToWWT(wwtmessage::createImageLayer(image, _imageId));
|
||||
sendMessageToWWT(wwtmessage::setLayerOpacity(image, 1.0));
|
||||
_imageId++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,86 +12,177 @@
|
||||
|
||||
namespace openspace::skybrowser {
|
||||
|
||||
glm::dvec3 sphericalToCartesian(glm::dvec2 sphericalCoords) {
|
||||
glm::dvec3 sphericalToCartesian(glm::dvec2 sphericalCoords) {
|
||||
|
||||
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)
|
||||
);
|
||||
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)
|
||||
);
|
||||
|
||||
return cartesian;
|
||||
}
|
||||
return cartesian;
|
||||
}
|
||||
|
||||
glm::dvec2 cartesianToSpherical(glm::dvec3 cartesianCoords) {
|
||||
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])));
|
||||
double ra = atan2(cartesianCoords[1], cartesianCoords[0]);
|
||||
double dec = atan2(cartesianCoords[2], glm::sqrt((cartesianCoords[0] * cartesianCoords[0]) + (cartesianCoords[1] * cartesianCoords[1])));
|
||||
|
||||
ra = ra > 0 ? ra : ra + (2 * M_PI);
|
||||
ra = ra > 0 ? ra : ra + (2 * M_PI);
|
||||
|
||||
return glm::dvec2(RAD_TO_DEG * ra, RAD_TO_DEG * dec);
|
||||
}
|
||||
return glm::dvec2(RAD_TO_DEG * ra, RAD_TO_DEG * dec);
|
||||
}
|
||||
|
||||
glm::dvec3 galacticCartesianToJ2000Cartesian(glm::dvec3 rGal) {
|
||||
return glm::transpose(conversionMatrix) * rGal;
|
||||
}
|
||||
glm::dvec3 galacticCartesianToJ2000Cartesian(glm::dvec3 rGal) {
|
||||
return glm::transpose(conversionMatrix) * rGal;
|
||||
}
|
||||
|
||||
glm::dvec2 galacticCartesianToJ2000Spherical(glm::dvec3 rGal) {
|
||||
return cartesianToSpherical(galacticCartesianToJ2000Cartesian(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 J2000SphericalToGalacticCartesian(glm::dvec2 coords, double distance) {
|
||||
glm::dvec3 rGalactic = conversionMatrix * sphericalToCartesian(coords); // on the unit sphere
|
||||
return distance * rGalactic;
|
||||
}
|
||||
|
||||
glm::dvec3 J2000CartesianToGalacticCartesian(glm::dvec3 coords, double distance) {
|
||||
glm::dvec3 rGalactic = conversionMatrix * glm::normalize(coords); // on the unit sphere
|
||||
return distance * rGalactic;
|
||||
}
|
||||
glm::dvec3 J2000CartesianToGalacticCartesian(glm::dvec3 coords, double distance) {
|
||||
glm::dvec3 rGalactic = conversionMatrix * glm::normalize(coords); // on the unit sphere
|
||||
return distance * rGalactic;
|
||||
}
|
||||
|
||||
glm::dvec3 galacticToScreenSpace(glm::dvec3 imageCoordsGalacticCartesian) {
|
||||
glm::dvec3 galacticToScreenSpace(glm::dvec3 imageCoordsGalacticCartesian) {
|
||||
|
||||
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 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;
|
||||
|
||||
// Calculate screen space coords x and y
|
||||
long double tan_x = viewDirectionLocal.x / viewDirectionLocal.z;
|
||||
long double tan_y = viewDirectionLocal.y / viewDirectionLocal.z;
|
||||
// Calculate screen space coords x and y
|
||||
long double tan_x = viewDirectionLocal.x / viewDirectionLocal.z;
|
||||
long double tan_y = viewDirectionLocal.y / viewDirectionLocal.z;
|
||||
|
||||
glm::dvec2 angleCoordsLocal = glm::dvec2(std::atanl(tan_x), std::atanl(tan_y));
|
||||
glm::dvec3 imageCoordsScreenSpace = glm::dvec3(zCoord * static_cast<double>(std::tanl(angleCoordsLocal.x)), zCoord * static_cast<double>(std::tanl(angleCoordsLocal.y)), zCoord);
|
||||
glm::dvec2 angleCoordsLocal = glm::dvec2(std::atanl(tan_x), std::atanl(tan_y));
|
||||
glm::dvec3 imageCoordsScreenSpace = glm::dvec3(zCoord * static_cast<double>(std::tanl(angleCoordsLocal.x)), zCoord * static_cast<double>(std::tanl(angleCoordsLocal.y)), zCoord);
|
||||
|
||||
return imageCoordsScreenSpace;
|
||||
}
|
||||
|
||||
glm::dvec3 galacticCartesianToCameraLocalCartesian(glm::dvec3 galCoords) {
|
||||
// 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 J2000CartesianToScreenSpace(glm::dvec3 coords) {
|
||||
// Transform equatorial J2000 to galactic coord with infinite radius
|
||||
glm::dvec3 imageCoordsGalacticCartesian = J2000CartesianToGalacticCartesian(coords, infinity);
|
||||
// Transform galactic coord to screen space
|
||||
return galacticToScreenSpace(imageCoordsGalacticCartesian);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return imageCoordsScreenSpace;
|
||||
}
|
||||
|
||||
glm::dvec3 galacticCartesianToCameraLocalCartesian(glm::dvec3 galCoords) {
|
||||
// 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 J2000CartesianToScreenSpace(glm::dvec3 coords) {
|
||||
// Transform equatorial J2000 to galactic coord with infinite radius
|
||||
glm::dvec3 imageCoordsGalacticCartesian = J2000CartesianToGalacticCartesian(coords, infinity);
|
||||
// Transform galactic coord to screen space
|
||||
return galacticToScreenSpace(imageCoordsGalacticCartesian);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// WWT messages
|
||||
namespace openspace::wwtmessage {
|
||||
// WWT messages
|
||||
ghoul::Dictionary moveCamera(const glm::dvec2 celestCoords, const double fov, const bool moveInstantly) {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
|
||||
// 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();
|
||||
glm::dvec3 camUpJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(upVector);
|
||||
glm::dvec3 camForwardJ2000 = skybrowser::galacticCartesianToJ2000Cartesian(viewVector);
|
||||
|
||||
glm::dvec3 crossUpNorth = glm::cross(camUpJ2000, skybrowser::NORTH_POLE);
|
||||
double dotNorthUp = glm::dot(skybrowser::NORTH_POLE, camUpJ2000);
|
||||
double dotCrossUpNorthForward = glm::dot(crossUpNorth, camForwardJ2000);
|
||||
double roll = glm::degrees(atan2(dotCrossUpNorthForward, dotNorthUp));
|
||||
|
||||
// Create message
|
||||
msg.setValue("event", "center_on_coordinates"s);
|
||||
msg.setValue("ra", celestCoords.x);
|
||||
msg.setValue("dec", celestCoords.y);
|
||||
msg.setValue("fov", fov);
|
||||
msg.setValue("roll", roll);
|
||||
msg.setValue("instant", moveInstantly);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary loadCollection(const std::string& url) {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "load_image_collection"s);
|
||||
msg.setValue("url", url);
|
||||
msg.setValue("loadChildFolders", true);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary setForeground(const std::string& name) {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "set_foreground_by_name"s);
|
||||
msg.setValue("name", name);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary createImageLayer(ImageData& image, int id) {
|
||||
std::string idString = std::to_string(id);
|
||||
image.id = id;
|
||||
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "image_layer_create"s);
|
||||
msg.setValue("id", idString);
|
||||
msg.setValue("url", image.imageUrl);
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary removeImageLayer(const std::string& id) {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "image_layer_remove"s);
|
||||
msg.setValue("id", id);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary setLayerOpacity(const ImageData& image, double opacity) {
|
||||
std::string idString = std::to_string(image.id);
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "image_layer_set"s);
|
||||
msg.setValue("id", idString);
|
||||
msg.setValue("setting", "opacity"s);
|
||||
msg.setValue("value", opacity);
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
ghoul::Dictionary setForegroundOpacity(double val) {
|
||||
using namespace std::string_literals;
|
||||
ghoul::Dictionary msg;
|
||||
msg.setValue("event", "set_foreground_opacity"s);
|
||||
msg.setValue("value", val);
|
||||
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -272,15 +272,16 @@ namespace openspace {
|
||||
ImageData& img) {
|
||||
// Get attributes for the image
|
||||
img.name = node->FindAttribute("Name") ? node->FindAttribute("Name")->Value() : "";
|
||||
img.hasCoords = node->FindAttribute("RA") && node->FindAttribute("Dec");
|
||||
if (img.hasCoords) {
|
||||
img.hasCelestCoords = node->FindAttribute("RA") && node->FindAttribute("Dec");
|
||||
if (img.hasCelestCoords) {
|
||||
// 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.collection = collectionName;
|
||||
img.thumbnailUrl = thumbnail;
|
||||
img.zoomLevel = node->FindAttribute("ZoomLevel") ? std::stof(node->FindAttribute("ZoomLevel")->Value()) : 0.f;
|
||||
// In WWT, the definition of ZoomLevel is: VFOV = ZoomLevel / 6
|
||||
img.fov = node->FindAttribute("ZoomLevel") ? std::stof(node->FindAttribute("ZoomLevel")->Value()) / 6: 0.f;
|
||||
img.credits = credits;
|
||||
img.creditsUrl = creditsUrl;
|
||||
img.imageUrl = imageUrl;
|
||||
@@ -290,6 +291,7 @@ namespace openspace {
|
||||
auto it = _3dPositions.find(str);
|
||||
if (it != _3dPositions.end()) {
|
||||
img.position3d = it->second;
|
||||
img.has3dCoords = true;
|
||||
nImagesWith3dPositions++;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user