Updates to EMFX cameras and better support for character follow behavior (#7676)

* initial wip change to help resolve EMFX camera viewport issue

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* some updates to add/remove camera input API

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* add additional comments and remove some optimize off calls

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* improvements to camera behavior in EMFX editor

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>

* add some tests for add/remove logic for cameras

Signed-off-by: Tom Hulton-Harrop <82228511+hultonha@users.noreply.github.com>
development
Tom Hulton-Harrop 4 years ago committed by GitHub
parent d31200ee5c
commit 6ffc2620e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -287,16 +287,16 @@ namespace SandboxEditor
return SandboxEditor::CameraBoostMultiplier();
};
m_orbitDollyScrollCamera = AZStd::make_shared<AzFramework::OrbitDollyScrollCameraInput>();
m_orbitScrollDollyCamera = AZStd::make_shared<AzFramework::OrbitScrollDollyCameraInput>();
m_orbitDollyScrollCamera->m_scrollSpeedFn = []
m_orbitScrollDollyCamera->m_scrollSpeedFn = []
{
return SandboxEditor::CameraScrollSpeed();
};
m_orbitDollyMoveCamera = AZStd::make_shared<AzFramework::OrbitDollyMotionCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitMotionDollyCamera = AZStd::make_shared<AzFramework::OrbitMotionDollyCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitDollyMoveCamera->m_motionSpeedFn = []
m_orbitMotionDollyCamera->m_motionSpeedFn = []
{
return SandboxEditor::CameraDollyMotionSpeed();
};
@ -326,8 +326,8 @@ namespace SandboxEditor
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitRotateCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitTranslateCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitDollyScrollCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitDollyMoveCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitScrollDollyCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitMotionDollyCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitPanCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitFocusCamera);
}
@ -344,7 +344,7 @@ namespace SandboxEditor
m_orbitTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
m_orbitPanCamera->SetPanInputChannelId(SandboxEditor::CameraOrbitPanChannelId());
m_orbitRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraOrbitLookChannelId());
m_orbitDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitMotionDollyCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
m_orbitFocusCamera->SetFocusInputChannelId(SandboxEditor::CameraFocusChannelId());
}

@ -56,8 +56,8 @@ namespace SandboxEditor
AZStd::shared_ptr<AzFramework::OrbitCameraInput> m_orbitCamera;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_orbitRotateCamera;
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_orbitTranslateCamera;
AZStd::shared_ptr<AzFramework::OrbitDollyScrollCameraInput> m_orbitDollyScrollCamera;
AZStd::shared_ptr<AzFramework::OrbitDollyMotionCameraInput> m_orbitDollyMoveCamera;
AZStd::shared_ptr<AzFramework::OrbitScrollDollyCameraInput> m_orbitScrollDollyCamera;
AZStd::shared_ptr<AzFramework::OrbitMotionDollyCameraInput> m_orbitMotionDollyCamera;
AZStd::shared_ptr<AzFramework::PanCameraInput> m_orbitPanCamera;
AZStd::shared_ptr<AzFramework::FocusCameraInput> m_orbitFocusCamera;

