Skip to content

Commit 3d824e6

Browse files
Merge pull request #55 from adriengivry/feature/gizmo_snapping
Gizmo snapping implemented
2 parents e3249b8 + e30ff57 commit 3d824e6

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)