From 4874a48c18803cfa14ff5897017dc5b9503f356a Mon Sep 17 00:00:00 2001 From: nvsickle Date: Mon, 28 Jun 2021 15:43:37 -0700 Subject: [PATCH 1/2] 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(); } } From 26c123dd568c758f7bb3fbab9cc0440b90a90bd9 Mon Sep 17 00:00:00 2001 From: nvsickle Date: Tue, 29 Jun 2021 11:33:12 -0700 Subject: [PATCH 2/2] Switch Python camera API to use Atom directly Signed-off-by: nvsickle --- Code/Sandbox/Editor/CryEditPy.cpp | 44 ++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/Code/Sandbox/Editor/CryEditPy.cpp b/Code/Sandbox/Editor/CryEditPy.cpp index a4ac36ac12..f989e82d0d 100644 --- a/Code/Sandbox/Editor/CryEditPy.cpp +++ b/Code/Sandbox/Editor/CryEditPy.cpp @@ -28,6 +28,10 @@ #include "UndoConfigSpec.h" #include "ViewManager.h" +// Atom +#include +#include + ////////////////////////////////////////////////////////////////////////// namespace { @@ -224,33 +228,49 @@ namespace AZ::Vector3 PyGetCurrentViewPosition() { - Vec3 pos = GetIEditor()->GetSystem()->GetViewCamera().GetPosition(); - return AZ::Vector3(pos.x, pos.y, pos.z); + auto viewportContextRequests = AZ::RPI::ViewportContextRequests::Get(); + if (viewportContextRequests) + { + AZ::RPI::ViewportContextPtr viewportContext = viewportContextRequests->GetDefaultViewportContext(); + AZ::Transform transform = viewportContext->GetCameraTransform(); + return transform.GetTranslation(); + } + return AZ::Vector3(); } AZ::Vector3 PyGetCurrentViewRotation() { - Ang3 ang = RAD2DEG(Ang3::GetAnglesXYZ(Matrix33(GetIEditor()->GetSystem()->GetViewCamera().GetMatrix()))); - return AZ::Vector3(ang.x, ang.y, ang.z); + auto viewportContextRequests = AZ::RPI::ViewportContextRequests::Get(); + if (viewportContextRequests) + { + AZ::RPI::ViewportContextPtr viewportContext = viewportContextRequests->GetDefaultViewportContext(); + AZ::Transform transform = viewportContext->GetCameraTransform(); + return transform.GetRotation().GetEulerDegrees(); + } + return AZ::Vector3(); } void PySetCurrentViewPosition(float x, float y, float z) { - AzToolsFramework::IEditorCameraController* editorCameraController = AZ::Interface::Get(); - AZ_Error("editor", editorCameraController, "IEditorCameraController is not registered."); - if (editorCameraController) + auto viewportContextRequests = AZ::RPI::ViewportContextRequests::Get(); + if (viewportContextRequests) { - editorCameraController->SetCurrentViewPosition(AZ::Vector3{ x, y, z }); + AZ::RPI::ViewportContextPtr viewportContext = viewportContextRequests->GetDefaultViewportContext(); + AZ::Transform transform = viewportContext->GetCameraTransform(); + transform.SetTranslation(x, y, z); + viewportContextRequests->GetDefaultViewportContext()->SetCameraTransform(transform); } } void PySetCurrentViewRotation(float x, float y, float z) { - AzToolsFramework::IEditorCameraController* editorCameraController = AZ::Interface::Get(); - AZ_Error("editor", editorCameraController, "IEditorCameraController is not registered."); - if (editorCameraController) + auto viewportContextRequests = AZ::RPI::ViewportContextRequests::Get(); + if (viewportContextRequests) { - editorCameraController->SetCurrentViewRotation(AZ::Vector3{ x, y, z }); + AZ::RPI::ViewportContextPtr viewportContext = viewportContextRequests->GetDefaultViewportContext(); + AZ::Transform transform = viewportContext->GetCameraTransform(); + transform.SetRotation(AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(x, y, z))); + viewportContextRequests->GetDefaultViewportContext()->SetCameraTransform(transform); } } }