@ -190,9 +190,67 @@ namespace AzFramework
return nextCamera;
}
void Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
bool Cameras::AddCamera(AZStd::shared_ptr<CameraInput> cameraInput)
{
m_idleCameraInputs.push_back(AZStd::move(cameraInput));
const auto idleCameraIt = AZStd::find(m_idleCameraInputs.begin(), m_idleCameraInputs.end(), cameraInput);
const auto activeCameraIt = AZStd::find(m_activeCameraInputs.begin(), m_activeCameraInputs.end(), cameraInput);
if (idleCameraIt == m_idleCameraInputs.end() && activeCameraIt == m_activeCameraInputs.end())
{
m_idleCameraInputs.push_back(AZStd::move(cameraInput));
return true;
}
return false;
}
bool Cameras::AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
bool allAdded = true;
for (auto cameraInput : cameraInputs)
{
allAdded = AddCamera(AZStd::move(cameraInput)) && allAdded;
}
return allAdded;
}
bool Cameras::RemoveCamera(const AZStd::shared_ptr<CameraInput>& cameraInput)
{
if (const auto idleCameraIt = AZStd::find(m_idleCameraInputs.begin(), m_idleCameraInputs.end(), cameraInput);
idleCameraIt != m_idleCameraInputs.end())
{
const auto idleIndex = idleCameraIt - m_idleCameraInputs.begin();
using AZStd::swap;
swap(m_idleCameraInputs[idleIndex], m_idleCameraInputs[m_idleCameraInputs.size() - 1]);
m_idleCameraInputs.pop_back();
return true;
}
if (const auto activeCameraIt = AZStd::find(m_activeCameraInputs.begin(), m_activeCameraInputs.end(), cameraInput);
activeCameraIt != m_activeCameraInputs.end())
{
(*activeCameraIt)->Reset();
const auto activeIndex = activeCameraIt - m_idleCameraInputs.begin();
using AZStd::swap;
swap(m_activeCameraInputs[activeIndex], m_activeCameraInputs[m_activeCameraInputs.size() - 1]);
m_activeCameraInputs.pop_back();
return true;
}
return false;
}
bool Cameras::RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
bool allRemoved = true;
for (const auto& cameraInput : cameraInputs)
{
allRemoved = RemoveCamera(cameraInput) && allRemoved;
}
return allRemoved;
}
bool Cameras::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, const float scrollDelta)
@ -645,7 +703,7 @@ namespace AzFramework
m_orbitChannelId = orbitChanneId;
}
OrbitDollyScrollCameraInput::OrbitDollyScrollCameraInput()
OrbitScrollDollyCameraInput::OrbitScrollDollyCameraInput()
{
m_scrollSpeedFn = []() constexpr
{
@ -653,7 +711,7 @@ namespace AzFramework
};
}
bool OrbitDollyScrollCameraInput::HandleEvents(
bool OrbitScrollDollyCameraInput::HandleEvents(
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta)
{
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
@ -691,7 +749,7 @@ namespace AzFramework
return nextCamera;
}
Camera OrbitDollyScrollCameraInput::StepCamera(
Camera OrbitScrollDollyCameraInput::StepCamera(
const Camera& targetCamera,
[[maybe_unused]] const ScreenVector& cursorDelta,
const float scrollDelta,
@ -702,7 +760,7 @@ namespace AzFramework
return nextCamera;
}
OrbitDollyMotionCameraInput::OrbitDollyMotionCameraInput(const InputChannelId& dollyChannelId)
OrbitMotionDollyCameraInput::OrbitMotionDollyCameraInput(const InputChannelId& dollyChannelId)
: m_dollyChannelId(dollyChannelId)
{
m_motionSpeedFn = []() constexpr
@ -711,14 +769,14 @@ namespace AzFramework
};
}
bool OrbitDollyMotionCameraInput::HandleEvents(
bool OrbitMotionDollyCameraInput::HandleEvents(
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta)
{
HandleActivationEvents(event, m_dollyChannelId, cursorDelta, m_clickDetector, *this);
return CameraInputUpdatingAfterMotion(*this);
}
Camera OrbitDollyMotionCameraInput::StepCamera(
Camera OrbitMotionDollyCameraInput::StepCamera(
const Camera& targetCamera,
const ScreenVector& cursorDelta,
[[maybe_unused]] const float scrollDelta,
@ -727,7 +785,7 @@ namespace AzFramework
return OrbitDolly(targetCamera, aznumeric_cast<float>(cursorDelta.m_y) * m_motionSpeedFn());
}
void OrbitDollyMotionCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
void OrbitMotionDollyCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
{
m_dollyChannelId = dollyChannelId;
}

@ -289,7 +289,17 @@ namespace AzFramework
//! Add a camera input (behavior) to run in this set of camera inputs.
//! The camera inputs added here will determine the overall behavior of the camera.
void AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
//! @return Returns if the camera was successfully added (if the camera already exists it is not added and AddCamera returns false).
bool AddCamera(AZStd::shared_ptr<CameraInput> cameraInput);
//! Add a collection of camera inputs (behaviors) to run in this set of camera inputs.
//! @return Returns if all cameras were added successfully.
bool AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs);
//! Remove a camera input (behavior) to stop it running in the set of camera inputs.
//! @return Returns if the camera was removed successfully (if the could not be found RemoveCamera returns false).
bool RemoveCamera(const AZStd::shared_ptr<CameraInput>& cameraInput);
//! Remove a collection of camera inputs (behaviors) to stop them running in the set of camera inputs.
//! @return Returns if all cameras were removed successfully.
bool RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs);
//! Reset the state of all cameras.
void Reset();
//! Remove all cameras that were added.
@ -299,9 +309,10 @@ namespace AzFramework
bool Exclusive() const;
private:
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_activeCameraInputs; //!< Active camera inputs updating the camera (empty initially).
AZStd::vector<AZStd::shared_ptr<CameraInput>>
m_idleCameraInputs; //!< Idle camera inputs not contributing to the update (filled initially).
//! Active camera inputs updating the camera (empty initially).
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_activeCameraInputs;
//! Idle camera inputs not contributing to the update (filled initially).
AZStd::vector<AZStd::shared_ptr<CameraInput>> m_idleCameraInputs;
};
//! Responsible for updating a series of cameras given various inputs.
@ -586,10 +597,10 @@ namespace AzFramework
};
//! A camera input to handle discrete scroll events that can modify the camera offset.
class OrbitDollyScrollCameraInput : public CameraInput
class OrbitScrollDollyCameraInput : public CameraInput
{
public:
OrbitDollyScrollCameraInput();
OrbitScrollDollyCameraInput();
// CameraInput overrides ...
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
@ -599,10 +610,10 @@ namespace AzFramework
};
//! A camera input to handle motion deltas that can modify the camera offset.
class OrbitDollyMotionCameraInput : public CameraInput
class OrbitMotionDollyCameraInput : public CameraInput
{
public:
explicit OrbitDollyMotionCameraInput(const InputChannelId& dollyChannelId);
explicit OrbitMotionDollyCameraInput(const InputChannelId& dollyChannelId);
// CameraInput overrides ...
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;

@ -490,4 +490,40 @@ namespace UnitTest
EXPECT_THAT(m_orbitCamera->Ending(), IsFalse());
EXPECT_THAT(m_orbitCamera->Idle(), IsTrue());
}
TEST_F(CameraInputFixture, NewCameraInputCanBeAddedToCameraSystem)
{
auto firstPersonPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
AzFramework::InputDeviceMouse::Button::Middle, AzFramework::LookPan, AzFramework::TranslatePivotLook);
const bool added =
m_cameraSystem->m_cameras.AddCameras(AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ firstPersonPanCamera });
EXPECT_THAT(added, ::testing::IsTrue());
}
TEST_F(CameraInputFixture, ExistingCameraInputCannotBeAddedToCameraSystem)
{
const bool added =
m_cameraSystem->m_cameras.AddCameras(AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ m_firstPersonRotateCamera });
EXPECT_THAT(added, ::testing::IsFalse());
}
TEST_F(CameraInputFixture, ExistingCameraInputCanBeRemovedFromCameraSystem)
{
const bool removed = m_cameraSystem->m_cameras.RemoveCameras(
AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ m_firstPersonRotateCamera });
EXPECT_THAT(removed, ::testing::IsTrue());
}
TEST_F(CameraInputFixture, NonExistentCameraInputCannotBeRemovedFromCameraSystem)
{
auto firstPersonPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
AzFramework::InputDeviceMouse::Button::Middle, AzFramework::LookPan, AzFramework::TranslatePivotLook);
const bool removed = m_cameraSystem->m_cameras.RemoveCameras(
AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ firstPersonPanCamera });
EXPECT_THAT(removed, ::testing::IsFalse());
}
} // namespace UnitTest

