Skip to content

Commit 098ef77

Browse files
authored
Add snap option to gizmos (Ctrl+drag) (#994)
* Add snap option to gizmos (Ctrl+drag) * fix computeSnapPtr: use bitmask for ROTATE, set all axes for SCALE snap - ROTATE comparison changed from == to & for consistency with TRANSLATE/SCALE - SCALE snap now fills all three axes instead of only buf[0]
1 parent 0df8393 commit 098ef77

1 file changed

Lines changed: 24 additions & 3 deletions

File tree

src/visualizer/gui/gizmo_manager.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ namespace lfs::vis::gui {
5353
}
5454
} // namespace
5555
constexpr float MIN_GIZMO_SCALE = 0.001f;
56+
constexpr float ROTATION_SNAP_DEGREES = 5.0f;
57+
constexpr float TRANSLATE_SNAP_UNITS = 0.1f;
58+
constexpr float SCALE_SNAP_RATIO = 0.1f;
5659

5760
namespace {
5861
inline glm::mat3 extractRotation(const glm::mat4& m) {
@@ -64,6 +67,18 @@ namespace lfs::vis::gui {
6467
return glm::vec3(glm::length(glm::vec3(m[0])), glm::length(glm::vec3(m[1])),
6568
glm::length(glm::vec3(m[2])));
6669
}
70+
71+
inline const float* computeSnapPtr(float* buf, ImGuizmo::OPERATION op) {
72+
if (!ImGui::GetIO().KeyCtrl)
73+
return nullptr;
74+
if (op & ImGuizmo::ROTATE)
75+
buf[0] = ROTATION_SNAP_DEGREES;
76+
else if (op & ImGuizmo::TRANSLATE)
77+
buf[0] = buf[1] = buf[2] = TRANSLATE_SNAP_UNITS;
78+
else if (op & ImGuizmo::SCALE)
79+
buf[0] = buf[1] = buf[2] = SCALE_SNAP_RATIO;
80+
return buf;
81+
}
6782
} // namespace
6883

6984
GizmoManager::GizmoManager(VisualizerImpl* viewer)
@@ -497,10 +512,12 @@ namespace lfs::vis::gui {
497512
const ImGuizmo::MODE gizmo_mode = (actually_using_bounds || !use_world_space) ? ImGuizmo::LOCAL : ImGuizmo::WORLD;
498513

499514
glm::mat4 delta_matrix;
515+
float snap_buf[3] = {};
516+
const float* snap_ptr = computeSnapPtr(snap_buf, effective_op);
500517
const bool gizmo_changed = ImGuizmo::Manipulate(
501518
glm::value_ptr(view), glm::value_ptr(projection),
502519
effective_op, gizmo_mode,
503-
glm::value_ptr(gizmo_matrix), glm::value_ptr(delta_matrix), nullptr, bounds_ptr);
520+
glm::value_ptr(gizmo_matrix), glm::value_ptr(delta_matrix), snap_ptr, bounds_ptr);
504521

505522
if (node_gizmo_operation_ == ImGuizmo::ROTATE) {
506523
const glm::vec3 pivot_pos = glm::vec3(gizmo_matrix[3]);
@@ -899,10 +916,12 @@ namespace lfs::vis::gui {
899916
glm::mat4 delta_matrix;
900917
const ImGuizmo::MODE gizmo_mode = gizmo_local_aligned ? ImGuizmo::LOCAL : ImGuizmo::WORLD;
901918

919+
float snap_buf[3] = {};
920+
const float* snap_ptr = computeSnapPtr(snap_buf, effective_op);
902921
const bool gizmo_changed = ImGuizmo::Manipulate(
903922
glm::value_ptr(view), glm::value_ptr(projection),
904923
effective_op, gizmo_mode, glm::value_ptr(gizmo_matrix),
905-
glm::value_ptr(delta_matrix), nullptr, bounds_ptr);
924+
glm::value_ptr(delta_matrix), snap_ptr, bounds_ptr);
906925

907926
const bool is_using = ImGuizmo::IsUsing();
908927

@@ -1082,10 +1101,12 @@ namespace lfs::vis::gui {
10821101
glm::mat4 delta_matrix;
10831102
const ImGuizmo::MODE gizmo_mode = gizmo_local_aligned ? ImGuizmo::LOCAL : ImGuizmo::WORLD;
10841103

1104+
float snap_buf[3] = {};
1105+
const float* snap_ptr = computeSnapPtr(snap_buf, effective_op);
10851106
const bool gizmo_changed = ImGuizmo::Manipulate(
10861107
glm::value_ptr(view), glm::value_ptr(projection),
10871108
effective_op, gizmo_mode, glm::value_ptr(gizmo_matrix),
1088-
glm::value_ptr(delta_matrix), nullptr, bounds_ptr);
1109+
glm::value_ptr(delta_matrix), snap_ptr, bounds_ptr);
10891110

10901111
const bool is_using = ImGuizmo::IsUsing();
10911112

0 commit comments

Comments
 (0)