浏览代码

Camera fix again (#15119)

* restore backed out code

Signed-off-by: Tom Hulton-Harrop <[email protected]>

* fix for camera restore issue working with change in PR 14889

Signed-off-by: Tom Hulton-Harrop <[email protected]>

* last fix for be this camera

Signed-off-by: Tom Hulton-Harrop <[email protected]>

---------

Signed-off-by: Tom Hulton-Harrop <[email protected]>
Tom Hulton-Harrop 2 年之前
父节点
当前提交
e1fa4744ef

+ 108 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EditorWorkflow_EditorCameraInBeThisCameraReturnsToOriginalPositionWhenLeavingGameMode.py

@@ -0,0 +1,108 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+
+class Tests:
+    camera_moved_to_entity_position_game_mode = (
+        "Editor camera view moved to the camera entity position in game mode"
+        "Editor camera view did not move to the camera entity position in game mode"
+    )
+
+    camera_returned_to_initial_position = (
+        "Editor camera view restored after returning from game mode"
+        "Editor camera view was not restored after returning from game mode"
+    )
+
+
+def EditorWorkflow_EditorCameraInBeThisCameraReturnsToOriginalPositionWhenLeavingGameMode():
+    """
+    Summary:
+    Test camera position when entering/leaving game mode
+
+    Expected Behavior:
+    Editor camera view returns to original editor camera position after leaving game mode
+    """
+
+    import azlmbr.bus as bus
+    import azlmbr.camera as camera
+    import azlmbr.editor as editor
+    import azlmbr.components as components
+    import azlmbr.legacy.general as general
+    import azlmbr.math as math
+
+    from editor_python_test_tools.editor_entity_utils import EditorEntity
+    from editor_python_test_tools.editor_test_helper import EditorTestHelper
+    from editor_python_test_tools.utils import Report, TestHelper
+
+    def get_current_view_position_as_vector3() -> math.Vector3:
+        view_position = general.get_current_view_position()
+        x = view_position.get_property('x')
+        y = view_position.get_property('y')
+        z = view_position.get_property('z')
+        return math.Vector3(float(x), float(y), float(z))
+
+    helper = EditorTestHelper(log_prefix="Editor Camera")
+
+    helper.open_level("Base")
+
+    # where we expect the camera to end up
+    entity_camera_position = math.Vector3(20.0, 40.0, 60.0)
+
+    # begin recording an undo batch for the newly created entity
+    editor.ToolsApplicationRequestBus(bus.Broadcast, 'BeginUndoBatch', "Create camera entity")
+
+    # create a new entity with a camera component
+    camera_entity = EditorEntity.create_editor_entity(name="CameraEntity")
+    camera_entity.add_component("Camera")
+
+    # explicitly track the entity in the newly created undo batch
+    editor.ToolsApplicationRequestBus(bus.Broadcast, 'AddDirtyEntity', camera_entity.id)
+
+    # position the entity in the world
+    components.TransformBus(bus.Event, "SetWorldTranslation",
+                            camera_entity.id, entity_camera_position)
+
+    # after modifying the entity, end the undo batch (this will ensure the change is tracked
+    # when moving to/from game mode)
+    editor.ToolsApplicationRequestBus(bus.Broadcast, 'EndUndoBatch')
+
+    general.idle_wait_frames(1)
+
+    # trigger 'Be this camera'
+    camera.EditorCameraViewRequestBus(
+        bus.Event, "ToggleCameraAsActiveView", camera_entity.id)
+    
+    general.idle_wait_frames(1)
+
+    # note: this will match the entity transform
+    initial_camera_position = get_current_view_position_as_vector3()
+
+    # enter/exit game mode
+    general.enter_game_mode()
+    helper.wait_for_condition(lambda: general.is_in_game_mode(), 5.0)
+
+    game_mode_camera_position = get_current_view_position_as_vector3()
+
+    position_changed_game_mode = game_mode_camera_position.IsClose(entity_camera_position)
+    Report.result(Tests.camera_moved_to_entity_position_game_mode, position_changed_game_mode)
+
+    general.exit_game_mode()
+    helper.wait_for_condition(lambda: not general.is_in_game_mode(), 5.0)
+
+    # ensure camera position has returned to the position it was when starting 'be this camera'
+    actual_camera_position = get_current_view_position_as_vector3()
+
+    position_restored = actual_camera_position.IsClose(initial_camera_position)
+
+    # verify the position has been updated
+    Report.result(Tests.camera_returned_to_initial_position, position_restored)
+
+
+if __name__ == "__main__":
+    from editor_python_test_tools.utils import Report
+    Report.start_test(
+        EditorWorkflow_EditorCameraInBeThisCameraReturnsToOriginalPositionWhenLeavingGameMode)

+ 82 - 0
AutomatedTesting/Gem/PythonTests/editor/EditorScripts/EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingFullscreenGameMode.py

@@ -0,0 +1,82 @@
+"""
+Copyright (c) Contributors to the Open 3D Engine Project.
+For complete copyright and license terms please see the LICENSE at the root of this distribution.
+
+SPDX-License-Identifier: Apache-2.0 OR MIT
+"""
+
+
+class Tests:
+    camera_moved_to_position_edit_mode = (
+        "Editor camera view moved to the new position in edit mode"
+        "Editor camera view did not move to the new position in edit mode"
+    )
+
+    camera_returned_to_initial_position_in_edit_mode_after_fullscreen_preview = (
+        "Editor camera view restored after returning from game mode in fullscreen"
+        "Editor camera view was not restored after returning from game mode in fullscreen"
+    )
+
+
+def EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingFullscreenGameMode():
+    """
+    Summary:
+    Test camera position when entering/leaving game mode fullscreen preview
+
+    Expected Behavior:
+    Editor camera view returns to original editor camera position after leaving game mode fullscreen preview
+    """
+
+    import azlmbr.bus as bus
+    import azlmbr.editor as editor
+    import azlmbr.components as components
+    import azlmbr.legacy.general as general
+    import azlmbr.math as math
+
+    from editor_python_test_tools.editor_entity_utils import EditorEntity
+    from editor_python_test_tools.editor_test_helper import EditorTestHelper
+    from editor_python_test_tools.utils import Report, TestHelper
+
+    def get_current_view_position_as_vector3() -> math.Vector3:
+        view_position = general.get_current_view_position()
+        x = view_position.get_property('x')
+        y = view_position.get_property('y')
+        z = view_position.get_property('z')
+        return math.Vector3(float(x), float(y), float(z))
+
+    def set_current_view_position_with_vector3(view_position: math.Vector3):
+        general.set_current_view_position(
+            view_position.x, view_position.y, view_position.z)
+
+    helper = EditorTestHelper(log_prefix="Editor Camera")
+
+    helper.open_level("Base")
+
+    # where we expect the editor camera to end up
+    editor_camera_position = math.Vector3(20.0, 40.0, 60.0)
+    set_current_view_position_with_vector3(editor_camera_position)
+
+    general.idle_wait_frames(1)
+
+    initial_camera_position = get_current_view_position_as_vector3()
+    initial_camera_position_position_set = initial_camera_position.IsClose(editor_camera_position)
+    Report.result(Tests.camera_moved_to_position_edit_mode, initial_camera_position_position_set)
+
+    # enter/exit game mode
+    general.enter_game_mode_fullscreen()
+    helper.wait_for_condition(lambda: general.is_in_game_mode(), 5.0)
+
+    general.exit_game_mode()
+    helper.wait_for_condition(lambda: not general.is_in_game_mode(), 5.0)
+
+    # ensure camera position has returned to the initial camera position
+    actual_camera_position = get_current_view_position_as_vector3()
+    position_restored = actual_camera_position.IsClose(initial_camera_position)
+    # verify the position has been updated
+    Report.result(Tests.camera_returned_to_initial_position_in_edit_mode_after_fullscreen_preview, position_restored)
+
+
+if __name__ == "__main__":
+    from editor_python_test_tools.utils import Report
+    Report.start_test(
+        EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingFullscreenGameMode)

+ 6 - 0
AutomatedTesting/Gem/PythonTests/editor/TestSuite_Main.py

@@ -117,6 +117,12 @@ class TestAutomation(EditorTestSuite):
     class test_EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingGameMode(EditorSingleTest):
         from .EditorScripts import EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingGameMode as test_module
 
+    class test_EditorWorkflow_EditorCameraInBeThisCameraReturnsToOriginalPositionWhenLeavingGameMode(EditorSingleTest):
+        from .EditorScripts import EditorWorkflow_EditorCameraInBeThisCameraReturnsToOriginalPositionWhenLeavingGameMode as test_module
+
+    class test_EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingFullscreenGameMode(EditorSingleTest):
+        from .EditorScripts import EditorWorkflow_EditorCameraReturnsToOriginalPositionWhenLeavingFullscreenGameMode as test_module
+
     class test_EditorWorkflow_EditorCameraTransformCanBeModifiedWhileInBeThisCamera(EditorSingleTest):
         from .EditorScripts import EditorWorkflow_EditorCameraTransformCanBeModifiedWhileInBeThisCamera as test_module
 

+ 14 - 19
Code/Editor/EditorViewportWidget.cpp

@@ -603,6 +603,7 @@ void EditorViewportWidget::OnEditorNotifyEvent(EEditorNotifyEvent event)
                 }
 
                 m_preGameModeViewTM = GetViewTM();