@ -10,6 +10,7 @@
#include <Atom/RPI.Public/ViewportContext.h>
#include <AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Viewport/CameraInput.h>
#include <AzFramework/Viewport/MultiViewportController.h>
@ -120,6 +121,8 @@ namespace AtomToolsFramework
void SetCameraPivotAttached(const AZ::Vector3& pivot) override;
void SetCameraPivotDetached(const AZ::Vector3& pivot) override;
void SetCameraOffset(const AZ::Vector3& offset) override;
bool AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) override;
bool RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) override;
private:
//! Combine the current camera transform with any potential roll from the tracked

@ -9,6 +9,7 @@
#pragma once
#include <AzCore/EBus/EBus.h>
#include <AzCore/std/smart_ptr/shared_ptr.h>
#include <AzFramework/Viewport/ViewportId.h>
namespace AZ
@ -16,6 +17,11 @@ namespace AZ
class Transform;
}
namespace AzFramework
{
class CameraInput;
}
namespace AtomToolsFramework
{
//! Provides an interface to control the modern viewport camera controller from the Editor.
@ -54,6 +60,10 @@ namespace AtomToolsFramework
//! @note The offset value is in the current space of the camera, not world space. Setting
//! a negative Z value will move the camera backwards from the pivot.
virtual void SetCameraOffset(const AZ::Vector3& offset) = 0;
//! Add one or more camera inputs (behaviors) to run for the current camera.
virtual bool AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) = 0;
//! Remove one or more camera inputs (behaviors) to stop them running for the current camera.
virtual bool RemoveCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs) = 0;
protected:
~ModularViewportCameraControllerRequests() = default;

