diff --git a/modules/skybrowser/skybrowsermodule.cpp b/modules/skybrowser/skybrowsermodule.cpp index 293fe89143..19cf31ed07 100644 --- a/modules/skybrowser/skybrowsermodule.cpp +++ b/modules/skybrowser/skybrowsermodule.cpp @@ -337,6 +337,9 @@ SkyBrowserModule::SkyBrowserModule() browser->getSkyTarget()->animateToCoord(global::windowDelegate->deltaTime()); } } + if (isRotating) { + rotateCamera(global::windowDelegate->deltaTime()); + } }); } @@ -398,6 +401,40 @@ std::vector SkyBrowserModule::getSkyBrowsers() { return browsers; } +void SkyBrowserModule::startRotation(glm::dvec2 coordsEnd) { + + // Save coordinates to rotate to in galactic world coordinates + glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); + _coordsToAnimateTo = skybrowser::J2000SphericalToGalacticCartesian(coordsEnd); + _coordsStartAnimation = (global::navigationHandler->camera()->viewDirectionWorldSpace() * skybrowser::infinity) + camPos; + isRotating = true; +} + +void SkyBrowserModule::rotateCamera(double deltaTime) { + + // Find smallest angle between the two vectors + double smallestAngle = std::acos(glm::dot(_coordsStartAnimation, _coordsToAnimateTo) / (glm::length(_coordsStartAnimation) * glm::length(_coordsToAnimateTo))); + // Only keep animating when target is not at final position + if (abs(smallestAngle) > 0.0001) { + // Calculate rotation this frame + double rotationAngle = smallestAngle * deltaTime; + // Create the rotation matrix for local camera space + glm::dvec3 rotationAxis = glm::normalize(glm::cross(_coordsStartAnimation, _coordsToAnimateTo)); + glm::dmat4 camMat = global::navigationHandler->camera()->viewRotationMatrix(); + glm::dvec3 viewDirectionLocal = camMat * glm::dvec4(rotationAxis, 1.0); + glm::dmat4 rotmat = glm::rotate(rotationAngle, rotationAxis); + // Rotate + global::navigationHandler->camera()->rotate(glm::quat_cast(rotmat)); + + // Update camera direction + glm::dvec3 camPos = global::navigationHandler->camera()->positionVec3(); + _coordsStartAnimation = (global::navigationHandler->camera()->viewDirectionWorldSpace() * skybrowser::infinity) + camPos; + } + else { + isRotating = false; + } +} + /* std::vector SkyBrowserModule::documentations() const { return { diff --git a/modules/skybrowser/skybrowsermodule.h b/modules/skybrowser/skybrowsermodule.h index 8d3aebd090..3d9248cafc 100644 --- a/modules/skybrowser/skybrowsermodule.h +++ b/modules/skybrowser/skybrowsermodule.h @@ -55,6 +55,8 @@ public: void addRenderable(ScreenSpaceRenderable* object); WWTDataHandler* getWWTDataHandler(); std::vector getSkyBrowsers(); + void startRotation(glm::dvec2 coordsEnd); + void rotateCamera(double deltaTime); scripting::LuaLibrary luaLibrary() const override; //std::vector documentations() const override; @@ -88,6 +90,10 @@ protected: // For capping the calls to change the zoom from scrolling constexpr static const std::chrono::milliseconds TimeUpdateInterval{ 50 }; std::chrono::system_clock::time_point _lastUpdateTime; + // For animating rotation of camera to look at coordinate + glm::dvec3 _coordsToAnimateTo; + glm::dvec3 _coordsStartAnimation; + bool isRotating = false; }; } // namespace openspace diff --git a/modules/skybrowser/skybrowsermodule_lua.inl b/modules/skybrowser/skybrowsermodule_lua.inl index 4eb0aefc08..9f822b936c 100644 --- a/modules/skybrowser/skybrowsermodule_lua.inl +++ b/modules/skybrowser/skybrowsermodule_lua.inl @@ -284,7 +284,14 @@ namespace openspace::skybrowser::luascriptfunctions { return 1; } int adjustCamera(lua_State* L) { - ghoul::lua::checkArgumentsAndThrow(L, 0, "lua::adjustCamera"); + ghoul::lua::checkArgumentsAndThrow(L, 1, "lua::adjustCamera"); + const int i = ghoul::lua::value(L, 1); + SkyBrowserModule* module = global::moduleEngine->module(); + //module->getSkyBrowsers()[0]->getSkyTarget()->lock(); + if (module->getSkyBrowsers().size() > i) { + module->startRotation(module->getSkyBrowsers()[i]->getSkyTarget()->getTargetDirectionCelestial()); + } + return 0; }