From 4874a48c18803cfa14ff5897017dc5b9503f356a Mon Sep 17 00:00:00 2001 From: nvsickle Date: Mon, 28 Jun 2021 15:43:37 -0700 Subject: [PATCH] Fix switching cameras rapidly in the Editor accidentally copying camera positions Signed-off-by: nvsickle --- Code/Sandbox/Editor/EditorViewportWidget.cpp | 35 ++++++++----------- Code/Sandbox/Editor/EditorViewportWidget.h | 2 +- .../Code/Source/CameraComponentController.cpp | 2 +- 3 files changed, 17 insertions(+), 22 deletions(-) diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index c57347a809..ae60566cf3 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -452,8 +452,19 @@ void EditorViewportWidget::Update() return; } - m_updatingCameraPosition = true; - if (!ed_useNewCameraSystem) + if (m_updateCameraPositionNextTick) + { + auto cameraState = m_renderViewport->GetCameraState(); + AZ::Matrix3x4 matrix; + matrix.SetBasisAndTranslation(cameraState.m_side, cameraState.m_forward, cameraState.m_up, cameraState.m_position); + auto m = AZMatrix3x4ToLYMatrix3x4(matrix); + + SetViewTM(m); + SetFOV(cameraState.m_fovOrZoom); + m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip); + m_updateCameraPositionNextTick = false; + } + else if (!ed_useNewCameraSystem) { m_renderViewport->GetViewportContext()->SetCameraTransform(LYTransformToAZTransform(m_Camera.GetMatrix())); } @@ -472,8 +483,6 @@ void EditorViewportWidget::Update() ); m_renderViewport->GetViewportContext()->SetCameraProjectionMatrix(clipMatrix); } - m_updatingCameraPosition = false; - // Don't wait for changes to update the focused viewport. if (CheckRespondToInput()) @@ -2894,22 +2903,8 @@ void EditorViewportWidget::UpdateScene() void EditorViewportWidget::UpdateCameraFromViewportContext() { - // If we're not updating because the cry camera position changed, we should make sure our position gets copied back to the Cry Camera - if (m_updatingCameraPosition) - { - return; - } - - auto cameraState = m_renderViewport->GetCameraState(); - AZ::Matrix3x4 matrix; - matrix.SetBasisAndTranslation(cameraState.m_side, cameraState.m_forward, cameraState.m_up, cameraState.m_position); - auto m = AZMatrix3x4ToLYMatrix3x4(matrix); - - m_updatingCameraPosition = true; - SetViewTM(m); - SetFOV(cameraState.m_fovOrZoom); - m_Camera.SetZRange(cameraState.m_nearClip, cameraState.m_farClip); - m_updatingCameraPosition = false; + // Queue a sync for the next tick, to ensure the latest version of the viewport context transform is used + m_updateCameraPositionNextTick = true; } void EditorViewportWidget::SetAsActiveViewport() diff --git a/Code/Sandbox/Editor/EditorViewportWidget.h b/Code/Sandbox/Editor/EditorViewportWidget.h index 7b12afc470..029bdef284 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.h +++ b/Code/Sandbox/Editor/EditorViewportWidget.h @@ -579,7 +579,7 @@ private: AZStd::unique_ptr m_editorEntityNotifications; AtomToolsFramework::RenderViewportWidget* m_renderViewport = nullptr; - bool m_updatingCameraPosition = false; + bool m_updateCameraPositionNextTick = false; AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraViewMatrixChangeHandler; AZ::RPI::ViewportContext::MatrixChangedEvent::Handler m_cameraProjectionMatrixChangeHandler; AzFramework::DebugDisplayRequests* m_debugDisplay = nullptr; diff --git a/Gems/Camera/Code/Source/CameraComponentController.cpp b/Gems/Camera/Code/Source/CameraComponentController.cpp index 63ebbd667a..51f1360117 100644 --- a/Gems/Camera/Code/Source/CameraComponentController.cpp +++ b/Gems/Camera/Code/Source/CameraComponentController.cpp @@ -101,9 +101,9 @@ namespace Camera OnTransformChanged(localTransform, worldTransform); // Push the Atom camera after we make sure we're up-to-date with our component's transform to ensure the viewport reads the correct state + UpdateCamera(); atomViewportRequests->PushView(contextName, m_atomCamera); AZ::RPI::ViewportContextNotificationBus::Handler::BusConnect(contextName); - UpdateCamera(); } }