diff --git a/modules/skybrowser/include/screenspaceskybrowser.h b/modules/skybrowser/include/screenspaceskybrowser.h index 525d61bafe..f13457f562 100644 --- a/modules/skybrowser/include/screenspaceskybrowser.h +++ b/modules/skybrowser/include/screenspaceskybrowser.h @@ -19,8 +19,16 @@ namespace openspace { glm::vec2 getUpperRightCornerScreenSpace(); glm::vec2 getLowerLeftCornerScreenSpace(); bool coordIsInsideCornersScreenSpace(glm::vec2 coord); - private: + bool coordIsOnResizeButton(glm::vec2 coord); + void scale(glm::vec2 scalingFactor); + glm::mat4 scaleMatrix() override; + void saveResizeStartSize(); + void updateBrowserSize(); + void scale(float scalingFactor); + private: + glm::vec2 _startSize; + float _startScale; }; } diff --git a/modules/skybrowser/skybrowsermodule.cpp b/modules/skybrowser/skybrowsermodule.cpp index 619a895e56..40e82d48e7 100644 --- a/modules/skybrowser/skybrowsermodule.cpp +++ b/modules/skybrowser/skybrowsermodule.cpp @@ -91,6 +91,7 @@ SkyBrowserModule::SkyBrowserModule() , _camIsSyncedWWT(true) , currentlyDraggingBrowser(false) , currentlyDraggingTarget(false) + , currentlyResizingBrowser(false) , _listenForInteractions(true) , mouseIsOnBrowser(false) , mouseIsOnTarget(false) @@ -103,6 +104,7 @@ SkyBrowserModule::SkyBrowserModule() global::callback::mousePosition->emplace_back( [&](double x, double y) { glm::vec2 pos = glm::vec2(static_cast(x), static_cast(y)); + _mousePosition = getMousePositionInScreenSpaceCoords(pos); if (_skyTarget) { @@ -112,7 +114,7 @@ SkyBrowserModule::SkyBrowserModule() mouseIsOnTarget = false; } if (_skyBrowser) { - mouseIsOnBrowser = _skyBrowser->coordIsInsideCornersScreenSpace(_mousePosition); + mouseIsOnBrowser = _skyBrowser->coordIsInsideCornersScreenSpace(_mousePosition); } else { mouseIsOnBrowser = false; @@ -141,7 +143,16 @@ SkyBrowserModule::SkyBrowserModule() startDragMousePosBrowser = _mousePosition; startDragObjectPosBrowser = _skyBrowser->getScreenSpacePosition(); - currentlyDraggingBrowser = true; + // Resize browser if mouse is over resize button + if (_skyBrowser->coordIsOnResizeButton(_mousePosition)) { + _skyBrowser->saveResizeStartSize(); + startResizeBrowserSize = _skyBrowser->getScreenSpaceDimensions(); + currentlyResizingBrowser = true; + } + else { + currentlyDraggingBrowser = true; + } + return true; } else if (mouseIsOnTarget && button == MouseButton::Left) { @@ -168,13 +179,16 @@ SkyBrowserModule::SkyBrowserModule() currentlyDraggingTarget = false; return true; } + if (currentlyResizingBrowser) { + currentlyResizingBrowser = false; + _skyBrowser->updateBrowserSize(); + return true; + } } return false; } ); - - } void SkyBrowserModule::internalDeinitialize() { @@ -279,15 +293,27 @@ void SkyBrowserModule::handleInteractions() { if (currentlyDraggingTarget) { _skyTarget->translate(_mousePosition - startDragMousePosTarget, startDragObjectPosTarget); } + if (currentlyResizingBrowser) { + // Calculate scaling factor + glm::vec2 mouseDragVector = _mousePosition - startDragMousePosBrowser; + + glm::vec2 newSizeRelToOld = (startResizeBrowserSize + mouseDragVector) / startResizeBrowserSize; + _skyBrowser->scale(newSizeRelToOld); + _skyBrowser->translate(mouseDragVector/2.f, startDragObjectPosBrowser); + } } }); } glm::vec2 SkyBrowserModule::getMousePositionInScreenSpaceCoords(glm::vec2& mousePos) { - glm::vec2 size = glm::vec2(global::windowDelegate->currentWindowSize()); - - // Transform pixel coordinates to screen space coordinates [-1,1] - return glm::vec2((mousePos - (size / 2.0f)) * glm::vec2(1.0f,-1.0f) / (size / 2.0f)); + glm::vec2 size = global::windowDelegate->currentWindowSize(); + // Change origin to middle of the window + glm::vec2 screenSpacePos = glm::vec2((mousePos - (size / 2.0f))); + // Ensure the upper right corner is positive on the y axis + screenSpacePos *= glm::vec2(1.0f, -1.0f); + // Transform pixel coordinates to screen space coordinates [-1,1][-ratio, ratio] + screenSpacePos /= (0.5f*size.y); + return screenSpacePos; } void SkyBrowserModule::WWTfollowCamera() { diff --git a/modules/skybrowser/skybrowsermodule.h b/modules/skybrowser/skybrowsermodule.h index a6d0e9fc34..a912136ff6 100644 --- a/modules/skybrowser/skybrowsermodule.h +++ b/modules/skybrowser/skybrowsermodule.h @@ -84,7 +84,9 @@ protected: glm::vec2 startDragObjectPosBrowser; glm::vec2 startDragMousePosTarget; glm::vec2 startDragObjectPosTarget; + glm::vec2 startResizeBrowserSize; bool currentlyDraggingBrowser; + bool currentlyResizingBrowser; bool currentlyDraggingTarget; glm::vec2 _mousePosition; double _mouseScroll; diff --git a/modules/skybrowser/src/screenspaceskybrowser.cpp b/modules/skybrowser/src/screenspaceskybrowser.cpp index c212535e6e..c48102137b 100644 --- a/modules/skybrowser/src/screenspaceskybrowser.cpp +++ b/modules/skybrowser/src/screenspaceskybrowser.cpp @@ -15,6 +15,7 @@ #include #include #include +#include namespace { constexpr const char* _loggerCat = "ScreenSpaceSkyBrowser"; @@ -34,15 +35,17 @@ namespace openspace { } identifier = makeUniqueIdentifier(identifier); setIdentifier(identifier); - + // The projection plane seems to be located at z = -2.1 so at that place the ScreenSpaceRenderables behaves like + // they are in screen space + _cartesianPosition.setValue(glm::vec3(_cartesianPosition.value().x, _cartesianPosition.value().y, -2.1f)); } + void ScreenSpaceSkyBrowser::executeJavascript(std::string& script) const { //LINFOC(_loggerCat, "Executing javascript " + script); if (_browserInstance && _browserInstance->getBrowser() && _browserInstance->getBrowser()->GetMainFrame()) { CefRefPtr frame = _browserInstance->getBrowser()->GetMainFrame(); frame->ExecuteJavaScript(script, frame->GetURL(), 0); - } - + } } void ScreenSpaceSkyBrowser::sendMouseEvent(CefStructBase event, int x, int y) const { @@ -54,64 +57,26 @@ namespace openspace { //LINFOC(_loggerCat, "Sending scroll"); } - } void ScreenSpaceSkyBrowser::translate(glm::vec2 translation) { - - glm::vec3 position = _cartesianPosition; - + glm::vec3 position = _cartesianPosition; _cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, 1.0f); } void ScreenSpaceSkyBrowser::translate(glm::vec2 translation, glm::vec2 position) { - - glm::vec2 windowRatio = global::windowDelegate->currentWindowSize(); - windowRatio /= windowRatio.y; - - _cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation * windowRatio, 0.0f)) * glm::vec4(position * windowRatio, _cartesianPosition.value().z, 1.0f); + _cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, _cartesianPosition.value().z, 1.0f); } glm::vec2 ScreenSpaceSkyBrowser::getScreenSpacePosition() { - glm::mat4 modelTransform = globalRotationMatrix() * translationMatrix() * - localRotationMatrix() * scaleMatrix(); - glm::mat4 viewProj = global::renderEngine->scene()->camera()->viewProjectionMatrix(); - glm::mat4 screenSpaceTransform = viewProj * modelTransform; - - glm::vec3 scale; - glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(screenSpaceTransform, scale, rotation, translation, skew, perspective); - - return translation; + return glm::vec2(_cartesianPosition.value().x, _cartesianPosition.value().y); } glm::vec2 ScreenSpaceSkyBrowser::getScreenSpaceDimensions() { - glm::mat4 modelTransform = globalRotationMatrix() * translationMatrix() * - localRotationMatrix() * scaleMatrix(); - glm::mat4 viewProj = global::renderEngine->scene()->camera()->viewProjectionMatrix(); - glm::mat4 screenSpaceTransform = viewProj * modelTransform; - - - glm::vec3 scale; - glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(screenSpaceTransform, scale, rotation, translation, skew, perspective); - - // Scale is negative and relative to the whole screen - // Changing to positive and View Coordinates [-1,1] - // E.g. a full screen screenspacebrowser will have [2,2] - scale = -2.0f * scale; - - return scale; + return glm::vec2(2.f*_scale* static_cast(_objectSize.x) / static_cast(_objectSize.y), 2.f*_scale); } glm::vec2 ScreenSpaceSkyBrowser::getUpperRightCornerScreenSpace() { - return getScreenSpacePosition() + (getScreenSpaceDimensions()/2.0f); } @@ -125,4 +90,47 @@ namespace openspace { return lessThanUpperRight && moreThanLowerLeft; } + bool ScreenSpaceSkyBrowser::coordIsOnResizeButton(glm::vec2 coord) { + float resizeButtonSize = 0.05f; + bool lessThanUpperRight = coord.x < getUpperRightCornerScreenSpace().x && coord.y < getUpperRightCornerScreenSpace().y; + bool moreThanLowerLeft = coord.x > getUpperRightCornerScreenSpace().x - (getScreenSpaceDimensions().x * resizeButtonSize) && + coord.y > getLowerLeftCornerScreenSpace().y - (getScreenSpaceDimensions().y * resizeButtonSize); + return lessThanUpperRight && moreThanLowerLeft; + } + // Scales the ScreenSpaceBrowser to a new ratio + void ScreenSpaceSkyBrowser::scale(glm::vec2 scalingFactor) { + // Resize the dimensions of the texture on the x axis + glm::vec2 newSize = abs(scalingFactor) * _startSize; + _texture->setDimensions(glm::ivec3(newSize, 1)); + // Scale on the y axis, this is to ensure that _scale = 1 is + // equal to the height of the window + scale(abs(scalingFactor.y)); + } + + glm::mat4 ScreenSpaceSkyBrowser::scaleMatrix() { + // To ensure the plane has the right ratio + // The _scale us how much of the windows height the + // browser covers: eg a browser that covers 0.25 of the + // height of the window will have scale = 0.25 + float textureRatio = + static_cast(_objectSize.x) / static_cast(_objectSize.y); + + glm::mat4 scale = glm::scale( + glm::mat4(1.f), + glm::vec3(textureRatio * _scale, _scale, 1.f) + ); + return scale; + } + + void ScreenSpaceSkyBrowser::saveResizeStartSize() { + _startSize = glm::vec2(_dimensions.value().x, _dimensions.value().y); + _startScale = _scale.value(); + } + // Updates the browser size to match the size of the texture + void ScreenSpaceSkyBrowser::updateBrowserSize() { + _dimensions = _texture->dimensions(); + } + void ScreenSpaceSkyBrowser::scale(float scalingFactor) { + _scale = _startScale * scalingFactor; + } } diff --git a/modules/skybrowser/src/screenspaceskytarget.cpp b/modules/skybrowser/src/screenspaceskytarget.cpp index 032db8749f..bbcfc1589f 100644 --- a/modules/skybrowser/src/screenspaceskytarget.cpp +++ b/modules/skybrowser/src/screenspaceskytarget.cpp @@ -65,6 +65,7 @@ namespace openspace { _texture = std::move(texture); _objectSize = _texture->dimensions(); } + _cartesianPosition.setValue(glm::vec3(_cartesianPosition.value().x, _cartesianPosition.value().y, -2.1f)); } void ScreenSpaceSkyTarget::bindTexture() { @@ -74,27 +75,7 @@ namespace openspace { } void ScreenSpaceSkyTarget::translate(glm::vec2 translation, glm::vec2 position) { - - glm::vec2 windowRatio = global::windowDelegate->currentWindowSize(); - windowRatio /= windowRatio.y; - - _cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation * windowRatio, 0.0f)) * glm::vec4(position * windowRatio, _cartesianPosition.value().z, 1.0f); - } - - glm::vec2 ScreenSpaceSkyTarget::getScreenSpacePosition() { - glm::mat4 modelTransform = globalRotationMatrix() * translationMatrix() * - localRotationMatrix() * scaleMatrix(); - glm::mat4 viewProj = global::renderEngine->scene()->camera()->viewProjectionMatrix(); - glm::mat4 screenSpaceTransform = viewProj * modelTransform; - - glm::vec3 scale; - glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(screenSpaceTransform, scale, rotation, translation, skew, perspective); - - return translation; + _cartesianPosition = glm::translate(glm::mat4(1.f), glm::vec3(translation, 0.0f)) * glm::vec4(position, _cartesianPosition.value().z, 1.0f); } glm::vec2 ScreenSpaceSkyTarget::getAnglePosition() { @@ -102,26 +83,12 @@ namespace openspace { return glm::vec2(atan(pos.x / pos.z), atan(pos.y / pos.z)); } + glm::vec2 ScreenSpaceSkyTarget::getScreenSpacePosition() { + return glm::vec2(_cartesianPosition.value().x, _cartesianPosition.value().y); + } + glm::vec2 ScreenSpaceSkyTarget::getScreenSpaceDimensions() { - glm::mat4 modelTransform = globalRotationMatrix() * translationMatrix() * - localRotationMatrix() * scaleMatrix(); - glm::mat4 viewProj = global::renderEngine->scene()->camera()->viewProjectionMatrix(); - glm::mat4 screenSpaceTransform = viewProj * modelTransform; - - - glm::vec3 scale; - glm::quat rotation; - glm::vec3 translation; - glm::vec3 skew; - glm::vec4 perspective; - glm::decompose(screenSpaceTransform, scale, rotation, translation, skew, perspective); - - // Scale is negative and relative to the whole screen - // Changing to positive and View Coordinates [-1,1] - // E.g. a full screen screenspacebrowser will have [2,2] - scale = -2.0f * scale; - - return scale; + return glm::vec2(2.f * _scale * static_cast(_objectSize.x) / static_cast(_objectSize.y), 2.f * _scale); } glm::vec2 ScreenSpaceSkyTarget::getUpperRightCornerScreenSpace() { @@ -138,4 +105,5 @@ namespace openspace { bool moreThanLowerLeft = coord.x > getLowerLeftCornerScreenSpace().x && coord.y > getLowerLeftCornerScreenSpace().y; return lessThanUpperRight && moreThanLowerLeft; } + }