Restructure browser and target to not have pointers to each other

This commit is contained in:
sylvass
2021-11-23 15:49:20 -05:00
parent 54ed28ce66
commit 68c0635a9a
12 changed files with 844 additions and 759 deletions
+14 -10
View File
@@ -55,13 +55,12 @@ namespace ghoul::opengl { class Texture; }
namespace openspace {
class BrowserInstance;
class RenderHandler;
class WebKeyboardHandler;
class BrowserInstance;
class RenderHandler;
class WebKeyboardHandler;
class Browser {
public:
Browser(const ghoul::Dictionary& dictionary);
Browser(Browser const&) = default;
~Browser();
@@ -73,17 +72,23 @@ public:
void update();
bool isReady() const;
glm::vec2 browserPixelDimensions() const;
void updateBrowserSize();
// Getters
glm::vec2 browserPixelDimensions() const;
float browserRatio() const;
void setCallbackDimensions(const std::function<void(const glm::dvec2&)>& function);
protected:
properties::Vec2Property _dimensions;
properties::StringProperty _url;
properties::TriggerProperty _reload;
std::unique_ptr<BrowserInstance> _browserInstance;
std::unique_ptr<ghoul::opengl::Texture> _texture;
void executeJavascript(const std::string& script) const;
private:
class RenderHandler : public WebRenderHandler {
public:
void draw() override;
@@ -92,14 +97,13 @@ protected:
void setTexture(GLuint t);
};
private:
void bindTexture();
std::unique_ptr<BrowserInstance> _browserInstance;
CefRefPtr<RenderHandler> _renderHandler;
CefRefPtr<WebKeyboardHandler> _keyboardHandler;
bool _isUrlDirty = false;
bool _isDimensionsDirty = false;
bool _shouldReload = false;
};
} // namespace openspace
+18 -11
View File
@@ -25,28 +25,30 @@
#ifndef __OPENSPACE_MODULE_SKYBROWSER___PAIR___H__
#define __OPENSPACE_MODULE_SKYBROWSER___PAIR___H__
#include <modules/skybrowser/include/wwtdatahandler.h>
//#include <modules/skybrowser/include/screenspaceskybrowser.h>
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include <openspace/documentation/documentation.h>
#include <deque>
namespace openspace {
class ScreenSpaceSkyBrowser;
class ScreenSpaceSkyTarget;
class ImageData;
class Pair {
public:
constexpr static const float AcceptableDiff = 0.01f;
constexpr static const double epsilon = std::numeric_limits<double>::epsilon();
Pair(ScreenSpaceSkyBrowser* browser, ScreenSpaceSkyTarget* target);
Pair(Pair const&) = default;
// user-defined copy assignment (copy-and-swap idiom)
Pair& operator=(Pair other);
void lock();
void unlock();
void setImageOrder(int i, int order);
void connectPair();
void synchronizeWithWwt();
void removeHighlight(glm::ivec3 color);
void highlight(glm::ivec3 color);
void enable();
@@ -61,26 +63,31 @@ public:
bool isEnabled();
bool isLocked();
void initialize();
glm::ivec3 borderColor();
glm::dvec3 targetDirectionEquatorial();
glm::dvec3 targetDirectionGalactic();
std::string browserGuiName();
std::string browserId();
std::string targetId();
const std::string& browserId() const;
const std::string& targetId() const;
float verticalFov();
const std::deque<int>& getSelectedImages();
void selectImage(const ImageData& image, const int i);
void removeSelectedImage(const int i);
void loadImages(std::string collection);
void loadImageCollection(std::string collection);
void setImageOpacity(const int i, float opacity);
void sendIdToBrowser();
void updateBrowserSize();
void setIsSyncedWithWwt(bool isSynced);
ScreenSpaceSkyTarget* getTarget();
ScreenSpaceSkyBrowser* getBrowser();
friend bool operator==(const Pair& lhs, const Pair& rhs);
friend bool operator!=(const Pair& lhs, const Pair& rhs);
friend bool operator==(const Pair& lhs,
const Pair& rhs);
friend bool operator!=(const Pair& lhs,
const Pair& rhs);
private:
@@ -25,37 +25,35 @@ namespace openspace {
bool deinitializeGL() override;
bool isReady() const override;
void render() override;
void update() override;
glm::mat4 scaleMatrix() override;
void bindTexture() override; // Empty function but has to be defined
void createShaders();
// Sky browser functionality
bool connectoToSkyBrowser();
void matchAppearanceToSkyBrowser();
// Getters
ScreenSpaceSkyBrowser* getSkyBrowser();
glm::ivec3 borderColor() const;
float opacity() const;
// Setters
void setScale(float verticalFov);
void setScaleFromVfov(float verticalFov);
void setDimensions(glm::vec2 dimensions);
void setColor(glm::ivec3 color);
void setOpacity(float opacity);
void setLock(bool isLocked);
// Set callbacks
void setCallbackEnabled(std::function<void(bool)> function);
void setCallbackPosition(std::function<void(const glm::vec3&)> function);
// Target directions
glm::dvec3 directionGalactic() const;
glm::dvec3 directionEquatorial() const;
// Locking functionality
void lock();
void unlock();
bool isLocked();
bool isLocked() const;
// Animation
bool isAnimated();
void startAnimation(glm::dvec3 end, bool shouldLockAfter);
void startAnimation(glm::dvec3 end, bool shouldLockAfter = true);
void incrementallyAnimateToCoordinate(float deltaTime);
// Display
void highlight(glm::ivec3 addition);
@@ -63,7 +61,6 @@ namespace openspace {
private:
// Properties
properties::StringProperty _skyBrowserId;
properties::FloatProperty _showCrosshairThreshold;
properties::FloatProperty _showRectangleThreshold;
properties::DoubleProperty _stopAnimationThreshold;
@@ -87,15 +84,15 @@ namespace openspace {
GLuint _vertexBuffer = 0;
// Sky browser
ScreenSpaceSkyBrowser* _skyBrowser;
glm::ivec3 _color;
float _verticalFov{ 0.f };
// Lock target to a coordinate on the sky
glm::dvec3 _lockedCoordinates; // Spherical celestial coordinates
std::thread _lockTarget;
glm::dvec3 _lockedCoordinates; // Cartesian equatorial coordinates
glm::dvec3 _animationEnd; // Cartesian celestial coordinates
glm::dvec3 _animationStart; // Cartesian celestial coordinates
// Animation
glm::dvec3 _animationEnd; // Cartesian equatorial coordinates
glm::dvec3 _animationStart; // Cartesian equatorial coordinates
};
}
+13 -26
View File
@@ -21,22 +21,22 @@ namespace openspace {
// Galactic coordinates are projected onto the celestial sphere
// Equatorial coordinates are unit length
// Conversion spherical <-> Cartesian
glm::dvec2 cartesianToSpherical(glm::dvec3 coords);
glm::dvec3 sphericalToCartesian(glm::dvec2 coords);
glm::dvec2 cartesianToSpherical(const glm::dvec3& coords);
glm::dvec3 sphericalToCartesian(const glm::dvec2& coords);
// Conversion J2000 equatorial <-> galactic
glm::dvec3 galacticToEquatorial(glm::dvec3 coords);
glm::dvec3 equatorialToGalactic(glm::dvec3 coords);
glm::dvec3 galacticToEquatorial(const glm::dvec3& coords);
glm::dvec3 equatorialToGalactic(const glm::dvec3& coords);
// Conversion to screen space from J2000 equatorial / galactic / pixels
glm::dvec3 equatorialToScreenSpace3d(glm::dvec3 coords);
glm::dvec3 galacticToScreenSpace3d(glm::dvec3 coords);
glm::vec2 pixelToScreenSpace2d(glm::vec2& mouseCoordinate);
glm::dvec3 equatorialToScreenSpace3d(const glm::dvec3& coords);
glm::dvec3 galacticToScreenSpace3d(const glm::dvec3& coords);
glm::vec2 pixelToScreenSpace2d(const glm::vec2& mouseCoordinate);
// Conversion local camera space <-> galactic / equatorial
glm::dvec3 galacticToLocalCamera(glm::dvec3 coords);
glm::dvec3 localCameraToGalactic(glm::dvec3 coords);
glm::dvec3 localCameraToEquatorial(glm::dvec3 coords);
glm::dvec3 galacticToLocalCamera(const glm::dvec3& coords);
glm::dvec3 localCameraToGalactic(const glm::dvec3& coords);
glm::dvec3 localCameraToEquatorial(const glm::dvec3& coords);
// Camera roll and direction
double cameraRoll(); // Camera roll is with respect to the equatorial North Pole
@@ -46,26 +46,13 @@ namespace openspace {
// Window and field of view
float windowRatio();
glm::dvec2 fovWindow();
bool isCoordinateInView(glm::dvec3 equatorial);
bool isCoordinateInView(const glm::dvec3& equatorial);
// Animation for target and camera
double angleBetweenVectors(glm::dvec3 start, glm::dvec3 end);
glm::dmat4 incrementalAnimationMatrix(glm::dvec3 start, glm::dvec3 end,
double angleBetweenVectors(const glm::dvec3& start, const glm::dvec3& end);
glm::dmat4 incrementalAnimationMatrix(const glm::dvec3& start, const glm::dvec3& end,
double deltaTime, double speedFactor = 1.0);
}
// WorldWide Telescope messages
namespace wwtmessage {
inline int messageCounter{ 0 };
ghoul::Dictionary moveCamera(const glm::dvec2 celestCoords, const double fov,
const double roll, const bool shouldMoveInstantly = true);
ghoul::Dictionary loadCollection(const std::string& url);
ghoul::Dictionary setForeground(const std::string& name);
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 version);
}
}
#endif // __OPENSPACE_MODULE_SKYBROWSER___UTILITY___H__
+30 -5
View File
@@ -27,6 +27,7 @@
#include <modules/skybrowser/include/browser.h>
#include <openspace/properties/vector/ivec3property.h>
#include <openspace/properties/vector/dvec2property.h>
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/documentation/documentation.h>
#include <deque>
@@ -45,11 +46,12 @@ public:
virtual ~WwtCommunicator();
// WorldWide Telescope communication
void displayImage(const std::string& url, const int i);
void displayImage(const std::string& url, int i);
void removeSelectedImage(const int i);
void setImageOrder(int i, int order);
void loadImageCollection(const std::string& collection);
void setImageOpacity(const int i, float opacity);
void setImageOpacity(int i, float opacity);
void update();
// Getters
const std::deque<int>& getSelectedImages();
@@ -57,29 +59,52 @@ public:
float verticalFov() const;
glm::dvec2 fieldsOfView();
bool hasLoadedImages() const;
glm::dvec3 equatorialAimCartesian() const;
// Setters
void setHasLoadedImages(bool isLoaded);
void setVerticalFov(float vfov);
void setWebpageBorderColor(glm::ivec3 color);
void setIsSyncedWithWwt(bool isSynced);
void setEquatorialAim(glm::dvec3 cartesian);
// Display
void highlight(glm::ivec3 addition);
void removeHighlight(glm::ivec3 removal);
void updateBorderColor();
protected:
void sendMessageToWwt(const ghoul::Dictionary& msg);
// Web page communication
void setIdInBrowser(const std::string& id);
properties::DVec2Property _equatorialAim;
properties::FloatProperty _verticalFov;
properties::IVec3Property _borderColor;
std::deque<int> _selectedImages;
bool _hasLoadedImages{ false };
private:
void executeJavascript(const std::string& script) const;
bool _isSyncedWithWwt{ false };
const std::chrono::microseconds interval = std::chrono::microseconds(10000);
std::chrono::time_point<std::chrono::high_resolution_clock> latestCall;
void setWebpageBorderColor(glm::ivec3 color);
void sendMessageToWwt(const ghoul::Dictionary& msg);
int messageCounter{ 0 };
ghoul::Dictionary moveCamera(const glm::dvec2& celestCoords, const double fov,
const double roll, const bool shouldMoveInstantly = true);
ghoul::Dictionary loadCollection(const std::string& url);
ghoul::Dictionary setForeground(const std::string& name);
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 version);
};
} // namespace openspace
+1 -18
View File
@@ -186,14 +186,6 @@ 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"
},
{
"connectBrowserTarget",
&skybrowser::luascriptfunctions::connectBrowserTarget,
{},
"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"
},
{
"add3dBrowserToSkyBrowserModule",
&skybrowser::luascriptfunctions::add3dBrowserToSkyBrowserModule,
@@ -429,9 +421,7 @@ SkyBrowserModule::SkyBrowserModule()
if (_isCameraRotating) {
incrementallyRotateCamera(deltaTime);
}
});
});
}
SkyBrowserModule::~SkyBrowserModule() {
@@ -539,7 +529,6 @@ void SkyBrowserModule::createTargetBrowserPair() {
"Name = '" + nameBrowser + "',"
"Url = '"+ url +"',"
"FaceCamera = false,"
"TargetId = '" + idTarget + "',"
"CartesianPosition = " + ghoul::to_string(positionBrowser) + ","
"}";
const std::string target = "{"
@@ -547,7 +536,6 @@ void SkyBrowserModule::createTargetBrowserPair() {
"Type = 'ScreenSpaceSkyTarget',"
"Name = '" + nameTarget + "',"
"FaceCamera = false,"
"BrowserId = '" + idBrowser + "',"
"}";
openspace::global::scriptEngine->queueScript(
@@ -566,11 +554,6 @@ void SkyBrowserModule::createTargetBrowserPair() {
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.connectBrowserTarget('" + idBrowser + "');",
scripting::ScriptEngine::RemoteScripting::Yes
);
openspace::global::scriptEngine->queueScript(
"openspace.skybrowser.setSelectedBrowser('" + idBrowser + "');",
scripting::ScriptEngine::RemoteScripting::Yes
+400 -416
View File
@@ -16,378 +16,320 @@ namespace {
namespace openspace::skybrowser::luascriptfunctions {
int selectImage(lua_State* L) {
// Load image
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::selectImage");
const int i = ghoul::lua::value<int>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
int selectImage(lua_State* L) {
// Load image
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::selectImage");
const int i = ghoul::lua::value<int>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->isCameraInSolarSystem()) {
module->selectImage2dBrowser(i);
}
else {
module->selectImage3dBrowser(i);
}
if (module->isCameraInSolarSystem()) {
module->selectImage2dBrowser(i);
}
else {
module->selectImage3dBrowser(i);
}
return 0;
}
return 0;
}
int moveCircleToHoverImage(lua_State* L) {
// Load image
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::moveCircleToHoverImage");
const int i = ghoul::lua::value<int>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->moveHoverCircle(i);
int moveCircleToHoverImage(lua_State* L) {
// Load image
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::moveCircleToHoverImage");
const int i = ghoul::lua::value<int>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->moveHoverCircle(i);
return 0;
}
return 0;
}
int disableHoverCircle(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::disableHoverCircle");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->disableHoverCircle();
int disableHoverCircle(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::disableHoverCircle");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->disableHoverCircle();
return 0;
return 0;
}
int lockTarget(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::lockTarget");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->lock();
}
return 0;
}
int unlockTarget(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::unlockTarget");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->unlock();
}
return 0;
}
int setImageLayerOrder(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setImageLayerOrder");
const std::string id = ghoul::lua::value<std::string>(L, 1);
const int i = ghoul::lua::value<int>(L, 2);
int order = ghoul::lua::value<int>(L, 3);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->setImageOrder(i, order);
}
else if (module->get3dBrowser(id)) {
module->get3dBrowser(id)->setImageOrder(i, order);
}
int lockTarget(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::lockTarget");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->lock();
}
return 0;
}
int unlockTarget(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::unlockTarget");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->unlock();
}
return 0;
}
int setImageLayerOrder(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setImageLayerOrder");
const std::string id = ghoul::lua::value<std::string>(L, 1);
const int i = ghoul::lua::value<int>(L, 2);
int order = ghoul::lua::value<int>(L, 3);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->setImageOrder(i, order);
}
else if (module->get3dBrowser(id)) {
module->get3dBrowser(id)->setImageLayerOrder(i, order);
}
return 0;
}
return 0;
}
int loadImagesToWWT(lua_State* L) {
// Load images from url
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadImagesToWWT");
const std::string id = ghoul::lua::value<std::string>(L, 1);
LINFO("Connection established to WorldWide Telescope application in " + id);
LINFO("Loading image collections to " + id);
int loadImagesToWWT(lua_State* L) {
// Load images from url
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::loadImagesToWWT");
const std::string id = ghoul::lua::value<std::string>(L, 1);
LINFO("Connection established to WorldWide Telescope application in " + id);
LINFO("Loading image collections to " + id);
// Load the collections here because here we know that the browser can execute
// javascript
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
"wwt-web-client/master/assets/webclient-explore-root.wtml";
// Load the collections here because here we know that the browser can execute
// javascript
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
"wwt-web-client/master/assets/webclient-explore-root.wtml";
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->loadImages(root);
}
else if (module->get3dBrowser(id)) {
if (module->getPair(id)) {
module->getPair(id)->loadImageCollection(root);
}
else if (module->get3dBrowser(id)) {
// Load Image collections
module->get3dBrowser(id)->stopSyncingWwtView();
LINFO("Load images to " + module->get3dBrowser(id)->identifier());
module->get3dBrowser(id)->sendMessageToWwt(wwtmessage::loadCollection(root));
LINFO("Image collection loaded in " + module->get3dBrowser(id)->identifier());
// Load Image collections
module->get3dBrowser(id)->stopSyncingWwtView();
LINFO("Load images to " + module->get3dBrowser(id)->identifier());
module->get3dBrowser(id)->loadImageCollection(root);
LINFO("Image collection loaded in " + module->get3dBrowser(id)->identifier());
}
return 0;
}
int sendOutIdsToBrowsers(lua_State* L) {
// This is called when the sky_browser website is connected to OpenSpace
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::sendOutIdsToBrowsers");
// Send out ID's to the browsers
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
std::vector<Pair> pairs = module->getPairs();
for (Pair pair : pairs) {
pair.sendIdToBrowser();
}
if(module->get3dBrowser()) {
std::string id = module->get3dBrowserNode()->identifier();
module->get3dBrowser()->setIdInBrowser(id);
}
return 0;
}
int connectBrowserTarget(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::connectBrowserTarget");
const std::string id = ghoul::lua::value<std::string>(L, 1);
return 0;
}
// Connect the target and browser to each other
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->connectPair();
}
int sendOutIdsToBrowsers(lua_State* L) {
// This is called when the sky_browser website is connected to OpenSpace
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::sendOutIdsToBrowsers");
return 0;
// Send out ID's to the browsers
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
std::vector<std::unique_ptr<Pair>>& pairs = module->getPairs();
for (std::unique_ptr<Pair>& pair : pairs) {
pair->sendIdToBrowser();
}
int initializeBrowser(lua_State* L) {
// Initialize browser with ID and its corresponding target
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::initializeBrowser");
const std::string id = ghoul::lua::value<std::string>(L, 1);
LINFO("Initializing sky browser " + id);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->synchronizeWithWwt();
}
else if(module->get3dBrowser(id)) {
// Initialize
LINFO("Initializing 3D sky browsers");
module->get3dBrowser()->syncWwtView();
}
return 0;
}
int add3dBrowserToSkyBrowserModule(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::add3dBrowserToSkyBrowserModule");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
LINFO("Add to sky browser module id " + id);
module->set3dBrowser(id);
return 0;
}
int addPairToSkyBrowserModule(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addPairToSkyBrowserModule");
const std::string targetId = ghoul::lua::value<std::string>(L, 1);
const std::string browserId = ghoul::lua::value<std::string>(L, 2);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
LINFO("Add browser " + browserId + " to sky browser module.");
LINFO("Add target " + targetId + " to sky browser module.");
module->addTargetBrowserPair(targetId, browserId);
return 0;
}
int getListOfImages(lua_State* L) {
// Send image list to GUI
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getListOfImages");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
// If no data has been loaded yet, download the data from the web!
if (module->nLoadedImages() == 0) {
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
"wwt-web-client/master/assets/webclient-explore-root.wtml";
//std::string hubble = "http://www.worldwidetelescope.org/wwtweb/"
//"catalog.aspx?W=hubble";
std::string directory = absPath("${MODULE_SKYBROWSER}/WWTimagedata/");
// 3D images
std::string http = "${BASE}/sync/http/";
std::string globular = "digitaluniverse_globularclusters_speck/2/gc.speck";
std::string open = "digitaluniverse_openclusters_speck/2/oc.speck";
// Load speck files for 3D positions
std::filesystem::path globularClusters = absPath(http + globular);
std::filesystem::path openClusters = absPath(http + open);
std::vector<std::filesystem::path> specks = {
openClusters,
globularClusters
};
module->loadImages(root, directory, specks);
}
// Create Lua table to send to the GUI
lua_newtable(L);
for (int i = 0; i < module->nLoadedImages(); i++) {
const ImageData& img = module->getWWTDataHandler()->getImage(i);
glm::dvec3 coords = img.equatorialCartesian;
glm::dvec3 position = img.position3d;
// Conversions for ghoul
std::vector<double> cartCoordsVec = { coords.x, coords.y, coords.z };
std::vector<double> position3d = { position.x, position.y, position.z };
if(module->get3dBrowser()) {
// Index for current ImageData
ghoul::lua::push(L, i + 1);
lua_newtable(L);
// Push ("Key", value)
ghoul::lua::push(L, "name", img.name);
lua_settable(L, -3);
ghoul::lua::push(L, "thumbnail", img.thumbnailUrl);
lua_settable(L, -3);
ghoul::lua::push(L, "ra", img.equatorialSpherical.x);
lua_settable(L, -3);
ghoul::lua::push(L, "dec", img.equatorialSpherical.y);
lua_settable(L, -3);
ghoul::lua::push(L, "cartesianDirection", cartCoordsVec);
lua_settable(L, -3);
ghoul::lua::push(L, "hasCelestialCoords", img.hasCelestialCoords);
lua_settable(L, -3);
ghoul::lua::push(L, "credits", img.credits);
lua_settable(L, -3);
ghoul::lua::push(L, "creditsUrl", img.creditsUrl);
lua_settable(L, -3);
ghoul::lua::push(L, "identifier", std::to_string(i));
lua_settable(L, -3);
ghoul::lua::push(L, "has3dCoords", img.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);
}
module->get3dBrowser()->setIdInBrowser();
}
return 0;
}
return 1;
}
int initializeBrowser(lua_State* L) {
// Initialize browser with ID and its corresponding target
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::initializeBrowser");
const std::string id = ghoul::lua::value<std::string>(L, 1);
int getTargetData(lua_State* L) {
// Send image list to GUI
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getTargetData");
LINFO("Initializing sky browser " + id);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->setIsSyncedWithWwt(true);
module->getPair(id)->initialize();
}
else if(module->get3dBrowser(id)) {
// Initialize
LINFO("Initializing 3D sky browsers");
module->get3dBrowser()->setIsSyncedWithWwt(true);
}
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
return 0;
}
int add3dBrowserToSkyBrowserModule(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::add3dBrowserToSkyBrowserModule");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
lua_newtable(L);
LINFO("Add to sky browser module id " + id);
module->set3dBrowser(id);
return 0;
}
int addPairToSkyBrowserModule(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::addPairToSkyBrowserModule");
const std::string targetId = ghoul::lua::value<std::string>(L, 1);
const std::string browserId = ghoul::lua::value<std::string>(L, 2);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
LINFO("Add browser " + browserId + " to sky browser module.");
LINFO("Add target " + targetId + " to sky browser module.");
// Add the window data for OpenSpace
ghoul::lua::push(L, "OpenSpace");
lua_newtable(L);
glm::dvec3 cartesianCam = skybrowser::cameraDirectionEquatorial();
glm::dvec2 sphericalCam = skybrowser::cartesianToSpherical(cartesianCam);
// Convert to vector so ghoul can read it
std::vector<double> viewDirCelestVec = {
cartesianCam.x,
cartesianCam.y,
cartesianCam.z
module->addTargetBrowserPair(targetId, browserId);
return 0;
}
int getListOfImages(lua_State* L) {
// Send image list to GUI
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getListOfImages");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
// If no data has been loaded yet, download the data from the web!
if (module->nLoadedImages() == 0) {
std::string root = "https://raw.githubusercontent.com/WorldWideTelescope/"
"wwt-web-client/master/assets/webclient-explore-root.wtml";
//std::string hubble = "http://www.worldwidetelescope.org/wwtweb/"
//"catalog.aspx?W=hubble";
std::string directory = absPath("${MODULE_SKYBROWSER}/WWTimagedata/");
// 3D images
std::string http = "${BASE}/sync/http/";
std::string globular = "digitaluniverse_globularclusters_speck/2/gc.speck";
std::string open = "digitaluniverse_openclusters_speck/2/oc.speck";
// Load speck files for 3D positions
std::filesystem::path globularClusters = absPath(http + globular);
std::filesystem::path openClusters = absPath(http + open);
std::vector<std::filesystem::path> specks = {
openClusters,
globularClusters
};
// Calculate the smallest FOV of vertical and horizontal
glm::dvec2 fovs = skybrowser::fovWindow();
double FOV = std::min(fovs.x, fovs.y);
// Push window data
ghoul::lua::push(L, "windowHFOV", FOV);
module->loadImages(root, directory, specks);
}
// Create Lua table to send to the GUI
lua_newtable(L);
for (int i = 0; i < module->nLoadedImages(); i++) {
const ImageData& img = module->getWWTDataHandler()->getImage(i);
glm::dvec3 coords = img.equatorialCartesian;
glm::dvec3 position = img.position3d;
// Conversions for ghoul
std::vector<double> cartCoordsVec = { coords.x, coords.y, coords.z };
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", img.name);
lua_settable(L, -3);
ghoul::lua::push(L, "cartesianDirection", viewDirCelestVec);
ghoul::lua::push(L, "thumbnail", img.thumbnailUrl);
lua_settable(L, -3);
ghoul::lua::push(L, "ra", sphericalCam.x);
ghoul::lua::push(L, "ra", img.equatorialSpherical.x);
lua_settable(L, -3);
ghoul::lua::push(L, "dec", sphericalCam.y);
ghoul::lua::push(L, "dec", img.equatorialSpherical.y);
lua_settable(L, -3);
ghoul::lua::push(L, "selectedBrowserId", module->selectedBrowserId());
ghoul::lua::push(L, "cartesianDirection", cartCoordsVec);
lua_settable(L, -3);
ghoul::lua::push(L, "cameraInSolarSystem", module->isCameraInSolarSystem());
ghoul::lua::push(L, "hasCelestialCoords", img.hasCelestialCoords);
lua_settable(L, -3);
ghoul::lua::push(L, "credits", img.credits);
lua_settable(L, -3);
ghoul::lua::push(L, "creditsUrl", img.creditsUrl);
lua_settable(L, -3);
ghoul::lua::push(L, "identifier", std::to_string(i));
lua_settable(L, -3);
ghoul::lua::push(L, "has3dCoords", img.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);
lua_settable(L, -3);
}
// Pass data for all the browsers and the corresponding targets
if (module->isCameraInSolarSystem()) {
std::vector<Pair> pairs = module->getPairs();
return 1;
}
for (Pair pair : pairs) {
std::string id = pair.browserId();
// Convert deque to vector so ghoul can read it
std::vector<int> selectedImagesVector;
const std::deque<int> selectedImages = pair.getSelectedImages();
std::for_each(selectedImages.begin(), selectedImages.end(), [&](int i) {
selectedImagesVector.push_back(i);
});
glm::dvec3 cartesian = pair.targetDirectionEquatorial();
glm::dvec2 spherical = skybrowser::cartesianToSpherical(cartesian);
std::vector<double> cartesianVec = {
cartesian.x,
cartesian.y,
cartesian.z
};
// Convert color to vector so ghoul can read it
glm::ivec3 color = pair.borderColor();
std::vector<int> colorVec = { color.r, color.g, color.b };
int getTargetData(lua_State* L) {
// Send image list to GUI
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::getTargetData");
ghoul::lua::push(L, id);
lua_newtable(L);
// Push ("Key", value)
ghoul::lua::push(L, "id", id);
lua_settable(L, -3);
ghoul::lua::push(L, "name", pair.browserGuiName());
lua_settable(L, -3);
ghoul::lua::push(L, "FOV", pair.verticalFov());
lua_settable(L, -3);
ghoul::lua::push(L, "selectedImages", selectedImagesVector);
lua_settable(L, -3);
ghoul::lua::push(L, "cartesianDirection", cartesianVec);
lua_settable(L, -3);
ghoul::lua::push(L, "ra", spherical.x);
lua_settable(L, -3);
ghoul::lua::push(L, "dec", spherical.y);
lua_settable(L, -3);
ghoul::lua::push(L, "color", colorVec);
lua_settable(L, -3);
ghoul::lua::push(L, "isLocked", pair.isLocked());
lua_settable(L, -3);
// Set table for the current target
lua_settable(L, -3);
}
}
else if(module->get3dBrowser()){
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
lua_newtable(L);
// Add the window data for OpenSpace
ghoul::lua::push(L, "OpenSpace");
lua_newtable(L);
glm::dvec3 cartesianCam = skybrowser::cameraDirectionEquatorial();
glm::dvec2 sphericalCam = skybrowser::cartesianToSpherical(cartesianCam);
// Convert to vector so ghoul can read it
std::vector<double> viewDirCelestVec = {
cartesianCam.x,
cartesianCam.y,
cartesianCam.z
};
// Calculate the smallest FOV of vertical and horizontal
glm::dvec2 fovs = skybrowser::fovWindow();
double FOV = std::min(fovs.x, fovs.y);
// Push window data
ghoul::lua::push(L, "windowHFOV", FOV);
lua_settable(L, -3);
ghoul::lua::push(L, "cartesianDirection", viewDirCelestVec);
lua_settable(L, -3);
ghoul::lua::push(L, "ra", sphericalCam.x);
lua_settable(L, -3);
ghoul::lua::push(L, "dec", sphericalCam.y);
lua_settable(L, -3);
ghoul::lua::push(L, "selectedBrowserId", module->selectedBrowserId());
lua_settable(L, -3);
ghoul::lua::push(L, "cameraInSolarSystem", module->isCameraInSolarSystem());
lua_settable(L, -3);
// Set table for the current ImageData
lua_settable(L, -3);
// Pass data for all the browsers and the corresponding targets
if (module->isCameraInSolarSystem()) {
std::vector<std::unique_ptr<Pair>>& pairs = module->getPairs();
for (std::unique_ptr<Pair>& pair : pairs) {
std::string id = pair->browserId();
// Convert deque to vector so ghoul can read it
std::vector<int> selectedImagesVector;
std::deque<int> selectedImages = module->get3dBrowser()->getSelectedImages();
std::for_each(selectedImages.begin(), selectedImages.end(), [&](int index) {
selectedImagesVector.push_back(index);
const std::deque<int> selectedImages = pair->getSelectedImages();
std::for_each(selectedImages.begin(), selectedImages.end(), [&](int i) {
selectedImagesVector.push_back(i);
});
glm::dvec3 position3dBrowser = module->get3dBrowserNode()->position();
glm::dvec3 cartesian = skybrowser::galacticToEquatorial(position3dBrowser);
glm::dvec3 cartesian = pair->targetDirectionEquatorial();
glm::dvec2 spherical = skybrowser::cartesianToSpherical(cartesian);
std::vector<double> celestialCartVec = {
std::vector<double> cartesianVec = {
cartesian.x,
cartesian.y,
cartesian.z
};
// Convert color to vector so ghoul can read it
//glm::ivec3 color = browser->_borderColor.value();
std::vector<int> colorVec = { 200, 200, 200 };
glm::ivec3 color = pair->borderColor();
std::vector<int> colorVec = { color.r, color.g, color.b };
ghoul::lua::push(L, module->get3dBrowser()->identifier());
ghoul::lua::push(L, id);
lua_newtable(L);
// Push ("Key", value)
ghoul::lua::push(L, "id", module->get3dBrowser()->identifier());
ghoul::lua::push(L, "id", id);
lua_settable(L, -3);
ghoul::lua::push(L, "name", module->get3dBrowserNode()->guiName());
ghoul::lua::push(L, "name", pair->browserGuiName());
lua_settable(L, -3);
ghoul::lua::push(L, "FOV", module->get3dBrowser()->verticalFov());
ghoul::lua::push(L, "FOV", pair->verticalFov());
lua_settable(L, -3);
ghoul::lua::push(L, "selectedImages", selectedImagesVector);
lua_settable(L, -3);
ghoul::lua::push(L, "cartesianDirection", celestialCartVec);
ghoul::lua::push(L, "cartesianDirection", cartesianVec);
lua_settable(L, -3);
ghoul::lua::push(L, "ra", spherical.x);
lua_settable(L, -3);
@@ -395,129 +337,171 @@ namespace openspace::skybrowser::luascriptfunctions {
lua_settable(L, -3);
ghoul::lua::push(L, "color", colorVec);
lua_settable(L, -3);
ghoul::lua::push(L, "isLocked", pair->isLocked());
lua_settable(L, -3);
// Set table for the current target
lua_settable(L, -3);
}
}
else if(module->get3dBrowser()){
// Convert deque to vector so ghoul can read it
std::vector<int> selectedImagesVector;
std::deque<int> selectedImages = module->get3dBrowser()->getSelectedImages();
std::for_each(selectedImages.begin(), selectedImages.end(), [&](int index) {
selectedImagesVector.push_back(index);
});
glm::dvec3 position3dBrowser = module->get3dBrowserNode()->position();
glm::dvec3 cartesian = skybrowser::galacticToEquatorial(position3dBrowser);
glm::dvec2 spherical = skybrowser::cartesianToSpherical(cartesian);
std::vector<double> celestialCartVec = {
cartesian.x,
cartesian.y,
cartesian.z
};
// Convert color to vector so ghoul can read it
//glm::ivec3 color = browser->_borderColor.value();
std::vector<int> colorVec = { 200, 200, 200 };
ghoul::lua::push(L, module->get3dBrowser()->identifier());
lua_newtable(L);
// Push ("Key", value)
ghoul::lua::push(L, "id", module->get3dBrowser()->identifier());
lua_settable(L, -3);
ghoul::lua::push(L, "name", module->get3dBrowserNode()->guiName());
lua_settable(L, -3);
ghoul::lua::push(L, "FOV", module->get3dBrowser()->verticalFov());
lua_settable(L, -3);
ghoul::lua::push(L, "selectedImages", selectedImagesVector);
lua_settable(L, -3);
ghoul::lua::push(L, "cartesianDirection", celestialCartVec);
lua_settable(L, -3);
ghoul::lua::push(L, "ra", spherical.x);
lua_settable(L, -3);
ghoul::lua::push(L, "dec", spherical.y);
lua_settable(L, -3);
ghoul::lua::push(L, "color", colorVec);
lua_settable(L, -3);
// Set table for the current target
lua_settable(L, -3);
}
return 1;
return 1;
}
int adjustCamera(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::adjustCamera");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if(module->isCameraInSolarSystem()) {
module->lookAtTarget(id);
}
int adjustCamera(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::adjustCamera");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if(module->isCameraInSolarSystem()) {
module->lookAtTarget(id);
}
else {
module->lookAt3dBrowser();
}
return 0;
}
int set3dSelectedImagesAs2dSelection(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::set3dSelectedImagesAs2dSelection");
const std::string pairId = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->add2dSelectedImagesTo3d(pairId);
return 0;
else {
module->lookAt3dBrowser();
}
int setOpacityOfImageLayer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setOpacityOfImageLayer");
const std::string id = ghoul::lua::value<std::string>(L, 1);
const int i = ghoul::lua::value<int>(L, 2);
double opacity = ghoul::lua::value<double>(L, 3);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
ghoul::Dictionary message = wwtmessage::setImageOpacity(
std::to_string(i),
opacity
);
return 0;
}
if (module->getPair(id)) {
module->getPair(id)->setImageOpacity(i, opacity);
int set3dSelectedImagesAs2dSelection(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::set3dSelectedImagesAs2dSelection");
const std::string pairId = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->add2dSelectedImagesTo3d(pairId);
return 0;
}
int setOpacityOfImageLayer(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 3, "lua::setOpacityOfImageLayer");
const std::string id = ghoul::lua::value<std::string>(L, 1);
const int i = ghoul::lua::value<int>(L, 2);
double opacity = ghoul::lua::value<double>(L, 3);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
if (module->getPair(id)) {
module->getPair(id)->setImageOpacity(i, opacity);
}
else if (module->get3dBrowser(id)) {
module->get3dBrowser(id)->sendMessageToWwt(message);
}
return 0;
}
else if (module->get3dBrowser(id)) {
module->get3dBrowser(id)->setImageOpacity(i, opacity);
}
int centerTargetOnScreen(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::centerTargetOnScreen");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
Pair* pair = module->getPair(id);
if (pair) {
pair->centerTargetOnScreen();
}
return 0;
}
int centerTargetOnScreen(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::centerTargetOnScreen");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
Pair* pair = module->getPair(id);
if (pair) {
pair->centerTargetOnScreen();
}
return 0;
}
return 0;
}
int setSelectedBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setSelectedBrowser");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
int setSelectedBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::setSelectedBrowser");
const std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->setSelectedBrowser(id);
module->setSelectedBrowser(id);
return 0;
}
return 0;
}
int createTargetBrowserPair(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::createTargetBrowserPair");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->createTargetBrowserPair();
int createTargetBrowserPair(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::createTargetBrowserPair");
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->createTargetBrowserPair();
return 0;
}
return 0;
}
int removeTargetBrowserPair(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeTargetBrowserPair");
std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->removeTargetBrowserPair(id);
int removeTargetBrowserPair(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::removeTargetBrowserPair");
std::string id = ghoul::lua::value<std::string>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
module->removeTargetBrowserPair(id);
return 0;
}
return 0;
}
int place3dSkyBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::place3dSkyBrowser");
// Image index to place in 3D
const int i = ghoul::lua::value<int>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const ImageData image = module->getWWTDataHandler()->getImage(i);
int place3dSkyBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::place3dSkyBrowser");
// Image index to place in 3D
const int i = ghoul::lua::value<int>(L, 1);
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const ImageData image = module->getWWTDataHandler()->getImage(i);
module->place3dBrowser(image, i);
module->place3dBrowser(image, i);
return 0;
}
return 0;
}
int removeSelectedImageInBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::removeSelectedImageInBrowser");
// Image index
const int i = ghoul::lua::value<int>(L, 1);
const std::string id = ghoul::lua::value<std::string>(L, 2);
// Get browser
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const ImageData& image = module->getWWTDataHandler()->getImage(i);
int removeSelectedImageInBrowser(lua_State* L) {
ghoul::lua::checkArgumentsAndThrow(L, 2, "lua::removeSelectedImageInBrowser");
// Image index
const int i = ghoul::lua::value<int>(L, 1);
const std::string id = ghoul::lua::value<std::string>(L, 2);
// Get browser
SkyBrowserModule* module = global::moduleEngine->module<SkyBrowserModule>();
const ImageData& image = module->getWWTDataHandler()->getImage(i);
Pair* pair = module->getPair(id);
if (pair) {
pair->removeSelectedImage(i);
}
else if (module->get3dBrowser(id)) {
module->get3dBrowser(id)->removeSelectedImage(image, i);
}
return 0;
Pair* pair = module->getPair(id);
if (pair) {
pair->removeSelectedImage(i);
}
else if (module->get3dBrowser(id)) {
module->get3dBrowser(id)->removeSelectedImage(i);
}
return 0;
}
}
+42 -9
View File
@@ -81,7 +81,7 @@ namespace openspace {
_url.onChange([this]() { _isUrlDirty = true; });
_dimensions.onChange([this]() { _isDimensionsDirty = true; });
_reload.onChange([this]() { _browserInstance->reloadBrowser(); });
_reload.onChange([this]() { _shouldReload = true; });
// Create browser and render handler
_renderHandler = new RenderHandler();
@@ -98,9 +98,7 @@ namespace openspace {
}
Browser::~Browser() {
// Delete
_browserInstance.reset();
_texture.reset();
}
bool Browser::initializeGL() {
@@ -118,11 +116,12 @@ namespace openspace {
bool Browser::deinitializeGL() {
_renderHandler->setTexture(0);
_texture = nullptr;
std::string urlString;
_url.getStringValue(urlString);
LDEBUG(fmt::format("Deinitializing ScreenSpaceBrowser: {}", urlString));
LDEBUG(fmt::format("Deinitializing browser: {}", urlString));
_browserInstance->close(true);
@@ -157,19 +156,53 @@ namespace openspace {
_browserInstance->reshape(_dimensions.value());
_isDimensionsDirty = false;
}
if (_shouldReload) {
_browserInstance->reloadBrowser();
_shouldReload = false;
}
}
bool Browser::isReady() const {
return _texture.get();
}
void Browser::bindTexture() {
_texture->bind();
}
glm::vec2 Browser::browserPixelDimensions() const {
return _dimensions.value();
}
// Updates the browser size to match the size of the texture
void Browser::updateBrowserSize() {
_dimensions = _texture->dimensions();
}
float Browser::browserRatio() const
{
return static_cast<float>(_texture->dimensions().x) /
static_cast<float>(_texture->dimensions().y);
}
void Browser::setCallbackDimensions(
const std::function<void(const glm::dvec2&)>& function)
{
_dimensions.onChange([&]() {
function(_dimensions.value());
});
}
void Browser::executeJavascript(const std::string& script) const {
// Make sure that the browser has a main frame
const bool browserExists = _browserInstance && _browserInstance->getBrowser();
const bool frameIsLoaded = browserExists &&
_browserInstance->getBrowser()->GetMainFrame();
if (frameIsLoaded) {
_browserInstance->getBrowser()->GetMainFrame()->ExecuteJavaScript(
script,
_browserInstance->getBrowser()->GetMainFrame()->GetURL(),
0
);
}
}
} // namespace openspace
+86 -21
View File
@@ -25,8 +25,14 @@
#include <modules/skybrowser/include/pair.h>
#include <modules/skybrowser/include/screenspaceskybrowser.h>
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include <modules/skybrowser/include/wwtdatahandler.h>
#include <modules/skybrowser/include/utility.h>
#include <ghoul/misc/assert.h>
#include <glm/gtc/constants.hpp>
#include <functional>
#pragma optimize("", off)
namespace openspace {
@@ -37,31 +43,76 @@ namespace openspace {
{
ghoul_assert(browser != nullptr, "Sky browser is null pointer!");
ghoul_assert(target != nullptr, "Sky target is null pointer!");
// Set callback functions so that the target and the browser update each other
_browser->setCallbackEquatorialAim(
[&](const glm::dvec3& equatorialAim, bool) {
double diff = glm::length(equatorialAim - _target->directionEquatorial());
if ( diff > epsilon) {
_target->startAnimation(equatorialAim, false);
}
}
);
_browser->setCallbackBorderColor(
[&](const glm::ivec3& color) {
_target->setColor(color);
}
);
_browser->setCallbackVerticalFov(
[&](float vfov) {
_target->setScaleFromVfov(vfov);
}
);
_browser->setCallbackDimensions(
[&](const glm::vec2& dimensions) {
_target->setDimensions(dimensions);
}
);
// Always make sure that the target and browser are visible together
_browser->setCallbackEnabled(
[&](bool enabled) {
_target->setEnabled(enabled);
}
);
_target->setCallbackEnabled(
[&](bool enabled) {
_browser->setEnabled(enabled);
}
);
_target->setCallbackPosition(
[&](glm::vec3 localCameraPosition) {
double diff = glm::length(
_browser->equatorialAimCartesian() - _target->directionEquatorial()
);
if (diff > epsilon) {
_browser->setEquatorialAim(
skybrowser::localCameraToEquatorial(localCameraPosition)
);
}
}
);
}
Pair& Pair::operator=(Pair other)
{
std::swap(_target, other._target);
std::swap(_browser, other._browser);
return *this;
}
void Pair::lock() {
_target->lock();
_target->setLock(true);
}
void Pair::unlock() {
_target->unlock();
_target->setLock(false);
}
void Pair::setImageOrder(int i, int order) {
_browser->setImageOrder(i, order);
}
void Pair::connectPair()
{
_browser->connectToSkyTarget();
_target->connectoToSkyBrowser();
}
void Pair::synchronizeWithWwt()
{
_browser->startSyncingWithWwt();
}
void Pair::removeHighlight(glm::ivec3 color)
{
_target->removeHighlight(color);
@@ -84,7 +135,7 @@ namespace openspace {
bool Pair::isBrowserFadeFinished(float goalState)
{
float browserDiff = abs(_browser->getOpacity().value() - goalState);
float browserDiff = abs(_browser->opacity() - goalState);
return browserDiff < AcceptableDiff;
}
@@ -124,6 +175,14 @@ namespace openspace {
return _target->isLocked();
}
void Pair::initialize()
{
_target->setColor(_browser->borderColor());
_target->setDimensions(_browser->browserPixelDimensions());
_target->setScaleFromVfov(_browser->verticalFov());
_browser->updateBorderColor();
}
glm::ivec3 Pair::borderColor()
{
return _browser->borderColor();
@@ -144,12 +203,12 @@ namespace openspace {
return _browser->guiName();
}
std::string Pair::browserId()
const std::string& Pair::browserId() const
{
return _browser->identifier();
}
std::string Pair::targetId()
const std::string& Pair::targetId() const
{
return _target->identifier();
}
@@ -183,7 +242,7 @@ namespace openspace {
_browser->removeSelectedImage(i);
}
void Pair::loadImages(std::string collection)
void Pair::loadImageCollection(std::string collection)
{
_browser->loadImageCollection(collection);
}
@@ -202,6 +261,11 @@ namespace openspace {
_browser->updateBrowserSize();
}
void Pair::setIsSyncedWithWwt(bool isSynced)
{
_browser->setIsSyncedWithWwt(isSynced);
}
void Pair::incrementallyAnimateToCoordinate(double deltaTime)
{
// Animate the target before the field of view starts to animate
@@ -258,18 +322,19 @@ namespace openspace {
}
if (!isBrowserFadeFinished(goalState)) {
_browser->getOpacity() = _browser->getOpacity().value() + opacityDelta;
_browser->setOpacity(_browser->opacity() + opacityDelta);
}
else {
_browser->getOpacity() = goalState;
_browser->setOpacity(goalState);
}
}
bool operator==(const Pair& lhs, const Pair& rhs) {
return lhs._target == rhs._target && lhs._browser == rhs._browser;
}
bool operator!=(const Pair & lhs, const Pair & rhs) {
bool operator!=(const Pair& lhs, const Pair& rhs) {
return !(lhs == rhs);
}
} // namespace openspace
+40 -87
View File
@@ -1,6 +1,5 @@
#include <modules/skybrowser/include/screenspaceskytarget.h>
#include <modules/skybrowser/include/screenspaceskybrowser.h>
#include <modules/skybrowser/include/utility.h>
#include <openspace/engine/globals.h>
#include <openspace/interaction/navigationhandler.h>
@@ -19,13 +18,6 @@ namespace {
"dimensions", "lineColor"
};
constexpr const openspace::properties::Property::PropertyInfo BrowserIDInfo =
{
"BrowserId",
"Browser Identifier",
"The identifier of the corresponding sky browser."
};
constexpr const openspace::properties::Property::PropertyInfo CrosshairThresholdInfo =
{
"CrosshairThreshold",
@@ -60,9 +52,6 @@ namespace {
struct [[codegen::Dictionary(ScreenSpaceSkyTarget)]] Parameters {
// [[codegen::verbatim(BrowserIDInfo.description)]]
std::optional<std::string> browserId;
// [[codegen::verbatim(CrosshairThresholdInfo.description)]]
std::optional<float> crosshairThreshold;
@@ -84,8 +73,6 @@ namespace {
namespace openspace {
ScreenSpaceSkyTarget::ScreenSpaceSkyTarget(const ghoul::Dictionary& dictionary)
: ScreenSpaceRenderable(dictionary)
, _skyBrowserId(BrowserIDInfo)
, _skyBrowser(nullptr)
, _showCrosshairThreshold(CrosshairThresholdInfo, 2.0f, 0.1f, 70.f)
, _showRectangleThreshold(RectangleThresholdInfo, 0.6f, 0.1f, 70.f)
, _stopAnimationThreshold(AnimationThresholdInfo, 0.0005, 0.0, 1.0)
@@ -94,30 +81,16 @@ namespace openspace {
{
// Handle target dimension property
const Parameters p = codegen::bake<Parameters>(dictionary);
_skyBrowserId = p.browserId.value_or(_skyBrowserId);
_showCrosshairThreshold = p.crosshairThreshold.value_or(_showCrosshairThreshold);
_showRectangleThreshold = p.rectangleThreshold.value_or(_showRectangleThreshold);
_stopAnimationThreshold = p.crosshairThreshold.value_or(_stopAnimationThreshold);
_animationSpeed = p.animationSpeed.value_or(_animationSpeed);
addProperty(_skyBrowserId);
addProperty(_showCrosshairThreshold);
addProperty(_showRectangleThreshold);
addProperty(_stopAnimationThreshold);
addProperty(_animationSpeed);
// If the ID changes for the corresponding browser, update
_skyBrowserId.onChange([&]() {
connectoToSkyBrowser();
});
// Always make sure that the target and browser are visible together
_enabled.onChange([&]() {
if (_skyBrowser) {
_skyBrowser->property("Enabled")->set(_enabled.value());
}
});
// Set a unique identifier
std::string identifier;
if (dictionary.hasValue<std::string>(KeyIdentifier)) {
@@ -137,9 +110,7 @@ namespace openspace {
}
ScreenSpaceSkyTarget::~ScreenSpaceSkyTarget() {
if (_lockTarget.joinable()) {
_lockTarget.join();
}
}
// Pure virtual in the screen space renderable class and hence must be defined
@@ -147,21 +118,6 @@ namespace openspace {
}
bool ScreenSpaceSkyTarget::connectoToSkyBrowser() {
_skyBrowser = dynamic_cast<ScreenSpaceSkyBrowser*>(
global::renderEngine->screenSpaceRenderable(_skyBrowserId.value()));
matchAppearanceToSkyBrowser();
return _skyBrowser;
}
void ScreenSpaceSkyTarget::matchAppearanceToSkyBrowser() {
if (_skyBrowser) {
_color = _skyBrowser->borderColor();
_objectSize = _skyBrowser->browserPixelDimensions();
setScale(_skyBrowser->verticalFov());
}
}
bool ScreenSpaceSkyTarget::isReady() const {
return _shader != nullptr;
}
@@ -177,9 +133,6 @@ namespace openspace {
bool ScreenSpaceSkyTarget::deinitializeGL()
{
if (isLocked()) {
unlock();
}
return ScreenSpaceRenderable::deinitializeGL();
}
@@ -219,18 +172,10 @@ namespace openspace {
return _color;
}
ScreenSpaceSkyBrowser* ScreenSpaceSkyTarget::getSkyBrowser() {
return _skyBrowser;
}
void ScreenSpaceSkyTarget::render() {
bool showCrosshair = false;
bool showRectangle = true;
if (_skyBrowser) {
showCrosshair = _skyBrowser->verticalFov() < _showCrosshairThreshold;
showRectangle = _skyBrowser->verticalFov() > _showRectangleThreshold;
}
bool showCrosshair = _verticalFov < _showCrosshairThreshold;
bool showRectangle = _verticalFov > _showRectangleThreshold;
glm::vec4 color = { glm::vec3(_color) / 255.f, _opacity.value() };
glm::mat4 modelTransform = globalRotationMatrix() * translationMatrix() *
@@ -259,6 +204,15 @@ namespace openspace {
_shader->deactivate();
}
void ScreenSpaceSkyTarget::update()
{
if (_isLocked) {
_cartesianPosition = skybrowser::equatorialToScreenSpace3d(
_lockedCoordinates
);
}
}
void ScreenSpaceSkyTarget::setDimensions(glm::vec2 dimensions) {
_objectSize = dimensions;
}
@@ -275,8 +229,9 @@ namespace openspace {
// Update the scale of the target (the height of the target in relation to the
// OpenSpace window)
void ScreenSpaceSkyTarget::setScale(float verticalFov) {
void ScreenSpaceSkyTarget::setScaleFromVfov(float verticalFov) {
_verticalFov = verticalFov;
glm::dvec2 fovs = skybrowser::fovWindow();
// Cap the scale at small scales so it is still visible
@@ -286,31 +241,7 @@ namespace openspace {
_scale = std::max(heightRatio, smallestHeightRatio);
}
void ScreenSpaceSkyTarget::unlock() {
_isLocked = false;
if (_lockTarget.joinable()) {
_lockTarget.join();
}
}
void ScreenSpaceSkyTarget::lock() {
if (_isLocked) {
unlock();
}
_isLocked = true;
_lockedCoordinates = directionEquatorial();
// Start a thread to enable user interactions while locking target
_lockTarget = std::thread([&] {
while (_isLocked) {
_cartesianPosition = skybrowser::equatorialToScreenSpace3d(
_lockedCoordinates
);
}
});
}
bool ScreenSpaceSkyTarget::isLocked() {
bool ScreenSpaceSkyTarget::isLocked() const {
return _isLocked;
}
@@ -325,12 +256,14 @@ namespace openspace {
_animationEnd = glm::normalize(end);
_shouldLockAfterAnimation = shouldLockAfter;
_isAnimated = true;
_isLocked = false;
}
void ScreenSpaceSkyTarget::incrementallyAnimateToCoordinate(float deltaTime)
{
// Find smallest angle between the two vectors
double smallestAngle = skybrowser::angleBetweenVectors(_animationStart, _animationEnd);
double smallestAngle = skybrowser::angleBetweenVectors(_animationStart,
_animationEnd);
const bool shouldAnimate = smallestAngle > _stopAnimationThreshold;
// Only keep animating when target is not at goal position
@@ -357,8 +290,8 @@ namespace openspace {
_isAnimated = false;
// Lock target when it first arrives to the position
if (!isLocked() && _shouldLockAfterAnimation) {
lock();
if (!_isLocked && _shouldLockAfterAnimation) {
_isLocked = true;
}
}
}
@@ -387,4 +320,24 @@ namespace openspace {
void ScreenSpaceSkyTarget::setOpacity(float opacity) {
_opacity = opacity;
}
void ScreenSpaceSkyTarget::setLock(bool isLocked)
{
_isLocked = isLocked;
if (_isLocked) {
_lockedCoordinates = directionEquatorial();
}
}
void ScreenSpaceSkyTarget::setCallbackEnabled(std::function<void(bool)> function)
{
_enabled.onChange([this, f = std::move(function)]() {
f(_enabled);
});
}
void ScreenSpaceSkyTarget::setCallbackPosition(
std::function<void(const glm::vec3&)> function)
{
_cartesianPosition.onChange([this, f = std::move(function)]() {
f(_cartesianPosition);
});
}
}
+14 -109
View File
@@ -11,7 +11,7 @@
namespace openspace::skybrowser {
glm::dvec3 sphericalToCartesian(glm::dvec2 coords) {
glm::dvec3 sphericalToCartesian(const glm::dvec2& coords) {
glm::dvec2 coordsRadians = glm::radians(coords);
@@ -24,7 +24,7 @@ namespace openspace::skybrowser {
return cartesian;
}
glm::dvec2 cartesianToSpherical(glm::dvec3 coord) {
glm::dvec2 cartesianToSpherical(const 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)));
@@ -36,17 +36,17 @@ namespace openspace::skybrowser {
return glm::degrees(celestialCoords);
}
glm::dvec3 galacticToEquatorial(glm::dvec3 coords) {
glm::dvec3 galacticToEquatorial(const glm::dvec3& coords) {
return glm::transpose(conversionMatrix) * glm::normalize(coords);
}
glm::dvec3 equatorialToGalactic(glm::dvec3 coords) {
glm::dvec3 equatorialToGalactic(const glm::dvec3& coords) {
// On the unit sphere
glm::dvec3 rGalactic = conversionMatrix * glm::normalize(coords);
return rGalactic * CelestialSphereRadius;
}
glm::dvec3 galacticToScreenSpace3d(glm::dvec3 coords) {
glm::dvec3 galacticToScreenSpace3d(const glm::dvec3& coords) {
glm::dvec3 localCameraSpace = galacticToLocalCamera(coords);
// Ensure that if the coord is behind the camera,
@@ -62,7 +62,7 @@ namespace openspace::skybrowser {
return screenSpace;
}
glm::dvec3 localCameraToGalactic(glm::dvec3 coords) {
glm::dvec3 localCameraToGalactic(const glm::dvec3& coords) {
glm::dmat4 rotation = glm::inverse(
global::navigationHandler->camera()->viewRotationMatrix());
glm::dvec4 position = glm::dvec4(coords, 1.0);
@@ -70,7 +70,7 @@ namespace openspace::skybrowser {
return glm::normalize(rotation * position) * skybrowser::CelestialSphereRadius;
}
glm::dvec3 localCameraToEquatorial(glm::dvec3 coords) {
glm::dvec3 localCameraToEquatorial(const glm::dvec3& coords) {
// Calculate the galactic coordinate of the target direction
// projected onto the celestial sphere
glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3();
@@ -79,7 +79,7 @@ namespace openspace::skybrowser {
return skybrowser::galacticToEquatorial(galactic);
}
glm::dvec3 galacticToLocalCamera(glm::dvec3 coords) {
glm::dvec3 galacticToLocalCamera(const glm::dvec3& coords) {
// Transform vector to camera's local coordinate system
glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3();
glm::dmat4 camMat = global::navigationHandler->camera()->viewRotationMatrix();
@@ -89,7 +89,7 @@ namespace openspace::skybrowser {
return glm::normalize(viewDirectionLocal);
}
glm::dvec3 equatorialToScreenSpace3d(glm::dvec3 coords) {
glm::dvec3 equatorialToScreenSpace3d(const glm::dvec3& coords) {
// Transform equatorial J2000 to galactic coord with infinite radius
glm::dvec3 galactic = equatorialToGalactic(coords);
// Transform galactic coord to screen space
@@ -130,7 +130,7 @@ namespace openspace::skybrowser {
return windowRatio.x / windowRatio.y;
}
bool isCoordinateInView(glm::dvec3 equatorial) {
bool isCoordinateInView(const glm::dvec3& equatorial) {
// Check if image coordinate is within current FOV
glm::dvec3 coordsScreen = equatorialToScreenSpace3d(equatorial);
double r = static_cast<float>(windowRatio());
@@ -143,7 +143,7 @@ namespace openspace::skybrowser {
}
// Transforms a pixel coordinate to a screen space coordinate
glm::vec2 pixelToScreenSpace2d(glm::vec2& mouseCoordinate) {
glm::vec2 pixelToScreenSpace2d(const glm::vec2& mouseCoordinate) {
glm::vec2 size = glm::vec2(global::windowDelegate->currentWindowSize());
// Change origin to middle of the window
glm::vec2 screenSpacePos = mouseCoordinate - (size / 2.0f);
@@ -164,15 +164,15 @@ namespace openspace::skybrowser {
return OpenSpaceFOV;
}
double angleBetweenVectors(glm::dvec3 start, glm::dvec3 end) {
double angleBetweenVectors(const glm::dvec3& start, const glm::dvec3& end) {
// Find smallest angle between the two vectors
double cos = glm::dot(start, end) / (glm::length(start) * glm::length(end));
return std::acos(cos);
}
glm::dmat4 incrementalAnimationMatrix(glm::dvec3 start,
glm::dvec3 end, double deltaTime,
glm::dmat4 incrementalAnimationMatrix(const glm::dvec3& start,
const glm::dvec3& end, double deltaTime,
double speedFactor) {
double smallestAngle = angleBetweenVectors(start, end);
@@ -186,101 +186,6 @@ namespace openspace::skybrowser {
}
// WWT messages
namespace openspace::wwtmessage {
// WWT messages
ghoul::Dictionary moveCamera(const glm::dvec2 celestCoords, const double fov,
const double roll, const bool shouldMoveInstantly) {
using namespace std::string_literals;
ghoul::Dictionary msg;
// 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", shouldMoveInstantly);
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 addImage(const std::string& id, const std::string& url) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_create"s);
msg.setValue("id", id);
msg.setValue("url", url);
msg.setValue("mode", "preloaded"s);
msg.setValue("goto", false);
return msg;
}
ghoul::Dictionary removeImage(const std::string& imageId) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_remove"s);
msg.setValue("id", imageId);
return msg;
}
ghoul::Dictionary setImageOpacity(const std::string& imageId, double opacity) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_set"s);
msg.setValue("id", imageId);
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;
}
ghoul::Dictionary setLayerOrder(const std::string& id, int order) {
// The lower the layer order, the more towards the back the image is placed
// 0 is the background
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_order"s);
msg.setValue("id", id);
msg.setValue("order", order);
msg.setValue("version", messageCounter);
messageCounter++;
return msg;
}
}
+172 -30
View File
@@ -29,7 +29,10 @@
#include <modules/webbrowser/include/browserinstance.h>
#include <ghoul/misc/dictionaryjsonformatter.h> // formatJson
#include <modules/skybrowser/include/utility.h>
#include <glm/gtx/vector_angle.hpp>
#include <cmath> // For atan2
#define _USE_MATH_DEFINES
#include <math.h> // For M_PI
namespace {
constexpr const char* _loggerCat = "WwtCommunicator";
@@ -46,6 +49,13 @@ namespace {
"Vertical Field Of View",
"The vertical field of view in degrees."
};
constexpr const openspace::properties::Property::PropertyInfo EquatorialAimInfo =
{
"EquatorialAim",
"Equatorial aim of the sky browser",
"The aim of the sky browser given in spherical equatorial coordinates right "
"ascension (RA) and declination (Dec) in epoch J2000. The unit is degrees."
};
} // namespace
@@ -54,9 +64,13 @@ namespace openspace {
WwtCommunicator::WwtCommunicator(const ghoul::Dictionary& dictionary)
: Browser(dictionary),
_verticalFov(VerticalFovInfo, 10.f, 0.01f, 70.0f),
_borderColor(BorderColorInfo, glm::ivec3(200), glm::ivec3(0), glm::ivec3(255))
_borderColor(BorderColorInfo, glm::ivec3(200), glm::ivec3(0), glm::ivec3(255)),
_equatorialAim(EquatorialAimInfo, glm::dvec2(0.0), glm::dvec2(0.0, -90.0),
glm::dvec2(360.0, 90.0))
{
_borderColor.onChange([this]() {
updateBorderColor();
});
}
WwtCommunicator::~WwtCommunicator() {
@@ -71,18 +85,18 @@ namespace openspace {
// 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::addImage(std::to_string(i), url));
sendMessageToWwt(wwtmessage::setImageOpacity(std::to_string(i), 1.0));
sendMessageToWwt(addImage(std::to_string(i), url));
sendMessageToWwt(setImageOpacity(std::to_string(i), 1.0));
}
}
void WwtCommunicator::removeSelectedImage(const int i) {
void WwtCommunicator::removeSelectedImage(int i) {
// Remove from selected list
auto it = std::find(std::begin(_selectedImages), std::end(_selectedImages), i);
if (it != std::end(_selectedImages)) {
_selectedImages.erase(it);
sendMessageToWwt(wwtmessage::removeImage(std::to_string(i)));
sendMessageToWwt(removeImage(std::to_string(i)));
}
}
@@ -107,21 +121,33 @@ namespace openspace {
executeJavascript(script);
}
void WwtCommunicator::setIsSyncedWithWwt(bool isSynced)
{
_isSyncedWithWwt = isSynced;
}
void WwtCommunicator::setEquatorialAim(glm::dvec3 cartesian)
{
_equatorialAim = skybrowser::cartesianToSpherical(cartesian);
}
void WwtCommunicator::highlight(glm::ivec3 addition)
{
glm::ivec3 color = glm::ivec3(_borderColor.value());
setWebpageBorderColor(color + addition);
setWebpageBorderColor(_borderColor.value() + addition);
}
void WwtCommunicator::removeHighlight(glm::ivec3 removal)
{
glm::ivec3 color = glm::ivec3(_borderColor.value());
setWebpageBorderColor(color - removal);
setWebpageBorderColor(_borderColor.value() - removal);
}
void WwtCommunicator::updateBorderColor()
{
setWebpageBorderColor(_borderColor);
}
glm::dvec2 WwtCommunicator::fieldsOfView() {
float browserRatio = _dimensions.value().x / _dimensions.value().y;
glm::dvec2 browserFov = glm::dvec2(verticalFov() * browserRatio, verticalFov());
glm::dvec2 browserFov = glm::dvec2(verticalFov() * browserRatio(), verticalFov());
return browserFov;
}
@@ -130,6 +156,11 @@ namespace openspace {
return _hasLoadedImages;
}
glm::dvec3 WwtCommunicator::equatorialAimCartesian() const
{
return skybrowser::sphericalToCartesian(_equatorialAim);
}
void WwtCommunicator::setImageOrder(int i, int order) {
// Find in selected images list
auto current = std::find(
@@ -146,21 +177,48 @@ namespace openspace {
}
int reverseOrder = _selectedImages.size() - order - 1;
ghoul::Dictionary message = wwtmessage::setLayerOrder(std::to_string(i),
ghoul::Dictionary message = setLayerOrder(std::to_string(i),
reverseOrder);
sendMessageToWwt(message);
}
void WwtCommunicator::loadImageCollection(const std::string& collection) {
sendMessageToWwt(wwtmessage::loadCollection(collection));
sendMessageToWwt(loadCollection(collection));
_hasLoadedImages = true;
}
void WwtCommunicator::setImageOpacity(const int i, float opacity) {
ghoul::Dictionary msg = wwtmessage::setImageOpacity(std::to_string(i), opacity);
void WwtCommunicator::setImageOpacity(int i, float opacity) {
ghoul::Dictionary msg = setImageOpacity(std::to_string(i), opacity);
sendMessageToWwt(msg);
}
void WwtCommunicator::update()
{
if (_isSyncedWithWwt) {
const std::chrono::time_point<std::chrono::high_resolution_clock>
timeBefore = std::chrono::high_resolution_clock::now();
std::chrono::microseconds duration =
std::chrono::duration_cast<std::chrono::microseconds>(
timeBefore - latestCall
);
if (duration > interval) {
// Message WorldWide Telescope current view
ghoul::Dictionary message = moveCamera(
_equatorialAim,
_verticalFov,
skybrowser::cameraRoll()
);
sendMessageToWwt(message);
latestCall = std::chrono::high_resolution_clock::now();
}
}
Browser::update();
}
void WwtCommunicator::setHasLoadedImages(bool isLoaded) {
_hasLoadedImages = isLoaded;
}
@@ -170,24 +228,108 @@ namespace openspace {
executeJavascript("setId('" + id + "')");
}
void WwtCommunicator::executeJavascript(const std::string& script) const {
// Make sure that the browser has a main frame
const bool browserExists = _browserInstance && _browserInstance->getBrowser();
const bool frameIsLoaded = browserExists &&
_browserInstance->getBrowser()->GetMainFrame();
if (frameIsLoaded) {
CefRefPtr<CefFrame> frame = _browserInstance->getBrowser()->GetMainFrame();
frame->ExecuteJavaScript(script, frame->GetURL(), 0);
}
}
glm::ivec3 WwtCommunicator::borderColor() const {
return _borderColor.value();
return _borderColor;
}
float WwtCommunicator::verticalFov() const {
return _verticalFov.value();
return _verticalFov;
}
// WWT messages
ghoul::Dictionary WwtCommunicator::moveCamera(const glm::dvec2& celestCoords,
double fov, double roll,
bool shouldMoveInstantly) {
using namespace std::string_literals;
ghoul::Dictionary msg;
// 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", shouldMoveInstantly);
return msg;
}
ghoul::Dictionary WwtCommunicator::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 WwtCommunicator::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 WwtCommunicator::addImage(const std::string& id,
const std::string& url) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_create"s);
msg.setValue("id", id);
msg.setValue("url", url);
msg.setValue("mode", "preloaded"s);
msg.setValue("goto", false);
return msg;
}
ghoul::Dictionary WwtCommunicator::removeImage(const std::string& imageId) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_remove"s);
msg.setValue("id", imageId);
return msg;
}
ghoul::Dictionary WwtCommunicator::setImageOpacity(const std::string& imageId,
double opacity) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_set"s);
msg.setValue("id", imageId);
msg.setValue("setting", "opacity"s);
msg.setValue("value", opacity);
return msg;
}
ghoul::Dictionary WwtCommunicator::setForegroundOpacity(double val) {
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "set_foreground_opacity"s);
msg.setValue("value", val);
return msg;
}
ghoul::Dictionary WwtCommunicator::setLayerOrder(const std::string& id, int order) {
// The lower the layer order, the more towards the back the image is placed
// 0 is the background
using namespace std::string_literals;
ghoul::Dictionary msg;
msg.setValue("event", "image_layer_order"s);
msg.setValue("id", id);
msg.setValue("order", order);
msg.setValue("version", messageCounter);
messageCounter++;
return msg;
}
} // namespace openspace