Skip to content

Commit 8ecae34

Browse files
Updated gizmo scaling behaviour to match translation (#489)
* Updated gizmo scaling behaviour to match translation
1 parent aa7b23a commit 8ecae34

File tree

2 files changed

+65
-10
lines changed

2 files changed

+65
-10
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,10 @@ namespace OvEditor::Core
129129
* Handle the scale behaviour
130130
* @param p_viewMatrix
131131
* @param p_projectionMatrix
132+
* @param p_cameraPosition
132133
* @param p_viewSize
133134
*/
134-
void ApplyScale(const OvMaths::FMatrix4& p_viewMatrix, const OvMaths::FMatrix4& p_projectionMatrix, const OvMaths::FVector2& p_viewSize) const;
135+
void ApplyScale(const OvMaths::FMatrix4& p_viewMatrix, const OvMaths::FMatrix4& p_projectionMatrix, const OvMaths::FVector3& p_cameraPosition, const OvMaths::FVector2& p_viewSize);
135136

136137
private:
137138
bool m_firstMouse = true;

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

Lines changed: 63 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -179,22 +179,76 @@ void OvEditor::Core::GizmoBehaviour::ApplyRotation(const OvMaths::FMatrix4& p_vi
179179
m_target->transform.SetWorldRotation(originRotation * rotationToApply);
180180
}
181181

182-
void OvEditor::Core::GizmoBehaviour::ApplyScale(const OvMaths::FMatrix4& p_viewMatrix, const OvMaths::FMatrix4& p_projectionMatrix, const OvMaths::FVector2& p_viewSize) const
182+
void OvEditor::Core::GizmoBehaviour::ApplyScale(const OvMaths::FMatrix4& p_viewMatrix, const OvMaths::FMatrix4& p_projectionMatrix, const OvMaths::FVector3& p_cameraPosition, const OvMaths::FVector2& p_viewSize)
183183
{
184-
auto unitsPerPixel = 0.01f;
185-
auto originScale = m_originalTransform.GetWorldScale();
184+
if (!m_target)
185+
return;
186186

187-
auto screenDirection = GetScreenDirection(p_viewMatrix, p_projectionMatrix, p_viewSize);
187+
const auto ray = GetMouseRay(m_currentMouse, p_viewMatrix, p_projectionMatrix, p_viewSize);
188188

189-
auto totalDisplacement = m_currentMouse - m_originMouse;
190-
auto scaleCoefficient = OvMaths::FVector2::Dot(totalDisplacement, screenDirection) * unitsPerPixel;
189+
const OvMaths::FVector3 gizmoAxisDirection = GetRealDirection(true);
190+
191+
OvMaths::FVector3 vectorToCamera = m_target->transform.GetWorldPosition() - p_cameraPosition;
192+
if (OvMaths::FVector3::Dot(vectorToCamera, vectorToCamera) < 0.0001f)
193+
{
194+
vectorToCamera = m_originalTransform.GetWorldUp();
195+
if (std::abs(OvMaths::FVector3::Dot(gizmoAxisDirection, vectorToCamera)) > 0.99f)
196+
{
197+
vectorToCamera = m_originalTransform.GetWorldRight();
198+
}
199+
}
200+
201+
const OvMaths::FVector3 planeTangent = OvMaths::FVector3::Cross(gizmoAxisDirection, vectorToCamera);
202+
203+
OvMaths::FVector3 tempPlaneNormal = OvMaths::FVector3::Cross(gizmoAxisDirection, planeTangent);
204+
if (OvMaths::FVector3::Dot(tempPlaneNormal, tempPlaneNormal) < 0.0001f)
205+
{
206+
OvMaths::FVector3 nonCollinearVector = OvMaths::FVector3::Up;
207+
if (std::abs(OvMaths::FVector3::Dot(gizmoAxisDirection, nonCollinearVector)) > 0.99f)
208+
{
209+
nonCollinearVector = OvMaths::FVector3::Right;
210+
}
211+
tempPlaneNormal = OvMaths::FVector3::Cross(gizmoAxisDirection, nonCollinearVector);
212+
}
213+
const OvMaths::FVector3 planeNormal = OvMaths::FVector3::Normalize(tempPlaneNormal);
214+
215+
216+
const OvMaths::FVector3 planePoint = m_originalTransform.GetWorldPosition();
217+
218+
const float denom = OvMaths::FVector3::Dot(ray, planeNormal);
219+
220+
if (std::abs(denom) <= 0.001f)
221+
return;
222+
223+
const float t = OvMaths::FVector3::Dot(planePoint - p_cameraPosition, planeNormal) / denom;
224+
225+
if (t <= 0.001f)
226+
return;
227+
228+
const OvMaths::FVector3 pointOnPlane = p_cameraPosition + ray * t * 2.0f;
229+
230+
OvMaths::FVector3 displacementOnPlane;
231+
if (m_firstPick)
232+
{
233+
m_initialOffset = m_originalTransform.GetWorldPosition() - pointOnPlane;
234+
m_firstPick = false;
235+
displacementOnPlane = OvMaths::FVector3::Zero;
236+
}
237+
else
238+
{
239+
displacementOnPlane = pointOnPlane - m_originalTransform.GetWorldPosition() + m_initialOffset;
240+
}
241+
242+
float scaleDeltaCoefficient = OvMaths::FVector3::Dot(displacementOnPlane, gizmoAxisDirection);
191243

192244
if (IsSnappedBehaviourEnabled())
193245
{
194-
scaleCoefficient = SnapValue(scaleCoefficient, OvEditor::Settings::EditorSettings::ScalingSnapUnit);
246+
scaleDeltaCoefficient = SnapValue(scaleDeltaCoefficient, OvEditor::Settings::EditorSettings::ScalingSnapUnit);
195247
}
196248

197-
auto newScale = originScale + GetFakeDirection() * scaleCoefficient;
249+
const auto originScale = m_originalTransform.GetWorldScale();
250+
251+
auto newScale = originScale + GetFakeDirection() * scaleDeltaCoefficient;
198252

199253
/* Prevent scale from being negative*/
200254
newScale.x = std::max(newScale.x, 0.0001f);
@@ -217,7 +271,7 @@ void OvEditor::Core::GizmoBehaviour::ApplyOperation(const OvMaths::FMatrix4& p_v
217271
break;
218272

219273
case EGizmoOperation::SCALE:
220-
ApplyScale(p_viewMatrix, p_projectionMatrix, p_viewSize);
274+
ApplyScale(p_viewMatrix, p_projectionMatrix, p_cameraPosition, p_viewSize);
221275
break;
222276
}
223277
}

0 commit comments

Comments
 (0)