Merge branch 'development' into Atom/santorac/RemixableMaterialTypes
This commit is contained in:
@@ -7,7 +7,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
|
||||
#include <AzToolsFramework/API/ToolsApplicationAPI.h>
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/UserSettings/UserSettings.h>
|
||||
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
|
||||
#include <QWidget>
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#include <AzToolsFramework/UI/SearchWidget/SearchCriteriaWidget.hxx>
|
||||
#include <AzToolsFramework/Editor/EditorSettingsAPIBus.h>
|
||||
|
||||
//AzCore
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
// Editor
|
||||
#include "Clipboard.h"
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
#if !defined(Q_MOC_RUN)
|
||||
#include <AzToolsFramework/UI/PropertyEditor/PropertyEditorAPI.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include "Include/EditorCoreAPI.h"
|
||||
#include "ReflectedPropertyItem.h"
|
||||
|
||||
@@ -10,10 +10,10 @@
|
||||
#define CRYINCLUDE_EDITOR_UTILS_REFLECTEDVAR_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include "Util/VariablePropertyType.h"
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Vector4.h>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzFramework/Render/IntersectorInterface.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
#include <AzToolsFramework/ViewportSelection/EditorTransformComponentSelectionRequestBus.h>
|
||||
#include <EditorViewportSettings.h>
|
||||
|
||||
namespace SandboxEditor
|
||||
@@ -94,7 +95,7 @@ namespace SandboxEditor
|
||||
cameras.AddCamera(m_firstPersonPanCamera);
|
||||
cameras.AddCamera(m_firstPersonTranslateCamera);
|
||||
cameras.AddCamera(m_firstPersonScrollCamera);
|
||||
cameras.AddCamera(m_orbitCamera);
|
||||
cameras.AddCamera(m_pivotCamera);
|
||||
});
|
||||
|
||||
return controller;
|
||||
@@ -131,8 +132,8 @@ namespace SandboxEditor
|
||||
m_firstPersonRotateCamera->SetActivationBeganFn(hideCursor);
|
||||
m_firstPersonRotateCamera->SetActivationEndedFn(showCursor);
|
||||
|
||||
m_firstPersonPanCamera =
|
||||
AZStd::make_shared<AzFramework::PanCameraInput>(SandboxEditor::CameraFreePanChannelId(), AzFramework::LookPan);
|
||||
m_firstPersonPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
|
||||
SandboxEditor::CameraFreePanChannelId(), AzFramework::LookPan, AzFramework::TranslatePivot);
|
||||
|
||||
m_firstPersonPanCamera->m_panSpeedFn = []
|
||||
{
|
||||
@@ -151,8 +152,8 @@ namespace SandboxEditor
|
||||
|
||||
const auto translateCameraInputChannelIds = BuildTranslateCameraInputChannelIds();
|
||||
|
||||
m_firstPersonTranslateCamera =
|
||||
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::LookTranslation, translateCameraInputChannelIds);
|
||||
m_firstPersonTranslateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
|
||||
translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivot);
|
||||
|
||||
m_firstPersonTranslateCamera->m_translateSpeedFn = []
|
||||
{
|
||||
@@ -171,120 +172,97 @@ namespace SandboxEditor
|
||||
return SandboxEditor::CameraScrollSpeed();
|
||||
};
|
||||
|
||||
m_orbitCamera = AZStd::make_shared<AzFramework::OrbitCameraInput>(SandboxEditor::CameraOrbitChannelId());
|
||||
m_pivotCamera = AZStd::make_shared<AzFramework::PivotCameraInput>(SandboxEditor::CameraPivotChannelId());
|
||||
|
||||
m_orbitCamera->SetLookAtFn(
|
||||
[viewportId = m_viewportId](const AZ::Vector3& position, const AZ::Vector3& direction) -> AZStd::optional<AZ::Vector3>
|
||||
m_pivotCamera->SetPivotFn(
|
||||
[]([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
|
||||
{
|
||||
AZStd::optional<AZ::Vector3> lookAtAfterInterpolation;
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::EventResult(
|
||||
lookAtAfterInterpolation, viewportId,
|
||||
&AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::LookAtAfterInterpolation);
|
||||
// use the manipulator transform as the pivot point
|
||||
AZStd::optional<AZ::Transform> entityPivot;
|
||||
AzToolsFramework::EditorTransformComponentSelectionRequestBus::EventResult(
|
||||
entityPivot, AzToolsFramework::GetEntityContextId(),
|
||||
&AzToolsFramework::EditorTransformComponentSelectionRequestBus::Events::GetManipulatorTransform);
|
||||
|
||||
// initially attempt to use the last set look at point after an interpolation has finished
|
||||
if (lookAtAfterInterpolation.has_value())
|
||||
{
|
||||
return *lookAtAfterInterpolation;
|
||||
}
|
||||
|
||||
const float RayDistance = 1000.0f;
|
||||
AzFramework::RenderGeometry::RayRequest ray;
|
||||
ray.m_startWorldPosition = position;
|
||||
ray.m_endWorldPosition = position + direction * RayDistance;
|
||||
ray.m_onlyVisible = true;
|
||||
|
||||
AzFramework::RenderGeometry::RayResult renderGeometryIntersectionResult;
|
||||
AzFramework::RenderGeometry::IntersectorBus::EventResult(
|
||||
renderGeometryIntersectionResult, AzToolsFramework::GetEntityContextId(),
|
||||
&AzFramework::RenderGeometry::IntersectorBus::Events::RayIntersect, ray);
|
||||
|
||||
// attempt a ray intersection with any visible mesh and return the intersection position if successful
|
||||
if (renderGeometryIntersectionResult)
|
||||
{
|
||||
return renderGeometryIntersectionResult.m_worldPosition;
|
||||
}
|
||||
|
||||
// if there is no selection or no intersection, fallback to default camera orbit behavior (ground plane
|
||||
// intersection)
|
||||
return {};
|
||||
// otherwise just use the identity
|
||||
return entityPivot.value_or(AZ::Transform::CreateIdentity()).GetTranslation();
|
||||
});
|
||||
|
||||
m_orbitRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(SandboxEditor::CameraOrbitLookChannelId());
|
||||
m_pivotRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(SandboxEditor::CameraPivotLookChannelId());
|
||||
|
||||
m_orbitRotateCamera->m_rotateSpeedFn = []
|
||||
m_pivotRotateCamera->m_rotateSpeedFn = []
|
||||
{
|
||||
return SandboxEditor::CameraRotateSpeed();
|
||||
};
|
||||
|
||||
m_orbitRotateCamera->m_invertYawFn = []
|
||||
m_pivotRotateCamera->m_invertYawFn = []
|
||||
{
|
||||
return SandboxEditor::CameraOrbitYawRotationInverted();
|
||||
return SandboxEditor::CameraPivotYawRotationInverted();
|
||||
};
|
||||
|
||||
m_orbitTranslateCamera =
|
||||
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::OrbitTranslation, translateCameraInputChannelIds);
|
||||
m_pivotTranslateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
|
||||
translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslateOffset);
|
||||
|
||||
m_orbitTranslateCamera->m_translateSpeedFn = []
|
||||
m_pivotTranslateCamera->m_translateSpeedFn = []
|
||||
{
|
||||
return SandboxEditor::CameraTranslateSpeed();
|
||||
};
|
||||
|
||||
m_orbitTranslateCamera->m_boostMultiplierFn = []
|
||||
m_pivotTranslateCamera->m_boostMultiplierFn = []
|
||||
{
|
||||
return SandboxEditor::CameraBoostMultiplier();
|
||||
};
|
||||
|
||||
m_orbitDollyScrollCamera = AZStd::make_shared<AzFramework::OrbitDollyScrollCameraInput>();
|
||||
m_pivotDollyScrollCamera = AZStd::make_shared<AzFramework::PivotDollyScrollCameraInput>();
|
||||
|
||||
m_orbitDollyScrollCamera->m_scrollSpeedFn = []
|
||||
m_pivotDollyScrollCamera->m_scrollSpeedFn = []
|
||||
{
|
||||
return SandboxEditor::CameraScrollSpeed();
|
||||
};
|
||||
|
||||
m_orbitDollyMoveCamera =
|
||||
AZStd::make_shared<AzFramework::OrbitDollyCursorMoveCameraInput>(SandboxEditor::CameraOrbitDollyChannelId());
|
||||
m_pivotDollyMoveCamera = AZStd::make_shared<AzFramework::PivotDollyMotionCameraInput>(SandboxEditor::CameraPivotDollyChannelId());
|
||||
|
||||
m_orbitDollyMoveCamera->m_cursorSpeedFn = []
|
||||
m_pivotDollyMoveCamera->m_motionSpeedFn = []
|
||||
{
|
||||
return SandboxEditor::CameraDollyMotionSpeed();
|
||||
};
|
||||
|
||||
m_orbitPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(SandboxEditor::CameraOrbitPanChannelId(), AzFramework::OrbitPan);
|
||||
m_pivotPanCamera = AZStd::make_shared<AzFramework::PanCameraInput>(
|
||||
SandboxEditor::CameraPivotPanChannelId(), AzFramework::LookPan, AzFramework::TranslateOffset);
|
||||
|
||||
m_orbitPanCamera->m_panSpeedFn = []
|
||||
m_pivotPanCamera->m_panSpeedFn = []
|
||||
{
|
||||
return SandboxEditor::CameraPanSpeed();
|
||||
};
|
||||
|
||||
m_orbitPanCamera->m_invertPanXFn = []
|
||||
m_pivotPanCamera->m_invertPanXFn = []
|
||||
{
|
||||
return SandboxEditor::CameraPanInvertedX();
|
||||
};
|
||||
|
||||
m_orbitPanCamera->m_invertPanYFn = []
|
||||
m_pivotPanCamera->m_invertPanYFn = []
|
||||
{
|
||||
return SandboxEditor::CameraPanInvertedY();
|
||||
};
|
||||
|
||||
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_orbitPanCamera);
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(m_pivotRotateCamera);
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(m_pivotTranslateCamera);
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(m_pivotDollyScrollCamera);
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(m_pivotDollyMoveCamera);
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(m_pivotPanCamera);
|
||||
}
|
||||
|
||||
void EditorModularViewportCameraComposer::OnEditorModularViewportCameraComposerSettingsChanged()
|
||||
{
|
||||
const auto translateCameraInputChannelIds = BuildTranslateCameraInputChannelIds();
|
||||
m_firstPersonTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
|
||||
m_orbitTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
|
||||
|
||||
m_firstPersonPanCamera->SetPanInputChannelId(SandboxEditor::CameraFreePanChannelId());
|
||||
m_orbitPanCamera->SetPanInputChannelId(SandboxEditor::CameraOrbitPanChannelId());
|
||||
m_firstPersonRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraFreeLookChannelId());
|
||||
m_orbitRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraOrbitLookChannelId());
|
||||
m_orbitCamera->SetOrbitInputChannelId(SandboxEditor::CameraOrbitChannelId());
|
||||
m_orbitDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraOrbitDollyChannelId());
|
||||
|
||||
m_pivotCamera->SetPivotInputChannelId(SandboxEditor::CameraPivotChannelId());
|
||||
m_pivotTranslateCamera->SetTranslateCameraInputChannelIds(translateCameraInputChannelIds);
|
||||
m_pivotPanCamera->SetPanInputChannelId(SandboxEditor::CameraPivotPanChannelId());
|
||||
m_pivotRotateCamera->SetRotateInputChannelId(SandboxEditor::CameraPivotLookChannelId());
|
||||
m_pivotDollyMoveCamera->SetDollyInputChannelId(SandboxEditor::CameraPivotDollyChannelId());
|
||||
}
|
||||
|
||||
void EditorModularViewportCameraComposer::OnViewportViewEntityChanged(const AZ::EntityId& viewEntityId)
|
||||
@@ -295,8 +273,7 @@ namespace SandboxEditor
|
||||
AZ::TransformBus::EventResult(worldFromLocal, viewEntityId, &AZ::TransformBus::Events::GetWorldTM);
|
||||
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
m_viewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::SetReferenceFrame,
|
||||
worldFromLocal);
|
||||
m_viewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::SetReferenceFrame, worldFromLocal);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -42,12 +42,12 @@ namespace SandboxEditor
|
||||
AZStd::shared_ptr<AzFramework::PanCameraInput> m_firstPersonPanCamera;
|
||||
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_firstPersonTranslateCamera;
|
||||
AZStd::shared_ptr<AzFramework::ScrollTranslationCameraInput> m_firstPersonScrollCamera;
|
||||
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::OrbitDollyCursorMoveCameraInput> m_orbitDollyMoveCamera;
|
||||
AZStd::shared_ptr<AzFramework::PanCameraInput> m_orbitPanCamera;
|
||||
AZStd::shared_ptr<AzFramework::PivotCameraInput> m_pivotCamera;
|
||||
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_pivotRotateCamera;
|
||||
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_pivotTranslateCamera;
|
||||
AZStd::shared_ptr<AzFramework::PivotDollyScrollCameraInput> m_pivotDollyScrollCamera;
|
||||
AZStd::shared_ptr<AzFramework::PivotDollyMotionCameraInput> m_pivotDollyMoveCamera;
|
||||
AZStd::shared_ptr<AzFramework::PanCameraInput> m_pivotPanCamera;
|
||||
|
||||
AzFramework::ViewportId m_viewportId;
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ static AZStd::vector<AZStd::string> GetEditorInputNames()
|
||||
void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serialize)
|
||||
{
|
||||
serialize.Class<CameraMovementSettings>()
|
||||
->Version(2)
|
||||
->Version(3)
|
||||
->Field("TranslateSpeed", &CameraMovementSettings::m_translateSpeed)
|
||||
->Field("RotateSpeed", &CameraMovementSettings::m_rotateSpeed)
|
||||
->Field("BoostMultiplier", &CameraMovementSettings::m_boostMultiplier)
|
||||
@@ -73,12 +73,12 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
|
||||
->Field("TranslateSmoothing", &CameraMovementSettings::m_translateSmoothing)
|
||||
->Field("TranslateSmoothness", &CameraMovementSettings::m_translateSmoothness)
|
||||
->Field("CaptureCursorLook", &CameraMovementSettings::m_captureCursorLook)
|
||||
->Field("OrbitYawRotationInverted", &CameraMovementSettings::m_orbitYawRotationInverted)
|
||||
->Field("PivotYawRotationInverted", &CameraMovementSettings::m_pivotYawRotationInverted)
|
||||
->Field("PanInvertedX", &CameraMovementSettings::m_panInvertedX)
|
||||
->Field("PanInvertedY", &CameraMovementSettings::m_panInvertedY);
|
||||
|
||||
serialize.Class<CameraInputSettings>()
|
||||
->Version(1)
|
||||
->Version(2)
|
||||
->Field("TranslateForward", &CameraInputSettings::m_translateForwardChannelId)
|
||||
->Field("TranslateBackward", &CameraInputSettings::m_translateBackwardChannelId)
|
||||
->Field("TranslateLeft", &CameraInputSettings::m_translateLeftChannelId)
|
||||
@@ -86,12 +86,12 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
|
||||
->Field("TranslateUp", &CameraInputSettings::m_translateUpChannelId)
|
||||
->Field("TranslateDown", &CameraInputSettings::m_translateDownChannelId)
|
||||
->Field("Boost", &CameraInputSettings::m_boostChannelId)
|
||||
->Field("Orbit", &CameraInputSettings::m_orbitChannelId)
|
||||
->Field("Pivot", &CameraInputSettings::m_pivotChannelId)
|
||||
->Field("FreeLook", &CameraInputSettings::m_freeLookChannelId)
|
||||
->Field("FreePan", &CameraInputSettings::m_freePanChannelId)
|
||||
->Field("OrbitLook", &CameraInputSettings::m_orbitLookChannelId)
|
||||
->Field("OrbitDolly", &CameraInputSettings::m_orbitDollyChannelId)
|
||||
->Field("OrbitPan", &CameraInputSettings::m_orbitPanChannelId);
|
||||
->Field("PivotLook", &CameraInputSettings::m_pivotLookChannelId)
|
||||
->Field("PivotDolly", &CameraInputSettings::m_pivotDollyChannelId)
|
||||
->Field("PivotPan", &CameraInputSettings::m_pivotPanChannelId);
|
||||
|
||||
serialize.Class<CEditorPreferencesPage_ViewportCamera>()
|
||||
->Version(1)
|
||||
@@ -143,8 +143,8 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
|
||||
->Attribute(AZ::Edit::Attributes::Min, minValue)
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, &CameraMovementSettings::TranslateSmoothingVisibility)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_orbitYawRotationInverted, "Camera Orbit Yaw Inverted",
|
||||
"Inverted yaw rotation while orbiting")
|
||||
AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_pivotYawRotationInverted, "Camera Pivot Yaw Inverted",
|
||||
"Inverted yaw rotation while pivoting")
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::CheckBox, &CameraMovementSettings::m_panInvertedX, "Invert Pan X",
|
||||
"Invert direction of pan in local X axis")
|
||||
@@ -185,8 +185,8 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
|
||||
"Key/button to move the camera more quickly")
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitChannelId, "Orbit",
|
||||
"Key/button to begin the camera orbit behavior")
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotChannelId, "Pivot",
|
||||
"Key/button to begin the camera pivot behavior")
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_freeLookChannelId, "Free Look",
|
||||
@@ -196,16 +196,16 @@ void CEditorPreferencesPage_ViewportCamera::Reflect(AZ::SerializeContext& serial
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_freePanChannelId, "Free Pan", "Key/button to begin camera free pan")
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitLookChannelId, "Orbit Look",
|
||||
"Key/button to begin camera orbit look")
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotLookChannelId, "Pivot Look",
|
||||
"Key/button to begin camera pivot look")
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitDollyChannelId, "Orbit Dolly",
|
||||
"Key/button to begin camera orbit dolly")
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotDollyChannelId, "Pivot Dolly",
|
||||
"Key/button to begin camera pivot dolly")
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames)
|
||||
->DataElement(
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_orbitPanChannelId, "Orbit Pan",
|
||||
"Key/button to begin camera orbit pan")
|
||||
AZ::Edit::UIHandlers::ComboBox, &CameraInputSettings::m_pivotPanChannelId, "Pivot Pan",
|
||||
"Key/button to begin camera pivot pan")
|
||||
->Attribute(AZ::Edit::Attributes::StringList, &GetEditorInputNames);
|
||||
|
||||
editContext->Class<CEditorPreferencesPage_ViewportCamera>("Viewport Preferences", "Viewport Preferences")
|
||||
@@ -264,7 +264,7 @@ void CEditorPreferencesPage_ViewportCamera::OnApply()
|
||||
SandboxEditor::SetCameraTranslateSmoothness(m_cameraMovementSettings.m_translateSmoothness);
|
||||
SandboxEditor::SetCameraTranslateSmoothingEnabled(m_cameraMovementSettings.m_translateSmoothing);
|
||||
SandboxEditor::SetCameraCaptureCursorForLook(m_cameraMovementSettings.m_captureCursorLook);
|
||||
SandboxEditor::SetCameraOrbitYawRotationInverted(m_cameraMovementSettings.m_orbitYawRotationInverted);
|
||||
SandboxEditor::SetCameraPivotYawRotationInverted(m_cameraMovementSettings.m_pivotYawRotationInverted);
|
||||
SandboxEditor::SetCameraPanInvertedX(m_cameraMovementSettings.m_panInvertedX);
|
||||
SandboxEditor::SetCameraPanInvertedY(m_cameraMovementSettings.m_panInvertedY);
|
||||
|
||||
@@ -275,12 +275,12 @@ void CEditorPreferencesPage_ViewportCamera::OnApply()
|
||||
SandboxEditor::SetCameraTranslateUpChannelId(m_cameraInputSettings.m_translateUpChannelId);
|
||||
SandboxEditor::SetCameraTranslateDownChannelId(m_cameraInputSettings.m_translateDownChannelId);
|
||||
SandboxEditor::SetCameraTranslateBoostChannelId(m_cameraInputSettings.m_boostChannelId);
|
||||
SandboxEditor::SetCameraOrbitChannelId(m_cameraInputSettings.m_orbitChannelId);
|
||||
SandboxEditor::SetCameraPivotChannelId(m_cameraInputSettings.m_pivotChannelId);
|
||||
SandboxEditor::SetCameraFreeLookChannelId(m_cameraInputSettings.m_freeLookChannelId);
|
||||
SandboxEditor::SetCameraFreePanChannelId(m_cameraInputSettings.m_freePanChannelId);
|
||||
SandboxEditor::SetCameraOrbitLookChannelId(m_cameraInputSettings.m_orbitLookChannelId);
|
||||
SandboxEditor::SetCameraOrbitDollyChannelId(m_cameraInputSettings.m_orbitDollyChannelId);
|
||||
SandboxEditor::SetCameraOrbitPanChannelId(m_cameraInputSettings.m_orbitPanChannelId);
|
||||
SandboxEditor::SetCameraPivotLookChannelId(m_cameraInputSettings.m_pivotLookChannelId);
|
||||
SandboxEditor::SetCameraPivotDollyChannelId(m_cameraInputSettings.m_pivotDollyChannelId);
|
||||
SandboxEditor::SetCameraPivotPanChannelId(m_cameraInputSettings.m_pivotPanChannelId);
|
||||
|
||||
SandboxEditor::EditorModularViewportCameraComposerNotificationBus::Broadcast(
|
||||
&SandboxEditor::EditorModularViewportCameraComposerNotificationBus::Events::OnEditorModularViewportCameraComposerSettingsChanged);
|
||||
@@ -299,7 +299,7 @@ void CEditorPreferencesPage_ViewportCamera::InitializeSettings()
|
||||
m_cameraMovementSettings.m_translateSmoothness = SandboxEditor::CameraTranslateSmoothness();
|
||||
m_cameraMovementSettings.m_translateSmoothing = SandboxEditor::CameraTranslateSmoothingEnabled();
|
||||
m_cameraMovementSettings.m_captureCursorLook = SandboxEditor::CameraCaptureCursorForLook();
|
||||
m_cameraMovementSettings.m_orbitYawRotationInverted = SandboxEditor::CameraOrbitYawRotationInverted();
|
||||
m_cameraMovementSettings.m_pivotYawRotationInverted = SandboxEditor::CameraPivotYawRotationInverted();
|
||||
m_cameraMovementSettings.m_panInvertedX = SandboxEditor::CameraPanInvertedX();
|
||||
m_cameraMovementSettings.m_panInvertedY = SandboxEditor::CameraPanInvertedY();
|
||||
|
||||
@@ -310,10 +310,10 @@ void CEditorPreferencesPage_ViewportCamera::InitializeSettings()
|
||||
m_cameraInputSettings.m_translateUpChannelId = SandboxEditor::CameraTranslateUpChannelId().GetName();
|
||||
m_cameraInputSettings.m_translateDownChannelId = SandboxEditor::CameraTranslateDownChannelId().GetName();
|
||||
m_cameraInputSettings.m_boostChannelId = SandboxEditor::CameraTranslateBoostChannelId().GetName();
|
||||
m_cameraInputSettings.m_orbitChannelId = SandboxEditor::CameraOrbitChannelId().GetName();
|
||||
m_cameraInputSettings.m_pivotChannelId = SandboxEditor::CameraPivotChannelId().GetName();
|
||||
m_cameraInputSettings.m_freeLookChannelId = SandboxEditor::CameraFreeLookChannelId().GetName();
|
||||
m_cameraInputSettings.m_freePanChannelId = SandboxEditor::CameraFreePanChannelId().GetName();
|
||||
m_cameraInputSettings.m_orbitLookChannelId = SandboxEditor::CameraOrbitLookChannelId().GetName();
|
||||
m_cameraInputSettings.m_orbitDollyChannelId = SandboxEditor::CameraOrbitDollyChannelId().GetName();
|
||||
m_cameraInputSettings.m_orbitPanChannelId = SandboxEditor::CameraOrbitPanChannelId().GetName();
|
||||
m_cameraInputSettings.m_pivotLookChannelId = SandboxEditor::CameraPivotLookChannelId().GetName();
|
||||
m_cameraInputSettings.m_pivotDollyChannelId = SandboxEditor::CameraPivotDollyChannelId().GetName();
|
||||
m_cameraInputSettings.m_pivotPanChannelId = SandboxEditor::CameraPivotPanChannelId().GetName();
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ private:
|
||||
float m_translateSmoothness;
|
||||
bool m_translateSmoothing;
|
||||
bool m_captureCursorLook;
|
||||
bool m_orbitYawRotationInverted;
|
||||
bool m_pivotYawRotationInverted;
|
||||
bool m_panInvertedX;
|
||||
bool m_panInvertedY;
|
||||
|
||||
@@ -80,12 +80,12 @@ private:
|
||||
AZStd::string m_translateUpChannelId;
|
||||
AZStd::string m_translateDownChannelId;
|
||||
AZStd::string m_boostChannelId;
|
||||
AZStd::string m_orbitChannelId;
|
||||
AZStd::string m_pivotChannelId;
|
||||
AZStd::string m_freeLookChannelId;
|
||||
AZStd::string m_freePanChannelId;
|
||||
AZStd::string m_orbitLookChannelId;
|
||||
AZStd::string m_orbitDollyChannelId;
|
||||
AZStd::string m_orbitPanChannelId;
|
||||
AZStd::string m_pivotLookChannelId;
|
||||
AZStd::string m_pivotDollyChannelId;
|
||||
AZStd::string m_pivotPanChannelId;
|
||||
};
|
||||
|
||||
CameraMovementSettings m_cameraMovementSettings;
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
|
||||
#include "EditorPreferencesTreeWidgetItem.h"
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzToolsFramework/UI/PropertyEditor/ReflectedPropertyEditor.hxx>
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace SandboxEditor
|
||||
{
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
viewportContext->GetId(), &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(CameraRotation(pitch, yaw), position), 0.0f);
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(CameraRotation(pitch, yaw), position));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace SandboxEditor
|
||||
constexpr AZStd::string_view CameraRotateSpeedSetting = "/Amazon/Preferences/Editor/Camera/RotateSpeed";
|
||||
constexpr AZStd::string_view CameraScrollSpeedSetting = "/Amazon/Preferences/Editor/Camera/DollyScrollSpeed";
|
||||
constexpr AZStd::string_view CameraDollyMotionSpeedSetting = "/Amazon/Preferences/Editor/Camera/DollyMotionSpeed";
|
||||
constexpr AZStd::string_view CameraOrbitYawRotationInvertedSetting = "/Amazon/Preferences/Editor/Camera/YawRotationInverted";
|
||||
constexpr AZStd::string_view CameraPivotYawRotationInvertedSetting = "/Amazon/Preferences/Editor/Camera/YawRotationInverted";
|
||||
constexpr AZStd::string_view CameraPanInvertedXSetting = "/Amazon/Preferences/Editor/Camera/PanInvertedX";
|
||||
constexpr AZStd::string_view CameraPanInvertedYSetting = "/Amazon/Preferences/Editor/Camera/PanInvertedY";
|
||||
constexpr AZStd::string_view CameraPanSpeedSetting = "/Amazon/Preferences/Editor/Camera/PanSpeed";
|
||||
@@ -44,12 +44,12 @@ namespace SandboxEditor
|
||||
constexpr AZStd::string_view CameraTranslateUpIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpId";
|
||||
constexpr AZStd::string_view CameraTranslateDownIdSetting = "/Amazon/Preferences/Editor/Camera/CameraTranslateUpDownId";
|
||||
constexpr AZStd::string_view CameraTranslateBoostIdSetting = "/Amazon/Preferences/Editor/Camera/TranslateBoostId";
|
||||
constexpr AZStd::string_view CameraOrbitIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitId";
|
||||
constexpr AZStd::string_view CameraPivotIdSetting = "/Amazon/Preferences/Editor/Camera/PivotId";
|
||||
constexpr AZStd::string_view CameraFreeLookIdSetting = "/Amazon/Preferences/Editor/Camera/FreeLookId";
|
||||
constexpr AZStd::string_view CameraFreePanIdSetting = "/Amazon/Preferences/Editor/Camera/FreePanId";
|
||||
constexpr AZStd::string_view CameraOrbitLookIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitLookId";
|
||||
constexpr AZStd::string_view CameraOrbitDollyIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitDollyId";
|
||||
constexpr AZStd::string_view CameraOrbitPanIdSetting = "/Amazon/Preferences/Editor/Camera/OrbitPanId";
|
||||
constexpr AZStd::string_view CameraPivotLookIdSetting = "/Amazon/Preferences/Editor/Camera/PivotLookId";
|
||||
constexpr AZStd::string_view CameraPivotDollyIdSetting = "/Amazon/Preferences/Editor/Camera/PivotDollyId";
|
||||
constexpr AZStd::string_view CameraPivotPanIdSetting = "/Amazon/Preferences/Editor/Camera/PivotPanId";
|
||||
|
||||
template<typename T>
|
||||
void SetRegistry(const AZStd::string_view setting, T&& value)
|
||||
@@ -239,14 +239,14 @@ namespace SandboxEditor
|
||||
SetRegistry(CameraDollyMotionSpeedSetting, speed);
|
||||
}
|
||||
|
||||
bool CameraOrbitYawRotationInverted()
|
||||
bool CameraPivotYawRotationInverted()
|
||||
{
|
||||
return GetRegistry(CameraOrbitYawRotationInvertedSetting, false);
|
||||
return GetRegistry(CameraPivotYawRotationInvertedSetting, false);
|
||||
}
|
||||
|
||||
void SetCameraOrbitYawRotationInverted(const bool inverted)
|
||||
void SetCameraPivotYawRotationInverted(const bool inverted)
|
||||
{
|
||||
SetRegistry(CameraOrbitYawRotationInvertedSetting, inverted);
|
||||
SetRegistry(CameraPivotYawRotationInvertedSetting, inverted);
|
||||
}
|
||||
|
||||
bool CameraPanInvertedX()
|
||||
@@ -403,14 +403,14 @@ namespace SandboxEditor
|
||||
SetRegistry(CameraTranslateBoostIdSetting, cameraTranslateBoostId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitChannelId()
|
||||
AzFramework::InputChannelId CameraPivotChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraPivotIdSetting, AZStd::string("keyboard_key_modifier_alt_l")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId)
|
||||
void SetCameraPivotChannelId(AZStd::string_view cameraPivotId)
|
||||
{
|
||||
SetRegistry(CameraOrbitIdSetting, cameraOrbitId);
|
||||
SetRegistry(CameraPivotIdSetting, cameraPivotId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraFreeLookChannelId()
|
||||
@@ -433,33 +433,33 @@ namespace SandboxEditor
|
||||
SetRegistry(CameraFreePanIdSetting, cameraFreePanId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitLookChannelId()
|
||||
AzFramework::InputChannelId CameraPivotLookChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitLookIdSetting, AZStd::string("mouse_button_left")).c_str());
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraPivotLookIdSetting, AZStd::string("mouse_button_left")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId)
|
||||
void SetCameraPivotLookChannelId(AZStd::string_view cameraPivotLookId)
|
||||
{
|
||||
SetRegistry(CameraOrbitLookIdSetting, cameraOrbitLookId);
|
||||
SetRegistry(CameraPivotLookIdSetting, cameraPivotLookId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitDollyChannelId()
|
||||
AzFramework::InputChannelId CameraPivotDollyChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraPivotDollyIdSetting, AZStd::string("mouse_button_right")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId)
|
||||
void SetCameraPivotDollyChannelId(AZStd::string_view cameraPivotDollyId)
|
||||
{
|
||||
SetRegistry(CameraOrbitDollyIdSetting, cameraOrbitDollyId);
|
||||
SetRegistry(CameraPivotDollyIdSetting, cameraPivotDollyId);
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId CameraOrbitPanChannelId()
|
||||
AzFramework::InputChannelId CameraPivotPanChannelId()
|
||||
{
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraOrbitPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
|
||||
return AzFramework::InputChannelId(GetRegistry(CameraPivotPanIdSetting, AZStd::string("mouse_button_middle")).c_str());
|
||||
}
|
||||
|
||||
void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId)
|
||||
void SetCameraPivotPanChannelId(AZStd::string_view cameraPivotPanId)
|
||||
{
|
||||
SetRegistry(CameraOrbitPanIdSetting, cameraOrbitPanId);
|
||||
SetRegistry(CameraPivotPanIdSetting, cameraPivotPanId);
|
||||
}
|
||||
} // namespace SandboxEditor
|
||||
|
||||
@@ -71,8 +71,8 @@ namespace SandboxEditor
|
||||
SANDBOX_API float CameraDollyMotionSpeed();
|
||||
SANDBOX_API void SetCameraDollyMotionSpeed(float speed);
|
||||
|
||||
SANDBOX_API bool CameraOrbitYawRotationInverted();
|
||||
SANDBOX_API void SetCameraOrbitYawRotationInverted(bool inverted);
|
||||
SANDBOX_API bool CameraPivotYawRotationInverted();
|
||||
SANDBOX_API void SetCameraPivotYawRotationInverted(bool inverted);
|
||||
|
||||
SANDBOX_API bool CameraPanInvertedX();
|
||||
SANDBOX_API void SetCameraPanInvertedX(bool inverted);
|
||||
@@ -119,8 +119,8 @@ namespace SandboxEditor
|
||||
SANDBOX_API AzFramework::InputChannelId CameraTranslateBoostChannelId();
|
||||
SANDBOX_API void SetCameraTranslateBoostChannelId(AZStd::string_view cameraTranslateBoostId);
|
||||
|
||||
SANDBOX_API AzFramework::InputChannelId CameraOrbitChannelId();
|
||||
SANDBOX_API void SetCameraOrbitChannelId(AZStd::string_view cameraOrbitId);
|
||||
SANDBOX_API AzFramework::InputChannelId CameraPivotChannelId();
|
||||
SANDBOX_API void SetCameraPivotChannelId(AZStd::string_view cameraPivotId);
|
||||
|
||||
SANDBOX_API AzFramework::InputChannelId CameraFreeLookChannelId();
|
||||
SANDBOX_API void SetCameraFreeLookChannelId(AZStd::string_view cameraFreeLookId);
|
||||
@@ -128,12 +128,12 @@ namespace SandboxEditor
|
||||
SANDBOX_API AzFramework::InputChannelId CameraFreePanChannelId();
|
||||
SANDBOX_API void SetCameraFreePanChannelId(AZStd::string_view cameraFreePanId);
|
||||
|
||||
SANDBOX_API AzFramework::InputChannelId CameraOrbitLookChannelId();
|
||||
SANDBOX_API void SetCameraOrbitLookChannelId(AZStd::string_view cameraOrbitLookId);
|
||||
SANDBOX_API AzFramework::InputChannelId CameraPivotLookChannelId();
|
||||
SANDBOX_API void SetCameraPivotLookChannelId(AZStd::string_view cameraPivotLookId);
|
||||
|
||||
SANDBOX_API AzFramework::InputChannelId CameraOrbitDollyChannelId();
|
||||
SANDBOX_API void SetCameraOrbitDollyChannelId(AZStd::string_view cameraOrbitDollyId);
|
||||
SANDBOX_API AzFramework::InputChannelId CameraPivotDollyChannelId();
|
||||
SANDBOX_API void SetCameraPivotDollyChannelId(AZStd::string_view cameraPivotDollyId);
|
||||
|
||||
SANDBOX_API AzFramework::InputChannelId CameraOrbitPanChannelId();
|
||||
SANDBOX_API void SetCameraOrbitPanChannelId(AZStd::string_view cameraOrbitPanId);
|
||||
SANDBOX_API AzFramework::InputChannelId CameraPivotPanChannelId();
|
||||
SANDBOX_API void SetCameraPivotPanChannelId(AZStd::string_view cameraPivotPanId);
|
||||
} // namespace SandboxEditor
|
||||
|
||||
@@ -167,7 +167,7 @@ namespace UnitTest
|
||||
AZ::Quaternion::CreateRotationZ(AZ::DegToRad(90.0f)), AZ::Vector3(20.0f, 40.0f, 60.0f));
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
|
||||
transformToInterpolateTo, 0.0f);
|
||||
transformToInterpolateTo);
|
||||
|
||||
// simulate interpolation
|
||||
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(0.5f), AZ::ScriptTimePoint() });
|
||||
@@ -193,7 +193,7 @@ namespace UnitTest
|
||||
// When
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
TestViewportId, &AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform,
|
||||
transformToInterpolateTo, 0.0f);
|
||||
transformToInterpolateTo);
|
||||
|
||||
// simulate interpolation
|
||||
m_controllerList->UpdateViewport({ TestViewportId, AzFramework::FloatSeconds(0.5f), AZ::ScriptTimePoint() });
|
||||
|
||||
@@ -27,10 +27,11 @@ AZ_POP_DISABLE_WARNING
|
||||
#endif
|
||||
|
||||
// AzCore
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Component/ComponentApplication.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzFramework
|
||||
|
||||
@@ -1739,8 +1739,7 @@ void SandboxIntegrationManager::GoToEntitiesInViewports(const AzToolsFramework::
|
||||
|
||||
AtomToolsFramework::ModularViewportCameraControllerRequestBus::Event(
|
||||
viewportContext->GetId(),
|
||||
&AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform, nextCameraTransform,
|
||||
distanceToLookAt);
|
||||
&AtomToolsFramework::ModularViewportCameraControllerRequestBus::Events::InterpolateToTransform, nextCameraTransform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <AzCore/Utils/Utils.h>
|
||||
|
||||
// AzToolsFramework
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzToolsFramework/API/EditorPythonRunnerRequestsBus.h>
|
||||
#include <AzToolsFramework/UI/UICore/WidgetHelpers.h>
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
// Editor
|
||||
#include "AnimationContext.h"
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
@@ -36,8 +36,9 @@
|
||||
#include "MathConversion.h"
|
||||
#include "EditorViewportSettings.h"
|
||||
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Casting/numeric_cast.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzToolsFramework/Viewport/ViewportMessages.h>
|
||||
|
||||
#include <LmbrCentral/Audio/AudioSystemComponentBus.h>
|
||||
|
||||
@@ -89,6 +89,9 @@ namespace AZ
|
||||
|
||||
// Tracks the asset type used to create the instance.
|
||||
AssetType m_assetType;
|
||||
|
||||
// Boolean to indicate if the instance has been orphaned from the instance database
|
||||
bool m_isOrphaned = false;
|
||||
};
|
||||
|
||||
/// @cond EXCLUDE_DOCS
|
||||
|
||||
@@ -203,6 +203,16 @@ namespace AZ
|
||||
//! Calls FindOrCreate using a random InstanceId
|
||||
Data::Instance<Type> Create(const Asset<AssetData>& asset, const AZStd::any* param = nullptr);
|
||||
|
||||
/**
|
||||
* Removes the instance data from the database. Does not release it.
|
||||
* References to existing instances will remain valid, but new calls to Create/FindOrCreate will create a new instance
|
||||
* This function is temporary, to provide functionality needed for Model hot-reloading, but will be removed
|
||||
* once the Model class does not need it anymore.
|
||||
*
|
||||
* @param id The id of the instance to remove
|
||||
*/
|
||||
void TEMPOrphan(const InstanceId& id);
|
||||
|
||||
private:
|
||||
InstanceDatabase(const AssetType& assetType);
|
||||
~InstanceDatabase();
|
||||
@@ -356,6 +366,20 @@ namespace AZ
|
||||
return FindOrCreate(Data::InstanceId::CreateRandom(), asset, param);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::TEMPOrphan(const InstanceId& id)
|
||||
{
|
||||
AZStd::scoped_lock<AZStd::recursive_mutex> lock(m_databaseMutex);
|
||||
// Check if the instance is still in the database, in case it was orphaned twice
|
||||
auto instanceItr = m_database.find(id);
|
||||
if (instanceItr != m_database.end())
|
||||
{
|
||||
// Mark the instance as orphaned, and remove it from the database
|
||||
instanceItr->second->m_isOrphaned = true;
|
||||
m_database.erase(instanceItr);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void InstanceDatabase<Type>::ReleaseInstance(InstanceData* instance, const InstanceId& instanceId)
|
||||
{
|
||||
@@ -374,6 +398,12 @@ namespace AZ
|
||||
m_database.erase(instance->GetId());
|
||||
m_instanceHandler.m_deleteFunction(static_cast<Type*>(instance));
|
||||
}
|
||||
else if (instance->m_isOrphaned && instance->m_useCount.compare_exchange_strong(expectedRefCount, -1))
|
||||
{
|
||||
// If the instance was orphaned, it has already been removed from the database,
|
||||
// but still needs to be deleted when the refcount drops to 0
|
||||
m_instanceHandler.m_deleteFunction(static_cast<Type*>(instance));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
|
||||
@@ -181,7 +181,76 @@ namespace UnitTest
|
||||
EXPECT_EQ(instance, instance3);
|
||||
}
|
||||
|
||||
void ParallelInstanceCreateHelper(size_t threadCountMax, size_t assetIdCount, size_t durationSeconds)
|
||||
TEST_F(InstanceDatabaseTest, InstanceOrphan)
|
||||
{
|
||||
auto& assetManager = AssetManager::Instance();
|
||||
auto& instanceDatabase = InstanceDatabase<TestInstanceA>::Instance();
|
||||
|
||||
Asset<TestAssetType> someAsset = assetManager.CreateAsset<TestAssetType>(s_assetId0, AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
Instance<TestInstanceA> orphanedInstance = instanceDatabase.FindOrCreate(s_instanceId0, someAsset);
|
||||
EXPECT_NE(orphanedInstance, nullptr);
|
||||
|
||||
instanceDatabase.TEMPOrphan(s_instanceId0);
|
||||
// After orphan, the instance should not be found in the database, but it should still be valid
|
||||
EXPECT_EQ(instanceDatabase.Find(s_instanceId0), nullptr);
|
||||
EXPECT_NE(orphanedInstance, nullptr);
|
||||
|
||||
instanceDatabase.TEMPOrphan(s_instanceId0);
|
||||
// Orphaning twice should be a no-op
|
||||
EXPECT_EQ(instanceDatabase.Find(s_instanceId0), nullptr);
|
||||
EXPECT_NE(orphanedInstance, nullptr);
|
||||
|
||||
Instance<TestInstanceA> instance2 = instanceDatabase.FindOrCreate(s_instanceId0, someAsset);
|
||||
// Creating another instance with the same id should return a different instance than the one that was orphaned
|
||||
EXPECT_NE(orphanedInstance, instance2);
|
||||
}
|
||||
|
||||
enum class ParallelInstanceTestCases
|
||||
{
|
||||
Create,
|
||||
CreateAndDeferRemoval,
|
||||
CreateAndOrphan,
|
||||
CreateDeferRemovalAndOrphan
|
||||
};
|
||||
|
||||
enum class ParralleInstanceCurrentAction
|
||||
{
|
||||
Create,
|
||||
DeferredRemoval,
|
||||
Orphan
|
||||
};
|
||||
|
||||
ParralleInstanceCurrentAction ParallelInstanceGetCurrentAction(ParallelInstanceTestCases testCase)
|
||||
{
|
||||
switch (testCase)
|
||||
{
|
||||
case ParallelInstanceTestCases::CreateAndDeferRemoval:
|
||||
switch (rand() % 2)
|
||||
{
|
||||
case 0: return ParralleInstanceCurrentAction::Create;
|
||||
case 1: return ParralleInstanceCurrentAction::DeferredRemoval;
|
||||
}
|
||||
case ParallelInstanceTestCases::CreateAndOrphan:
|
||||
switch (rand() % 2)
|
||||
{
|
||||
case 0: return ParralleInstanceCurrentAction::Create;
|
||||
case 1: return ParralleInstanceCurrentAction::Orphan;
|
||||
}
|
||||
case ParallelInstanceTestCases::CreateDeferRemovalAndOrphan:
|
||||
switch (rand() % 3)
|
||||
{
|
||||
case 0: return ParralleInstanceCurrentAction::Create;
|
||||
case 1: return ParralleInstanceCurrentAction::DeferredRemoval;
|
||||
case 2: return ParralleInstanceCurrentAction::Orphan;
|
||||
}
|
||||
case ParallelInstanceTestCases::Create:
|
||||
default:
|
||||
return ParralleInstanceCurrentAction::Create;
|
||||
}
|
||||
}
|
||||
|
||||
void ParallelInstanceCreateHelper(size_t threadCountMax, size_t assetIdCount, float durationSeconds, ParallelInstanceTestCases testCase)
|
||||
{
|
||||
printf("Testing threads=%zu assetIds=%zu ... ", threadCountMax, assetIdCount);
|
||||
|
||||
@@ -192,6 +261,7 @@ namespace UnitTest
|
||||
auto& instanceManager = InstanceDatabase<TestInstanceA>::Instance();
|
||||
|
||||
AZStd::vector<Uuid> guids;
|
||||
AZStd::vector<Data::Instance<Data::InstanceData>> instances;
|
||||
AZStd::vector<Asset<TestAssetType>> assets;
|
||||
|
||||
for (size_t i = 0; i < assetIdCount; ++i)
|
||||
@@ -199,6 +269,7 @@ namespace UnitTest
|
||||
Uuid guid = Uuid::CreateRandom();
|
||||
|
||||
guids.emplace_back(guid);
|
||||
instances.emplace_back(nullptr);
|
||||
|
||||
// Pre-create asset so we don't attempt to load it from the catalog.
|
||||
assets.emplace_back(assetManager.CreateAsset<TestAssetType>(guid, AZ::Data::AssetLoadBehavior::Default));
|
||||
@@ -206,6 +277,7 @@ namespace UnitTest
|
||||
|
||||
AZStd::vector<AZStd::thread> threads;
|
||||
AZStd::mutex mutex;
|
||||
AZStd::mutex referenceTableMutex;
|
||||
AZStd::atomic<int> threadCount((int)threadCountMax);
|
||||
AZStd::condition_variable cv;
|
||||
AZStd::atomic_bool keepDispatching(true);
|
||||
@@ -225,11 +297,15 @@ namespace UnitTest
|
||||
for (size_t i = 0; i < threadCountMax; ++i)
|
||||
{
|
||||
threads.emplace_back(
|
||||
[&instanceManager, &threadCount, &cv, &guids, &assets, &durationSeconds]()
|
||||
[&instanceManager, &threadCount, &cv, &guids, &instances, &assets, &durationSeconds, &testCase, &referenceTableMutex]()
|
||||
{
|
||||
AZ::Debug::Timer timer;
|
||||
timer.Stamp();
|
||||
|
||||
bool deferRemoval = testCase == ParallelInstanceTestCases::CreateAndDeferRemoval ||
|
||||
testCase == ParallelInstanceTestCases::CreateDeferRemovalAndOrphan
|
||||
? true : false;
|
||||
|
||||
while (timer.GetDeltaTimeInSeconds() < durationSeconds)
|
||||
{
|
||||
const size_t index = rand() % guids.size();
|
||||
@@ -237,11 +313,36 @@ namespace UnitTest
|
||||
const InstanceId instanceId{ uuid };
|
||||
const AssetId assetId{ uuid };
|
||||
|
||||
Instance<TestInstanceA> instance =
|
||||
instanceManager.FindOrCreate(instanceId, Asset<TestAssetType>(assetId, azrtti_typeid<TestAssetType>()));
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
ParralleInstanceCurrentAction currentAction = ParallelInstanceGetCurrentAction(testCase);
|
||||
|
||||
if (currentAction == ParralleInstanceCurrentAction::Orphan)
|
||||
{
|
||||
// Orphan the instance, but don't decrease its refcount
|
||||
instanceManager.TEMPOrphan(instanceId);
|
||||
}
|
||||
else if (currentAction == ParralleInstanceCurrentAction::DeferredRemoval)
|
||||
{
|
||||
// Drop the refcount to zero so the instance will be released
|
||||
referenceTableMutex.lock();
|
||||
instances[index] = nullptr;
|
||||
referenceTableMutex.unlock();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, add a new instance
|
||||
Instance<TestInstanceA> instance = instanceManager.FindOrCreate(instanceId, assets[index]);
|
||||
EXPECT_NE(instance, nullptr);
|
||||
EXPECT_EQ(instance->GetId(), instanceId);
|
||||
EXPECT_EQ(instance->m_asset, assets[index]);
|
||||
|
||||
if (deferRemoval)
|
||||
{
|
||||
// Keep a reference to the instance alive so it can be removed later
|
||||
referenceTableMutex.lock();
|
||||
instances[index] = instance;
|
||||
referenceTableMutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
threadCount--;
|
||||
@@ -254,10 +355,12 @@ namespace UnitTest
|
||||
// Used to detect a deadlock. If we wait for more than 10 seconds, it's likely a deadlock has occurred
|
||||
while (threadCount > 0 && !timedOut)
|
||||
{
|
||||
size_t durationSecondsRoundedUp = static_cast<size_t>(std::ceil(durationSeconds));
|
||||
|
||||
AZStd::unique_lock<AZStd::mutex> lock(mutex);
|
||||
timedOut =
|
||||
(AZStd::cv_status::timeout ==
|
||||
cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSeconds * 2)));
|
||||
cv.wait_until(lock, AZStd::chrono::system_clock::now() + AZStd::chrono::seconds(durationSecondsRoundedUp * 2)));
|
||||
}
|
||||
|
||||
EXPECT_TRUE(threadCount == 0) << "One or more threads appear to be deadlocked at " << timer.GetDeltaTimeInSeconds() << " seconds";
|
||||
@@ -273,11 +376,11 @@ namespace UnitTest
|
||||
printf("Took %f seconds\n", timer.GetDeltaTimeInSeconds());
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreate)
|
||||
void ParallelCreateTest(ParallelInstanceTestCases testCase)
|
||||
{
|
||||
// This is the original test scenario from when InstanceDatabase was first implemented
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(8, 100, 5);
|
||||
ParallelInstanceCreateHelper(8, 100, 5, testCase);
|
||||
|
||||
// This value is checked in as 1 so this test doesn't take too much time, but can be increased locally to soak the test.
|
||||
const size_t attempts = 1;
|
||||
@@ -289,11 +392,11 @@ namespace UnitTest
|
||||
// The idea behind this series of tests is that there are two threads sharing one Instance, and both threads try to
|
||||
// create or release that instance at the same time.
|
||||
// At the time, this set of scenarios has something like a 10% failure rate.
|
||||
const size_t duration = 2;
|
||||
const float duration = 2.0f;
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(8, 1, duration);
|
||||
ParallelInstanceCreateHelper(2, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 1, duration, testCase);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < attempts; ++i)
|
||||
@@ -301,19 +404,39 @@ namespace UnitTest
|
||||
printf("Attempt %zu of %zu... \n", i, attempts);
|
||||
|
||||
// Here we try a bunch of different threadCount:assetCount ratios to be thorough
|
||||
const size_t duration = 2;
|
||||
const float duration = 2.0f;
|
||||
// threads, AssetIds, seconds
|
||||
ParallelInstanceCreateHelper(2, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 1, duration);
|
||||
ParallelInstanceCreateHelper(4, 2, duration);
|
||||
ParallelInstanceCreateHelper(4, 4, duration);
|
||||
ParallelInstanceCreateHelper(8, 1, duration);
|
||||
ParallelInstanceCreateHelper(8, 2, duration);
|
||||
ParallelInstanceCreateHelper(8, 3, duration);
|
||||
ParallelInstanceCreateHelper(8, 4, duration);
|
||||
ParallelInstanceCreateHelper(2, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 2, duration, testCase);
|
||||
ParallelInstanceCreateHelper(4, 4, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 1, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 2, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 3, duration, testCase);
|
||||
ParallelInstanceCreateHelper(8, 4, duration, testCase);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreate)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::Create);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreateAndDeferRemoval)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::CreateAndDeferRemoval);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreateAndOrphan)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::CreateAndOrphan);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, ParallelInstanceCreateDeferRemovalAndOrphan)
|
||||
{
|
||||
ParallelCreateTest(ParallelInstanceTestCases::CreateDeferRemovalAndOrphan);
|
||||
}
|
||||
|
||||
TEST_F(InstanceDatabaseTest, InstanceCreateNoDatabase)
|
||||
{
|
||||
bool m_deleted = false;
|
||||
|
||||
@@ -340,6 +340,14 @@ namespace AZ
|
||||
// (Load jobs will attempt to reuse blocked threads before spinning off new job threads)
|
||||
ProcessLoadJob();
|
||||
}
|
||||
|
||||
// Pump the AssetBus function queue once more after the load has completed in case additional
|
||||
// functions have been queued between the last call to DispatchEvents and the completion
|
||||
// of the current load job
|
||||
if (m_shouldDispatchEvents)
|
||||
{
|
||||
AssetManager::Instance().DispatchEvents();
|
||||
}
|
||||
}
|
||||
|
||||
void Finish()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/Json/RegistrationContext.h>
|
||||
#include <AzCore/Slice/SliceAssetHandler.h>
|
||||
#include <AzCore/Slice/SliceComponent.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
namespace AZ {
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <AzCore/Memory/Memory.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h> // Used as the allocator for most components.
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_ENTITY_UTILS_H
|
||||
#define AZCORE_ENTITY_UTILS_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
@@ -217,6 +216,3 @@ namespace AZ
|
||||
|
||||
} // namespace EntityUtils
|
||||
} // namespace AZ
|
||||
|
||||
#endif // AZCORE_ENTITY_UTILS_H
|
||||
#pragma once
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/OSAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/EBus/Policies.h>
|
||||
|
||||
|
||||
@@ -19,14 +19,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/BusImpl.h>
|
||||
#include <AzCore/EBus/Environment.h>
|
||||
#include <AzCore/EBus/Results.h>
|
||||
#include <AzCore/EBus/Internal/Debug.h>
|
||||
|
||||
// Included for backwards compatibility purposes
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/typetraits/is_same.h>
|
||||
// End backwards compat
|
||||
|
||||
#include <AzCore/std/utils.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
@@ -90,14 +87,14 @@ namespace AZ
|
||||
* For available settings, see AZ::EBusHandlerPolicy.
|
||||
* By default, an EBus supports any number of handlers.
|
||||
*/
|
||||
static const EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple;
|
||||
static constexpr EBusHandlerPolicy HandlerPolicy = EBusHandlerPolicy::Multiple;
|
||||
|
||||
/**
|
||||
* Defines how many addresses exist on the EBus.
|
||||
* For available settings, see AZ::EBusAddressPolicy.
|
||||
* By default, an EBus uses a single address.
|
||||
*/
|
||||
static const EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
|
||||
static constexpr EBusAddressPolicy AddressPolicy = EBusAddressPolicy::Single;
|
||||
|
||||
/**
|
||||
* The type of ID that is used to address the EBus.
|
||||
@@ -152,14 +149,14 @@ namespace AZ
|
||||
* `<BusName>::ExecuteQueuedEvents()`.
|
||||
* By default, the event queue is disabled.
|
||||
*/
|
||||
static const bool EnableEventQueue = false;
|
||||
static constexpr bool EnableEventQueue = false;
|
||||
|
||||
/**
|
||||
* Specifies whether the bus should accept queued messages by default or not.
|
||||
* If set to false, Bus::AllowFunctionQueuing(true) must be called before events are accepted.
|
||||
* Used only when #EnableEventQueue is true.
|
||||
*/
|
||||
static const bool EventQueueingActiveByDefault = true;
|
||||
static constexpr bool EventQueueingActiveByDefault = true;
|
||||
|
||||
/**
|
||||
* Specifies whether the EBus supports queueing functions which take reference
|
||||
@@ -168,7 +165,7 @@ namespace AZ
|
||||
* You should only use this if you know that the data being passed as arguments will
|
||||
* outlive the dispatch of the queued event.
|
||||
*/
|
||||
static const bool EnableQueuedReferences = false;
|
||||
static constexpr bool EnableQueuedReferences = false;
|
||||
|
||||
/**
|
||||
* Locking primitive that is used when adding and removing
|
||||
@@ -197,7 +194,7 @@ namespace AZ
|
||||
* to do.
|
||||
* By default, the standard policy is used, which locks around all dispatches
|
||||
*/
|
||||
static const bool LocklessDispatch = false;
|
||||
static constexpr bool LocklessDispatch = false;
|
||||
|
||||
/**
|
||||
* Specifies where EBus data is stored.
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/RTTI/TypeSafeIntegral.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -18,9 +18,8 @@
|
||||
#include <AzCore/std/function/invoke.h>
|
||||
#include <AzCore/std/containers/queue.h>
|
||||
#include <AzCore/std/containers/intrusive_set.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
|
||||
#include <AzCore/Module/Environment.h>
|
||||
#include <AzCore/EBus/Environment.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
@@ -251,29 +250,21 @@ namespace AZ
|
||||
void Execute()
|
||||
{
|
||||
AZ_Warning("System", m_isActive, "You are calling execute queued functions on a bus which has not activated its function queuing! Call YourBus::AllowFunctionQueuing(true)!");
|
||||
while (true)
|
||||
|
||||
MessageQueueType localMessages;
|
||||
|
||||
// Swap the current list of queue functions with a local instance
|
||||
{
|
||||
BusMessageCall invoke;
|
||||
AZStd::scoped_lock lock(m_messagesMutex);
|
||||
AZStd::swap(localMessages, m_messages);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Pop element from the queue.
|
||||
{
|
||||
AZStd::lock_guard<MutexType> lock(m_messagesMutex);
|
||||
size_t numMessages = m_messages.size();
|
||||
if (numMessages == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
AZStd::swap(invoke, m_messages.front());
|
||||
m_messages.pop();
|
||||
if (numMessages == 1)
|
||||
{
|
||||
m_messages = {};
|
||||
}
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
invoke();
|
||||
// Execute the queue functions safely now that are owned by the function
|
||||
while (!localMessages.empty())
|
||||
{
|
||||
const BusMessageCall& localMessage = localMessages.front();
|
||||
localMessage();
|
||||
localMessages.pop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Name/NameSerializer.h>
|
||||
#include <AzCore/IO/GenericStreams.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/std/containers/array.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/function/invoke.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/string/string_view.h>
|
||||
|
||||
@@ -5,11 +5,13 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Script/lua/lua.h>
|
||||
#include <AzCore/Script/ScriptProperty.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_SCRIPT_SCRIPTPROPERTY_H
|
||||
#define AZCORE_SCRIPT_SCRIPTPROPERTY_H
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
@@ -490,5 +489,4 @@ namespace AZ
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/DataPatch.h>
|
||||
#include <AzCore/Serialization/DataPatchBus.h>
|
||||
#include <AzCore/Serialization/DataPatchUpgradeManager.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "AzCore/RTTI/TypeInfo.h"
|
||||
#include <AzCore/Math/UuidSerializer.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/CastingHelpers.h>
|
||||
#include <AzCore/Serialization/Json/JsonDeserializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonStringConversionUtils.h>
|
||||
|
||||
@@ -6,7 +6,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerializer.h>
|
||||
#include <AzCore/Serialization/Json/BaseJsonSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/Json/BasicContainerSerializer.h>
|
||||
#include <AzCore/Serialization/Json/JsonSerialization.h>
|
||||
#include <AzCore/Serialization/Json/MapSerializer.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/ObjectStream.h>
|
||||
#include <AzCore/Serialization/DataOverlayInstanceMsgs.h>
|
||||
#include <AzCore/Serialization/DataOverlayProviderMsgs.h>
|
||||
|
||||
@@ -37,7 +37,8 @@ namespace AZ
|
||||
class GenericStream;
|
||||
}
|
||||
|
||||
namespace ObjectStreamInternal {
|
||||
namespace ObjectStreamInternal
|
||||
{
|
||||
class ObjectStreamImpl;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/DataOverlay.h>
|
||||
#include <AzCore/Serialization/DynamicSerializableField.h>
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
#ifndef AZCORE_SERIALIZE_CONTEXT_H
|
||||
#define AZCORE_SERIALIZE_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
|
||||
@@ -43,6 +42,12 @@
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
namespace Data
|
||||
{
|
||||
template<typename T>
|
||||
class Asset;
|
||||
}
|
||||
|
||||
class EditContext;
|
||||
|
||||
class ObjectStream;
|
||||
@@ -2562,11 +2567,13 @@ namespace AZ
|
||||
#include <AzCore/Serialization/AZStdContainers.inl>
|
||||
#include <AzCore/Serialization/std/VariantReflection.inl>
|
||||
|
||||
/// include asset generics
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
// Forward declare asset serialization helper specialization
|
||||
namespace AZ
|
||||
{
|
||||
template<typename T>
|
||||
struct SerializeGenericTypeInfo< Data::Asset<T> >;
|
||||
}
|
||||
|
||||
/// include implementation of SerializeContext::EnumBuilder
|
||||
#include <AzCore/Serialization/SerializeContextEnum.inl>
|
||||
|
||||
#endif // AZCORE_SERIALIZE_CONTEXT_H
|
||||
#pragma once
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Debug/Profiler.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Component/TransformBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/std/algorithm.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/EBus/BusImpl.h> //Just to get AZ::NullMutex
|
||||
#include <AzCore/std/chrono/types.h>
|
||||
#include <AzCore/Statistics/StatisticsManager.h>
|
||||
#include <AzCore/std/chrono/chrono.h>
|
||||
#include <AzCore/std/parallel/scoped_lock.h>
|
||||
|
||||
namespace AZ
|
||||
@@ -243,7 +244,7 @@ namespace AZ
|
||||
|
||||
//! This one is needed because running statistics are collected many times across
|
||||
//! several frames. This value is used to calculate a per frame sample for @m_totalTimePerFrameStat,
|
||||
//! by subtracting @m_prevAccumulatedSums from the accumulated sum in @m_statisticsManager.
|
||||
//! by subtracting @m_prevAccumulatedSums from the accumulated sum in @m_statisticsManager.
|
||||
double m_prevAccumulatedSums;
|
||||
};
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <SerializeContextFixture.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/std/any.h>
|
||||
#include <AzCore/std/containers/variant.h>
|
||||
#include <AzCore/Component/Entity.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/Console.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
@@ -365,6 +366,42 @@ namespace UnitTest
|
||||
|
||||
};
|
||||
|
||||
static constexpr AZStd::chrono::seconds MaxDispatchTimeoutSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds * 12;
|
||||
|
||||
template <typename Pred>
|
||||
bool DispatchEventsUntilCondition(AZ::Data::AssetManager& assetManager, Pred&& conditionPredicate,
|
||||
AZStd::chrono::seconds logIntervalSeconds = BaseAssetManagerTest::DefaultTimeoutSeconds,
|
||||
AZStd::chrono::seconds maxTimeoutSeconds = MaxDispatchTimeoutSeconds)
|
||||
{
|
||||
// If the Max Timeout is hit the test will be marked as a failure
|
||||
|
||||
AZStd::chrono::time_point dispatchEventTimeStart = AZStd::chrono::system_clock::now();
|
||||
AZStd::chrono::seconds dispatchEventNextLogTime = logIntervalSeconds;
|
||||
|
||||
while (!conditionPredicate())
|
||||
{
|
||||
AZStd::chrono::time_point currentTime = AZStd::chrono::system_clock::now();
|
||||
if (AZStd::chrono::seconds elapsedTime{ currentTime - dispatchEventTimeStart };
|
||||
elapsedTime >= dispatchEventNextLogTime)
|
||||
{
|
||||
const testing::TestInfo* test_info = ::testing::UnitTest::GetInstance()->current_test_info();
|
||||
AZ_Printf("AssetManagerLoadingTest", "The DispatchEventsUntiTimeout function has been waiting for %llu seconds"
|
||||
" in test %s.%s", elapsedTime.count(), test_info->test_case_name(), test_info->name());
|
||||
// Update the next log time to be the next multiple of DefaultTimeout Seconds
|
||||
// after current elapsed time
|
||||
dispatchEventNextLogTime = elapsedTime + logIntervalSeconds - ((elapsedTime + logIntervalSeconds) % logIntervalSeconds);
|
||||
if (elapsedTime >= maxTimeoutSeconds)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
assetManager.DispatchEvents();
|
||||
AZStd::this_thread::yield();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if AZ_TRAIT_DISABLE_FAILED_ASSET_MANAGER_TESTS || AZ_TRAIT_DISABLE_ASSET_MANAGER_FLOOD_TEST
|
||||
TEST_F(AssetJobsFloodTest, DISABLED_FloodTest)
|
||||
#else
|
||||
@@ -1357,42 +1394,74 @@ namespace UnitTest
|
||||
m_assetHandlerAndCatalog->m_numCreations = 0;
|
||||
m_assetHandlerAndCatalog->m_numDestructions = 0;
|
||||
{
|
||||
ContainerReadyListener containerLoadingCompleteListener(NoLoadAssetId);
|
||||
OnAssetReadyListener readyListener(NoLoadAssetId, azrtti_typeid<AssetWithAssetReference>());
|
||||
OnAssetReadyListener depenencyListener(MyAsset2Id, azrtti_typeid<AssetWithAssetReference>());
|
||||
OnAssetReadyListener dependencyListener(MyAsset2Id, azrtti_typeid<AssetWithAssetReference>());
|
||||
|
||||
SCOPED_TRACE("LoadDependencies_BehaviorObeyed");
|
||||
|
||||
auto AssetOnlyReady = [&readyListener]() -> bool
|
||||
{
|
||||
return readyListener.m_ready;
|
||||
};
|
||||
auto AssetAndDependencyReady = [&readyListener, &dependencyListener]() -> bool
|
||||
{
|
||||
return readyListener.m_ready && dependencyListener.m_ready;
|
||||
};
|
||||
auto AssetContainerReady = [&containerLoadingCompleteListener]() -> bool
|
||||
{
|
||||
return containerLoadingCompleteListener.m_ready;
|
||||
};
|
||||
|
||||
auto noLoadRef = m_testAssetManager->GetAsset(NoLoadAssetId, azrtti_typeid<AssetWithAssetReference>(),
|
||||
AZ::Data::AssetLoadBehavior::Default);
|
||||
|
||||
auto maxTimeout = AZStd::chrono::system_clock::now() + DefaultTimeoutSeconds;
|
||||
// Dispatch AssetBus events until the NoLoadAssetId has signaled an OnAssetReady
|
||||
// event or the timeout has been reached
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetOnlyReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
|
||||
// Dispatch AssetBus events until the asset container used to load
|
||||
// NoLoadAssetId has signaled an OnAssetContainerReady event
|
||||
// or the timeout has been reached
|
||||
// Wait until the current asset container has finished loading the NoLoadAssetId
|
||||
// before trigger another load
|
||||
// If the wait does not occur here, most likely what would occur is
|
||||
// the AssetManager::m_ownedAssetContainers object is still loading the NoLoadAssetId
|
||||
// using the default AssetLoadParameters
|
||||
// If a call to GetAsset occurs at this point while the Asset is still loading
|
||||
// it will ignore the new loadParams below and instead just re-use the existing
|
||||
// AssetContainerReader instance, resulting in the dependent MyAsset2Id not
|
||||
// being loaded
|
||||
// The function that can return an existing AssetContainer instance is the
|
||||
// AssetManager::GetAssetContainer. Since it can be in the middle of a load,
|
||||
// updating the AssetLoadParams would have an effect on the current in progress
|
||||
// load
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetContainerReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
|
||||
// Reset the ContainerLoadingComplete ready status back to 0
|
||||
containerLoadingCompleteListener.m_ready = 0;
|
||||
|
||||
while (!readyListener.m_ready)
|
||||
{
|
||||
m_testAssetManager->DispatchEvents();
|
||||
if (AZStd::chrono::system_clock::now() > maxTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
AZStd::this_thread::yield();
|
||||
}
|
||||
EXPECT_EQ(readyListener.m_ready, 1);
|
||||
EXPECT_EQ(depenencyListener.m_ready, 0);
|
||||
|
||||
AZ::Data::AssetLoadParameters loadParams(nullptr, AZ::Data::AssetDependencyLoadRules::LoadAll);
|
||||
loadParams.m_reloadMissingDependencies = true;
|
||||
auto loadDependencyRef = m_testAssetManager->GetAsset(NoLoadAssetId, azrtti_typeid<AssetWithAssetReference>(),
|
||||
AZ::Data::AssetLoadBehavior::Default, loadParams);
|
||||
|
||||
while (!depenencyListener.m_ready || !readyListener.m_ready)
|
||||
{
|
||||
m_testAssetManager->DispatchEvents();
|
||||
if (AZStd::chrono::system_clock::now() > maxTimeout)
|
||||
{
|
||||
break;
|
||||
}
|
||||
AZStd::this_thread::yield();
|
||||
}
|
||||
// Dispatch AssetBus events until the NoLoadAssetId and the MyAsset2Id has signaled
|
||||
// an OnAssetReady event or the timeout has been reached
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetAndDependencyReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
|
||||
EXPECT_EQ(readyListener.m_ready, 1);
|
||||
EXPECT_EQ(depenencyListener.m_ready, 1);
|
||||
EXPECT_EQ(dependencyListener.m_ready, 1);
|
||||
|
||||
EXPECT_TRUE(DispatchEventsUntilCondition(*m_testAssetManager, AssetContainerReady))
|
||||
<< "The DispatchEventsUntiTimeout function has not completed in "
|
||||
<< MaxDispatchTimeoutSeconds.count() << " seconds. The test will be marked as a failure\n";
|
||||
}
|
||||
|
||||
CheckFinishedCreationsAndDestructions();
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <Tests/Asset/BaseAssetManagerTest.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <AzCore/Asset/AssetJsonSerializer.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetManagerComponent.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/IO/Streamer/StreamerComponent.h>
|
||||
#include <AzCore/Jobs/JobManagerComponent.h>
|
||||
#include <AzCore/Jobs/JobManager.h>
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*
|
||||
*/
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "FileIOBaseTestTypes.h"
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
#include <AzCore/UnitTest/TestTypes.h>
|
||||
#include <AzCore/Math/Uuid.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
using namespace AZ;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
#include <AzCore/Memory/PoolAllocator.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/smart_ptr/intrusive_base.h>
|
||||
#include <AzFramework/Archive/Codec.h>
|
||||
#include <AzFramework/Archive/ZipDirStructures.h>
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Asset/AssetSeedList.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzFramework/Platform/PlatformDefaults.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Asset/Benchmark/BenchmarkAsset.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Asset/SimpleAsset.h>
|
||||
|
||||
namespace AzFramework
|
||||
@@ -36,4 +37,36 @@ namespace AzFramework
|
||||
|
||||
return "";
|
||||
}
|
||||
void SimpleAssetReferenceBase::Reflect(AZ::ReflectContext *context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SimpleAssetReferenceBase>()
|
||||
->Version(1)
|
||||
->Field("AssetPath", &SimpleAssetReferenceBase::m_assetPath);
|
||||
|
||||
AZ::EditContext* edit = serializeContext->GetEditContext();
|
||||
if (edit)
|
||||
{
|
||||
edit->Class<SimpleAssetReferenceBase>("Asset path", "Asset reference as a project-relative path")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SimpleAssetReferenceBase>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Asset")
|
||||
->Attribute(AZ::Script::Attributes::Module, "asset")
|
||||
->Property("assetPath", &SimpleAssetReferenceBase::GetAssetPath, nullptr)
|
||||
->Property("assetType", &SimpleAssetReferenceBase::GetAssetType, nullptr)
|
||||
->Property("fileFilter", &SimpleAssetReferenceBase::GetFileFilter, nullptr)
|
||||
->Method("SetAssetPath", &SimpleAssetReferenceBase::SetAssetPath)
|
||||
->Attribute(AZ::Script::Attributes::Alias, "set_asset_path")
|
||||
;
|
||||
}
|
||||
}
|
||||
} // namespace AzFramework
|
||||
|
||||
@@ -42,7 +42,6 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Component/Component.h>
|
||||
@@ -74,38 +73,7 @@ namespace AzFramework
|
||||
virtual AZ::Data::AssetType GetAssetType() const = 0;
|
||||
virtual const char* GetFileFilter() const = 0;
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<SimpleAssetReferenceBase>()
|
||||
->Version(1)
|
||||
->Field("AssetPath", &SimpleAssetReferenceBase::m_assetPath);
|
||||
|
||||
AZ::EditContext* edit = serializeContext->GetEditContext();
|
||||
if (edit)
|
||||
{
|
||||
edit->Class<SimpleAssetReferenceBase>("Asset path", "Asset reference as a project-relative path")
|
||||
->ClassElement(AZ::Edit::ClassElements::EditorData, "")
|
||||
->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::Hide)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
|
||||
{
|
||||
behaviorContext->Class<SimpleAssetReferenceBase>()
|
||||
->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common)
|
||||
->Attribute(AZ::Script::Attributes::Category, "Asset")
|
||||
->Attribute(AZ::Script::Attributes::Module, "asset")
|
||||
->Property("assetPath", &SimpleAssetReferenceBase::GetAssetPath, nullptr)
|
||||
->Property("assetType", &SimpleAssetReferenceBase::GetAssetType, nullptr)
|
||||
->Property("fileFilter", &SimpleAssetReferenceBase::GetFileFilter, nullptr)
|
||||
->Method("SetAssetPath", &SimpleAssetReferenceBase::SetAssetPath)
|
||||
->Attribute(AZ::Script::Attributes::Alias, "set_asset_path")
|
||||
;
|
||||
}
|
||||
}
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/vector.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/RTTI/ReflectContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
|
||||
namespace AZ
|
||||
{
|
||||
class Entity;
|
||||
}
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
using EntityContextId = AZ::Uuid;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
#include <AzFramework/Logging/MissingAssetNotificationBus.h>
|
||||
|
||||
namespace AzFramework { class LogFile; }
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <AzFramework/Physics/Ragdoll.h>
|
||||
#include <AzFramework/Physics/Shape.h>
|
||||
#include <AzFramework/Physics/SystemBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
#include <AzCore/std/utils.h>
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <AzFramework/Physics/Collision/CollisionEvents.h>
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Physics/Common/PhysicsSimulatedBody.h>
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#include <AzFramework/Physics/Collision/CollisionGroups.h>
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Script/ScriptContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
#include <AzFramework/Physics/CollisionBus.h>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/smart_ptr/make_shared.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <AzFramework/Physics/Configuration/SystemConfiguration.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
#include <AzFramework/Physics/Configuration/SceneConfiguration.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
|
||||
namespace AzPhysics
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
#include <AzFramework/Physics/PhysicsSystem.h>
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzPhysics
|
||||
{
|
||||
void SystemInterface::Reflect(AZ::ReflectContext* context)
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Physics/Material.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionGroups.h>
|
||||
#include <AzFramework/Physics/Collision/CollisionLayers.h>
|
||||
|
||||
@@ -7,9 +7,11 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/PropertyTypes.h>
|
||||
#include <AzFramework/Physics/SystemBus.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace Physics
|
||||
{
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace Physics
|
||||
|
||||
@@ -10,12 +10,14 @@
|
||||
#include "Utils.h"
|
||||
#include "Material.h"
|
||||
#include "Shape.h"
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/AnimationConfiguration.h>
|
||||
#include <AzFramework/Physics/CharacterBus.h>
|
||||
#include <AzFramework/Physics/Character.h>
|
||||
#include <AzFramework/Physics/Ragdoll.h>
|
||||
#include <AzFramework/Physics/ShapeConfiguration.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzFramework/Physics/CollisionBus.h>
|
||||
#include <AzFramework/Physics/Components/SimulatedBodyComponentBus.h>
|
||||
#include <AzFramework/Physics/WindBus.h>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzCore/Math/Vector2.h>
|
||||
#include <AzCore/Math/Vector3.h>
|
||||
#include <AzCore/Component/ComponentBus.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/functional.h>
|
||||
|
||||
//! Common structures for Render geometry queries
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
|
||||
#include <AzCore/Component/Entity.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Settings/SettingsRegistry.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzFramework/Spawnable/SpawnableMetaData.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzFramework/StreamingInstall/StreamingInstallNotifications.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include "StreamingInstall.h"
|
||||
|
||||
namespace AzFramework
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/EBus/EBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/EditContextConstants.inl>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
|
||||
@@ -17,15 +17,6 @@
|
||||
|
||||
namespace AzFramework
|
||||
{
|
||||
AZ_CVAR(
|
||||
float,
|
||||
ed_cameraSystemDefaultPlaneHeight,
|
||||
34.0f,
|
||||
nullptr,
|
||||
AZ::ConsoleFunctorFlags::Null,
|
||||
"The default height of the ground plane to do intersection tests against when orbiting");
|
||||
AZ_CVAR(float, ed_cameraSystemMinOrbitDistance, 10.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(float, ed_cameraSystemMaxOrbitDistance, 50.0f, nullptr, AZ::ConsoleFunctorFlags::Null, "");
|
||||
AZ_CVAR(
|
||||
bool,
|
||||
ed_cameraSystemUseCursor,
|
||||
@@ -135,8 +126,8 @@ namespace AzFramework
|
||||
|
||||
camera.m_pitch = eulerAngles.GetX();
|
||||
camera.m_yaw = eulerAngles.GetZ();
|
||||
// note: m_lookDist is negative so we must invert it here
|
||||
camera.m_lookAt = transform.GetTranslation() + (camera.Rotation().GetBasisY() * -camera.m_lookDist);
|
||||
camera.m_pivot = transform.GetTranslation();
|
||||
camera.m_offset = AZ::Vector3::CreateZero();
|
||||
}
|
||||
|
||||
bool CameraSystem::HandleEvents(const InputEvent& event)
|
||||
@@ -320,14 +311,8 @@ namespace AzFramework
|
||||
nextCamera.m_pitch -= float(cursorDelta.m_y) * rotateSpeed * Invert(m_invertPitchFn());
|
||||
nextCamera.m_yaw -= float(cursorDelta.m_x) * rotateSpeed * Invert(m_invertYawFn());
|
||||
|
||||
const auto clampRotation = [](const float angle)
|
||||
{
|
||||
return AZStd::fmod(angle + AZ::Constants::TwoPi, AZ::Constants::TwoPi);
|
||||
};
|
||||
|
||||
nextCamera.m_yaw = clampRotation(nextCamera.m_yaw);
|
||||
// clamp pitch to be +/-90 degrees
|
||||
nextCamera.m_pitch = AZ::GetClamp(nextCamera.m_pitch, -AZ::Constants::HalfPi, AZ::Constants::HalfPi);
|
||||
nextCamera.m_yaw = WrapYawRotation(nextCamera.m_yaw);
|
||||
nextCamera.m_pitch = ClampPitchRotation(nextCamera.m_pitch);
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
@@ -337,9 +322,10 @@ namespace AzFramework
|
||||
m_rotateChannelId = rotateChannelId;
|
||||
}
|
||||
|
||||
PanCameraInput::PanCameraInput(const InputChannelId& panChannelId, PanAxesFn panAxesFn)
|
||||
PanCameraInput::PanCameraInput(const InputChannelId& panChannelId, PanAxesFn panAxesFn, TranslationDeltaFn translationDeltaFn)
|
||||
: m_panAxesFn(AZStd::move(panAxesFn))
|
||||
, m_panChannelId(panChannelId)
|
||||
, m_translationDeltaFn(translationDeltaFn)
|
||||
{
|
||||
m_panSpeedFn = []() constexpr
|
||||
{
|
||||
@@ -375,11 +361,11 @@ namespace AzFramework
|
||||
const auto panAxes = m_panAxesFn(nextCamera);
|
||||
|
||||
const float panSpeed = m_panSpeedFn();
|
||||
const auto deltaPanX = float(cursorDelta.m_x) * panAxes.m_horizontalAxis * panSpeed;
|
||||
const auto deltaPanY = float(cursorDelta.m_y) * panAxes.m_verticalAxis * panSpeed;
|
||||
const auto deltaPanX = aznumeric_cast<float>(cursorDelta.m_x) * panAxes.m_horizontalAxis * panSpeed;
|
||||
const auto deltaPanY = aznumeric_cast<float>(cursorDelta.m_y) * panAxes.m_verticalAxis * panSpeed;
|
||||
|
||||
nextCamera.m_lookAt += deltaPanX * Invert(m_invertPanXFn());
|
||||
nextCamera.m_lookAt += deltaPanY * -Invert(m_invertPanYFn());
|
||||
m_translationDeltaFn(nextCamera, deltaPanX * Invert(m_invertPanXFn()));
|
||||
m_translationDeltaFn(nextCamera, deltaPanY * -Invert(m_invertPanYFn()));
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
@@ -426,8 +412,11 @@ namespace AzFramework
|
||||
}
|
||||
|
||||
TranslateCameraInput::TranslateCameraInput(
|
||||
TranslationAxesFn translationAxesFn, const TranslateCameraInputChannelIds& translateCameraInputChannelIds)
|
||||
const TranslateCameraInputChannelIds& translateCameraInputChannelIds,
|
||||
TranslationAxesFn translationAxesFn,
|
||||
TranslationDeltaFn translateDeltaFn)
|
||||
: m_translationAxesFn(AZStd::move(translationAxesFn))
|
||||
, m_translateDeltaFn(AZStd::move(translateDeltaFn))
|
||||
, m_translateCameraInputChannelIds(translateCameraInputChannelIds)
|
||||
{
|
||||
m_translateSpeedFn = []() constexpr
|
||||
@@ -497,32 +486,32 @@ namespace AzFramework
|
||||
|
||||
if ((m_translation & TranslationType::Forward) == TranslationType::Forward)
|
||||
{
|
||||
nextCamera.m_lookAt += axisY * speed * deltaTime;
|
||||
m_translateDeltaFn(nextCamera, axisY * speed * deltaTime);
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Backward) == TranslationType::Backward)
|
||||
{
|
||||
nextCamera.m_lookAt -= axisY * speed * deltaTime;
|
||||
m_translateDeltaFn(nextCamera, -axisY * speed * deltaTime);
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Left) == TranslationType::Left)
|
||||
{
|
||||
nextCamera.m_lookAt -= axisX * speed * deltaTime;
|
||||
m_translateDeltaFn(nextCamera, -axisX * speed * deltaTime);
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Right) == TranslationType::Right)
|
||||
{
|
||||
nextCamera.m_lookAt += axisX * speed * deltaTime;
|
||||
m_translateDeltaFn(nextCamera, axisX * speed * deltaTime);
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Up) == TranslationType::Up)
|
||||
{
|
||||
nextCamera.m_lookAt += axisZ * speed * deltaTime;
|
||||
m_translateDeltaFn(nextCamera, axisZ * speed * deltaTime);
|
||||
}
|
||||
|
||||
if ((m_translation & TranslationType::Down) == TranslationType::Down)
|
||||
{
|
||||
nextCamera.m_lookAt -= axisZ * speed * deltaTime;
|
||||
m_translateDeltaFn(nextCamera, -axisZ * speed * deltaTime);
|
||||
}
|
||||
|
||||
if (Ending())
|
||||
@@ -544,16 +533,20 @@ namespace AzFramework
|
||||
m_translateCameraInputChannelIds = translateCameraInputChannelIds;
|
||||
}
|
||||
|
||||
OrbitCameraInput::OrbitCameraInput(const InputChannelId& orbitChannelId)
|
||||
: m_orbitChannelId(orbitChannelId)
|
||||
PivotCameraInput::PivotCameraInput(const InputChannelId& pivotChannelId)
|
||||
: m_pivotChannelId(pivotChannelId)
|
||||
{
|
||||
m_pivotFn = []([[maybe_unused]] const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
|
||||
{
|
||||
return AZ::Vector3::CreateZero();
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, const float scrollDelta)
|
||||
bool PivotCameraInput::HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, const float scrollDelta)
|
||||
{
|
||||
if (const auto* input = AZStd::get_if<DiscreteInputEvent>(&event))
|
||||
{
|
||||
if (input->m_channelId == m_orbitChannelId)
|
||||
if (input->m_channelId == m_pivotChannelId)
|
||||
{
|
||||
if (input->m_state == InputChannel::State::Began)
|
||||
{
|
||||
@@ -568,85 +561,46 @@ namespace AzFramework
|
||||
|
||||
if (Active())
|
||||
{
|
||||
return m_orbitCameras.HandleEvents(event, cursorDelta, scrollDelta);
|
||||
return m_pivotCameras.HandleEvents(event, cursorDelta, scrollDelta);
|
||||
}
|
||||
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera OrbitCameraInput::StepCamera(
|
||||
Camera PivotCameraInput::StepCamera(
|
||||
const Camera& targetCamera, const ScreenVector& cursorDelta, const float scrollDelta, const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
if (Beginning())
|
||||
{
|
||||
const auto hasLookAt = [&nextCamera, &targetCamera, &lookAtFn = m_lookAtFn]
|
||||
{
|
||||
if (lookAtFn)
|
||||
{
|
||||
// pass through the camera's position and look vector for use in the lookAt function
|
||||
if (const auto lookAt = lookAtFn(targetCamera.Translation(), targetCamera.Rotation().GetBasisY()))
|
||||
{
|
||||
// default to internal look at behavior if the look at point matches the camera translation
|
||||
if (targetCamera.m_lookAt.IsClose(*lookAt))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto transform = AZ::Transform::CreateLookAt(targetCamera.m_lookAt, *lookAt);
|
||||
nextCamera.m_lookDist = -lookAt->GetDistance(targetCamera.m_lookAt);
|
||||
UpdateCameraFromTransform(nextCamera, transform);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}();
|
||||
|
||||
if (!hasLookAt)
|
||||
{
|
||||
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<float>(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;
|
||||
}
|
||||
}
|
||||
nextCamera.m_pivot = m_pivotFn(targetCamera.Translation(), targetCamera.Rotation().GetBasisY());
|
||||
nextCamera.m_offset = nextCamera.View().TransformPoint(targetCamera.Translation());
|
||||
}
|
||||
|
||||
if (Active())
|
||||
{
|
||||
nextCamera = m_orbitCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
MovePivotDetached(nextCamera, m_pivotFn(targetCamera.Translation(), targetCamera.Rotation().GetBasisY()));
|
||||
nextCamera = m_pivotCameras.StepCamera(nextCamera, cursorDelta, scrollDelta, deltaTime);
|
||||
}
|
||||
|
||||
if (Ending())
|
||||
{
|
||||
m_orbitCameras.Reset();
|
||||
m_pivotCameras.Reset();
|
||||
|
||||
nextCamera.m_lookAt = nextCamera.Translation();
|
||||
nextCamera.m_lookDist = 0.0f;
|
||||
nextCamera.m_pivot = nextCamera.Translation();
|
||||
nextCamera.m_offset = AZ::Vector3::CreateZero();
|
||||
}
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
void OrbitCameraInput::SetOrbitInputChannelId(const InputChannelId& orbitChanneId)
|
||||
void PivotCameraInput::SetPivotInputChannelId(const InputChannelId& pivotChanneId)
|
||||
{
|
||||
m_orbitChannelId = orbitChanneId;
|
||||
m_pivotChannelId = pivotChanneId;
|
||||
}
|
||||
|
||||
OrbitDollyScrollCameraInput::OrbitDollyScrollCameraInput()
|
||||
PivotDollyScrollCameraInput::PivotDollyScrollCameraInput()
|
||||
{
|
||||
m_scrollSpeedFn = []() constexpr
|
||||
{
|
||||
@@ -654,7 +608,7 @@ namespace AzFramework
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitDollyScrollCameraInput::HandleEvents(
|
||||
bool PivotDollyScrollCameraInput::HandleEvents(
|
||||
const InputEvent& event, [[maybe_unused]] const ScreenVector& cursorDelta, [[maybe_unused]] const float scrollDelta)
|
||||
{
|
||||
if (const auto* scroll = AZStd::get_if<ScrollEvent>(&event))
|
||||
@@ -665,46 +619,61 @@ namespace AzFramework
|
||||
return !Idle();
|
||||
}
|
||||
|
||||
Camera OrbitDollyScrollCameraInput::StepCamera(
|
||||
static Camera PivotDolly(const Camera& targetCamera, const float delta)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
|
||||
const auto pivotDirection = targetCamera.m_offset.GetNormalized();
|
||||
nextCamera.m_offset -= pivotDirection * delta;
|
||||
const auto pivotDot = targetCamera.m_offset.Dot(nextCamera.m_offset);
|
||||
const auto distance = nextCamera.m_offset.GetLength() * AZ::GetSign(pivotDot);
|
||||
|
||||
const auto minDistance = 0.01f;
|
||||
if (distance < minDistance || pivotDot < 0.0f)
|
||||
{
|
||||
nextCamera.m_offset = pivotDirection * minDistance;
|
||||
}
|
||||
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
Camera PivotDollyScrollCameraInput::StepCamera(
|
||||
const Camera& targetCamera,
|
||||
[[maybe_unused]] const ScreenVector& cursorDelta,
|
||||
const float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + scrollDelta * m_scrollSpeedFn(), 0.0f);
|
||||
const auto nextCamera = PivotDolly(targetCamera, aznumeric_cast<float>(scrollDelta) * m_scrollSpeedFn());
|
||||
EndActivation();
|
||||
return nextCamera;
|
||||
}
|
||||
|
||||
OrbitDollyCursorMoveCameraInput::OrbitDollyCursorMoveCameraInput(const InputChannelId& dollyChannelId)
|
||||
PivotDollyMotionCameraInput::PivotDollyMotionCameraInput(const InputChannelId& dollyChannelId)
|
||||
: m_dollyChannelId(dollyChannelId)
|
||||
{
|
||||
m_cursorSpeedFn = []() constexpr
|
||||
m_motionSpeedFn = []() constexpr
|
||||
{
|
||||
return 0.01f;
|
||||
};
|
||||
}
|
||||
|
||||
bool OrbitDollyCursorMoveCameraInput::HandleEvents(
|
||||
bool PivotDollyMotionCameraInput::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 OrbitDollyCursorMoveCameraInput::StepCamera(
|
||||
Camera PivotDollyMotionCameraInput::StepCamera(
|
||||
const Camera& targetCamera,
|
||||
const ScreenVector& cursorDelta,
|
||||
[[maybe_unused]] const float scrollDelta,
|
||||
[[maybe_unused]] const float deltaTime)
|
||||
{
|
||||
Camera nextCamera = targetCamera;
|
||||
nextCamera.m_lookDist = AZ::GetMin(nextCamera.m_lookDist + float(cursorDelta.m_y) * m_cursorSpeedFn(), 0.0f);
|
||||
return nextCamera;
|
||||
return PivotDolly(targetCamera, aznumeric_cast<float>(cursorDelta.m_y) * m_motionSpeedFn());
|
||||
}
|
||||
|
||||
void OrbitDollyCursorMoveCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
|
||||
void PivotDollyMotionCameraInput::SetDollyInputChannelId(const InputChannelId& dollyChannelId)
|
||||
{
|
||||
m_dollyChannelId = dollyChannelId;
|
||||
}
|
||||
@@ -739,7 +708,7 @@ namespace AzFramework
|
||||
const auto translation_basis = LookTranslation(nextCamera);
|
||||
const auto axisY = translation_basis.GetBasisY();
|
||||
|
||||
nextCamera.m_lookAt += axisY * scrollDelta * m_scrollSpeedFn();
|
||||
nextCamera.m_pivot += axisY * scrollDelta * m_scrollSpeedFn();
|
||||
|
||||
EndActivation();
|
||||
|
||||
@@ -790,13 +759,13 @@ namespace AzFramework
|
||||
{
|
||||
const float moveRate = AZStd::exp2(cameraProps.m_translateSmoothnessFn());
|
||||
const float moveTime = AZStd::exp2(-moveRate * deltaTime);
|
||||
camera.m_lookDist = AZ::Lerp(targetCamera.m_lookDist, currentCamera.m_lookDist, moveTime);
|
||||
camera.m_lookAt = targetCamera.m_lookAt.Lerp(currentCamera.m_lookAt, moveTime);
|
||||
camera.m_pivot = targetCamera.m_pivot.Lerp(currentCamera.m_pivot, moveTime);
|
||||
camera.m_offset = targetCamera.m_offset.Lerp(currentCamera.m_offset, moveTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
camera.m_lookDist = targetCamera.m_lookDist;
|
||||
camera.m_lookAt = targetCamera.m_lookAt;
|
||||
camera.m_pivot = targetCamera.m_pivot;
|
||||
camera.m_offset = targetCamera.m_offset;
|
||||
}
|
||||
|
||||
return camera;
|
||||
|
||||
@@ -29,17 +29,15 @@ namespace AzFramework
|
||||
//! @note Order of rotation is Z, Y, X.
|
||||
AZ::Vector3 EulerAngles(const AZ::Matrix3x3& orientation);
|
||||
|
||||
//! A simple camera representation using spherical coordinates as input (pitch, yaw and look distance).
|
||||
//! A simple camera representation using spherical coordinates as input (pitch, yaw, pivot and offset).
|
||||
//! The cameras transform and view can be obtained through accessor functions that use the internal
|
||||
//! spherical coordinates to calculate the position and orientation.
|
||||
struct Camera
|
||||
{
|
||||
AZ::Vector3 m_lookAt = AZ::Vector3::CreateZero(); //!< Position of camera when m_lookDist is zero,
|
||||
//!< or position of m_lookAt when m_lookDist is greater
|
||||
//!< than zero.
|
||||
float m_yaw{ 0.0 }; //!< Yaw rotation of camera (stored in radians) usually clamped to 0-360 degrees (0-2Pi radians).
|
||||
float m_pitch{ 0.0 }; //!< Pitch rotation of the camera (stored in radians) usually clamped to +/-90 degrees (-Pi/2 - Pi/2 radians).
|
||||
float m_lookDist{ 0.0 }; //!< Zero gives first person free look, otherwise orbit about m_lookAt
|
||||
AZ::Vector3 m_pivot = AZ::Vector3::CreateZero(); //!< Pivot point to rotate about (modified in world space).
|
||||
AZ::Vector3 m_offset = AZ::Vector3::CreateZero(); //!< Offset relative to pivot (modified in camera space).
|
||||
float m_yaw = 0.0f; //!< Yaw rotation of camera (stored in radians) usually clamped to 0-360 degrees (0-2Pi radians).
|
||||
float m_pitch = 0.0f; //!< Pitch rotation of the camera (stored in radians) usually clamped to +/-90 degrees (-Pi/2 - Pi/2 radians).
|
||||
|
||||
//! View camera transform (V in model-view-projection matrix (MVP)).
|
||||
AZ::Transform View() const;
|
||||
@@ -51,6 +49,15 @@ namespace AzFramework
|
||||
AZ::Vector3 Translation() const;
|
||||
};
|
||||
|
||||
//! Helper to allow the pivot to be positioned without altering the camera's position.
|
||||
inline void MovePivotDetached(Camera& camera, const AZ::Vector3& pivot)
|
||||
{
|
||||
const auto& view = camera.View();
|
||||
const auto delta = view.TransformPoint(pivot) - view.TransformPoint(camera.m_pivot);
|
||||
camera.m_offset -= delta;
|
||||
camera.m_pivot = pivot;
|
||||
}
|
||||
|
||||
inline AZ::Transform Camera::View() const
|
||||
{
|
||||
return Transform().GetInverse();
|
||||
@@ -58,8 +65,8 @@ namespace AzFramework
|
||||
|
||||
inline AZ::Transform Camera::Transform() const
|
||||
{
|
||||
return AZ::Transform::CreateTranslation(m_lookAt) * AZ::Transform::CreateRotationZ(m_yaw) *
|
||||
AZ::Transform::CreateRotationX(m_pitch) * AZ::Transform::CreateTranslation(AZ::Vector3::CreateAxisY(m_lookDist));
|
||||
return AZ::Transform::CreateTranslation(m_pivot) * AZ::Transform::CreateRotationZ(m_yaw) * AZ::Transform::CreateRotationX(m_pitch) *
|
||||
AZ::Transform::CreateTranslation(m_offset);
|
||||
}
|
||||
|
||||
inline AZ::Matrix3x3 Camera::Rotation() const
|
||||
@@ -279,21 +286,37 @@ namespace AzFramework
|
||||
public:
|
||||
bool HandleEvents(const InputEvent& event);
|
||||
Camera StepCamera(const Camera& targetCamera, float deltaTime);
|
||||
bool HandlingEvents() const
|
||||
{
|
||||
return m_handlingEvents;
|
||||
}
|
||||
bool HandlingEvents() const;
|
||||
|
||||
Cameras m_cameras; //!< Represents a collection of camera inputs that together provide a camera controller.
|
||||
|
||||
private:
|
||||
ScreenVector m_motionDelta; //!< The delta used for look/orbit/pan (rotation + translation) - two dimensional.
|
||||
ScreenVector m_motionDelta; //!< The delta used for look/pivot/pan (rotation + translation) - two dimensional.
|
||||
CursorState m_cursorState; //!< The current and previous position of the cursor (used to calculate movement delta).
|
||||
float m_scrollDelta = 0.0f; //!< The delta used for dolly/movement (translation) - one dimensional.
|
||||
bool m_handlingEvents = false; //!< Is the camera system currently handling events (events are consumed and not propagated).
|
||||
};
|
||||
|
||||
//! A camera input to handle motion deltas that can rotate or orbit the camera.
|
||||
inline bool CameraSystem::HandlingEvents() const
|
||||
{
|
||||
return m_handlingEvents;
|
||||
}
|
||||
|
||||
//! Clamps pitch to be +/-90 degrees (-Pi/2, Pi/2).
|
||||
//! @param pitch Pitch angle in radians.
|
||||
inline float ClampPitchRotation(const float pitch)
|
||||
{
|
||||
return AZ::GetClamp(pitch, -AZ::Constants::HalfPi, AZ::Constants::HalfPi);
|
||||
}
|
||||
|
||||
//! Ensures yaw wraps between 0 and 360 degrees (0, 2Pi).
|
||||
//! @param yaw Yaw angle in radians.
|
||||
inline float WrapYawRotation(const float yaw)
|
||||
{
|
||||
return AZStd::fmod(yaw + AZ::Constants::TwoPi, AZ::Constants::TwoPi);
|
||||
}
|
||||
|
||||
//! A camera input to handle motion deltas that can rotate or pivot the camera.
|
||||
class RotateCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
@@ -332,8 +355,8 @@ namespace AzFramework
|
||||
return { orientation.GetBasisX(), orientation.GetBasisZ() };
|
||||
}
|
||||
|
||||
//! PanAxes to use while in 'orbit' camera behavior.
|
||||
inline PanAxes OrbitPan(const Camera& camera)
|
||||
//! PanAxes to use while in 'pivot' camera behavior.
|
||||
inline PanAxes PivotPan(const Camera& camera)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation = camera.Rotation();
|
||||
|
||||
@@ -347,11 +370,23 @@ namespace AzFramework
|
||||
return { basisX, basisY };
|
||||
}
|
||||
|
||||
using TranslationDeltaFn = AZStd::function<void(Camera& camera, const AZ::Vector3& delta)>;
|
||||
|
||||
inline void TranslatePivot(Camera& camera, const AZ::Vector3& delta)
|
||||
{
|
||||
camera.m_pivot += delta;
|
||||
}
|
||||
|
||||
inline void TranslateOffset(Camera& camera, const AZ::Vector3& delta)
|
||||
{
|
||||
camera.m_offset += camera.View().TransformVector(delta);
|
||||
}
|
||||
|
||||
//! A camera input to handle motion deltas that can pan the camera (translate in two axes).
|
||||
class PanCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
PanCameraInput(const InputChannelId& panChannelId, PanAxesFn panAxesFn);
|
||||
PanCameraInput(const InputChannelId& panChannelId, PanAxesFn panAxesFn, TranslationDeltaFn translationDeltaFn);
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
@@ -365,6 +400,7 @@ namespace AzFramework
|
||||
|
||||
private:
|
||||
PanAxesFn m_panAxesFn; //!< Builder for the particular pan axes (provided in the constructor).
|
||||
TranslationDeltaFn m_translationDeltaFn; //!< How to apply the translation delta to the camera offset or pivot.
|
||||
InputChannelId m_panChannelId; //!< Input channel to begin the pan camera input.
|
||||
ClickDetector m_clickDetector; //!< Used to determine when a sufficient motion delta has occurred after an initial discrete input
|
||||
//!< event has started (press and move event).
|
||||
@@ -385,8 +421,8 @@ namespace AzFramework
|
||||
return AZ::Matrix3x3::CreateFromColumns(basisX, basisY, basisZ);
|
||||
}
|
||||
|
||||
//! TranslationAxes to use while in 'orbit' camera behavior.
|
||||
inline AZ::Matrix3x3 OrbitTranslation(const Camera& camera)
|
||||
//! TranslationAxes to use while in 'pivot' camera behavior.
|
||||
inline AZ::Matrix3x3 PivotTranslation(const Camera& camera)
|
||||
{
|
||||
const AZ::Matrix3x3 orientation = camera.Rotation();
|
||||
|
||||
@@ -417,8 +453,10 @@ namespace AzFramework
|
||||
class TranslateCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit TranslateCameraInput(
|
||||
TranslationAxesFn translationAxesFn, const TranslateCameraInputChannelIds& translateCameraInputChannelIds);
|
||||
TranslateCameraInput(
|
||||
const TranslateCameraInputChannelIds& translateCameraInputChannelIds,
|
||||
TranslationAxesFn translationAxesFn,
|
||||
TranslationDeltaFn translateDeltaFn);
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
@@ -492,15 +530,16 @@ namespace AzFramework
|
||||
|
||||
TranslationType m_translation = TranslationType::Nil; //!< Types of translation the camera input is under.
|
||||
TranslationAxesFn m_translationAxesFn; //!< Builder for translation axes.
|
||||
TranslationDeltaFn m_translateDeltaFn; //!< How to apply the translation delta to the camera offset or pivot.
|
||||
TranslateCameraInputChannelIds m_translateCameraInputChannelIds; //!< Input channel ids that map to internal translation types.
|
||||
bool m_boost = false; //!< Is the translation speed currently being multiplied/scaled upwards.
|
||||
};
|
||||
|
||||
//! A camera input to handle discrete scroll events that can modify the camera look distance.
|
||||
class OrbitDollyScrollCameraInput : public CameraInput
|
||||
//! A camera input to handle discrete scroll events that can modify the camera pivot distance.
|
||||
class PivotDollyScrollCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
OrbitDollyScrollCameraInput();
|
||||
PivotDollyScrollCameraInput();
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
@@ -509,11 +548,11 @@ namespace AzFramework
|
||||
AZStd::function<float()> m_scrollSpeedFn;
|
||||
};
|
||||
|
||||
//! A camera input to handle motion deltas that can modify the camera look distance.
|
||||
class OrbitDollyCursorMoveCameraInput : public CameraInput
|
||||
//! A camera input to handle motion deltas that can modify the camera pivot distance.
|
||||
class PivotDollyMotionCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
explicit OrbitDollyCursorMoveCameraInput(const InputChannelId& dollyChannelId);
|
||||
explicit PivotDollyMotionCameraInput(const InputChannelId& dollyChannelId);
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool HandleEvents(const InputEvent& event, const ScreenVector& cursorDelta, float scrollDelta) override;
|
||||
@@ -521,7 +560,7 @@ namespace AzFramework
|
||||
|
||||
void SetDollyInputChannelId(const InputChannelId& dollyChannelId);
|
||||
|
||||
AZStd::function<float()> m_cursorSpeedFn;
|
||||
AZStd::function<float()> m_motionSpeedFn;
|
||||
|
||||
private:
|
||||
InputChannelId m_dollyChannelId; //!< Input channel to begin the dolly cursor camera input.
|
||||
@@ -544,36 +583,36 @@ namespace AzFramework
|
||||
|
||||
//! A camera input that doubles as its own set of camera inputs.
|
||||
//! It is 'exclusive', so does not overlap with other sibling camera inputs - it runs its own set of camera inputs as 'children'.
|
||||
class OrbitCameraInput : public CameraInput
|
||||
class PivotCameraInput : public CameraInput
|
||||
{
|
||||
public:
|
||||
using LookAtFn = AZStd::function<AZStd::optional<AZ::Vector3>(const AZ::Vector3& position, const AZ::Vector3& direction)>;
|
||||
using PivotFn = AZStd::function<AZ::Vector3(const AZ::Vector3& position, const AZ::Vector3& direction)>;
|
||||
|
||||
explicit OrbitCameraInput(const InputChannelId& orbitChannelId);
|
||||
explicit PivotCameraInput(const InputChannelId& pivotChannelId);
|
||||
|
||||
// CameraInput overrides ...
|
||||
bool 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;
|
||||
|
||||
void SetOrbitInputChannelId(const InputChannelId& orbitChanneId);
|
||||
void SetPivotInputChannelId(const InputChannelId& pivotChanneId);
|
||||
|
||||
Cameras m_orbitCameras; //!< The camera inputs to run when this camera input is active (only these will run as it is exclusive).
|
||||
Cameras m_pivotCameras; //!< The camera inputs to run when this camera input is active (only these will run as it is exclusive).
|
||||
|
||||
//! Override the default behavior for how a look-at point is calculated.
|
||||
void SetLookAtFn(const LookAtFn& lookAtFn);
|
||||
//! Override the default behavior for how a pivot point is calculated.
|
||||
void SetPivotFn(PivotFn pivotFn);
|
||||
|
||||
private:
|
||||
InputChannelId m_orbitChannelId; //!< Input channel to begin the orbit camera input.
|
||||
LookAtFn m_lookAtFn; //!< The look-at behavior to use for this orbit camera (how is the look-at point calculated/retrieved).
|
||||
InputChannelId m_pivotChannelId; //!< Input channel to begin the pivot camera input.
|
||||
PivotFn m_pivotFn; //!< The pivot position to use for this pivot camera (how is the pivot point calculated/retrieved).
|
||||
};
|
||||
|
||||
inline void OrbitCameraInput::SetLookAtFn(const LookAtFn& lookAtFn)
|
||||
inline void PivotCameraInput::SetPivotFn(PivotFn pivotFn)
|
||||
{
|
||||
m_lookAtFn = lookAtFn;
|
||||
m_pivotFn = AZStd::move(pivotFn);
|
||||
}
|
||||
|
||||
inline bool OrbitCameraInput::Exclusive() const
|
||||
inline bool PivotCameraInput::Exclusive() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
#include <AzFramework/Windowing/WindowBus.h>
|
||||
|
||||
|
||||
@@ -26,7 +26,8 @@ namespace UnitTest
|
||||
{
|
||||
constexpr float deltaTime = 0.01666f; // 60fps
|
||||
const bool consumed = m_cameraSystem->HandleEvents(event);
|
||||
m_camera = m_cameraSystem->StepCamera(m_targetCamera, deltaTime);
|
||||
m_targetCamera = m_cameraSystem->StepCamera(m_targetCamera, deltaTime);
|
||||
m_camera = m_targetCamera; // no smoothing
|
||||
return consumed;
|
||||
}
|
||||
|
||||
@@ -45,20 +46,38 @@ namespace UnitTest
|
||||
m_translateCameraInputChannelIds.m_boostChannelId = AzFramework::InputChannelId("keyboard_key_modifier_shift_l");
|
||||
|
||||
m_firstPersonRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(AzFramework::InputDeviceMouse::Button::Right);
|
||||
m_firstPersonTranslateCamera =
|
||||
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::LookTranslation, m_translateCameraInputChannelIds);
|
||||
// set rotate speed to be a value that will scale motion delta (pixels moved) by a thousandth.
|
||||
m_firstPersonRotateCamera->m_rotateSpeedFn = []()
|
||||
{
|
||||
return 0.001f;
|
||||
};
|
||||
|
||||
m_orbitCamera = AZStd::make_shared<AzFramework::OrbitCameraInput>(m_orbitChannelId);
|
||||
auto orbitRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(AzFramework::InputDeviceMouse::Button::Left);
|
||||
auto orbitTranslateCamera =
|
||||
AZStd::make_shared<AzFramework::TranslateCameraInput>(AzFramework::OrbitTranslation, m_translateCameraInputChannelIds);
|
||||
m_firstPersonTranslateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
|
||||
m_translateCameraInputChannelIds, AzFramework::LookTranslation, AzFramework::TranslatePivot);
|
||||
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(orbitRotateCamera);
|
||||
m_orbitCamera->m_orbitCameras.AddCamera(orbitTranslateCamera);
|
||||
m_pivotCamera = AZStd::make_shared<AzFramework::PivotCameraInput>(m_pivotChannelId);
|
||||
m_pivotCamera->SetPivotFn(
|
||||
[this](const AZ::Vector3&, const AZ::Vector3&)
|
||||
{
|
||||
return m_pivot;
|
||||
});
|
||||
|
||||
auto pivotRotateCamera = AZStd::make_shared<AzFramework::RotateCameraInput>(AzFramework::InputDeviceMouse::Button::Left);
|
||||
// set rotate speed to be a value that will scale motion delta (pixels moved) by a thousandth.
|
||||
pivotRotateCamera->m_rotateSpeedFn = []()
|
||||
{
|
||||
return 0.001f;
|
||||
};
|
||||
|
||||
auto pivotTranslateCamera = AZStd::make_shared<AzFramework::TranslateCameraInput>(
|
||||
m_translateCameraInputChannelIds, AzFramework::PivotTranslation, AzFramework::TranslateOffset);
|
||||
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(pivotRotateCamera);
|
||||
m_pivotCamera->m_pivotCameras.AddCamera(pivotTranslateCamera);
|
||||
|
||||
m_cameraSystem->m_cameras.AddCamera(m_firstPersonRotateCamera);
|
||||
m_cameraSystem->m_cameras.AddCamera(m_firstPersonTranslateCamera);
|
||||
m_cameraSystem->m_cameras.AddCamera(m_orbitCamera);
|
||||
m_cameraSystem->m_cameras.AddCamera(m_pivotCamera);
|
||||
|
||||
// these tests rely on using motion delta, not cursor positions (default is true)
|
||||
AzFramework::ed_cameraSystemUseCursor = false;
|
||||
@@ -68,7 +87,7 @@ namespace UnitTest
|
||||
{
|
||||
AzFramework::ed_cameraSystemUseCursor = true;
|
||||
|
||||
m_orbitCamera.reset();
|
||||
m_pivotCamera.reset();
|
||||
m_firstPersonRotateCamera.reset();
|
||||
m_firstPersonTranslateCamera.reset();
|
||||
|
||||
@@ -78,24 +97,29 @@ namespace UnitTest
|
||||
AllocatorsTestFixture::TearDown();
|
||||
}
|
||||
|
||||
AzFramework::InputChannelId m_orbitChannelId = AzFramework::InputChannelId("keyboard_key_modifier_alt_l");
|
||||
AzFramework::InputChannelId m_pivotChannelId = AzFramework::InputChannelId("keyboard_key_modifier_alt_l");
|
||||
AzFramework::TranslateCameraInputChannelIds m_translateCameraInputChannelIds;
|
||||
AZStd::shared_ptr<AzFramework::RotateCameraInput> m_firstPersonRotateCamera;
|
||||
AZStd::shared_ptr<AzFramework::TranslateCameraInput> m_firstPersonTranslateCamera;
|
||||
AZStd::shared_ptr<AzFramework::OrbitCameraInput> m_orbitCamera;
|
||||
AZStd::shared_ptr<AzFramework::PivotCameraInput> m_pivotCamera;
|
||||
AZ::Vector3 m_pivot = AZ::Vector3::CreateZero();
|
||||
|
||||
//! This is approximately Pi/2 * 1000 - this can be used to rotate the camera 90 degrees (pitch or yaw based
|
||||
//! on vertical or horizontal motion) as the rotate speed function is set to be 1/1000.
|
||||
inline static const int PixelMotionDelta = 1570;
|
||||
};
|
||||
|
||||
TEST_F(CameraInputFixture, BeginAndEndOrbitCameraInputConsumesCorrectEvents)
|
||||
TEST_F(CameraInputFixture, BeginAndEndPivotCameraInputConsumesCorrectEvents)
|
||||
{
|
||||
// begin orbit camera
|
||||
// begin pivot camera
|
||||
const bool consumed1 = HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceKeyboard::Key::ModifierAltL,
|
||||
AzFramework::InputChannel::State::Began });
|
||||
// begin listening for orbit rotate (click detector) - event is not consumed
|
||||
// begin listening for pivot rotate (click detector) - event is not consumed
|
||||
const bool consumed2 = HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceMouse::Button::Left, AzFramework::InputChannel::State::Began });
|
||||
// begin orbit rotate (mouse has moved sufficient distance to initiate)
|
||||
// begin pivot rotate (mouse has moved sufficient distance to initiate)
|
||||
const bool consumed3 = HandleEventAndUpdate(AzFramework::HorizontalMotionEvent{ 5 });
|
||||
// end orbit (mouse up) - event is not consumed
|
||||
// end pivot (mouse up) - event is not consumed
|
||||
const bool consumed4 = HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceMouse::Button::Left, AzFramework::InputChannel::State::Ended });
|
||||
|
||||
@@ -236,29 +260,110 @@ namespace UnitTest
|
||||
EXPECT_TRUE(activationEnded);
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, OrbitCameraInputHandlesLookAtPointAndSelfAtSamePositionWhenOrbiting)
|
||||
TEST_F(CameraInputFixture, PivotCameraInputHandlesLookAtPointAndSelfAtSamePositionWhenPivoting)
|
||||
{
|
||||
// create pathological lookAtFn that just returns the same position as the camera
|
||||
m_orbitCamera->SetLookAtFn(
|
||||
m_pivotCamera->SetPivotFn(
|
||||
[](const AZ::Vector3& position, [[maybe_unused]] const AZ::Vector3& direction)
|
||||
{
|
||||
return position;
|
||||
});
|
||||
|
||||
const auto expectedCameraPosition = AZ::Vector3(10.0f, 10.0f, 10.0f);
|
||||
AzFramework::UpdateCameraFromTransform(
|
||||
m_targetCamera,
|
||||
AZ::Transform::CreateFromQuaternionAndTranslation(
|
||||
AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(0.0f, 0.0f, 90.0f)), AZ::Vector3(10.0f, 10.0f, 10.0f)));
|
||||
AZ::Quaternion::CreateFromEulerAnglesDegrees(AZ::Vector3(0.0f, 0.0f, 90.0f)), expectedCameraPosition));
|
||||
|
||||
m_camera = m_targetCamera;
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_pivotChannelId, AzFramework::InputChannel::State::Began });
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_orbitChannelId, AzFramework::InputChannel::State::Began });
|
||||
// verify the camera yaw has not changed and pivot point matches the expected camera position
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(m_camera.m_yaw, FloatNear(AZ::DegToRad(90.0f), 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pitch, FloatNear(0.0f, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3::CreateZero()));
|
||||
EXPECT_THAT(m_camera.m_pivot, IsClose(expectedCameraPosition));
|
||||
}
|
||||
|
||||
// verify the camera yaw has not changed and the look at point
|
||||
// does not match that of the camera translation
|
||||
using ::testing::Eq;
|
||||
using ::testing::Not;
|
||||
EXPECT_THAT(m_camera.m_yaw, Eq(AZ::DegToRad(90.0f)));
|
||||
EXPECT_THAT(m_camera.m_lookAt, Not(IsClose(m_camera.Translation())));
|
||||
TEST_F(CameraInputFixture, FirstPersonRotateCameraInputRotatesYawByNinetyDegreesWithRequiredPixelDelta)
|
||||
{
|
||||
const auto cameraStartingPosition = AZ::Vector3::CreateAxisY(-10.0f);
|
||||
m_targetCamera.m_pivot = cameraStartingPosition;
|
||||
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceMouse::Button::Right, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::HorizontalMotionEvent{ PixelMotionDelta });
|
||||
|
||||
const float expectedYaw = AzFramework::WrapYawRotation(-AZ::Constants::HalfPi);
|
||||
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(m_camera.m_yaw, FloatNear(expectedYaw, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pitch, FloatNear(0.0f, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pivot, IsClose(cameraStartingPosition));
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3::CreateZero()));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, FirstPersonRotateCameraInputRotatesPitchByNinetyDegreesWithRequiredPixelDelta)
|
||||
{
|
||||
const auto cameraStartingPosition = AZ::Vector3::CreateAxisY(-10.0f);
|
||||
m_targetCamera.m_pivot = cameraStartingPosition;
|
||||
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceMouse::Button::Right, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::VerticalMotionEvent{ PixelMotionDelta });
|
||||
|
||||
const float expectedPitch = AzFramework::ClampPitchRotation(-AZ::Constants::HalfPi);
|
||||
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(m_camera.m_yaw, FloatNear(0.0f, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pitch, FloatNear(expectedPitch, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pivot, IsClose(cameraStartingPosition));
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3::CreateZero()));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, PivotRotateCameraInputRotatesPitchOffsetByNinetyDegreesWithRequiredPixelDelta)
|
||||
{
|
||||
const auto cameraStartingPosition = AZ::Vector3::CreateAxisY(-20.0f);
|
||||
m_targetCamera.m_pivot = cameraStartingPosition;
|
||||
|
||||
m_pivot = AZ::Vector3::CreateAxisY(-10.0f);
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_pivotChannelId, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceMouse::Button::Left, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::VerticalMotionEvent{ PixelMotionDelta });
|
||||
|
||||
const auto expectedCameraEndingPosition = AZ::Vector3(0.0f, -10.0f, 10.0f);
|
||||
const float expectedPitch = AzFramework::ClampPitchRotation(-AZ::Constants::HalfPi);
|
||||
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(m_camera.m_yaw, FloatNear(0.0f, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pitch, FloatNear(expectedPitch, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pivot, IsClose(m_pivot));
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3::CreateAxisY(-10.0f)));
|
||||
EXPECT_THAT(m_camera.Translation(), IsCloseTolerance(expectedCameraEndingPosition, 0.01f));
|
||||
}
|
||||
|
||||
TEST_F(CameraInputFixture, PivotRotateCameraInputRotatesYawOffsetByNinetyDegreesWithRequiredPixelDelta)
|
||||
{
|
||||
const auto cameraStartingPosition = AZ::Vector3(15.0f, -20.0f, 0.0f);
|
||||
m_targetCamera.m_pivot = cameraStartingPosition;
|
||||
|
||||
m_pivot = AZ::Vector3(10.0f, -10.0f, 0.0f);
|
||||
|
||||
HandleEventAndUpdate(AzFramework::DiscreteInputEvent{ m_pivotChannelId, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(
|
||||
AzFramework::DiscreteInputEvent{ AzFramework::InputDeviceMouse::Button::Left, AzFramework::InputChannel::State::Began });
|
||||
HandleEventAndUpdate(AzFramework::HorizontalMotionEvent{ -PixelMotionDelta });
|
||||
|
||||
const auto expectedCameraEndingPosition = AZ::Vector3(20.0f, -5.0f, 0.0f);
|
||||
const float expectedYaw = AzFramework::WrapYawRotation(AZ::Constants::HalfPi);
|
||||
|
||||
using ::testing::FloatNear;
|
||||
EXPECT_THAT(m_camera.m_yaw, FloatNear(expectedYaw, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pitch, FloatNear(0.0f, 0.001f));
|
||||
EXPECT_THAT(m_camera.m_pivot, IsClose(m_pivot));
|
||||
EXPECT_THAT(m_camera.m_offset, IsClose(AZ::Vector3(5.0f, -10.0f, 0.0f)));
|
||||
EXPECT_THAT(m_camera.Translation(), IsCloseTolerance(expectedCameraEndingPosition, 0.01f));
|
||||
}
|
||||
} // namespace UnitTest
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Console/IConsole.h>
|
||||
#include <AzCore/Console/ILogger.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzNetworking
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <AzCore/std/typetraits/conditional.h>
|
||||
#include <AzCore/std/typetraits/is_same.h>
|
||||
#include <AzCore/std/typetraits/is_enum.h>
|
||||
#include <AzCore/RTTI/TypeInfo.h>
|
||||
#include <AzCore/RTTI/TypeInfoSimple.h>
|
||||
#include <AzCore/RTTI/TypeSafeIntegral.h>
|
||||
#include <AzCore/Name/Name.h>
|
||||
#include <AzCore/Name/NameDictionary.h>
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <AzNetworking/Utilities/IpAddress.h>
|
||||
#include <AzNetworking/ConnectionLayer/IConnectionSet.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/std/smart_ptr/unique_ptr.h>
|
||||
|
||||
namespace AzNetworking
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "ReflectedPropertyEditorPage.h"
|
||||
#include <AzQtComponents/Gallery/ui_ReflectedPropertyEditorPage.h>
|
||||
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/EditContext.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
|
||||
@@ -15,7 +15,9 @@
|
||||
#include <AzToolsFramework/Asset/AssetProcessorMessages.h>
|
||||
#include <AzToolsFramework/Asset/AssetSystemComponent.h>
|
||||
#include <AzToolsFramework/AssetEditor/AssetEditorBus.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/RTTI/BehaviorContext.h>
|
||||
|
||||
namespace AzToolsFramework
|
||||
{
|
||||
|
||||
+1
@@ -9,6 +9,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Memory/SystemAllocator.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzToolsFramework/AssetBrowser/Entries/AssetBrowserEntry.h>
|
||||
|
||||
|
||||
+1
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/string/string.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/IO/Path/Path.h>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/Debug/Trace.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
#include <AzCore/IO/SystemFile.h>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) Contributors to the Open 3D Engine Project.
|
||||
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
||||
*
|
||||
*/
|
||||
|
||||
#include "AssetEditorBus.h"
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
namespace AzToolsFramework::AssetEditor
|
||||
{
|
||||
void AssetEditorWindowSettings::Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AssetEditorWindowSettings>()
|
||||
->Field("m_openAssets", &AssetEditorWindowSettings::m_openAssets)
|
||||
;
|
||||
}
|
||||
}
|
||||
} // namespace AzToolsFramework::AssetEditor
|
||||
@@ -8,12 +8,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/Outcome/Outcome.h>
|
||||
#include <AzCore/UserSettings/UserSettings.h>
|
||||
#include <AzCore/Asset/AssetCommon.h>
|
||||
#include <AzCore/std/containers/unordered_map.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
|
||||
namespace AZ { namespace Data { class AssetData; } }
|
||||
namespace AZ::Data
|
||||
{
|
||||
class AssetData;
|
||||
}
|
||||
|
||||
namespace AZStd
|
||||
{
|
||||
@@ -45,15 +47,7 @@ namespace AzToolsFramework
|
||||
|
||||
static constexpr const char* s_name = "AssetEditorWindowSettings";
|
||||
|
||||
static void Reflect(AZ::ReflectContext* context)
|
||||
{
|
||||
if (AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
|
||||
{
|
||||
serializeContext->Class<AssetEditorWindowSettings>()
|
||||
->Field("m_openAssets", &AssetEditorWindowSettings::m_openAssets)
|
||||
;
|
||||
}
|
||||
}
|
||||
static void Reflect(AZ::ReflectContext* context);
|
||||
};
|
||||
|
||||
// External interaction with Asset Editor
|
||||
|
||||
@@ -22,6 +22,7 @@ AZ_POP_DISABLE_WARNING
|
||||
|
||||
#include <AzCore/Asset/AssetManager.h>
|
||||
#include <AzCore/Asset/AssetManagerBus.h>
|
||||
#include <AzCore/Asset/AssetSerializer.h>
|
||||
#include <AzCore/Asset/AssetTypeInfoBus.h>
|
||||
#include <AzCore/Component/ComponentApplicationBus.h>
|
||||
#include <AzCore/IO/FileIO.h>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <AzCore/std/algorithm.h>
|
||||
#include <AzCore/std/sort.h>
|
||||
#include <AzCore/RTTI/AttributeReader.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
#include <AzToolsFramework/Commands/EntityStateCommand.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityInfoBus.h>
|
||||
#include <AzToolsFramework/Entity/EditorEntityContextBus.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AzCore/Component/EntityId.h>
|
||||
#include <AzCore/Interface/Interface.h>
|
||||
#include <AzCore/Serialization/SerializeContext.h>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <AzCore/Math/Quaternion.h>
|
||||
#include <AzCore/Math/Transform.h>
|
||||
#include <AzCore/RTTI/RTTI.h>
|
||||
#include <AzCore/std/containers/set.h>
|
||||
#include <AzCore/std/containers/unordered_set.h>
|
||||
#include <AzCore/std/smart_ptr/enable_shared_from_this.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorBus.h>
|
||||
#include <AzToolsFramework/Manipulators/ManipulatorSpace.h>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user