Fix world rotation extraction with scaled parents

This commit is contained in:
2026-04-01 01:25:16 +08:00
parent 618ebed05d
commit 1af3cf87c4
3 changed files with 94 additions and 2 deletions

View File

@@ -253,6 +253,43 @@ TEST_F(SceneViewportRotateGizmoTest, DraggingEdgeOnXAxisFallsBackToScreenSpaceRo
EXPECT_TRUE(m_context.GetUndoManager().CanUndo());
}
TEST_F(SceneViewportRotateGizmoTest, DraggingXAxisOnChildWithScaledParentRotatesObject) {
Components::GameObject* parent = GetSceneManager().CreateEntity("Parent");
ASSERT_NE(parent, nullptr);
parent->GetTransform()->SetLocalScale(Math::Vector3(0.38912f, 0.38912f, 0.38912f));
parent->GetTransform()->SetLocalRotation(Math::Quaternion::FromAxisAngle(Math::Vector3::Up(), Math::PI * 0.25f));
Components::GameObject* target = GetSceneManager().CreateEntity("Target", parent);
ASSERT_NE(target, nullptr);
target->GetTransform()->SetLocalPosition(Math::Vector3(1.0f, 0.0f, 0.0f));
SceneViewportRotateGizmo gizmo;
const SceneViewportOverlayData overlay = MakeIsometricOverlay();
gizmo.Update(MakeContext(target, Math::Vector2(400.0f, 300.0f), overlay));
const SceneViewportRotateGizmoHandleDrawData* xHandle =
FindHandle(gizmo.GetDrawData(), SceneViewportRotateGizmoAxis::X);
ASSERT_NE(xHandle, nullptr);
const SceneViewportRotateGizmoSegmentDrawData* startSegment = FindLongestVisibleSegment(*xHandle, true);
ASSERT_NE(startSegment, nullptr);
const Math::Vector2 startMouse = SegmentMidpoint(*startSegment);
const SceneViewportRotateGizmoSegmentDrawData* endSegment = FindFarthestVisibleSegment(*xHandle, startMouse, true);
ASSERT_NE(endSegment, nullptr);
const auto startContext = MakeContext(target, startMouse, overlay);
gizmo.Update(startContext);
ASSERT_TRUE(gizmo.IsHoveringHandle());
ASSERT_TRUE(gizmo.TryBeginDrag(startContext, m_context.GetUndoManager()));
const auto dragContext = MakeContext(target, SegmentMidpoint(*endSegment), overlay);
gizmo.Update(dragContext);
gizmo.UpdateDrag(dragContext);
gizmo.EndDrag(m_context.GetUndoManager());
const Math::Vector3 rotatedForward = target->GetTransform()->GetForward();
EXPECT_GT(std::abs(rotatedForward.y), 0.05f);
}
TEST_F(SceneViewportRotateGizmoTest, ViewRingIsVisibleAndHoverable) {
Components::GameObject* target = GetSceneManager().CreateEntity("Target");
ASSERT_NE(target, nullptr);