From bb059933558547ab39214942dc3d496fdf77dcde Mon Sep 17 00:00:00 2001 From: hultonha Date: Mon, 17 May 2021 12:05:13 +0100 Subject: [PATCH] add new orbit functionality for camrea --- .../AzFramework/Viewport/CameraInput.cpp | 46 +++++++++++++------ .../AzFramework/Viewport/CameraInput.h | 30 ++++++++++-- Code/Sandbox/Editor/EditorViewportWidget.cpp | 15 ++++++ 3 files changed, 74 insertions(+), 17 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp index daf2c63921..79c1a28e5d 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.cpp @@ -30,7 +30,8 @@ namespace AzFramework AZ_CVAR(float, ed_cameraSystemOrbitDollyScrollSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemOrbitDollyCursorSpeed, 0.01f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemScrollTranslateSpeed, 0.02f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); - AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 60.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 6.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); + AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemLookSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemTranslateSmoothness, 5.0f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); AZ_CVAR(float, ed_cameraSystemRotateSpeed, 0.005f, nullptr, AZ::ConsoleFunctorFlags::Null, ""); @@ -532,20 +533,39 @@ namespace AzFramework if (Beginning()) { - float hit_distance = 0.0f; - AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight)) - .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance); + const auto hasLookAt = [&nextCamera, &targetCamera, lookAtFn = m_lookAtFn] { + if (lookAtFn) + { + if (const auto lookAt = lookAtFn()) + { + auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt); + nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt); + UpdateCameraFromTransform(nextCamera, transform); - if (hit_distance > 0.0f) + return true; + } + } + return false; + }(); + + if (!hasLookAt) { - hit_distance = AZStd::min(hit_distance, ed_cameraSystemMaxOrbitDistance); - nextCamera.m_lookDist = -hit_distance; - nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance; - } - else - { - nextCamera.m_lookDist = -ed_cameraSystemMaxOrbitDistance; - nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMaxOrbitDistance; + float hit_distance = 0.0f; + AZ::Plane::CreateFromNormalAndPoint(AZ::Vector3::CreateAxisZ(), AZ::Vector3::CreateAxisZ(ed_cameraSystemDefaultPlaneHeight)) + .CastRay(targetCamera.Translation(), targetCamera.Rotation().GetBasisY(), hit_distance); + + if (hit_distance > 0.0f) + { + hit_distance = AZStd::min(hit_distance, ed_cameraSystemMaxOrbitDistance); + nextCamera.m_lookDist = -hit_distance; + nextCamera.m_lookAt = targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * hit_distance; + } + else + { + nextCamera.m_lookDist = -ed_cameraSystemMinOrbitDistance; + nextCamera.m_lookAt = + targetCamera.Translation() + targetCamera.Rotation().GetBasisY() * ed_cameraSystemMinOrbitDistance; + } } } diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h index 41d7f11385..b6b2bc1e6a 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraInput.h @@ -199,6 +199,7 @@ namespace AzFramework public: explicit RotateCameraInput(InputChannelId rotateChannelId); + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; @@ -239,6 +240,7 @@ namespace AzFramework public: PanCameraInput(InputChannelId panChannelId, PanAxesFn panAxesFn); + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; @@ -279,6 +281,7 @@ namespace AzFramework public: explicit TranslateCameraInput(TranslationAxesFn translationAxesFn); + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; void ResetImpl() override; @@ -348,6 +351,7 @@ namespace AzFramework class OrbitDollyScrollCameraInput : public CameraInput { public: + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; }; @@ -357,6 +361,7 @@ namespace AzFramework public: explicit OrbitDollyCursorMoveCameraInput(InputChannelId dollyChannelId); + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; @@ -367,6 +372,7 @@ namespace AzFramework class ScrollTranslationCameraInput : public CameraInput { public: + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; }; @@ -374,16 +380,32 @@ namespace AzFramework class OrbitCameraInput : public CameraInput { public: + using LookAtFn = AZStd::function()>; + + // CameraInput overrides ... void HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override; Camera StepCamera(const Camera& targetCamera, const ScreenVector& cursorDelta, float scrollDelta, float deltaTime) override; - bool Exclusive() const override - { - return true; - } + bool Exclusive() const override; Cameras m_orbitCameras; + + //! Override the default behavior for how a look-at point is calculated. + void SetLookAtFn(const LookAtFn& lookAtFn); + + private: + LookAtFn m_lookAtFn; }; + inline void OrbitCameraInput::SetLookAtFn(const LookAtFn& lookAtFn) + { + m_lookAtFn = lookAtFn; + } + + inline bool OrbitCameraInput::Exclusive() const + { + return true; + } + struct WindowSize; //! Map from a generic InputChannel event to a camera specific InputEvent. diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index 436d4bba63..85c40f2092 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -49,6 +49,7 @@ #include #include #include +#include // AtomToolsFramework #include @@ -1238,6 +1239,20 @@ void EditorViewportWidget::SetViewportId(int id) auto firstPersonWheelCamera = AZStd::make_shared(); auto orbitCamera = AZStd::make_shared(); + orbitCamera->SetLookAtFn([]() -> AZStd::optional { + AZStd::optional manipulatorTransform; + AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult( + manipulatorTransform, AzToolsFramework::GetEntityContextId(), + &AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform); + + if (manipulatorTransform) + { + return manipulatorTransform->GetTranslation(); + } + + return {}; + }); + auto orbitRotateCamera = AZStd::make_shared(AzFramework::CameraOrbitLookButton); auto orbitTranslateCamera = AZStd::make_shared(AzFramework::OrbitTranslation); auto orbitDollyWheelCamera = AZStd::make_shared();