From 28ccb5d381ae24cbba011047f507b0f8d12cf4ae Mon Sep 17 00:00:00 2001 From: mnaumov Date: Wed, 14 Apr 2021 12:17:45 -0700 Subject: [PATCH] Fixing camera panning and zooming --- ...MaterialEditorViewportInputControllerBus.h | 3 +++ .../Viewport/InputController/Behavior.cpp | 24 +++++++++++++++++++ .../MaterialEditorViewportInputController.cpp | 13 ++++++++++ .../MaterialEditorViewportInputController.h | 3 +++ .../InputController/PanCameraBehavior.cpp | 4 +--- 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h index 04250c4efd..2acdc79286 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Include/Atom/Viewport/InputController/MaterialEditorViewportInputControllerBus.h @@ -53,6 +53,9 @@ namespace MaterialEditor //! Modify camera's field of view //! @param value field of view in degrees virtual void SetFieldOfView(float value) = 0; + + //! Check if camera is looking directly at a model + virtual bool IsCameraCentered() const = 0; }; using MaterialEditorViewportInputControllerRequestBus = AZ::EBus; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp index 8355b390ef..159d3339be 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/Behavior.cpp @@ -76,11 +76,35 @@ namespace MaterialEditor void Behavior::TickInternal([[maybe_unused]] float x, [[maybe_unused]] float y, float z) { m_distanceToTarget = m_distanceToTarget - z; + + bool isCameraCentered = false; + MaterialEditorViewportInputControllerRequestBus::BroadcastResult( + isCameraCentered, + &MaterialEditorViewportInputControllerRequestBus::Handler::IsCameraCentered); + + // if camera is looking at the model (locked to the model) we don't want to zoom past the model's center + if (isCameraCentered) + { + m_distanceToTarget = AZ::GetMax(m_distanceToTarget, 0.0f); + } + AZ::Transform transform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM); AZ::Vector3 position = m_targetPosition - transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(m_distanceToTarget)); AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTranslation, position); + + // if camera is not locked to the model, move its focal point so we can free look + if (!isCameraCentered) + { + m_targetPosition += transform.GetRotation().TransformVector(AZ::Vector3::CreateAxisY(z)); + MaterialEditorViewportInputControllerRequestBus::Broadcast( + &MaterialEditorViewportInputControllerRequestBus::Handler::SetTargetPosition, + m_targetPosition); + MaterialEditorViewportInputControllerRequestBus::BroadcastResult( + m_distanceToTarget, + &MaterialEditorViewportInputControllerRequestBus::Handler::GetDistanceToTarget); + } } float Behavior::GetSensitivityX() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp index e180a5d979..83ec5a41c5 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.cpp @@ -96,6 +96,7 @@ namespace MaterialEditor void MaterialEditorViewportInputController::SetTargetPosition(const AZ::Vector3& targetPosition) { m_targetPosition = targetPosition; + m_isCameraCentered = false; } float MaterialEditorViewportInputController::GetDistanceToTarget() const @@ -246,6 +247,7 @@ namespace MaterialEditor cameraPosition = cameraRotation.TransformVector(cameraPosition); AZ::Transform cameraTransform = AZ::Transform::CreateFromQuaternionAndTranslation(cameraRotation, cameraPosition); AZ::TransformBus::Event(m_cameraEntityId, &AZ::TransformBus::Events::SetLocalTM, cameraTransform); + m_isCameraCentered = true; // reset model AZ::Transform modelTransform = AZ::Transform::CreateIdentity(); @@ -258,6 +260,12 @@ namespace MaterialEditor AZ::RPI::ScenePtr scene = AZ::RPI::RPISystemInterface::Get()->GetDefaultScene(); auto skyBoxFeatureProcessorInterface = scene->GetFeatureProcessor(); skyBoxFeatureProcessorInterface->SetCubemapRotationMatrix(rotationMatrix); + + if (m_behavior) + { + m_behavior->End(); + m_behavior->Start(); + } } void MaterialEditorViewportInputController::SetFieldOfView(float value) @@ -265,6 +273,11 @@ namespace MaterialEditor Camera::CameraRequestBus::Event(m_cameraEntityId, &Camera::CameraRequestBus::Events::SetFovDegrees, value); } + bool MaterialEditorViewportInputController::IsCameraCentered() const + { + return m_isCameraCentered; + } + void MaterialEditorViewportInputController::CalculateExtents() { AZ::TransformBus::EventResult(m_modelCenter, m_targetEntityId, &AZ::TransformBus::Events::GetLocalTranslation); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h index aa3dd836d6..ee40b5c259 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/MaterialEditorViewportInputController.h @@ -45,6 +45,7 @@ namespace MaterialEditor void GetExtents(float& distanceMin, float& distanceMax) const override; void Reset() override; void SetFieldOfView(float value) override; + bool IsCameraCentered() const override; // AzFramework::ViewportControllerInstance interface overrides... bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override; @@ -95,6 +96,8 @@ namespace MaterialEditor float m_distanceMin = 1.0f; //! Maximum distance from camera to target float m_distanceMax = 10.0f; + //! True if camera is centered on a model + bool m_isCameraCentered = true; static constexpr float MaxDistanceMultiplier = 2.5f; static constexpr float StartingDistanceMultiplier = 2.0f; diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp index 087591e6ea..e36a335129 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/Viewport/InputController/PanCameraBehavior.cpp @@ -34,10 +34,8 @@ namespace MaterialEditor targetPosition); } - void PanCameraBehavior::TickInternal(float x, float y, float z) + void PanCameraBehavior::TickInternal(float x, float y, [[maybe_unused]] float z) { - Behavior::TickInternal(x, y, z); - AZ::Transform transform = AZ::Transform::CreateIdentity(); AZ::TransformBus::EventResult(transform, m_cameraEntityId, &AZ::TransformBus::Events::GetLocalTM); AZ::Quaternion rotation = transform.GetRotation();