+
                 // this should only occur for the main viewport and no others.
                 ShowCursor();
 
@@ -891,6 +892,13 @@ void EditorViewportWidget::SetViewportId(int id)
     layout->setContentsMargins(QMargins());
     layout->addWidget(m_renderViewport);
 
+    UpdateScene();
+
+    if (m_pPrimaryViewport == this)
+    {
+        SetAsActiveViewport();
+    }
+
     m_renderViewport->GetControllerList()->Add(AZStd::make_shared<SandboxEditor::ViewportManipulatorController>());
 
     m_editorModularViewportCameraComposer =
@@ -899,13 +907,6 @@ void EditorViewportWidget::SetViewportId(int id)
 
     m_editorViewportSettings.Connect(AzFramework::ViewportId(id));
 
-    UpdateScene();
-
-    if (m_pPrimaryViewport == this)
-    {
-        SetAsActiveViewport();
-    }
-
     m_editorViewportSettingsCallbacks = SandboxEditor::CreateEditorViewportSettingsCallbacks();
 
     m_gridShowingHandler = SandboxEditor::GridShowingChangedEvent::Handler(
@@ -913,8 +914,7 @@ void EditorViewportWidget::SetViewportId(int id)
         {
             AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Event(
                 id, &AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Events::OnGridShowingChanged, showing);
-        }
-    );
+        });
     m_editorViewportSettingsCallbacks->SetGridShowingChangedEvent(m_gridShowingHandler);
 
     m_gridSnappingHandler = SandboxEditor::GridSnappingChangedEvent::Handler(
@@ -922,8 +922,7 @@ void EditorViewportWidget::SetViewportId(int id)
         {
             AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Event(
                 id, &AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Events::OnGridSnappingChanged, snapping);
-        }
-    );
+        });
     m_editorViewportSettingsCallbacks->SetGridSnappingChangedEvent(m_gridSnappingHandler);
 
     m_angleSnappingHandler = SandboxEditor::AngleSnappingChangedEvent::Handler(
@@ -931,8 +930,7 @@ void EditorViewportWidget::SetViewportId(int id)
         {
             AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Event(
                 id, &AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Events::OnAngleSnappingChanged, snapping);
-        }
-    );
+        });
     m_editorViewportSettingsCallbacks->SetAngleSnappingChangedEvent(m_angleSnappingHandler);
 
     m_cameraSpeedScaleHandler = SandboxEditor::CameraSpeedScaleChangedEvent::Handler(
@@ -940,8 +938,7 @@ void EditorViewportWidget::SetViewportId(int id)
         {
             AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Event(
                 id, &AzToolsFramework::ViewportInteraction::ViewportSettingsNotificationBus::Events::OnCameraSpeedScaleChanged, scale);
-        }
-    );
+        });
     m_editorViewportSettingsCallbacks->SetCameraSpeedScaleChangedEvent(m_cameraSpeedScaleHandler);
 
     m_perspectiveChangeHandler = SandboxEditor::PerspectiveChangedEvent::Handler(
@@ -962,16 +959,14 @@ void EditorViewportWidget::SetViewportId(int id)
         [this]([[maybe_unused]] float nearPlaneDistance)
         {
             OnDefaultCameraNearFarChanged();
-        }
-    );
+        });
     m_editorViewportSettingsCallbacks->SetNearPlaneDistanceChangedEvent(m_nearPlaneDistanceHandler);
 
     m_farPlaneDistanceHandler = SandboxEditor::NearFarPlaneChangedEvent::Handler(
         [this]([[maybe_unused]] float farPlaneDistance)
         {
             OnDefaultCameraNearFarChanged();
-        }
-    );
+        });
     m_editorViewportSettingsCallbacks->SetFarPlaneDistanceChangedEvent(m_farPlaneDistanceHandler);
 }
 

