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>
This commit is contained in:
committed by
GitHub
parent
d31200ee5c
commit
6ffc2620e4
@@ -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
|
||||
|
||||
+3
@@ -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
|
||||
|
||||
+10
@@ -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;
|
||||
|
||||
+11
@@ -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();
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user