diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp index b7603e5c4c..4a443cb4bf 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.cpp @@ -74,7 +74,6 @@ namespace AzFramework void SetCameraClippingVolumeFromPerspectiveFovMatrixRH(CameraState& cameraState, const AZ::Matrix4x4& clipFromView) { - const float m11 = clipFromView(1, 1); const float m22 = clipFromView(2, 2); const float m23 = clipFromView(2, 3); cameraState.m_nearClip = m23 / m22; @@ -84,7 +83,12 @@ namespace AzFramework { AZStd::swap(cameraState.m_nearClip, cameraState.m_farClip); } - cameraState.m_fovOrZoom = 2 * (AZ::Constants::HalfPi - atanf(m11)); + cameraState.m_fovOrZoom = RetrieveFov(clipFromView); + } + + float RetrieveFov(const AZ::Matrix4x4& clipFromView) + { + return 2.0f * (AZ::Constants::HalfPi - AZStd::atan(clipFromView(1, 1))); } void CameraState::Reflect(AZ::SerializeContext& serializeContext) diff --git a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h index 71d0a932c7..2565612bc3 100644 --- a/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h +++ b/Code/Framework/AzFramework/AzFramework/Viewport/CameraState.h @@ -17,54 +17,57 @@ namespace AzFramework { - /// Represents the camera state populated by the viewport camera. + //! Represents the camera state populated by the viewport camera. struct CameraState { - /// @cond + //! @cond AZ_TYPE_INFO(CameraState, "{D309D934-044C-4BA8-91F1-EA3A45177A52}") CameraState() = default; - /// @endcond + //! @endcond static void Reflect(AZ::SerializeContext& context); - /// Return the vertical fov of the camera when the view is in perspective. + //! Return the vertical fov of the camera when the view is in perspective. float VerticalFovRadian() const { return m_fovOrZoom; } - /// Return the zoom amount of the camera when the view is in orthographic. + //! Return the zoom amount of the camera when the view is in orthographic. float Zoom() const { return m_fovOrZoom; } - AZ::Vector3 m_position = AZ::Vector3::CreateZero(); ///< World position of the camera. - AZ::Vector3 m_forward = AZ::Vector3::CreateAxisY(); ///< Forward look direction of the camera (world space). - AZ::Vector3 m_side = AZ::Vector3::CreateAxisX(); ///< Side vector of camera (orthogonal to forward and up). - AZ::Vector3 m_up = AZ::Vector3::CreateAxisZ(); ///< Up vector of the camera (cameras frame - world space). - AZ::Vector2 m_viewportSize = AZ::Vector2::CreateZero(); ///< Dimensions of the viewport. - float m_nearClip = 0.01f; ///< Near clip plane of the camera. - float m_farClip = 100.0f; ///< Far clip plane of the camera. - float m_fovOrZoom = 0.0f; ///< Fov or zoom of camera depending on if it is using orthographic projection or not. - bool m_orthographic = false; ///< Is the camera using orthographic projection or not. + AZ::Vector3 m_position = AZ::Vector3::CreateZero(); //!< World position of the camera. + AZ::Vector3 m_forward = AZ::Vector3::CreateAxisY(); //!< Forward look direction of the camera (world space). + AZ::Vector3 m_side = AZ::Vector3::CreateAxisX(); //!< Side vector of camera (orthogonal to forward and up). + AZ::Vector3 m_up = AZ::Vector3::CreateAxisZ(); //!< Up vector of the camera (cameras frame - world space). + AZ::Vector2 m_viewportSize = AZ::Vector2::CreateZero(); //!< Dimensions of the viewport. + float m_nearClip = 0.01f; //!< Near clip plane of the camera. + float m_farClip = 100.0f; //!< Far clip plane of the camera. + float m_fovOrZoom = 0.0f; //!< Fov or zoom of camera depending on if it is using orthographic projection or not. + bool m_orthographic = false; //!< Is the camera using orthographic projection or not. }; - /// Create a camera at the given transform with a specific viewport size. - /// @note The near/far clip planes and fov are sensible default values - please - /// use SetCameraClippingVolume to override them. + //! Create a camera at the given transform with a specific viewport size. + //! @note The near/far clip planes and fov are sensible default values - please + //! use SetCameraClippingVolume to override them. CameraState CreateDefaultCamera(const AZ::Transform& transform, const AZ::Vector2& viewportSize); - /// Create a camera at the given position (no orientation) with a specific viewport size. - /// @note The near/far clip planes and fov are sensible default values - please - /// use SetCameraClippingVolume to override them. + //! Create a camera at the given position (no orientation) with a specific viewport size. + //! @note The near/far clip planes and fov are sensible default values - please + //! use SetCameraClippingVolume to override them. CameraState CreateIdentityDefaultCamera(const AZ::Vector3& position, const AZ::Vector2& viewportSize); - /// Create a camera transformed by the given view to world matrix with a specific viewport size. - /// @note The near/far clip planes and fov are sensible default values - please - /// use SetCameraClippingVolume to override them. + //! Create a camera transformed by the given view to world matrix with a specific viewport size. + //! @note The near/far clip planes and fov are sensible default values - please + //! use SetCameraClippingVolume to override them. CameraState CreateCameraFromWorldFromViewMatrix(const AZ::Matrix4x4& worldFromView, const AZ::Vector2& viewportSize); - /// Override the default near/far clipping planes and fov of the camera. + //! Override the default near/far clipping planes and fov of the camera. void SetCameraClippingVolume(CameraState& cameraState, float nearPlane, float farPlane, float fovRad); - /// Override the default near/far clipping planes and fov of the camera by inferring them the specified right handed transform into clip space. + //! Override the default near/far clipping planes and fov of the camera by inferring them the specified right handed transform into clip space. void SetCameraClippingVolumeFromPerspectiveFovMatrixRH(CameraState& cameraState, const AZ::Matrix4x4& clipFromView); - /// Set the transform for an existing camera. + //! Retrieve the field of view (Fov) from the perspective projection matrix (view space to clip space). + float RetrieveFov(const AZ::Matrix4x4& clipFromView); + + //! Set the transform for an existing camera. void SetCameraTransform(CameraState& cameraState, const AZ::Transform& transform); } // namespace AzFramework diff --git a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp index 8f4133de63..18462bc97b 100644 --- a/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp +++ b/Code/Framework/AzToolsFramework/Tests/Viewport/ViewportScreenTests.cpp @@ -237,4 +237,23 @@ namespace UnitTest EXPECT_THAT(cameraTransform, IsClose(cameraTransformFromView)); EXPECT_THAT(cameraView, IsClose(cameraViewFromTransform)); } + + TEST(ViewportScreen, FovCanBeRetrievedFromProjectionMatrix) + { + using ::testing::FloatNear; + + auto cameraState = AzFramework::CreateIdentityDefaultCamera(AZ::Vector3::CreateZero(), AZ::Vector2(800.0f, 600.0f)); + + { + const float fovRadians = AZ::DegToRad(45.0f); + AzFramework::SetCameraClippingVolume(cameraState, 0.1f, 100.0f, fovRadians); + EXPECT_THAT(AzFramework::RetrieveFov(AzFramework::CameraProjection(cameraState)), FloatNear(fovRadians, 0.001f)); + } + + { + const float fovRadians = AZ::DegToRad(90.0f); + AzFramework::SetCameraClippingVolume(cameraState, 0.1f, 100.0f, fovRadians); + EXPECT_THAT(AzFramework::RetrieveFov(AzFramework::CameraProjection(cameraState)), FloatNear(fovRadians, 0.001f)); + } + } } // namespace UnitTest diff --git a/Code/Sandbox/Editor/EditorViewportSettings.cpp b/Code/Sandbox/Editor/EditorViewportSettings.cpp index 362d0fab48..e34851c42b 100644 --- a/Code/Sandbox/Editor/EditorViewportSettings.cpp +++ b/Code/Sandbox/Editor/EditorViewportSettings.cpp @@ -16,7 +16,7 @@ #include #include -namespace Editor +namespace SandboxEditor { constexpr AZStd::string_view GridSnappingSetting = "/Amazon/Preferences/Editor/GridSnapping"; constexpr AZStd::string_view GridSizeSetting = "/Amazon/Preferences/Editor/GridSize"; @@ -113,4 +113,4 @@ namespace Editor registry->Set(ShowGridSetting, showing); } } -} // namespace Editor +} // namespace SandboxEditor diff --git a/Code/Sandbox/Editor/EditorViewportSettings.h b/Code/Sandbox/Editor/EditorViewportSettings.h index ca6a5f0797..c9b504fe74 100644 --- a/Code/Sandbox/Editor/EditorViewportSettings.h +++ b/Code/Sandbox/Editor/EditorViewportSettings.h @@ -12,27 +12,31 @@ #pragma once -#include +#include -namespace Editor +namespace SandboxEditor { - EDITOR_CORE_API bool GridSnappingEnabled(); + SANDBOX_API bool GridSnappingEnabled(); - EDITOR_CORE_API float GridSnappingSize(); + SANDBOX_API float GridSnappingSize(); - EDITOR_CORE_API bool AngleSnappingEnabled(); + SANDBOX_API bool AngleSnappingEnabled(); - EDITOR_CORE_API float AngleSnappingSize(); + SANDBOX_API float AngleSnappingSize(); - EDITOR_CORE_API bool ShowingGrid(); + SANDBOX_API bool ShowingGrid(); - EDITOR_CORE_API void SetGridSnapping(bool enabled); + SANDBOX_API void SetGridSnapping(bool enabled); - EDITOR_CORE_API void SetGridSnappingSize(float size); + SANDBOX_API void SetGridSnappingSize(float size); - EDITOR_CORE_API void SetAngleSnapping(bool enabled); + SANDBOX_API void SetAngleSnapping(bool enabled); - EDITOR_CORE_API void SetAngleSnappingSize(float size); + SANDBOX_API void SetAngleSnappingSize(float size); - EDITOR_CORE_API void SetShowingGrid(bool showing); -} // namespace Editor + SANDBOX_API void SetShowingGrid(bool showing); + + //! Return if the new editor camera system is enabled or not. + //! @note This is implemented in EditorViewportWidget.cpp + SANDBOX_API bool UsingNewCameraSystem(); +} // namespace SandboxEditor diff --git a/Code/Sandbox/Editor/EditorViewportWidget.cpp b/Code/Sandbox/Editor/EditorViewportWidget.cpp index adb97f1338..436d4bba63 100644 --- a/Code/Sandbox/Editor/EditorViewportWidget.cpp +++ b/Code/Sandbox/Editor/EditorViewportWidget.cpp @@ -102,8 +102,16 @@ #include AZ_CVAR( - bool, ed_visibility_logTiming, false, nullptr, AZ::ConsoleFunctorFlags::Null, - "Output the timing of the new IVisibilitySystem query"); + bool, ed_visibility_logTiming, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Output the timing of the new IVisibilitySystem query"); +AZ_CVAR(bool, ed_useNewCameraSystem, false, nullptr, AZ::ConsoleFunctorFlags::Null, "Use the new Editor camera system"); + +namespace SandboxEditor +{ + bool UsingNewCameraSystem() + { + return ed_useNewCameraSystem; + } +} // namespace SandboxEditor EditorViewportWidget* EditorViewportWidget::m_pPrimaryViewport = nullptr; @@ -114,7 +122,7 @@ namespace AzFramework extern InputChannelId CameraOrbitLookButton; extern InputChannelId CameraOrbitDollyButton; extern InputChannelId CameraOrbitPanButton; -} +} // namespace AzFramework #if AZ_TRAIT_OS_PLATFORM_APPLE void StopFixedCursorMode(); @@ -124,10 +132,6 @@ void StartFixedCursorMode(QObject *viewport); #define RENDER_MESH_TEST_DISTANCE (0.2f) #define CURSOR_FONT_HEIGHT 8.0f -AZ_CVAR( - bool, ed_useNewCameraSystem, false, nullptr, AZ::ConsoleFunctorFlags::Null, - "Use the new Editor camera system (the Atom-native Editor viewport (experimental) must also be enabled)"); - //! Viewport settings for the EditorViewportWidget struct EditorViewportSettings : public AzToolsFramework::ViewportInteraction::ViewportSettings { @@ -2885,27 +2889,27 @@ void EditorViewportWidget::SetAsActiveViewport() bool EditorViewportSettings::GridSnappingEnabled() const { - return Editor::GridSnappingEnabled(); + return SandboxEditor::GridSnappingEnabled(); } float EditorViewportSettings::GridSize() const { - return Editor::GridSnappingSize(); + return SandboxEditor::GridSnappingSize(); } bool EditorViewportSettings::ShowGrid() const { - return Editor::ShowingGrid(); + return SandboxEditor::ShowingGrid(); } bool EditorViewportSettings::AngleSnappingEnabled() const { - return Editor::AngleSnappingEnabled(); + return SandboxEditor::AngleSnappingEnabled(); } float EditorViewportSettings::AngleStep() const { - return Editor::AngleSnappingSize(); + return SandboxEditor::AngleSnappingSize(); } #include diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index f3e7532957..8086293207 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -874,9 +874,9 @@ void MainWindow::InitActions() .SetCheckable(true) .RegisterUpdateCallback([](QAction* action) { Q_ASSERT(action->isCheckable()); - action->setChecked(Editor::GridSnappingEnabled()); + action->setChecked(SandboxEditor::GridSnappingEnabled()); }) - .Connect(&QAction::triggered, []() { Editor::SetGridSnapping(!Editor::GridSnappingEnabled()); }); + .Connect(&QAction::triggered, []() { SandboxEditor::SetGridSnapping(!SandboxEditor::GridSnappingEnabled()); }); am->AddAction(ID_SNAPANGLE, tr("Snap angle")) .SetIcon(Style::icon("Angle")) @@ -885,9 +885,9 @@ void MainWindow::InitActions() .SetCheckable(true) .RegisterUpdateCallback([](QAction* action) { Q_ASSERT(action->isCheckable()); - action->setChecked(Editor::AngleSnappingEnabled()); + action->setChecked(SandboxEditor::AngleSnappingEnabled()); }) - .Connect(&QAction::triggered, []() { Editor::SetAngleSnapping(!Editor::AngleSnappingEnabled()); }); + .Connect(&QAction::triggered, []() { SandboxEditor::SetAngleSnapping(!SandboxEditor::AngleSnappingEnabled()); }); // Display actions am->AddAction(ID_WIREFRAME, tr("&Wireframe")) @@ -1275,12 +1275,12 @@ QWidget* MainWindow::CreateSnapToGridWidget() { SnapToWidget::SetValueCallback setCallback = [](double snapStep) { - Editor::SetGridSnappingSize(snapStep); + SandboxEditor::SetGridSnappingSize(snapStep); }; SnapToWidget::GetValueCallback getCallback = []() { - return Editor::GridSnappingSize(); + return SandboxEditor::GridSnappingSize(); }; return new SnapToWidget(m_actionManager->GetAction(ID_SNAP_TO_GRID), setCallback, getCallback); @@ -1290,12 +1290,12 @@ QWidget* MainWindow::CreateSnapToAngleWidget() { SnapToWidget::SetValueCallback setCallback = [](double snapAngle) { - Editor::SetAngleSnappingSize(snapAngle); + SandboxEditor::SetAngleSnappingSize(snapAngle); }; SnapToWidget::GetValueCallback getCallback = []() { - return Editor::AngleSnappingSize(); + return SandboxEditor::AngleSnappingSize(); }; return new SnapToWidget(m_actionManager->GetAction(ID_SNAPANGLE), setCallback, getCallback); diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.cpp b/Code/Sandbox/Editor/ModernViewportCameraController.cpp index f5df8d48ca..af161af493 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.cpp +++ b/Code/Sandbox/Editor/ModernViewportCameraController.cpp @@ -25,7 +25,8 @@ namespace SandboxEditor { - static void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength) + // debug + void DrawPreviewAxis(AzFramework::DebugDisplayRequests& display, const AZ::Transform& transform, const float axisLength) { display.SetColor(AZ::Colors::Red); display.DrawLine(transform.GetTranslation(), transform.GetTranslation() + transform.GetBasisX().GetNormalizedSafe() * axisLength); @@ -87,10 +88,12 @@ namespace SandboxEditor } AzFramework::ViewportDebugDisplayEventBus::Handler::BusConnect(AzToolsFramework::GetEntityContextId()); + ModernViewportCameraControllerRequestBus::Handler::BusConnect(viewportId); } ModernViewportCameraControllerInstance::~ModernViewportCameraControllerInstance() { + ModernViewportCameraControllerRequestBus::Handler::BusDisconnect(); AzFramework::ViewportDebugDisplayEventBus::Handler::BusDisconnect(); } @@ -100,27 +103,6 @@ namespace SandboxEditor AzFramework::WindowRequestBus::EventResult( windowSize, event.m_windowHandle, &AzFramework::WindowRequestBus::Events::GetClientAreaSize); - if (m_cameraMode == CameraMode::Control) - { - if (AzFramework::InputDeviceKeyboard::IsKeyboardDevice(event.m_inputChannel.GetInputDevice().GetInputDeviceId())) - { - if (event.m_inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::AlphanumericR) - { - m_transformEnd = m_camera.Transform(); - - return true; - } - else if (event.m_inputChannel.GetInputChannelId() == AzFramework::InputDeviceKeyboard::Key::AlphanumericP) - { - m_animationT = 0.0f; - m_cameraMode = CameraMode::Animation; - m_transformStart = m_camera.Transform(); - - return true; - } - } - } - return m_cameraSystem.HandleEvents(AzFramework::BuildInputEvent(event.m_inputChannel, windowSize)); } @@ -174,7 +156,13 @@ namespace SandboxEditor debugDisplay.SetColor(1.0f, 1.0f, 1.0f, alpha); debugDisplay.DrawWireSphere(m_camera.m_lookAt, 0.5f); } + } - DrawPreviewAxis(debugDisplay, m_transformEnd, 2.0f); + void ModernViewportCameraControllerInstance::InterpolateToTransform(const AZ::Transform& worldFromLocal) + { + m_animationT = 0.0f; + m_cameraMode = CameraMode::Animation; + m_transformStart = m_camera.Transform(); + m_transformEnd = worldFromLocal; } } // namespace SandboxEditor diff --git a/Code/Sandbox/Editor/ModernViewportCameraController.h b/Code/Sandbox/Editor/ModernViewportCameraController.h index edc034a78a..066c8efaa8 100644 --- a/Code/Sandbox/Editor/ModernViewportCameraController.h +++ b/Code/Sandbox/Editor/ModernViewportCameraController.h @@ -12,6 +12,8 @@ #pragma once +#include + #include #include #include @@ -36,6 +38,7 @@ namespace SandboxEditor class ModernViewportCameraControllerInstance final : public AzFramework::MultiViewportControllerInstanceInterface, + public ModernViewportCameraControllerRequestBus::Handler, private AzFramework::ViewportDebugDisplayEventBus::Handler { public: @@ -46,10 +49,13 @@ namespace SandboxEditor bool HandleInputChannelEvent(const AzFramework::ViewportControllerInputEvent& event) override; void UpdateViewport(const AzFramework::ViewportControllerUpdateEvent& event) override; + // ModernViewportCameraControllerRequestBus overrides ... + void InterpolateToTransform(const AZ::Transform& worldFromLocal) override; + + private: // AzFramework::ViewportDebugDisplayEventBus overrides ... void DisplayViewport(const AzFramework::ViewportInfo& viewportInfo, AzFramework::DebugDisplayRequests& debugDisplay) override; - private: enum class CameraMode { Control, diff --git a/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h b/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h new file mode 100644 index 0000000000..966facc8e9 --- /dev/null +++ b/Code/Sandbox/Editor/ModernViewportCameraControllerRequestBus.h @@ -0,0 +1,42 @@ +/* + * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or + * its licensors. + * + * For complete copyright and license terms please see the LICENSE at the root of this + * distribution (the "License"). All use of this software is governed by the License, + * or, if provided, by the license below or the license accompanying this file. Do not + * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * + */ + +#pragma once + +#include +#include + +namespace AZ +{ + class Transform; +} + +namespace SandboxEditor +{ + //! Provides an interface to control the modern viewport camera controller from the Editor. + //! @note The bus is addressed by viewport id. + class ModernViewportCameraControllerRequests : public AZ::EBusTraits + { + public: + using BusIdType = AzFramework::ViewportId; + static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::ById; + static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; + + //! Begin a smooth transition of the camera to the requested transform. + virtual void InterpolateToTransform(const AZ::Transform& worldFromLocal) = 0; + + protected: + ~ModernViewportCameraControllerRequests() = default; + }; + + using ModernViewportCameraControllerRequestBus = AZ::EBus; +} // namespace SandboxEditor diff --git a/Code/Sandbox/Editor/editor_core_files.cmake b/Code/Sandbox/Editor/editor_core_files.cmake index 486408159a..1aecbd03f6 100644 --- a/Code/Sandbox/Editor/editor_core_files.cmake +++ b/Code/Sandbox/Editor/editor_core_files.cmake @@ -22,8 +22,6 @@ set(FILES Include/IEditorMaterial.h Include/IEditorMaterialManager.h Include/IImageUtil.h - EditorViewportSettings.cpp - EditorViewportSettings.h Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.qrc Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.cpp Controls/ReflectedPropertyControl/ReflectedPropertyCtrl.h diff --git a/Code/Sandbox/Editor/editor_lib_files.cmake b/Code/Sandbox/Editor/editor_lib_files.cmake index 8ad8c8263f..448117610c 100644 --- a/Code/Sandbox/Editor/editor_lib_files.cmake +++ b/Code/Sandbox/Editor/editor_lib_files.cmake @@ -824,12 +824,15 @@ set(FILES LayoutWnd.h EditorViewportWidget.cpp EditorViewportWidget.h + EditorViewportSettings.cpp + EditorViewportSettings.h ViewportManipulatorController.cpp ViewportManipulatorController.h LegacyViewportCameraController.cpp LegacyViewportCameraController.h ModernViewportCameraController.cpp ModernViewportCameraController.h + ModernViewportCameraControllerRequestBus.h RenderViewport.cpp RenderViewport.h TopRendererWnd.cpp diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt index 275bb0ba9f..72d88b06b4 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/CMakeLists.txt @@ -36,6 +36,8 @@ ly_add_target( Legacy::CryCommon Legacy::EditorLib Gem::LmbrCentral + AZ::AtomCore + Gem::Atom_RPI.Public ) ly_add_dependencies(Editor ComponentEntityEditorPlugin) diff --git a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp index f38b295128..027487a435 100644 --- a/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp +++ b/Code/Sandbox/Plugins/ComponentEntityEditorPlugin/SandboxIntegration.cpp @@ -16,12 +16,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include #include @@ -30,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -56,8 +60,14 @@ #include #include #include +#include #include +#include +#include + +#include + #include "Objects/ComponentEntityObject.h" #include "ISourceControl.h" #include "UI/QComponentEntityEditorMainWindow.h" @@ -75,6 +85,7 @@ #include #include #include +#include #include #include "CryEdit.h" @@ -1674,32 +1685,77 @@ bool CollectEntityBoundingBoxesForZoom(const AZ::EntityId& entityId, AABB& selec ////////////////////////////////////////////////////////////////////////// void SandboxIntegrationManager::GoToEntitiesInViewports(const AzToolsFramework::EntityIdList& entityIds) { - if (entityIds.size() == 0) + if (entityIds.empty()) { return; } - AABB selectionBounds; - selectionBounds.Reset(); - bool entitiesAvailableForGoTo = false; - - for (const AZ::EntityId& entityId : entityIds) + if (SandboxEditor::UsingNewCameraSystem()) { - if(CollectEntityBoundingBoxesForZoom(entityId, selectionBounds)) + const AZ::Aabb aabb = AZStd::accumulate( + AZStd::begin(entityIds), AZStd::end(entityIds), AZ::Aabb::CreateNull(), [](AZ::Aabb acc, const AZ::EntityId entityId) { + const AZ::Aabb aabb = AzFramework::CalculateEntityWorldBoundsUnion(AzToolsFramework::GetEntityById(entityId)); + acc.AddAabb(aabb); + return acc; + }); + + float radius; + AZ::Vector3 center; + aabb.GetAsSphere(center, radius); + + // minimum center size is 40cm + const float minSelectionRadius = 0.4f; + const float selectionSize = AZ::GetMax(minSelectionRadius, radius); + + auto viewportContextManager = AZ::Interface::Get(); + + const int viewCount = GetIEditor()->GetViewManager()->GetViewCount(); // legacy call + for (int viewIndex = 0; viewIndex < viewCount; ++viewIndex) { - entitiesAvailableForGoTo = true; + if (auto viewportContext = viewportContextManager->GetViewportContextById(viewIndex)) + { + const AZ::Transform cameraTransform = viewportContext->GetCameraTransform(); + const AZ::Vector3 forward = (center - cameraTransform.GetTranslation()).GetNormalized(); + + // move camera 25% further back than required + const float centerScale = 1.25f; + // compute new camera transform + const float fov = AzFramework::RetrieveFov(viewportContext->GetCameraProjectionMatrix()); + const float fovScale = (1.0f / AZStd::tan(fov * 0.5f)); + const float distanceToTarget = selectionSize * fovScale * centerScale; + const AZ::Transform nextCameraTransform = + AZ::Transform::CreateLookAt(aabb.GetCenter() - (forward * distanceToTarget), aabb.GetCenter()); + + SandboxEditor::ModernViewportCameraControllerRequestBus::Event( + viewportContext->GetId(), &SandboxEditor::ModernViewportCameraControllerRequestBus::Events::InterpolateToTransform, + nextCameraTransform); + } } } - - if (entitiesAvailableForGoTo) + else { - int numViews = GetIEditor()->GetViewManager()->GetViewCount(); - for (int viewIndex = 0; viewIndex < numViews; ++viewIndex) + AABB selectionBounds; + selectionBounds.Reset(); + bool entitiesAvailableForGoTo = false; + + for (const AZ::EntityId& entityId : entityIds) { - CViewport* viewport = GetIEditor()->GetViewManager()->GetView(viewIndex); - if (viewport) + if (CollectEntityBoundingBoxesForZoom(entityId, selectionBounds)) { - viewport->CenterOnAABB(selectionBounds); + entitiesAvailableForGoTo = true; + } + } + + if (entitiesAvailableForGoTo) + { + int numViews = GetIEditor()->GetViewManager()->GetViewCount(); + for (int viewIndex = 0; viewIndex < numViews; ++viewIndex) + { + CViewport* viewport = GetIEditor()->GetViewManager()->GetView(viewIndex); + if (viewport) + { + viewport->CenterOnAABB(selectionBounds); + } } } }