mirror of
https://github.com/brunoherbelin/vimix.git
synced 2025-12-11 18:34:58 +01:00
Unified behavior in Geometry view: SHIFT for discrete transform (unit
translation, rotation, scaling) and ALT key for alternative transform (central scaling, axis translation)
This commit is contained in:
@@ -221,6 +221,7 @@ void UserInterface::handleKeyboard()
|
|||||||
{
|
{
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
alt_modifier_active = io.KeyAlt;
|
alt_modifier_active = io.KeyAlt;
|
||||||
|
shift_modifier_active = io.KeyShift;
|
||||||
auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
|
auto ctrl = io.ConfigMacOSXBehaviors ? io.KeySuper : io.KeyCtrl;
|
||||||
|
|
||||||
// Application "CTRL +"" Shortcuts
|
// Application "CTRL +"" Shortcuts
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ class UserInterface
|
|||||||
|
|
||||||
bool ctrl_modifier_active;
|
bool ctrl_modifier_active;
|
||||||
bool alt_modifier_active;
|
bool alt_modifier_active;
|
||||||
|
bool shift_modifier_active;
|
||||||
bool show_vimix_config;
|
bool show_vimix_config;
|
||||||
bool show_imgui_about;
|
bool show_imgui_about;
|
||||||
bool show_gst_about;
|
bool show_gst_about;
|
||||||
@@ -148,6 +149,7 @@ public:
|
|||||||
// status querries
|
// status querries
|
||||||
inline bool ctrlModifier() const { return ctrl_modifier_active; }
|
inline bool ctrlModifier() const { return ctrl_modifier_active; }
|
||||||
inline bool altModifier() const { return alt_modifier_active; }
|
inline bool altModifier() const { return alt_modifier_active; }
|
||||||
|
inline bool shiftModifier() const { return shift_modifier_active; }
|
||||||
|
|
||||||
void StartScreenshot();
|
void StartScreenshot();
|
||||||
void showPannel(int id = 0);
|
void showPannel(int id = 0);
|
||||||
|
|||||||
134
View.cpp
134
View.cpp
@@ -746,45 +746,57 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
glm::vec4 source_to = glm::inverse(s->stored_status_->transform_) * glm::vec4( scene_to, 1.f );
|
glm::vec4 source_to = glm::inverse(s->stored_status_->transform_) * glm::vec4( scene_to, 1.f );
|
||||||
glm::vec3 source_scaling = glm::vec3(source_to) / glm::vec3(source_from);
|
glm::vec3 source_scaling = glm::vec3(source_to) / glm::vec3(source_from);
|
||||||
|
|
||||||
|
if (UserInterface::manager().shiftModifier()) {
|
||||||
|
source_scaling.x = float( int( source_scaling.x * 10.f ) ) / 10.f;
|
||||||
|
source_scaling.y = float( int( source_scaling.y * 10.f ) ) / 10.f;
|
||||||
|
}
|
||||||
|
|
||||||
// which manipulation to perform?
|
// which manipulation to perform?
|
||||||
std::ostringstream info;
|
std::ostringstream info;
|
||||||
if (pick.first) {
|
if (pick.first) {
|
||||||
|
// which corner was picked ?
|
||||||
|
glm::vec2 corner = glm::sign(pick.second);
|
||||||
|
|
||||||
|
// transform from source center to corner
|
||||||
|
glm::mat4 T = GlmToolkit::transform(glm::vec3(corner.x, corner.y, 0.f), glm::vec3(0.f, 0.f, 0.f),
|
||||||
|
glm::vec3(1.f / s->frame()->aspectRatio(), 1.f, 1.f));
|
||||||
|
|
||||||
|
// transformation from scene to corner:
|
||||||
|
glm::mat4 scene_to_corner_transform = T * glm::inverse(s->stored_status_->transform_);
|
||||||
|
glm::mat4 corner_to_scene_transform = glm::inverse(scene_to_corner_transform);
|
||||||
|
|
||||||
|
// compute cursor movement in corner reference frame
|
||||||
|
glm::vec4 corner_from = scene_to_corner_transform * glm::vec4( scene_from, 1.f );
|
||||||
|
glm::vec4 corner_to = scene_to_corner_transform * glm::vec4( scene_to, 1.f );
|
||||||
|
// operation of scaling in corner reference frame
|
||||||
|
glm::vec3 corner_scaling = glm::vec3(corner_to) / glm::vec3(corner_from);
|
||||||
|
|
||||||
|
if (UserInterface::manager().shiftModifier()) {
|
||||||
|
corner_scaling.x = float( int( corner_scaling.x * 10.f ) ) / 10.f;
|
||||||
|
corner_scaling.y = float( int( corner_scaling.y * 10.f ) ) / 10.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert source position in corner reference frame
|
||||||
|
glm::vec4 center = scene_to_corner_transform * glm::vec4( s->stored_status_->translation_, 1.f);
|
||||||
|
|
||||||
// picking on the resizing handles in the corners
|
// picking on the resizing handles in the corners
|
||||||
if ( pick.first == s->handle_[Handles::RESIZE] ) {
|
if ( pick.first == s->handle_[Handles::RESIZE] ) {
|
||||||
|
|
||||||
// which corner was picked ?
|
// ALT resize : centered
|
||||||
glm::vec2 corner = glm::sign(pick.second);
|
if (UserInterface::manager().altModifier()) {
|
||||||
|
sourceNode->scale_ = s->stored_status_->scale_ * source_scaling;
|
||||||
// transform from source center to corner
|
}
|
||||||
glm::mat4 T = GlmToolkit::transform(glm::vec3(corner.x, corner.y, 0.f),
|
// normal resize: corner scale
|
||||||
glm::vec3(0.f, 0.f, 0.f),
|
else {
|
||||||
glm::vec3(1.f / s->frame()->aspectRatio(), 1.f, 1.f));
|
// transform source center (in corner reference frame)
|
||||||
|
center = glm::scale(glm::identity<glm::mat4>(), corner_scaling) * center;
|
||||||
// transformation from scene to corner:
|
// convert center back into scene reference frame
|
||||||
glm::mat4 scene_to_corner_transform = T * glm::inverse(s->stored_status_->transform_);
|
center = corner_to_scene_transform * center;
|
||||||
glm::mat4 corner_to_scene_transform = glm::inverse(scene_to_corner_transform);
|
// apply to node
|
||||||
|
sourceNode->translation_ = glm::vec3(center);
|
||||||
|
// scale nde
|
||||||
// A) OPERATION: SCALING IN CORNER REF
|
sourceNode->scale_ = s->stored_status_->scale_ * corner_scaling;
|
||||||
// compute cursor movement in corner reference frame
|
}
|
||||||
glm::vec4 corner_from = scene_to_corner_transform * glm::vec4( scene_from, 1.f );
|
|
||||||
glm::vec4 corner_to = scene_to_corner_transform * glm::vec4( scene_to, 1.f );
|
|
||||||
// operation of scaling in corner reference frame
|
|
||||||
glm::vec3 sca = glm::vec3(corner_to) / glm::vec3(corner_from);
|
|
||||||
glm::mat4 corner_scale_op = glm::scale(glm::identity<glm::mat4>(), sca);
|
|
||||||
|
|
||||||
// B) MOVES THE SOURCE CENTER
|
|
||||||
// convert source position in corner reference frame
|
|
||||||
glm::vec4 center = scene_to_corner_transform * glm::vec4( s->stored_status_->translation_, 1.f);
|
|
||||||
// transform source center (in corner reference frame)
|
|
||||||
center = corner_scale_op * center;
|
|
||||||
// convert center back into scene reference frame
|
|
||||||
center = corner_to_scene_transform * center;
|
|
||||||
// apply to source node
|
|
||||||
sourceNode->translation_ = glm::vec3(center);
|
|
||||||
|
|
||||||
// C) SCALE THE SOURCE
|
|
||||||
sourceNode->scale_ = sca * s->stored_status_->scale_;
|
|
||||||
|
|
||||||
// show cursor depending on diagonal (corner picked)
|
// show cursor depending on diagonal (corner picked)
|
||||||
ret.type = corner.x * corner.y > 0.f ? Cursor_ResizeNESW : Cursor_ResizeNWSE;
|
ret.type = corner.x * corner.y > 0.f ? Cursor_ResizeNESW : Cursor_ResizeNWSE;
|
||||||
@@ -793,9 +805,24 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
}
|
}
|
||||||
// picking on the resizing handles left or right
|
// picking on the resizing handles left or right
|
||||||
else if ( pick.first == s->handle_[Handles::RESIZE_H] ) {
|
else if ( pick.first == s->handle_[Handles::RESIZE_H] ) {
|
||||||
sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(source_scaling.x, 1.f, 1.f);
|
|
||||||
if (UserInterface::manager().altModifier())
|
// ALT resize : centered
|
||||||
sourceNode->scale_.x = float( int( sourceNode->scale_.x * 10.f ) ) / 10.f;
|
if (UserInterface::manager().altModifier()) {
|
||||||
|
sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(source_scaling.x, 1.f, 1.f);
|
||||||
|
}
|
||||||
|
// normal resize: side scale
|
||||||
|
else {
|
||||||
|
// HORIZONTAL only
|
||||||
|
corner_scaling = glm::vec3(corner_scaling.x, 1.f, 1.f);
|
||||||
|
// transform source center (in corner reference frame)
|
||||||
|
center = glm::scale(glm::identity<glm::mat4>(), corner_scaling) * center;
|
||||||
|
// convert center back into scene reference frame
|
||||||
|
center = corner_to_scene_transform * center;
|
||||||
|
// apply to node
|
||||||
|
sourceNode->translation_ = glm::vec3(center);
|
||||||
|
// scale
|
||||||
|
sourceNode->scale_ = s->stored_status_->scale_ * corner_scaling;
|
||||||
|
}
|
||||||
|
|
||||||
ret.type = Cursor_ResizeEW;
|
ret.type = Cursor_ResizeEW;
|
||||||
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
||||||
@@ -803,9 +830,24 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
}
|
}
|
||||||
// picking on the resizing handles top or bottom
|
// picking on the resizing handles top or bottom
|
||||||
else if ( pick.first == s->handle_[Handles::RESIZE_V] ) {
|
else if ( pick.first == s->handle_[Handles::RESIZE_V] ) {
|
||||||
sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(1.f, source_scaling.y, 1.f);
|
|
||||||
if (UserInterface::manager().altModifier())
|
// ALT resize : centered
|
||||||
sourceNode->scale_.y = float( int( sourceNode->scale_.y * 10.f ) ) / 10.f;
|
if (UserInterface::manager().altModifier()) {
|
||||||
|
sourceNode->scale_ = s->stored_status_->scale_ * glm::vec3(1.f, source_scaling.y, 1.f);
|
||||||
|
}
|
||||||
|
// normal resize: side scale
|
||||||
|
else {
|
||||||
|
// VERTICAL ONLY
|
||||||
|
corner_scaling = glm::vec3(1.f, corner_scaling.y, 1.f);
|
||||||
|
// transform source center (in corner reference frame)
|
||||||
|
center = glm::scale(glm::identity<glm::mat4>(), corner_scaling) * center;
|
||||||
|
// convert center back into scene reference frame
|
||||||
|
center = corner_to_scene_transform * center;
|
||||||
|
// apply to node
|
||||||
|
sourceNode->translation_ = glm::vec3(center);
|
||||||
|
// scale
|
||||||
|
sourceNode->scale_ = s->stored_status_->scale_ * corner_scaling;
|
||||||
|
}
|
||||||
|
|
||||||
ret.type = Cursor_ResizeNS;
|
ret.type = Cursor_ResizeNS;
|
||||||
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
info << "Size " << std::fixed << std::setprecision(3) << sourceNode->scale_.x;
|
||||||
@@ -823,7 +865,7 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
sourceNode->rotation_ = s->stored_status_->rotation_ + glm::vec3(0.f, 0.f, angle);
|
sourceNode->rotation_ = s->stored_status_->rotation_ + glm::vec3(0.f, 0.f, angle);
|
||||||
|
|
||||||
int degrees = int( glm::degrees(sourceNode->rotation_.z) );
|
int degrees = int( glm::degrees(sourceNode->rotation_.z) );
|
||||||
if (UserInterface::manager().altModifier()) {
|
if (UserInterface::manager().shiftModifier()) {
|
||||||
degrees = (degrees / 10) * 10;
|
degrees = (degrees / 10) * 10;
|
||||||
sourceNode->rotation_.z = glm::radians( float(degrees) );
|
sourceNode->rotation_.z = glm::radians( float(degrees) );
|
||||||
}
|
}
|
||||||
@@ -835,11 +877,20 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
else {
|
else {
|
||||||
sourceNode->translation_ = s->stored_status_->translation_ + scene_translation;
|
sourceNode->translation_ = s->stored_status_->translation_ + scene_translation;
|
||||||
|
|
||||||
if (UserInterface::manager().altModifier()) {
|
if (UserInterface::manager().shiftModifier()) {
|
||||||
sourceNode->translation_.x = float( int( sourceNode->translation_.x * 10.f ) ) / 10.f;
|
sourceNode->translation_.x = float( int( sourceNode->translation_.x * 10.f ) ) / 10.f;
|
||||||
sourceNode->translation_.y = float( int( sourceNode->translation_.y * 10.f ) ) / 10.f;
|
sourceNode->translation_.y = float( int( sourceNode->translation_.y * 10.f ) ) / 10.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ALT: single axis movement
|
||||||
|
if (UserInterface::manager().altModifier()) {
|
||||||
|
glm::vec3 dif = s->stored_status_->translation_ - sourceNode->translation_;
|
||||||
|
if (ABS(dif.x) > ABS(dif.y) )
|
||||||
|
sourceNode->translation_.y = s->stored_status_->translation_.y;
|
||||||
|
else
|
||||||
|
sourceNode->translation_.x = s->stored_status_->translation_.x;
|
||||||
|
}
|
||||||
|
|
||||||
ret.type = Cursor_ResizeAll;
|
ret.type = Cursor_ResizeAll;
|
||||||
info << "Position (" << std::fixed << std::setprecision(3) << sourceNode->translation_.x;
|
info << "Position (" << std::fixed << std::setprecision(3) << sourceNode->translation_.x;
|
||||||
info << ", " << sourceNode->translation_.y << ")";
|
info << ", " << sourceNode->translation_.y << ")";
|
||||||
@@ -853,6 +904,7 @@ View::Cursor GeometryView::grab (Source *s, glm::vec2 from, glm::vec2 to, std::p
|
|||||||
// info << ", " << sourceNode->translation_.y << ")";
|
// info << ", " << sourceNode->translation_.y << ")";
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// request update
|
// request update
|
||||||
s->touch();
|
s->touch();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user