Skip to content

Commit e30ff57

Browse files
author
Adrien GIVRY
committed
Gizmo snapping implemented
Gizmo behaviour can now be changed by pressing the CTRL key. While this key is pressed, any translation, rotation or scaling will be subject to snapping. The snapping units for each operation can be defined in the settings drop down menu.
1 parent e3249b8 commit e30ff57

4 files changed

Lines changed: 49 additions & 6 deletions

File tree

Sources/Overload/OvEditor/include/OvEditor/Core/GizmoBehaviour.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ namespace OvEditor::Core
2727
Y,
2828
Z
2929
};
30+
31+
/**
32+
* Returns true if the snapping behaviour is enabled
33+
*/
34+
bool IsSnappedBehaviourEnabled() const;
3035

3136
/**
3237
* Starts the gizmo picking behaviour for the given target in the given direction

Sources/Overload/OvEditor/include/OvEditor/Settings/EditorSettings.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,5 +77,8 @@ namespace OvEditor::Settings
7777
inline static Property<bool> ShowLightBounds = { false };
7878
inline static Property<bool> ShowGeometryFrustumCullingInSceneView = { false };
7979
inline static Property<bool> ShowLightFrustumCullingInSceneView = { false };
80+
inline static Property<float> TranslationSnapUnit = { 1.0f };
81+
inline static Property<float> RotationSnapUnit = { 15.0f };
82+
inline static Property<float> ScalingSnapUnit = { 1.0f };
8083
};
8184
}

Sources/Overload/OvEditor/src/OvEditor/Core/GizmoBehaviour.cpp

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,20 @@
55
*/
66

77
#include "OvEditor/Core/GizmoBehaviour.h"
8+
#include "OvEditor/Settings/EditorSettings.h"
9+
10+
float SnapValue(float p_value, float p_step)
11+
{
12+
return p_value - std::fmod(p_value, p_step);
13+
}
14+
15+
bool OvEditor::Core::GizmoBehaviour::IsSnappedBehaviourEnabled() const
16+
{
17+
using namespace OvWindowing::Inputs;
18+
19+
const auto& inputManager = EDITOR_CONTEXT(inputManager);
20+
return inputManager->GetKeyState(EKey::KEY_LEFT_CONTROL) == EKeyState::KEY_DOWN || inputManager->GetKeyState(EKey::KEY_RIGHT_CONTROL) == EKeyState::KEY_DOWN;
21+
}
822

923
void OvEditor::Core::GizmoBehaviour::StartPicking(OvCore::ECS::Actor& p_target, const OvMaths::FVector3& p_cameraPosition, EGizmoOperation p_operation, EDirection p_direction)
1024
{
@@ -101,9 +115,14 @@ void OvEditor::Core::GizmoBehaviour::ApplyTranslation(const OvMaths::FMatrix4& p
101115
auto screenDirection = GetScreenDirection(p_viewMatrix, p_projectionMatrix, p_viewSize);
102116

103117
auto totalDisplacement = m_currentMouse - m_originMouse;
104-
auto translationCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection);
118+
auto translationCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection) * unitsPerPixel;
119+
120+
if (IsSnappedBehaviourEnabled())
121+
{
122+
translationCoefficient = SnapValue(translationCoefficient, OvEditor::Settings::EditorSettings::TranslationSnapUnit);
123+
}
105124

106-
m_target->transform.SetLocalPosition(originPosition + GetRealDirection() * translationCoefficient * unitsPerPixel);
125+
m_target->transform.SetLocalPosition(originPosition + GetRealDirection() * translationCoefficient);
107126
}
108127

109128
void OvEditor::Core::GizmoBehaviour::ApplyRotation(const OvMaths::FMatrix4& p_viewMatrix, const OvMaths::FMatrix4& p_projectionMatrix, const OvMaths::FVector2& p_viewSize) const
@@ -115,9 +134,14 @@ void OvEditor::Core::GizmoBehaviour::ApplyRotation(const OvMaths::FMatrix4& p_vi
115134
screenDirection = OvMaths::FVector2(-screenDirection.y, screenDirection.x);
116135

117136
auto totalDisplacement = m_currentMouse - m_originMouse;
118-
auto rotationCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection);
137+
auto rotationCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection) * unitsPerPixel;
138+
139+
if (IsSnappedBehaviourEnabled())
140+
{
141+
rotationCoefficient = SnapValue(rotationCoefficient, OvEditor::Settings::EditorSettings::RotationSnapUnit);
142+
}
119143

