diff --git a/src/DisplaysView.cpp b/src/DisplaysView.cpp index f701316..513f818 100644 --- a/src/DisplaysView.cpp +++ b/src/DisplaysView.cpp @@ -1130,8 +1130,14 @@ bool DisplaysView::doubleclic (glm::vec2 P) return false; } +#define MAX_DURATION 1000.f +#define MIN_SPEED_D 0.1f +#define MAX_SPEED_D 2.f + void DisplaysView::arrow (glm::vec2 movement) { + static float _duration = 0.f; + // grab only works on current window if not fullscreen if (current_window_ > -1 && !Settings::application.windows[current_window_+1].fullscreen) { @@ -1147,10 +1153,13 @@ void DisplaysView::arrow (glm::vec2 movement) // initiate (terminated at key release) current_action_ongoing_ = true; + _duration = 0.f; } // add movement vector to position (pixel precision) - p += movement ; //* (dt_ * 0.5f); + _duration += dt_; + const float speed = MIN_SPEED_D + (MAX_SPEED_D - MIN_SPEED_D) * glm::min(1.f,_duration / MAX_DURATION); + p += movement * dt_ * speed; //* (dt_ * 0.5f); // discretized translation with ALT if (UserInterface::manager().altModifier()) { diff --git a/src/GeometryView.cpp b/src/GeometryView.cpp index 8ed7e6e..07163e9 100644 --- a/src/GeometryView.cpp +++ b/src/GeometryView.cpp @@ -40,6 +40,7 @@ #include "UserInterfaceManager.h" #include "BoundingBoxVisitor.h" #include "ActionManager.h" +#include "MousePointer.h" #include "GeometryView.h" @@ -1246,10 +1247,15 @@ void GeometryView::terminate(bool force) adaptGridToSource(); } +#define MAX_DURATION 1000.f +#define MIN_SPEED_A 0.005f +#define MAX_SPEED_A 0.5f + void GeometryView::arrow (glm::vec2 movement) { - static float accumulator = 0.f; - accumulator += dt_ * 0.2f; + static float _duration = 0.f; + static glm::vec2 _from(0.f); + static glm::vec2 _displacement(0.f); Source *current = Mixer::manager().currentSource(); @@ -1260,89 +1266,54 @@ void GeometryView::arrow (glm::vec2 movement) if (current_action_ongoing_) { - glm::vec2 Position_from = glm::vec2( Rendering::manager().project(current->stored_status_->translation_, scene.root()->transform_) ); - glm::vec2 Position_to = Position_from + movement * accumulator; + // add movement to displacement + _duration += dt_; + const float speed = MIN_SPEED_A + (MAX_SPEED_A - MIN_SPEED_A) * glm::min(1.f,_duration / MAX_DURATION); + _displacement += movement * dt_ * speed; - grab(current, Position_from, Position_to, std::make_pair(current->group(mode_), glm::vec2(0.f) ) ); + // set coordinates of target + glm::vec2 _to = _from + _displacement; + // update mouse pointer action + MousePointer::manager().active()->update(_to, dt_ / 1000.f); + + // simulate mouse grab + grab(current, _from, MousePointer::manager().active()->target(), + std::make_pair(current->group(mode_), glm::vec2(0.f) ) ); + + // draw mouse pointer effect + MousePointer::manager().active()->draw(); } else { + if (UserInterface::manager().altModifier() || Settings::application.mouse_pointer_lock) + MousePointer::manager().setActiveMode( (Pointer::Mode) Settings::application.mouse_pointer ); + else + MousePointer::manager().setActiveMode( Pointer::POINTER_DEFAULT ); + + // reset + _duration = 0.f; + _displacement = glm::vec2(0.f); + + // initiate view action and store status of source initiate(); - accumulator = 0.f; - adaptGridToSource(current); + // get coordinates of source and set this as start of mouse position + _from = glm::vec2( Rendering::manager().project(current->group(mode_)->translation_, scene.root()->transform_) ); + // Initiate mouse pointer action + MousePointer::manager().active()->initiate(_from); } - } - else + else { terminate(true); + // reset + _duration = 0.f; + _from = glm::vec2(0.f); + _displacement = glm::vec2(0.f); + } - -// glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); -// glm::vec3 gl_Position_to = Rendering::manager().unProject(movement, scene.root()->transform_); -// glm::vec3 gl_delta = gl_Position_to - gl_Position_from; - -// bool first = true; -// glm::vec3 delta_translation(0.f); -// for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); ++it) { - - -// Group *sourceNode = (*it)->group(mode_); -// glm::vec3 dest_translation(0.f); - -// if (first) { -// // dest starts at current -// dest_translation = sourceNode->translation_; - -// // + ALT : discrete displacement -// if (UserInterface::manager().altModifier()) { -// if (accumulator > 100.f) { -// // precise movement with SHIFT -// if ( UserInterface::manager().shiftModifier() ) { -// dest_translation += glm::sign(gl_delta) * 0.0011f; -// dest_translation.x = ROUND(dest_translation.x, 1000.f); -// dest_translation.y = ROUND(dest_translation.y, 1000.f); -// } -// else { -// dest_translation += glm::sign(gl_delta) * 0.11f; -// dest_translation.x = ROUND(dest_translation.x, 10.f); -// dest_translation.y = ROUND(dest_translation.y, 10.f); -// } -// accumulator = 0.f; -// } -// else -// break; -// } -// else -// { -// // normal case: dest += delta -// dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR * dt_; -// accumulator = 0.f; -// } - -// // store action in history -// std::ostringstream info; -// info << "Position " << std::fixed << std::setprecision(3) << sourceNode->translation_.x; -// info << ", " << sourceNode->translation_.y ; -// current_action_ = (*it)->name() + ": " + info.str(); - -// // delta for others to follow -// delta_translation = dest_translation - sourceNode->translation_; -// } -// else { -// // dest = current + delta from first -// dest_translation = sourceNode->translation_ + delta_translation; -// } - -// // apply & request update -// sourceNode->translation_ = dest_translation; -// (*it)->touch(); - -// first = false; -// } } void GeometryView::updateSelectionOverlay(glm::vec4 color) diff --git a/src/LayerView.cpp b/src/LayerView.cpp index 2d9fb68..bea3cd4 100644 --- a/src/LayerView.cpp +++ b/src/LayerView.cpp @@ -38,6 +38,7 @@ #include "UserInterfaceManager.h" #include "BoundingBoxVisitor.h" #include "ActionManager.h" +#include "MousePointer.h" #include "LayerView.h" @@ -386,62 +387,63 @@ View::Cursor LayerView::over (glm::vec2 pos) void LayerView::arrow (glm::vec2 movement) { -// static float accumulator = 0.f; -// accumulator += dt_; + static glm::vec2 _from(0.f); + static glm::vec2 _displacement(0.f); -// glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); -// glm::vec3 gl_Position_to = Rendering::manager().unProject(glm::vec2(movement.x-movement.y, 0.f), scene.root()->transform_); -// glm::vec3 gl_delta = gl_Position_to - gl_Position_from; + Source *current = Mixer::manager().currentSource(); -// bool first = true; -// glm::vec3 delta_translation(0.f); -// for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); it++) { + if (!current && !Mixer::selection().empty()) + Mixer::manager().setCurrentSource( Mixer::selection().back() ); -// // individual move with SHIFT -// if ( !Source::isCurrent(*it) && UserInterface::manager().shiftModifier() ) -// continue; + if (current) { -// Group *sourceNode = (*it)->group(mode_); -// glm::vec3 dest_translation(0.f); + if (current_action_ongoing_) { -// if (first) { -// // dest starts at current -// dest_translation = sourceNode->translation_; + // add movement to displacement + movement.x += movement.y * -0.5f; + _displacement += glm::vec2(movement.x, -0.5f * movement.x) * dt_ * 0.2f; -// // + ALT : discrete displacement -// if (UserInterface::manager().altModifier()) { -// if (accumulator > 100.f) { -// dest_translation += glm::sign(gl_delta) * 0.21f; -// dest_translation.x = ROUND(dest_translation.x, 10.f); -// accumulator = 0.f; -// } -// else -// break; -// } -// else { -// // normal case: dest += delta -// dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR * dt_; -// accumulator = 0.f; -// } + // set coordinates of target + glm::vec2 _to = _from + _displacement; -// // store action in history -// std::ostringstream info; -// info << "Depth " << std::fixed << std::setprecision(2) << (*it)->depth() << " "; -// current_action_ = (*it)->name() + ": " + info.str(); + // update mouse pointer action + MousePointer::manager().active()->update(_to, dt_ / 1000.f); -// // delta for others to follow -// delta_translation = dest_translation - sourceNode->translation_; -// } -// else { -// // dest = current + delta from first -// dest_translation = sourceNode->translation_ + delta_translation; -// } + // simulate mouse grab + grab(current, _from, MousePointer::manager().active()->target(), + std::make_pair(current->group(mode_), glm::vec2(0.f) ) ); -// // apply & request update -// setDepth( *it, MAX( -dest_translation.x, 0.f) ); + // draw mouse pointer effect + MousePointer::manager().active()->draw(); + } + else { + + if (UserInterface::manager().altModifier() || Settings::application.mouse_pointer_lock) + MousePointer::manager().setActiveMode( (Pointer::Mode) Settings::application.mouse_pointer ); + else + MousePointer::manager().setActiveMode( Pointer::POINTER_DEFAULT ); + + // initiate view action and store status of source + initiate(); + + // get coordinates of source and set this as start of mouse position + _from = glm::vec2( Rendering::manager().project(current->group(mode_)->translation_, scene.root()->transform_) ); + _displacement = glm::vec2(0.f); + + // Initiate mouse pointer action + MousePointer::manager().active()->initiate(_from); + } + + } + else { + + terminate(true); + + _from = glm::vec2(0.f); + _displacement = glm::vec2(0.f); + + } -// first = false; -// } } diff --git a/src/MixingView.cpp b/src/MixingView.cpp index 639638b..9f269a1 100644 --- a/src/MixingView.cpp +++ b/src/MixingView.cpp @@ -39,6 +39,7 @@ #include "BoundingBoxVisitor.h" #include "ActionManager.h" #include "MixingGroup.h" +#include "MousePointer.h" #include "MixingView.h" @@ -680,10 +681,16 @@ View::Cursor MixingView::over (glm::vec2 pos) return ret; } +#define MAX_DURATION 1000.f +#define MIN_SPEED_M 0.005f +#define MAX_SPEED_M 0.5f + void MixingView::arrow (glm::vec2 movement) { - static float accumulator = 0.f; - accumulator += dt_ * 0.2; + static float _duration = 0.f; + static glm::vec2 _from(0.f); + static glm::vec2 _displacement(0.f); + Source *current = Mixer::manager().currentSource(); if (!current && !Mixer::selection().empty()) @@ -693,88 +700,59 @@ void MixingView::arrow (glm::vec2 movement) if (current_action_ongoing_) { - glm::vec2 Position_from = glm::vec2( Rendering::manager().project(current->stored_status_->translation_, scene.root()->transform_) ); - glm::vec2 Position_to = Position_from + movement * accumulator; + // TODO : precise movement ? - if ( current->mixinggroup_ != nullptr ) + // add movement to displacement + _duration += dt_; + const float speed = MIN_SPEED_M + (MAX_SPEED_M - MIN_SPEED_M) * glm::min(1.f,_duration / MAX_DURATION); + _displacement += movement * dt_ * speed; + + // set coordinates of target + glm::vec2 _to = _from + _displacement; + + // update mouse pointer action + MousePointer::manager().active()->update(_to, dt_ / 1000.f); + + if (current->mixinggroup_ != nullptr ) current->mixinggroup_->setAction( MixingGroup::ACTION_GRAB_ALL ); - grab(current, Position_from, Position_to, std::make_pair(current->group(mode_), glm::vec2(0.f) ) ); + // simulate mouse grab + grab(current, _from, MousePointer::manager().active()->target(), + std::make_pair(current->group(mode_), glm::vec2(0.f) ) ); + // draw mouse pointer effect + MousePointer::manager().active()->draw(); } else { + if (UserInterface::manager().altModifier() || Settings::application.mouse_pointer_lock) + MousePointer::manager().setActiveMode( (Pointer::Mode) Settings::application.mouse_pointer ); + else + MousePointer::manager().setActiveMode( Pointer::POINTER_DEFAULT ); + + // reset + _duration = 0.f; + _displacement = glm::vec2(0.f); + + // initiate view action and store status of source initiate(); - accumulator = 0.f; + + // get coordinates of source and set this as start of mouse position + _from = glm::vec2( Rendering::manager().project(current->group(mode_)->translation_, scene.root()->transform_) ); + + // Initiate mouse pointer action + MousePointer::manager().active()->initiate(_from); } - } - else + else { terminate(true); - - // glm::vec3 gl_Position_from = Rendering::manager().unProject(glm::vec2(0.f), scene.root()->transform_); - // glm::vec3 gl_Position_to = Rendering::manager().unProject(movement, scene.root()->transform_); - // glm::vec3 gl_delta = gl_Position_to - gl_Position_from; - - -// bool first = true; -// glm::vec3 delta_translation(0.f); -// for (auto it = Mixer::selection().begin(); it != Mixer::selection().end(); ++it) { - -// // individual move with SHIFT -// if ( !Source::isCurrent(*it) && UserInterface::manager().shiftModifier() ) -// continue; - -// Group *sourceNode = (*it)->group(mode_); -// glm::vec3 dest_translation(0.f); - -// if (first) { -// // dest starts at current -// dest_translation = sourceNode->translation_; - -// // + ALT : discrete displacement -// if (UserInterface::manager().altModifier()) { -// if (accumulator > 100.f) { -// dest_translation += glm::sign(gl_delta) * 0.1f; -// dest_translation.x = ROUND(dest_translation.x, 10.f); -// dest_translation.y = ROUND(dest_translation.y, 10.f); -// accumulator = 0.f; -// } -// else -// break; -// } -// else { -// // normal case: dest += delta -// dest_translation += gl_delta * ARROWS_MOVEMENT_FACTOR * dt_; -// accumulator = 0.f; -// } - -// // store action in history -// std::ostringstream info; -// if ((*it)->active()) { -// info << "Alpha " << std::fixed << std::setprecision(3) << (*it)->blendingShader()->color.a << " "; -// info << ( ((*it)->blendingShader()->color.a > 0.f) ? ICON_FA_EYE : ICON_FA_EYE_SLASH); -// } -// else -// info << "Inactive " << ICON_FA_SNOWFLAKE; -// current_action_ = (*it)->name() + ": " + info.str(); - -// // delta for others to follow -// delta_translation = dest_translation - sourceNode->translation_; -// } -// else { -// // dest = current + delta from first -// dest_translation = sourceNode->translation_ + delta_translation; -// } - -// // apply & request update -// sourceNode->translation_ = dest_translation; -// (*it)->touch(); - -// first = false; -// } + // reset + _duration = 0.f; + _from = glm::vec2(0.f); + _displacement = glm::vec2(0.f); + } } diff --git a/src/MousePointer.cpp b/src/MousePointer.cpp index 9e8a4eb..a6ad35f 100644 --- a/src/MousePointer.cpp +++ b/src/MousePointer.cpp @@ -68,9 +68,10 @@ void PointerLinear::update(const glm::vec2 &pos, float dt) float speed = POINTER_LINEAR_MIN_SPEED + (POINTER_LINEAR_MAX_SPEED - POINTER_LINEAR_MIN_SPEED) * strength_; - glm::vec2 delta = pos - target_ ; + glm::vec2 delta = current_ - target_ ; + if (glm::length(delta) > 10.f ) - target_ += glm::normalize(delta) * (speed * dt); + target_ += glm::normalize(delta) * (speed * glm::max(dt,0.001f) ); } void PointerLinear::draw() @@ -179,9 +180,9 @@ void PointerSpring::update(const glm::vec2 &pos, float dt) // apply force on velocity : spring stiffness / mass velocity_ += delta * ( (POINTER_SPRING_MAX_MASS * stiffness) / mass ); // apply damping dynamics - velocity_ -= damping * dt * glm::normalize(delta); + velocity_ -= damping * glm::max(dt,0.001f) * glm::normalize(delta); // compute new position : add velocity x time - target_ += dt * velocity_; + target_ += glm::max(dt,0.001f) * velocity_; // diminish velocity by viscousness of substrate // (loss of energy between updates) velocity_ *= viscousness; diff --git a/src/MousePointer.h b/src/MousePointer.h index fe38fc4..66cf8f9 100644 --- a/src/MousePointer.h +++ b/src/MousePointer.h @@ -40,7 +40,7 @@ public: Pointer() : strength_(0.5) {} virtual ~Pointer() {} - inline glm::vec2 pos() { return target_; } + inline glm::vec2 target() const { return target_; } virtual void initiate(const glm::vec2 &pos) { current_ = target_ = pos; } virtual void update(const glm::vec2 &pos, float) { current_ = target_ = pos; } diff --git a/src/TextureView.cpp b/src/TextureView.cpp index 85036e7..cf0105a 100644 --- a/src/TextureView.cpp +++ b/src/TextureView.cpp @@ -40,6 +40,7 @@ #include "UserInterfaceManager.h" #include "ActionManager.h" #include "DialogToolkit.h" +#include "MousePointer.h" #include "TextureView.h" @@ -1531,8 +1532,71 @@ void TextureView::terminate(bool force) adaptGridToSource(); } +#define MAX_DURATION 1000.f +#define MIN_SPEED_A 0.005f +#define MAX_SPEED_A 0.5f + void TextureView::arrow (glm::vec2 movement) { + static float _duration = 0.f; + static glm::vec2 _from(0.f); + static glm::vec2 _displacement(0.f); + + Source *current = Mixer::manager().currentSource(); + + if (!current && !Mixer::selection().empty()) + Mixer::manager().setCurrentSource( Mixer::selection().back() ); + + if (current) { + + if (current_action_ongoing_) { + + // add movement to displacement + _duration += dt_; + const float speed = MIN_SPEED_A + (MAX_SPEED_A - MIN_SPEED_A) * glm::min(1.f,_duration / MAX_DURATION); + _displacement += movement * dt_ * speed; + + // set coordinates of target + glm::vec2 _to = _from + _displacement; + + // update mouse pointer action + MousePointer::manager().active()->update(_to, dt_ / 1000.f); + + // simulate mouse grab + grab(current, _from, MousePointer::manager().active()->target(), + std::make_pair(current->group(mode_), glm::vec2(0.f) ) ); + + // draw mouse pointer effect + MousePointer::manager().active()->draw(); + } + else { + + if (UserInterface::manager().altModifier() || Settings::application.mouse_pointer_lock) + MousePointer::manager().setActiveMode( (Pointer::Mode) Settings::application.mouse_pointer ); + else + MousePointer::manager().setActiveMode( Pointer::POINTER_DEFAULT ); + + // initiate view action and store status of source + initiate(); + + // get coordinates of source and set this as start of mouse position + _from = glm::vec2( Rendering::manager().project(current->group(mode_)->translation_, scene.root()->transform_) ); + _displacement = glm::vec2(0.f); + + // Initiate mouse pointer action + MousePointer::manager().active()->initiate(_from); + } + + } + else { + + terminate(true); + + _from = glm::vec2(0.f); + _displacement = glm::vec2(0.f); + + } + // Source *s = Mixer::manager().currentSource(); // if (s) { // static float accumulator = 0.f; diff --git a/src/UserInterfaceManager.cpp b/src/UserInterfaceManager.cpp index 3405e25..deb4e2e 100644 --- a/src/UserInterfaceManager.cpp +++ b/src/UserInterfaceManager.cpp @@ -416,8 +416,8 @@ void UserInterface::handleKeyboard() ImGui::IsKeyDown( GLFW_KEY_UP ) || ImGui::IsKeyDown( GLFW_KEY_DOWN ) ){ glm::vec2 delta(0.f, 0.f); - delta.x += ImGui::IsKeyDown( GLFW_KEY_RIGHT ) ? 1.f : ImGui::IsKeyDown( GLFW_KEY_LEFT ) ? -1.f : 0.f; - delta.y += ImGui::IsKeyDown( GLFW_KEY_DOWN ) ? 1.f : ImGui::IsKeyDown( GLFW_KEY_UP ) ? -1.f : 0.f; + delta.x += (int) ImGui::IsKeyDown( GLFW_KEY_RIGHT ) - (int) ImGui::IsKeyDown( GLFW_KEY_LEFT ); + delta.y += (int) ImGui::IsKeyDown( GLFW_KEY_DOWN ) - (int) ImGui::IsKeyDown( GLFW_KEY_UP ); Mixer::manager().view()->arrow( delta ); } else if ( ImGui::IsKeyReleased( GLFW_KEY_LEFT ) || @@ -425,8 +425,8 @@ void UserInterface::handleKeyboard() ImGui::IsKeyReleased( GLFW_KEY_UP ) || ImGui::IsKeyReleased( GLFW_KEY_DOWN ) ){ Mixer::manager().view()->terminate(true); + MousePointer::manager().active()->terminate(); } - } // special case: CTRL + TAB is ALT + TAB in OSX @@ -614,14 +614,14 @@ void UserInterface::handleMouse() { // grab current sources c = Mixer::manager().view()->grab(current, mouseclic[ImGuiMouseButton_Left], - MousePointer::manager().active()->pos(), picked); + MousePointer::manager().active()->target(), picked); } // action on other (non-source) elements in the view else { // grab picked object c = Mixer::manager().view()->grab(nullptr, mouseclic[ImGuiMouseButton_Left], - MousePointer::manager().active()->pos(), picked); + MousePointer::manager().active()->target(), picked); } // Set cursor appearance