@@ -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