@@ -179,22 +179,76 @@ void OvEditor::Core::GizmoBehaviour::ApplyRotation(const OvMaths::FMatrix4& p_vi
179
179
m_target->transform .SetWorldRotation (originRotation * rotationToApply);
180
180
}
181
181
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)
183
183
{
184
- auto unitsPerPixel = 0 . 01f ;
185
- auto originScale = m_originalTransform. GetWorldScale () ;
184
+ if (!m_target)
185
+ return ;
186
186
187
- auto screenDirection = GetScreenDirection ( p_viewMatrix, p_projectionMatrix, p_viewSize);
187
+ const auto ray = GetMouseRay (m_currentMouse, p_viewMatrix, p_projectionMatrix, p_viewSize);
188
188
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);
191
243
192
244
if (IsSnappedBehaviourEnabled ())
193
245
{
194
- scaleCoefficient = SnapValue (scaleCoefficient , OvEditor::Settings::EditorSettings::ScalingSnapUnit);
246
+ scaleDeltaCoefficient = SnapValue (scaleDeltaCoefficient , OvEditor::Settings::EditorSettings::ScalingSnapUnit);
195
247
}
196
248
197
- auto newScale = originScale + GetFakeDirection () * scaleCoefficient;
249
+ const auto originScale = m_originalTransform.GetWorldScale ();
250
+
251
+ auto newScale = originScale + GetFakeDirection () * scaleDeltaCoefficient;
198
252
199
253
/* Prevent scale from being negative*/
200
254
newScale.x = std::max (newScale.x , 0 .0001f );
@@ -217,7 +271,7 @@ void OvEditor::Core::GizmoBehaviour::ApplyOperation(const OvMaths::FMatrix4& p_v
217
271
break ;
218
272
219
273
case EGizmoOperation::SCALE:
220
- ApplyScale (p_viewMatrix, p_projectionMatrix, p_viewSize);
274
+ ApplyScale (p_viewMatrix, p_projectionMatrix, p_cameraPosition, p_viewSize);
221
275
break ;
222
276
}
223
277
}
0 commit comments