@ -294,6 +294,17 @@ namespace AtomToolsFramework
m_targetCamera.m_offset = offset;
}
bool ModularViewportCameraControllerInstance::AddCameras(const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
return m_cameraSystem.m_cameras.AddCameras(cameraInputs);
}
bool ModularViewportCameraControllerInstance::RemoveCameras(
const AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>& cameraInputs)
{
return m_cameraSystem.m_cameras.RemoveCameras(cameraInputs);
}
bool ModularViewportCameraControllerInstance::IsInterpolating() const
{
return m_cameraMode == CameraMode::Animation;

@ -24,6 +24,8 @@ namespace EMStudio::ViewportUtil
constexpr AZStd::string_view CameraTranslateBoostIdSetting = "/Amazon/Preferences/Editor/Camera/TranslateBoostId";
constexpr AZStd::string_view CameraOrbitIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitId";
constexpr AZStd::string_view CameraDefaultOrbitDistanceSetting = "/Amazon/Preferences/Editor/Camera/DefaultOrbitDistance";
constexpr AZStd::string_view CameraOrbitDollyIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitDollyId";
constexpr AZStd::string_view CameraFreePanIdSetting = "/Amazon/Preferences/Editor/Camera/FreePanId";
AzFramework::TranslateCameraInputChannelIds TranslateCameraInputChannelIds()
{
@ -78,12 +80,21 @@ namespace EMStudio::ViewportUtil
AzFramework::InputChannelId OrbitCameraInputChannelId()
{
return AzFramework::InputChannelId(
GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
}
AzFramework::InputChannelId OrbitLookCameraInputChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
}
}
AzFramework::InputChannelId OrbitDollyCameraInputChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
}
AzFramework::InputChannelId PanCameraInputChannelId()
{
return AzFramework::InputChannelId(GetRegistry(CameraFreePanIdSetting, AZStd::string("mouse_button_middle")).c_str());
}
} // namespace EMStudio::ViewportUtil

@ -5,9 +5,11 @@
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#pragma once
#include <AzCore/Settings/SettingsRegistry.h>
#include <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
#include <AzCore/Settings/SettingsRegistry.h>
namespace EMStudio::ViewportUtil
{
@ -37,4 +39,6 @@ namespace EMStudio::ViewportUtil
AzFramework::InputChannelId RotateCameraInputChannelId();
AzFramework::InputChannelId OrbitCameraInputChannelId();
AzFramework::InputChannelId OrbitLookCameraInputChannelId();
}
AzFramework::InputChannelId OrbitDollyCameraInputChannelId();
AzFramework::InputChannelId PanCameraInputChannelId();
} // namespace EMStudio::ViewportUtil