120-
auto rotationToApply = OvMaths::FQuaternion(OvMaths::FVector3(GetFakeDirection() * rotationCoefficient * unitsPerPixel));
144+
auto rotationToApply = OvMaths::FQuaternion(OvMaths::FVector3(GetFakeDirection() * rotationCoefficient));
121145
m_target->transform.SetLocalRotation(originRotation * rotationToApply);
122146
}
123147

@@ -129,9 +153,14 @@ void OvEditor::Core::GizmoBehaviour::ApplyScale(const OvMaths::FMatrix4& p_viewM
129153
auto screenDirection = GetScreenDirection(p_viewMatrix, p_projectionMatrix, p_viewSize);
130154

131155
auto totalDisplacement = m_currentMouse - m_originMouse;
132-
auto scaleCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection);
156+
auto scaleCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection) * unitsPerPixel;
157+
158+
if (IsSnappedBehaviourEnabled())
159+
{
160+
scaleCoefficient = SnapValue(scaleCoefficient, OvEditor::Settings::EditorSettings::ScalingSnapUnit);
161+
}
133162

134-
auto newScale = originScale + GetFakeDirection() * scaleCoefficient * unitsPerPixel;
163+
auto newScale = originScale + GetFakeDirection() * scaleCoefficient;
135164

136165
/* Prevent scale from being negative*/
137166
newScale.x = std::max(newScale.x, 0.0001f);

Sources/Overload/OvEditor/src/OvEditor/Panels/MenuBar.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include <OvUI/Widgets/Visual/Separator.h>
2222
#include <OvUI/Widgets/Sliders/SliderInt.h>
23+
#include <OvUI/Widgets/Drags/DragFloat.h>
2324
#include <OvUI/Widgets/Selection/ColorEdit.h>
2425

2526
#include "OvEditor/Panels/MenuBar.h"
@@ -200,6 +201,11 @@ void OvEditor::Panels::MenuBar::CreateSettingsMenu()
200201
assetViewGridPicker.color = OvUI::Types::Color::White;
201202
};
202203

204+
auto& snappingMenu = settingsMenu.CreateWidget<MenuList>("Snapping");
205+
snappingMenu.CreateWidget<Drags::DragFloat>(0.001f, 999999.0f, Settings::EditorSettings::TranslationSnapUnit, 0.05f, "Translation Unit").ValueChangedEvent += [this](float p_value) { Settings::EditorSettings::TranslationSnapUnit = p_value; };
206+
snappingMenu.CreateWidget<Drags::DragFloat>(0.001f, 999999.0f, Settings::EditorSettings::RotationSnapUnit, 1.0f, "Rotation Unit").ValueChangedEvent += [this](float p_value) { Settings::EditorSettings::RotationSnapUnit = p_value; };
207+
snappingMenu.CreateWidget<Drags::DragFloat>(0.001f, 999999.0f, Settings::EditorSettings::ScalingSnapUnit, 0.05f, "Scaling Unit").ValueChangedEvent += [this](float p_value) { Settings::EditorSettings::ScalingSnapUnit = p_value; };
208+
203209
auto& debuggingMenu = settingsMenu.CreateWidget<MenuList>("Debugging");
204210
debuggingMenu.CreateWidget<MenuItem>("Show geometry bounds", "", true, Settings::EditorSettings::ShowGeometryBounds).ValueChangedEvent += [this](bool p_value) { Settings::EditorSettings::ShowGeometryBounds = p_value; };
205211
debuggingMenu.CreateWidget<MenuItem>("Show lights bounds", "", true, Settings::EditorSettings::ShowLightBounds).ValueChangedEvent += [this](bool p_value) { Settings::EditorSettings::ShowLightBounds = p_value; };

0 commit comments

Comments
 (0)