New using arrow Keys to simulate source grabbing

Allows combining arrows with Mouse Pointer effects (e.g. grid). Also added progressive acceleration of movement during the first 1 second of key press (starting very slow movement for precise displacement). Bugs fixed in Mouse Pointer.
This commit is contained in:
Bruno Herbelin
2023-08-29 00:10:32 +02:00
parent 54fa642693
commit 007f7a0ce1
8 changed files with 225 additions and 200 deletions

View File

@@ -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()) {

View File

@@ -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 {
initiate();
accumulator = 0.f;
adaptGridToSource(current);
}
}
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();
// 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 {
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)

View File

@@ -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;
// }
}

View File

@@ -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 {
initiate();
accumulator = 0.f;
}
}
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();
// 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 {
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);
}
}

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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