mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-08 20:50:19 -06:00
Cleanup of mouse interaction
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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 };
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user