diff --git a/modules/skybrowser/include/screenspaceskytarget.h b/modules/skybrowser/include/screenspaceskytarget.h index 1a2a69b264..073eb15952 100644 --- a/modules/skybrowser/include/screenspaceskytarget.h +++ b/modules/skybrowser/include/screenspaceskytarget.h @@ -20,7 +20,7 @@ namespace openspace { public: ScreenSpaceSkyTarget(const ghoul::Dictionary& dictionary); - virtual ~ScreenSpaceSkyTarget() = default; + virtual ~ScreenSpaceSkyTarget(); bool initializeGL() override; bool isReady() const override; @@ -33,7 +33,7 @@ namespace openspace { void setDimensions(glm::vec2 currentBrowserDimensions); void updateFOV(float browserFOV); - glm::dvec3 getTargetDirection(); + glm::dvec3 getTargetDirectionGalactic(); glm::dvec2 getScreenSpacePosition(); void setConnectedBrowser(); void setBorderColor(glm::ivec3 color); @@ -43,11 +43,15 @@ namespace openspace { glm::dvec2 getUpperRightCornerScreenSpace(); glm::dvec2 getLowerLeftCornerScreenSpace(); bool coordIsInsideCornersScreenSpace(glm::dvec2 coord); + glm::dvec2 getTargetDirectionCelestial(); + void unlock(); + void lock(); glm::mat4 scaleMatrix() override; void bindTexture() override; properties::StringProperty _skyBrowserID; + private: properties::Vec2Property _targetDimensions; @@ -60,6 +64,9 @@ namespace openspace { float _fieldOfView = 100.f; ScreenSpaceSkyBrowser* _skyBrowser; glm::ivec3 _borderColor; + bool isLocked; + glm::dvec2 lockedCelestialCoords; + std::thread _lockTargetThread; }; } diff --git a/modules/skybrowser/skybrowsermodule.cpp b/modules/skybrowser/skybrowsermodule.cpp index 17e09e934a..0d96da97ed 100644 --- a/modules/skybrowser/skybrowsermodule.cpp +++ b/modules/skybrowser/skybrowsermodule.cpp @@ -128,6 +128,22 @@ 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" }, + { + "lockTarget", + &skybrowser::luascriptfunctions::lockTarget, + {}, + "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" + }, + { + "unlockTarget", + &skybrowser::luascriptfunctions::unlockTarget, + {}, + "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; @@ -276,6 +292,10 @@ SkyBrowserModule::SkyBrowserModule() return true; } } + // If you start dragging around the target, it should unlock + if (to_target(_mouseOnObject)) { + to_target(_mouseOnObject)->unlock(); + } currentlyDraggingObject = true; return true; diff --git a/modules/skybrowser/skybrowsermodule_lua.inl b/modules/skybrowser/skybrowsermodule_lua.inl index 616bd140a4..0d8629308d 100644 --- a/modules/skybrowser/skybrowsermodule_lua.inl +++ b/modules/skybrowser/skybrowsermodule_lua.inl @@ -92,6 +92,35 @@ namespace openspace::skybrowser::luascriptfunctions { return 0; } + int lockTarget(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::lockTarget"); + const int i = ghoul::lua::value(L, 1); + SkyBrowserModule* module = global::moduleEngine->module(); + std::vector browsers = module->getSkyBrowsers(); + ScreenSpaceSkyTarget* target = browsers[i]->getSkyTarget(); + if (i < browsers.size()) { + ScreenSpaceSkyTarget* target = browsers[i]->getSkyTarget(); + if (target) { + target->lock(); + } + } + return 0; + } + + int unlockTarget(lua_State* L) { + ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::unlockTarget"); + const int i = ghoul::lua::value(L, 1); + SkyBrowserModule* module = global::moduleEngine->module(); + std::vector browsers = module->getSkyBrowsers(); + if (i < browsers.size()) { + ScreenSpaceSkyTarget* target = browsers[i]->getSkyTarget(); + if (target) { + target->unlock(); + } + } + return 0; + } + int followCamera(lua_State* L) { // Load images from url @@ -189,7 +218,7 @@ namespace openspace::skybrowser::luascriptfunctions { // Only add browsers that have an initialized target ScreenSpaceSkyTarget* target = browsers[i]->getSkyTarget(); if (target) { - glm::dvec3 coords = target->getTargetDirection(); + glm::dvec3 coords = target->getTargetDirectionGalactic(); glm::dvec2 celestCoords = skybrowser::galacticCartesianToJ2000(coords); // Convert color to vector so ghoul can read it glm::ivec3 color = browsers[i]->_borderColor.value(); diff --git a/modules/skybrowser/src/screenspaceskybrowser.cpp b/modules/skybrowser/src/screenspaceskybrowser.cpp index b929b443c8..54f5933c60 100644 --- a/modules/skybrowser/src/screenspaceskybrowser.cpp +++ b/modules/skybrowser/src/screenspaceskybrowser.cpp @@ -285,14 +285,7 @@ namespace openspace { _threadWWTMessages = std::thread([&] { while (_camIsSyncedWWT) { if (_skyTarget) { - // Calculate the galactic coordinate of the target direction - // with infinite radius - glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); - constexpr double infinity = std::numeric_limits::max(); - glm::dvec3 galCoord = camPos + (infinity * _skyTarget->getTargetDirection()); - glm::dvec2 celestCoordsTarget = skybrowser::galacticCartesianToJ2000(galCoord); - ghoul::Dictionary message = createMessageForMovingWWTCamera(celestCoordsTarget, _vfieldOfView); - + ghoul::Dictionary message = createMessageForMovingWWTCamera(_skyTarget->getTargetDirectionCelestial(), _vfieldOfView); sendMessageToWWT(message); } diff --git a/modules/skybrowser/src/screenspaceskytarget.cpp b/modules/skybrowser/src/screenspaceskytarget.cpp index d0424410f3..0b0e8a0519 100644 --- a/modules/skybrowser/src/screenspaceskytarget.cpp +++ b/modules/skybrowser/src/screenspaceskytarget.cpp @@ -115,6 +115,12 @@ namespace openspace { } + ScreenSpaceSkyTarget::~ScreenSpaceSkyTarget() { + if (_lockTargetThread.joinable()) { + _lockTargetThread.join(); + } + } + void ScreenSpaceSkyTarget::bindTexture() { if (_texture) { _texture->bind(); @@ -274,7 +280,7 @@ namespace openspace { _targetDimensions = currentBrowserDimensions; } - glm::dvec3 ScreenSpaceSkyTarget::getTargetDirection() { + glm::dvec3 ScreenSpaceSkyTarget::getTargetDirectionGalactic() { // Get camera view direction and orthogonal coordinate system of camera view direction glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); glm::dvec3 targetPosWorldSpace = glm::inverse(global::navigationHandler->camera()->combinedViewMatrix()) * glm::dvec4(_cartesianPosition.value(), 1.0); @@ -282,8 +288,6 @@ namespace openspace { return targetDirection; } - - void ScreenSpaceSkyTarget::updateFOV(float VFOV) { float horizFOV = global::windowDelegate->getHorizFieldOfView(); @@ -294,5 +298,33 @@ namespace openspace { _fieldOfView = VFOV; } - + + void ScreenSpaceSkyTarget::unlock() { + isLocked = false; + if (_lockTargetThread.joinable()) { + _lockTargetThread.join(); + } + } + + void ScreenSpaceSkyTarget::lock() { + isLocked = true; + lockedCelestialCoords = getTargetDirectionCelestial(); + + // Start a thread to enable user interactions while locking target + _lockTargetThread = std::thread([&] { + while (isLocked) { + glm::dvec2 imageCoordsScreenSpace = skybrowser::J2000ToScreenSpace(lockedCelestialCoords.x, lockedCelestialCoords.y); + property("CartesianPosition")->set(glm::vec3 {imageCoordsScreenSpace, skybrowser::SCREENSPACE_Z }); + } + }); + } + + glm::dvec2 ScreenSpaceSkyTarget::getTargetDirectionCelestial() { + // Calculate the galactic coordinate of the target direction + // with infinite radius + glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); + constexpr double infinity = std::numeric_limits::max(); + glm::dvec3 galCoord = camPos + (infinity * getTargetDirectionGalactic()); + return skybrowser::galacticCartesianToJ2000(galCoord); + } }