Cleanup of mouse interaction

This commit is contained in:
sylvass
2021-12-03 17:32:41 -05:00
parent 7a0529b6d1
commit 14c6760859
6 changed files with 199 additions and 158 deletions

View File

@@ -58,7 +58,11 @@ public:
// Mouse interaction
bool checkMouseIntersection(glm::vec2 mousePosition);
glm::vec2 selectedScreenSpacePosition();
bool isSelectedBrowser();
bool isBrowserSelected();
bool isTargetSelected();
void fineTuneTarget(const glm::vec2& start, const glm::vec2& translation);
void translateSelected(const glm::vec2& start, const glm::vec2& translation);
void resizeBrowser(const glm::vec2& start, const glm::vec2& translation);
// Browser
void sendIdToBrowser();
@@ -71,6 +75,7 @@ public:
// Boolean functions
bool hasFinishedFading(float goalState) const;
bool isOnResizeArea(glm::vec2 mouseScreenSpaceCoords);
bool isEnabled() const;
bool isLocked() const;

View File

@@ -47,12 +47,8 @@ namespace openspace {
// Interaction. Resize
void saveResizeStartSize();
// Mouse interaction with the browser. Returns 1 or -1 at the coordinate in
// image if the mouse is on a side of the browser
// __1__
// y| -1 |_____|1
// |__x -1
glm::ivec2 isOnResizeArea(glm::vec2 screenSpaceCoord);
bool isOnResizeArea(glm::vec2 screenSpaceCoord);
void resize(const glm::vec2& start, const glm::vec2& mouseDrag);
glm::dvec2 fineTuneVector(glm::dvec2 drag);
void setIdInBrowser();
@@ -69,13 +65,15 @@ namespace openspace {
bool _isSyncedWithWwt{ false };
bool _isFovAnimated{ false };
// Animation of browser
// Animation of fieldOfView
float _endVfov{ 0.f };
// Resizing of browser
glm::vec2 _originalDimensions;
// Resizing
float _originalScale;
float _resizeAreaPercentage{ 0.1f };
glm::vec2 _originalDimensions;
glm::vec2 _originalScreenSpaceSize;
glm::ivec2 _resizeDirection;
// Time variables
// For capping the calls onchange properties from scrolling

View File

@@ -50,7 +50,7 @@ namespace {
} // namespace
namespace openspace {
scripting::LuaLibrary SkyBrowserModule::luaLibrary() const {
scripting::LuaLibrary res;
@@ -229,141 +229,77 @@ SkyBrowserModule::SkyBrowserModule()
global::callback::mouseButton->emplace_back(
[&](MouseButton button, MouseAction action, KeyModifier modifier) -> bool {
if (_mouseOnPair && action == MouseAction::Press) {
// Get the currently selected browser
setSelectedBrowser(_mouseOnPair->browserId());
if (button == MouseButton::Left) {
_isCameraRotating = false;
_startMousePosition = _mousePosition;
_startDragPosition = _mouseOnPair->selectedScreenSpacePosition();
// If current object is browser, check for resizing
if (_mouseOnPair->isSelectedBrowser()) {
// Resize browser if mouse is over resize button
_resizeDirection = _mouseOnPair->getBrowser()->isOnResizeArea(
_mousePosition
);
if (_resizeDirection != glm::ivec2{ 0 }) {
_mouseOnPair->getBrowser()->saveResizeStartSize();
_startBrowserSize = _mouseOnPair->getBrowser()->
screenSpaceDimensions();
_isResizing = true;
return true;
}
}
// If you start dragging around the target, it should unlock
else {
_mouseOnPair->unlock();
}
_isDragging = true;
return true;
}
// Fine tuning mode of target
else if (_mouseOnPair->isSelectedBrowser() &&
button == MouseButton::Right) {
// If you start dragging around on the browser, the target unlocks
_mouseOnPair->unlock();
// Change view (by moving target) within browser if right mouse
// click on browser
_startMousePosition = _mousePosition;
_startDragPosition = _mouseOnPair->getTarget()->screenSpacePosition();
_isFineTuneMode = true;
return true;
}
if (!_isCameraInSolarSystem) {
return false;
}
else if (action == MouseAction::Release) {
if (_isDragging) {
_isDragging = false;
return true;
}
if (_isFineTuneMode) {
_isFineTuneMode = false;
return true;
}
if (_isResizing) {
_isResizing = false;
if (action == MouseAction::Press && _mouseOnPair) {
handleMouseClick(button);
return true;
}
else if (_interactionMode != MouseInteraction::Hover &&
action == MouseAction::Release) {
// Update browser size if it has been resized
if (_interactionMode == MouseInteraction::Resize) {
_mouseOnPair->updateBrowserSize();
return true;
}
}
return false;
_interactionMode = MouseInteraction::Hover;
return true;
}
else {
return false;
}
}
);
global::callback::mousePosition->emplace_back(
[&](double x, double y) {
if (_isCameraInSolarSystem) {
glm::vec2 pixel{ static_cast<float>(x), static_cast<float>(y) };
_mousePosition = skybrowser::pixelToScreenSpace2d(pixel);
glm::vec2 translation = _mousePosition - _startMousePosition;
if (_isResizing) {
// Calculate scaling factor
glm::vec2 mouseDragVector = (_mousePosition - _startMousePosition);
glm::vec2 scaling = mouseDragVector * glm::vec2(_resizeDirection);
glm::vec2 newSizeRelToOld = (_startBrowserSize + (scaling)) /
_startBrowserSize;
// Scale the browser
_mouseOnPair->getBrowser()->setScale(newSizeRelToOld);
// For dragging functionality, translate so it looks like the
// browser isn't moving. Make sure the browser doesn't move in
// directions it's not supposed to
translation = 0.5f * mouseDragVector * abs(
glm::vec2(_resizeDirection)
);
}
if (_isDragging || _isResizing) {
// Translate
if (_mouseOnPair->isSelectedBrowser()) {
_mouseOnPair->getBrowser()->translate(
translation,
_startDragPosition
);
}
else {
_mouseOnPair->getTarget()->translate(
translation,
_startDragPosition
);
}
}
else if (_isFineTuneMode) {
glm::vec2 fineTune = _mouseOnPair->getBrowser()->fineTuneVector(
translation
);
_mouseOnPair->getTarget()->translate(fineTune, _startDragPosition);
}
// If there is no dragging or resizing, look for new objects
else {
setSelectedObject();
}
if (!_isCameraInSolarSystem) {
return false;
}
glm::vec2 pixel{ static_cast<float>(x), static_cast<float>(y) };
_mousePosition = skybrowser::pixelToScreenSpace2d(pixel);
glm::vec2 translation = _mousePosition - _startMousePosition;
switch (_interactionMode) {
case MouseInteraction::Hover:
setSelectedObject();
break;
case MouseInteraction::Resize:
_mouseOnPair->resizeBrowser(_startDragPosition, translation);
break;
case MouseInteraction::Drag:
_mouseOnPair->translateSelected(_startDragPosition, translation);
break;
case MouseInteraction::FineTune:
_mouseOnPair->fineTuneTarget(_startDragPosition, translation);
break;
default:
setSelectedObject();
break;
}
return false;
}
);
global::callback::mouseScrollWheel->emplace_back(
[&](double, double scroll) -> bool {
// If mouse is on browser or target, apply zoom
if (_mouseOnPair) {
_mouseOnPair->getBrowser()->setVerticalFovWithScroll(
static_cast<float>(scroll)
);
return true;
if (!_isCameraInSolarSystem || !_mouseOnPair) {
return false;
}
return false;
// If mouse is on browser or target, apply zoom
_mouseOnPair->getBrowser()->setVerticalFovWithScroll(
static_cast<float>(scroll)
);
return true;
}
);
@@ -374,27 +310,28 @@ SkyBrowserModule::SkyBrowserModule()
bool camWasInSolarSystem = _isCameraInSolarSystem;
glm::dvec3 cameraPos = global::navigationHandler->camera()->positionVec3();
_isCameraInSolarSystem = glm::length(cameraPos) < SolarSystemRadius;
bool vizModeChanged = _isCameraInSolarSystem != camWasInSolarSystem;
// Fading flags
if (_isCameraInSolarSystem != camWasInSolarSystem) {
_isTransitioningVizMode = true;
// Select the 3D browser when moving out of the solar system
if (!_isCameraInSolarSystem && _browser3dNode) {
_selectedBrowser = _browser3dNode->renderable()->identifier();
// Visualization mode changed. Start fading
if (vizModeChanged) {
_isFading = true;
// Camera moved into the solar system
if (!_isCameraInSolarSystem) {
_goal = Transparency::Transparent;
// Select the 3D browser when moving out of the solar system
if (_browser3dNode) {
_selectedBrowser = _browser3dNode->renderable()->identifier();
}
}
else {
_goal = Transparency::Opaque;
}
}
double deltaTime = global::windowDelegate->deltaTime();
// Fade pairs if the camera moved in or out the solar system
if (_isTransitioningVizMode) {
if (_isCameraInSolarSystem) {
incrementallyFadeBrowserTargets(Transparency::Opaque, deltaTime);
}
else {
incrementallyFadeBrowserTargets(Transparency::Transparent, deltaTime);
}
if (_isFading) {
incrementallyFadeBrowserTargets(_goal, deltaTime);
}
if (_isCameraInSolarSystem) {
incrementallyAnimateTargets(deltaTime);
}
@@ -435,6 +372,9 @@ void SkyBrowserModule::internalInitialize(const ghoul::Dictionary& dict) {
void SkyBrowserModule::setSelectedObject()
{
if (_interactionMode != MouseInteraction::Hover) {
return;
}
// Save old selection for removing highlight
Pair* previousPair = _mouseOnPair;
@@ -488,8 +428,8 @@ void SkyBrowserModule::createTargetBrowserPair() {
std::string idTarget = "SkyTarget" + std::to_string(noOfPairs);
glm::vec3 positionBrowser = { -1.0f, -0.5f, -2.1f };
std::string guiPath = "/SkyBrowser";
std::string url = "https://data.openspaceproject.com/dist/skybrowser/page/";
//std::string url = "http://localhost:8000";
//std::string url = "https://data.openspaceproject.com/dist/skybrowser/page/";
std::string url = "http://localhost:8000";
const std::string browser = "{"
"Identifier = '" + idBrowser + "',"
@@ -628,6 +568,45 @@ void SkyBrowserModule::add2dSelectedImagesTo3d(const std::string& pairId)
}
}
void SkyBrowserModule::handleMouseClick(const MouseButton& button)
{
setSelectedBrowser(_mouseOnPair->browserId());
if (button == MouseButton::Left) {
_startMousePosition = _mousePosition;
_startDragPosition = _mouseOnPair->selectedScreenSpacePosition();
// If current object is browser, check for resizing
bool shouldResize = _mouseOnPair->isBrowserSelected() &&
_mouseOnPair->isOnResizeArea(_mousePosition);
if (shouldResize) {
_mouseOnPair->getBrowser()->saveResizeStartSize();
_interactionMode = MouseInteraction::Resize;
return;
}
else {
// If it's not resize mode, it's drag mode
_interactionMode = MouseInteraction::Drag;
}
// If target is clicked, it should unlock
if (_mouseOnPair->isTargetSelected()) {
_mouseOnPair->unlock();
}
}
// Fine tuning mode of target
else if (button == MouseButton::Right && _mouseOnPair->isBrowserSelected()) {
// If you start dragging around on the browser, the target unlocks
_mouseOnPair->unlock();
// Change view (by moving target) within browser if right mouse
// click on browser
_startMousePosition = _mousePosition;
_startDragPosition = _mouseOnPair->getTarget()->screenSpacePosition();
_interactionMode = MouseInteraction::FineTune;
}
}
const std::unique_ptr<WwtDataHandler>& SkyBrowserModule::getWwtDataHandler() {
return _dataHandler;
}
@@ -769,7 +748,7 @@ void SkyBrowserModule::incrementallyFadeBrowserTargets(Transparency goal, float
// The transition is over when the fade is finished
if (isAllFinished) {
_isTransitioningVizMode = false;
_isFading = false;
}
}

View File

@@ -28,6 +28,7 @@
#include <openspace/documentation/documentation.h>
#include <openspace/util/openspacemodule.h>
#include <openspace/util/distanceconstants.h>
#include <openspace/util/mouse.h>
#include <fstream>
namespace openspace {
@@ -44,6 +45,13 @@ enum class Transparency {
Opaque
};
enum class MouseInteraction {
Hover,
Resize,
Drag,
FineTune,
};
class SkyBrowserModule : public OpenSpaceModule {
public:
@@ -96,6 +104,9 @@ public:
int nLoadedImages();
void add2dSelectedImagesTo3d(const std::string& pairId);
// Mouse interaction
void handleMouseClick(const MouseButton& button);
scripting::LuaLibrary luaLibrary() const override;
//std::vector<documentation::Documentation> documentations() const override;
@@ -114,24 +125,21 @@ private:
// Fading
double _fadingTime = 2.0;
Transparency _goal;
// Flags
bool _isFineTuneMode{ false };
bool _isResizing{ false };
bool _isDragging{ false };
bool _isCameraInSolarSystem{ true };
bool _isCameraInSolarSystem{ true }; // Visualization modes
bool _isFading{ false };
bool _isCameraRotating = false;
bool _isTransitioningVizMode{ false };
// Mouse interaction - dragging and resizing
glm::ivec3 _highlightAddition{ 35 }; // Highlight object when mouse hovers
// Mouse interaction
MouseInteraction _interactionMode;
glm::vec2 _mousePosition; // Current mouse position in screen space coordinates
glm::vec2 _startMousePosition;
glm::vec2 _startDragPosition;
glm::vec2 _startBrowserSize;
glm::ivec2 _resizeDirection{ 0 };
// Animation of rotation of camera to look at coordinate galactic coordinates
glm::ivec3 _highlightAddition{ 35 }; // Highlight object when mouse hovers
glm::dvec3 _startAnimation;
glm::dvec3 _endAnimation;
double _stopAnimationThreshold{ 0.05 };

View File

@@ -151,11 +151,32 @@ namespace openspace {
return _selected->screenSpacePosition();
}
bool Pair::isSelectedBrowser()
bool Pair::isBrowserSelected()
{
return _isSelectedBrowser;
}
bool Pair::isTargetSelected()
{
return _selected && !_isSelectedBrowser;
}
void Pair::fineTuneTarget(const glm::vec2& start, const glm::vec2& translation)
{
glm::vec2 fineTune = _browser->fineTuneVector(translation);
_target->translate(fineTune, start);
}
void Pair::translateSelected(const glm::vec2& start, const glm::vec2& translation)
{
_selected->translate(translation, start);
}
void Pair::resizeBrowser(const glm::vec2& start, const glm::vec2& translation)
{
_browser->resize(start, translation);
}
void Pair::setEnabled(bool enable)
{
_browser->setEnabled(enable);
@@ -297,6 +318,11 @@ namespace openspace {
return isTargetFadeFinished(goalState) && isBrowserFadeFinished(goalState);
}
bool Pair::isOnResizeArea(glm::vec2 mouseScreenSpaceCoords)
{
return _browser->isOnResizeArea(mouseScreenSpaceCoords);
}
ScreenSpaceSkyTarget* Pair::getTarget() {
return _target;
}

View File

@@ -242,10 +242,15 @@ namespace openspace {
_texture->bind();
}
glm::ivec2 ScreenSpaceSkyBrowser::isOnResizeArea(glm::vec2 coord) {
// Mouse interaction with the browser. Returns 1 or -1 at the coordinate in
// image if the mouse is on a side of the browser
// __1__
// y| -1 |_____|1
// |__x -1
bool ScreenSpaceSkyBrowser::isOnResizeArea(glm::vec2 coord) {
glm::ivec2 resizePosition = glm::ivec2{ 0 };
// Make sure coordinate is on browser
if (!intersection(coord)) return resizePosition;
if (!intersection(coord)) return false;
// TO DO: turn this into a vector and use prettier vector arithmetic
float resizeAreaY = screenSpaceDimensions().y * _resizeAreaPercentage;
@@ -259,7 +264,26 @@ namespace openspace {
resizePosition.x = isOnRight ? 1 : isOnLeft ? -1 : 0;
resizePosition.y = isOnTop ? 1 : isOnBottom ? -1 : 0;
return resizePosition;
_resizeDirection = resizePosition;
return isOnRight || isOnLeft || isOnTop || isOnBottom;
}
void ScreenSpaceSkyBrowser::resize(const glm::vec2& start, const glm::vec2& mouseDrag)
{
glm::vec2 scaling = mouseDrag * glm::vec2(_resizeDirection);
glm::vec2 newSizeRelToOld = (_originalScreenSpaceSize + (scaling)) /
_originalScreenSpaceSize;
// Scale the browser
setScale(newSizeRelToOld);
// For dragging functionality, translate so it looks like the
// browser isn't moving. Make sure the browser doesn't move in
// directions it's not supposed to
glm::vec2 translation = 0.5f * mouseDrag * abs(
glm::vec2(_resizeDirection)
);
translate(translation, start);
}
void ScreenSpaceSkyBrowser::setScale(float scalingFactor) {
@@ -292,6 +316,7 @@ namespace openspace {
}
void ScreenSpaceSkyBrowser::saveResizeStartSize() {
_originalScreenSpaceSize = screenSpaceDimensions();
_originalDimensions = _dimensions;
_originalScale = _scale;
}