@ -6,17 +6,17 @@
*
*/
#include <AzCore/Math/MatrixUtils.h>
#include <AzFramework/Viewport/ViewportControllerList.h>
#include <AzFramework/Viewport/CameraInput.h>
#include <Atom/RPI.Public/ViewportContext.h>
#include <Atom/RPI.Public/View.h>
#include <Atom/RPI.Public/ViewportContext.h>
#include <AtomToolsFramework/Viewport/ModularViewportCameraController.h>
#include <AzCore/Math/MatrixUtils.h>
#include <AzFramework/Viewport/CameraInput.h>
#include <AzFramework/Viewport/ViewportControllerList.h>
#include <EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/EMStudioManager.h>
#include <EMStudio/AnimViewportWidget.h>
#include <EMStudio/AnimViewportRenderer.h>
#include <EMStudio/AnimViewportSettings.h>
#include <EMStudio/AnimViewportWidget.h>
#include <EMStudio/AtomRenderPlugin.h>
namespace EMStudio
@ -64,31 +64,44 @@ namespace EMStudio
void AnimViewportWidget::SetupCameras()
{
m_rotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(EMStudio::ViewportUtil::RotateCameraInputChannelId());
const auto translateCameraInputChannelIds = EMStudio::ViewportUtil::TranslateCameraInputChannelIds();
m_translateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
m_lookRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(EMStudio::ViewportUtil::RotateCameraInputChannelId());
m_lookTranslateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivotLook);
m_translateCamera.get()->m_translateSpeedFn = []
m_lookTranslateCamera->m_translateSpeedFn = []
{
return 3.0f;
};
m_lookScrollCamera = AZStd::make_shared<AzFramework::LookScrollTranslationCameraInput>();
m_lookScrollTranslationCamera = AZStd::make_shared<AzFramework::LookScrollTranslationCameraInput>();
m_lookPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
EMStudio::ViewportUtil::PanCameraInputChannelId(), AzFramework::LookPan, AzFramework::TranslatePivotLook);
m_orbitCamera = AZStd::make_shared<AzFramework::OrbitCameraInput>(EMStudio::ViewportUtil::OrbitCameraInputChannelId());
m_orbitCamera->SetPivotFn(
[this](const AZ::Vector3& position, const AZ::Vector3& direction)
[this]([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
{
if (m_orbitCamera->Beginning())
{
m_defaultOrbitPoint = position + direction * EMStudio::ViewportUtil::CameraDefaultOrbitDistance();
}
return m_defaultOrbitPoint;
return m_renderer->GetCharacterCenter();
});
m_orbitTranslateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivotLook);
m_orbitRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(EMStudio::ViewportUtil::OrbitLookCameraInputChannelId());
m_orbitDollyScrollCamera = AZStd::make_shared<AzFramework::OrbitDollyScrollCameraInput>();
m_orbitScrollDollyCamera = AZStd::make_shared<AzFramework::OrbitScrollDollyCameraInput>();
m_orbitPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
EMStudio::ViewportUtil::PanCameraInputChannelId(), AzFramework::LookPan, AzFramework::TranslateOffsetOrbit);
m_orbitMotionDollyCamera =
AZStd::make_shared<AzFramework::OrbitMotionDollyCameraInput>(EMStudio::ViewportUtil::OrbitDollyCameraInputChannelId());
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitRotateCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitDollyScrollCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitScrollDollyCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitTranslateCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitMotionDollyCamera);
m_orbitCamera->m_orbitCameras.AddCamera(m_orbitPanCamera);
m_followRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(EMStudio::ViewportUtil::OrbitLookCameraInputChannelId());
m_followScrollDollyCamera = AZStd::make_shared<AzFramework::OrbitScrollDollyCameraInput>();
m_followScrollMotionCamera =
AZStd::make_shared<AzFramework::OrbitMotionDollyCameraInput>(EMStudio::ViewportUtil::OrbitDollyCameraInputChannelId());
}
void AnimViewportWidget::SetupCameraController()
@ -134,11 +147,13 @@ namespace EMStudio
controller->SetCameraListBuilderCallback(
[this](AzFramework::Cameras& cameras)
{
cameras.AddCamera(m_rotateCamera);
cameras.AddCamera(m_translateCamera);
cameras.AddCamera(m_lookScrollCamera);
cameras.AddCamera(m_lookRotateCamera);
cameras.AddCamera(m_lookTranslateCamera);
cameras.AddCamera(m_lookScrollTranslationCamera);
cameras.AddCamera(m_lookPanCamera);
cameras.AddCamera(m_orbitCamera);
});
GetControllerList()->Add(controller);
}
@ -183,14 +198,34 @@ namespace EMStudio
void AnimViewportWidget::UpdateCameraFollowUp(bool followUp)
{
const auto lookAndOrbitCameras =
AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ m_lookRotateCamera, m_lookTranslateCamera,
m_lookScrollTranslationCamera, m_lookPanCamera, m_orbitCamera };
const auto followCameras =
AZStd::vector<AZStd::shared_ptr<AzFramework::CameraInput>>{ m_followRotateCamera, m_followScrollDollyCamera,
m_followScrollMotionCamera };
if (followUp)
{
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
GetViewportId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::RemoveCameras,
lookAndOrbitCameras);
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
GetViewportId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::AddCameras, followCameras);
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
GetViewportId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::SetCameraOffset,
AZ::Vector3::CreateAxisY(-CameraDistance));
}
else
{
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
GetViewportId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::RemoveCameras, followCameras);
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
GetViewportId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::AddCameras, lookAndOrbitCameras);
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
GetViewportId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::SetCameraOffset,
AZ::Vector3::CreateZero());
@ -219,8 +254,9 @@ namespace EMStudio
const RenderOptions* renderOptions = m_plugin->GetRenderOptions();
AZ::Matrix4x4 viewToClipMatrix;
AZ::MakePerspectiveFovMatrixRH(viewToClipMatrix, AZ::DegToRad(renderOptions->GetFOV()), aspectRatio,
renderOptions->GetNearClipPlaneDistance(), renderOptions->GetFarClipPlaneDistance(), true);
AZ::MakePerspectiveFovMatrixRH(
viewToClipMatrix, AZ::DegToRad(renderOptions->GetFOV()), aspectRatio, renderOptions->GetNearClipPlaneDistance(),
renderOptions->GetFarClipPlaneDistance(), true);
viewportContext->GetDefaultView()->SetViewToClipMatrix(viewToClipMatrix);
}