+ 8 - 0
Code/Editor/PythonEditorFuncs.cpp

@@ -31,6 +31,7 @@
 #include "Objects/BaseObject.h"
 #include "Commands/CommandManager.h"
 
+AZ_CVAR_EXTERNED(bool, ed_previewGameInFullscreen_once);
 
 namespace
 {
@@ -166,6 +167,12 @@ namespace
         }
     }
 
+    void PyEnterGameModeFullscreen()
+    {
+        ed_previewGameInFullscreen_once = true;
+        PyEnterGameMode();
+    }
+
     void PyExitGameMode()
     {
         if (GetIEditor()->GetGameEngine())
@@ -1091,6 +1098,7 @@ namespace AzToolsFramework
             addLegacyGeneral(behaviorContext->Method("run_console", PyRunConsole, nullptr, "Runs a console command."));
 
             addLegacyGeneral(behaviorContext->Method("enter_game_mode", PyEnterGameMode, nullptr, "Enters the editor game mode."));
+            addLegacyGeneral(behaviorContext->Method("enter_game_mode_fullscreen", PyEnterGameModeFullscreen, nullptr, "Enters the editor game mode in fullscreen."));
             addLegacyGeneral(behaviorContext->Method("is_in_game_mode", PyIsInGameMode, nullptr, "Queries if it's in the game mode or not."));
             addLegacyGeneral(behaviorContext->Method("exit_game_mode", PyExitGameMode, nullptr, "Exits the editor game mode."));