mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-09 21:21:19 -06:00
Add working resize and dragging functionality
This commit is contained in:
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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<float>(x), static_cast<float>(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() {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <openspace/util/camera.h>
|
||||
#include <openspace/scene/scene.h>
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
|
||||
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<CefFrame> frame = _browserInstance->getBrowser()->GetMainFrame();
|
||||
frame->ExecuteJavaScript(script, frame->GetURL(), 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenSpaceSkyBrowser::sendMouseEvent(CefStructBase<CefMouseEventTraits> 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<float>(_objectSize.x) / static_cast<float>(_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<float>(_objectSize.x) / static_cast<float>(_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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<float>(_objectSize.x) / static_cast<float>(_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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user