@ -55,12 +55,22 @@ namespace EMStudio
AtomRenderPlugin* m_plugin;
AZStd::unique_ptr<AnimViewportRenderer> m_renderer;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_rotateCamera;
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_translateCamera;
AZStd::shared_ptr<AzFramework::LookScrollTranslationCameraInput> m_lookScrollCamera;
AZStd::shared_ptr<AzFramework::OrbitDollyScrollCameraInput> m_orbitDollyScrollCamera;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_lookRotateCamera;
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_lookTranslateCamera;
AZStd::shared_ptr<AzFramework::LookScrollTranslationCameraInput> m_lookScrollTranslationCamera;
AZStd::shared_ptr<AzFramework::PanCameraInput> m_lookPanCamera;
AZStd::shared_ptr<AzFramework::OrbitCameraInput> m_orbitCamera;
AZStd::shared_ptr<AzFramework::OrbitScrollDollyCameraInput> m_orbitScrollDollyCamera;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_orbitRotateCamera;
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_orbitTranslateCamera;
AZStd::shared_ptr<AzFramework::OrbitMotionDollyCameraInput> m_orbitMotionDollyCamera;
AZStd::shared_ptr<AzFramework::PanCameraInput> m_orbitPanCamera;
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_followRotateCamera;
AZStd::shared_ptr<AzFramework::OrbitScrollDollyCameraInput> m_followScrollDollyCamera;
AZStd::shared_ptr<AzFramework::OrbitMotionDollyCameraInput> m_followScrollMotionCamera;
AZ::Vector3 m_defaultOrbitPoint = AZ::Vector3::CreateZero();
};
}

Loading…
Cancel
Save