From b9b55c3eed5e98a4d6c0e9cef2ab3ae455da95f2 Mon Sep 17 00:00:00 2001 From: pconroy Date: Wed, 23 Jun 2021 20:33:43 -0700 Subject: [PATCH 01/16] Show mouse cursor as busy when deleting project --- Code/Tools/ProjectManager/Source/ProjectsScreen.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp index 38d3d3b751..e079d97a8b 100644 --- a/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectsScreen.cpp @@ -41,6 +41,7 @@ #include #include #include +#include //#define DISPLAY_PROJECT_DEV_DATA true @@ -403,9 +404,11 @@ namespace O3DE::ProjectManager if (warningResult == QMessageBox::Yes) { + QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); // Remove project from O3DE and delete from disk HandleRemoveProject(projectPath); ProjectUtils::DeleteProjectFiles(projectPath); + QGuiApplication::restoreOverrideCursor(); } } } From 5b277cc06189485dfc833e52e610088d1f04dc95 Mon Sep 17 00:00:00 2001 From: pconroy Date: Wed, 23 Jun 2021 20:51:55 -0700 Subject: [PATCH 02/16] Show mouse cursor as busy when copying project --- Code/Tools/ProjectManager/Source/ProjectUtils.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp index d2da1ef437..5b93e4faca 100644 --- a/Code/Tools/ProjectManager/Source/ProjectUtils.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectUtils.cpp @@ -14,6 +14,7 @@ #include #include #include +#include namespace O3DE::ProjectManager { @@ -118,9 +119,10 @@ namespace O3DE::ProjectManager return false; } - // TODO: Block UX and Notify User they need to wait - + QGuiApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); copyResult = CopyProject(origPath, newPath); + QGuiApplication::restoreOverrideCursor(); + } return copyResult; From 75dc5be7241b56712b1b5d382798d294b68173b0 Mon Sep 17 00:00:00 2001 From: scottr Date: Thu, 24 Jun 2021 14:59:21 -0700 Subject: [PATCH 03/16] [cpack/2106-compression] enable higher compression of installer artifacts --- cmake/Platform/Windows/Packaging/Template.wxs.in | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmake/Platform/Windows/Packaging/Template.wxs.in b/cmake/Platform/Windows/Packaging/Template.wxs.in index e14e064fbc..6d4dd54f75 100644 --- a/cmake/Platform/Windows/Packaging/Template.wxs.in +++ b/cmake/Platform/Windows/Packaging/Template.wxs.in @@ -14,8 +14,10 @@ - - + + Date: Thu, 24 Jun 2021 15:28:09 -0700 Subject: [PATCH 04/16] Hide cart popup when going back to previous page --- .../Source/GemCatalog/GemCatalogHeaderWidget.cpp | 8 ++++++++ .../Source/GemCatalog/GemCatalogHeaderWidget.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp index 883ae79043..8fb35b906c 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.cpp @@ -175,6 +175,14 @@ namespace O3DE::ProjectManager ShowOverlay(); } + void CartButton::hideEvent(QHideEvent*) + { + if (m_cartOverlay) + { + m_cartOverlay->hide(); + } + } + void CartButton::ShowOverlay() { const QVector toBeAdded = m_gemModel->GatherGemsToBeAdded(); diff --git a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h index 8d6606e63d..dc8f687b31 100644 --- a/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h +++ b/Code/Tools/ProjectManager/Source/GemCatalog/GemCatalogHeaderWidget.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #endif @@ -59,6 +60,7 @@ namespace O3DE::ProjectManager private: void mousePressEvent(QMouseEvent* event) override; + void hideEvent(QHideEvent*) override; GemModel* m_gemModel = nullptr; QHBoxLayout* m_layout = nullptr; From 1db5dc34359d1d26ad9982a84580044c7d22b67a Mon Sep 17 00:00:00 2001 From: mnaumov Date: Thu, 17 Jun 2021 17:21:04 -0700 Subject: [PATCH 05/16] Improving Editor performance while thumbnails are rendering --- .../Code/Source/Thumbnail/ImageThumbnail.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnail.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnail.cpp index 235bb66864..0a2a837539 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnail.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Source/Thumbnail/ImageThumbnail.cpp @@ -58,7 +58,7 @@ namespace ImageProcessingAtom void ImageThumbnail::LoadThread() { - AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::QueueEvent( + AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::Event( AZ::RPI::StreamingImageAsset::RTTI_Type(), &AzToolsFramework::Thumbnailer::ThumbnailerRendererRequests::RenderThumbnail, m_key, ImageThumbnailSize); From ac13551dc032a57e726b19cfd28de19f8a4dfea4 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Thu, 24 Jun 2021 20:14:28 -0500 Subject: [PATCH 06/16] Cherry picking a034500a10a1e0704efe6cb831d02a028cfc28d1 [a034500] (#1580) Adding a factor for alpha affecting specular in the standard and enhanced pbr materials (#1474) * Adding a factor for how much alpha should affect specular to standard and enhanced pbr. Currently blended and tinted transparency always assume that the geometry represents the surface, and the surface may just be transparent like glass. In this model, specular is unnaffected by alpha - perfectly clear glass still reflects light and obeys the Fresnel factor. However alpha may also represent the absence of a surface entirely for mateirals where cut-out alpha is a bad fit because of subpixel detail, like hair or cob webs. This change addresses that by allowing the alpha to also affect specular reflection if desired. * Adding material for ASV test. --- .../Materials/Types/EnhancedPBR.materialtype | 13 ++++++++++ .../Materials/Types/EnhancedPBR_Common.azsli | 1 + .../Types/EnhancedPBR_ForwardPass.azsl | 18 ++++++++++---- .../Materials/Types/StandardPBR.materialtype | 13 ++++++++++ .../Materials/Types/StandardPBR_Common.azsli | 1 + .../Types/StandardPBR_ForwardPass.azsl | 17 ++++++++++--- ...ty_Blended_Alpha_Affects_Specular.material | 24 +++++++++++++++++++ 7 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype index a71fc65e2a..9b2c465352 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR.materialtype @@ -714,6 +714,19 @@ "displayName": "Double-sided", "description": "Whether to render back-faces or just front-faces.", "type": "Bool" + }, + { + "id": "alphaAffectsSpecular", + "displayName": "Alpha affects specular", + "description": "How much the alpha value should also affect specular reflection. This should be 0.0 for materials where light can transmit through their physical surface (like glass), but 1.0 when alpha determines the very presence of a surface (like hair or grass)", + "type": "float", + "min": 0.0, + "max": 1.0, + "defaultValue": 0.0, + "connection": { + "type": "ShaderInput", + "id": "m_opacityAffectsSpecularFactor" + } } ], "uv": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli index dbd36735b8..cf699228c2 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_Common.azsli @@ -50,6 +50,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial float m_anisotropicFactor; // Base layer anisotropic strength of deviation: negative = Bi-Normal direction, positive = Tangent direction float m_opacityFactor; + float m_opacityAffectsSpecularFactor; Texture2D m_opacityMap; uint m_opacityMapUvIndex; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl index f4269d9320..8e9b75e2ad 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/EnhancedPBR_ForwardPass.azsl @@ -326,7 +326,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) { - alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. + float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. + alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor); } PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); @@ -344,8 +345,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular // to be added on top of the diffuse, but then the diffuse must be pre-multiplied. // It's done this way because surface transparency doesn't really change specular response (eg, glass). + lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; } else if (o_opacity_mode == OpacityMode::TintedTransparent) { @@ -362,7 +368,12 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0. lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; + lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w); } else @@ -410,4 +421,3 @@ ForwardPassOutput EnhancedPbr_ForwardPassPS_EDS(VSOutput IN, bool isFrontFace : return OUT; } - diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype index 93220973df..8b7e4b1c7e 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR.materialtype @@ -655,6 +655,19 @@ "displayName": "Double-sided", "description": "Whether to render back-faces or just front-faces.", "type": "Bool" + }, + { + "id": "alphaAffectsSpecular", + "displayName": "Alpha affects specular", + "description": "How much the alpha value should also affect specular reflection. This should be 0.0 for materials where light can transmit through their physical surface (like glass), but 1.0 when alpha determines the very presence of a surface (like hair or grass)", + "type": "float", + "min": 0.0, + "max": 1.0, + "defaultValue": 0.0, + "connection": { + "type": "ShaderInput", + "id": "m_opacityAffectsSpecularFactor" + } } ], "uv": [ diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Common.azsli b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Common.azsli index d4f4e905b1..f0637c6675 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Common.azsli +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_Common.azsli @@ -45,6 +45,7 @@ ShaderResourceGroup MaterialSrg : SRG_PerMaterial float4 m_pad2; // [GFX TODO][ATOM-14595] This is a workaround for a data stomping bug. Remove once it's fixed. float m_opacityFactor; + float m_opacityAffectsSpecularFactor; Texture2D m_opacityMap; uint m_opacityMapUvIndex; diff --git a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl index b2262a65de..2dfdd3681f 100644 --- a/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl +++ b/Gems/Atom/Feature/Common/Assets/Materials/Types/StandardPBR_ForwardPass.azsl @@ -254,7 +254,8 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float if (o_opacity_mode == OpacityMode::Blended || o_opacity_mode == OpacityMode::TintedTransparent) { - alpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. + float fresnelAlpha = FresnelSchlickWithRoughness(lightingData.NdotV, alpha, surface.roughnessLinear).x; // Increase opacity at grazing angles. + alpha = lerp(fresnelAlpha, alpha, MaterialSrg::m_opacityAffectsSpecularFactor); } PbrLightingOutput lightingOutput = GetPbrLightingOutput(surface, lightingData, alpha); @@ -269,8 +270,13 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // For blended mode, we do (dest * alpha) + (source * 1.0). This allows the specular // to be added on top of the diffuse, but then the diffuse must be pre-multiplied. // It's done this way because surface transparency doesn't really change specular response (eg, glass). + lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; } else if (o_opacity_mode == OpacityMode::TintedTransparent) { @@ -287,7 +293,12 @@ PbrLightingOutput ForwardPassPS_Common(VSOutput IN, bool isFrontFace, out float // m_diffuseColor.rgb (source) is added to that, and the final result is stored in render target 0. lightingOutput.m_diffuseColor.rgb *= lightingOutput.m_diffuseColor.w; // pre-multiply diffuse - lightingOutput.m_diffuseColor.rgb += lightingOutput.m_specularColor.rgb; // add specular + + // Add specular. m_opacityAffectsSpecularFactor controls how much the alpha masks out specular contribution. + float3 specular = lightingOutput.m_specularColor.rgb; + specular = lerp(specular, specular * lightingOutput.m_diffuseColor.w, MaterialSrg::m_opacityAffectsSpecularFactor); + lightingOutput.m_diffuseColor.rgb += specular; + lightingOutput.m_specularColor.rgb = baseColor * (1.0 - lightingOutput.m_diffuseColor.w); } else diff --git a/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material new file mode 100644 index 0000000000..dbaec36136 --- /dev/null +++ b/Gems/Atom/TestData/TestData/Materials/StandardPbrTestCases/009_Opacity_Blended_Alpha_Affects_Specular.material @@ -0,0 +1,24 @@ +{ + "description": "", + "materialType": "Materials/Types/StandardPBR.materialtype", + "parentMaterial": "", + "propertyLayoutVersion": 3, + "properties": { + "baseColor": { + "color": [ + 0.5906767249107361, + 1.0, + 0.11703670024871826, + 1.0 + ], + "textureMap": "Textures/Default/default_basecolor.tif" + }, + "opacity": { + "alphaSource": "Split", + "factor": 0.75, + "mode": "Blended", + "textureMap": "TestData/Textures/checker8x8_gray_512.png", + "alphaAffectsSpecular": 1.0 + } + } +} From 8530e783cab7d461a900c1362e04bc3e99c3ec40 Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Thu, 24 Jun 2021 22:23:51 -0500 Subject: [PATCH 07/16] Setting the build timeout for the ProjectBuilder CMake commands to -1 (#1583) This prevents Project build step from timing out Moving the project build directory to be under the /build/ folder to prevent two issues 1. The AssetProcessor from scanning that folder for assets. [Bb]uild is part of the excluded folders 2. To prevent git from seeing modified files in the build directory as the default .gitignore file ignores [Bb]uild --- Code/Tools/ProjectManager/Source/ProjectBuilder.cpp | 4 ++-- Code/Tools/ProjectManager/Source/ProjectManagerDefs.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp b/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp index a97499ab44..4dfe46b3bf 100644 --- a/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp +++ b/Code/Tools/ProjectManager/Source/ProjectBuilder.cpp @@ -24,8 +24,8 @@ namespace O3DE::ProjectManager { - // 10 Minutes - constexpr int MaxBuildTimeMSecs = 600000; + // QProcess::waitForFinished uses -1 to indicate that the process should not timeout + constexpr int MaxBuildTimeMSecs = -1; ProjectBuilderWorker::ProjectBuilderWorker(const ProjectInfo& projectInfo) : QObject() diff --git a/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h b/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h index 1295e84281..1058dae68a 100644 --- a/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h +++ b/Code/Tools/ProjectManager/Source/ProjectManagerDefs.h @@ -13,7 +13,7 @@ namespace O3DE::ProjectManager inline constexpr static int ProjectPreviewImageWidth = 210; inline constexpr static int ProjectPreviewImageHeight = 280; - static const QString ProjectBuildPathPostfix = "Windows_VS2019"; + static const QString ProjectBuildPathPostfix = "build/windows_vs2019"; static const QString ProjectBuildErrorLogPathPostfix = "CMakeFiles/CMakeProjectBuildError.log"; static const QString ProjectPreviewImagePath = "preview.png"; } // namespace O3DE::ProjectManager From 03138f49361f2f895e65d33bfff5e287adbc6037 Mon Sep 17 00:00:00 2001 From: michabr <82236305+michabr@users.noreply.github.com> Date: Thu, 24 Jun 2021 22:19:52 -0700 Subject: [PATCH 08/16] Fix for cursor not being displayed when asked to display (#1574) --- .../CryCommon/LyShine/Bus/UiSystemBus.h | 5 ---- Code/CryEngine/CrySystem/System.h | 1 - Code/CryEngine/CrySystem/SystemInit.cpp | 24 ------------------- .../Code/Source/LyShineSystemComponent.cpp | 8 ++----- .../Code/Source/LyShineSystemComponent.h | 1 - 5 files changed, 2 insertions(+), 37 deletions(-) diff --git a/Code/CryEngine/CryCommon/LyShine/Bus/UiSystemBus.h b/Code/CryEngine/CryCommon/LyShine/Bus/UiSystemBus.h index 682bfe753e..8b17ca591c 100644 --- a/Code/CryEngine/CryCommon/LyShine/Bus/UiSystemBus.h +++ b/Code/CryEngine/CryCommon/LyShine/Bus/UiSystemBus.h @@ -18,11 +18,6 @@ public: // Public functions - //! Initialize the UI system. This should be called when all other systems that the UI - //! system depends upon are initialized. Once the engine is fully modularized this - //! function will be unnecessary. - virtual void InitializeSystem() {} - //! Register a component type with the UI system. //! The order in which component types are registered is the order that they show up in //! the add component and in the properties pane. diff --git a/Code/CryEngine/CrySystem/System.h b/Code/CryEngine/CrySystem/System.h index 2ecc8ebeb2..8c122d0df2 100644 --- a/Code/CryEngine/CrySystem/System.h +++ b/Code/CryEngine/CrySystem/System.h @@ -431,7 +431,6 @@ private: bool InitFileSystem(); bool InitFileSystem_LoadEngineFolders(const SSystemInitParams& initParams); bool InitAudioSystem(const SSystemInitParams& initParams); - bool InitShine(const SSystemInitParams& initParams); //@} diff --git a/Code/CryEngine/CrySystem/SystemInit.cpp b/Code/CryEngine/CrySystem/SystemInit.cpp index 7464df8ec2..4b07de6933 100644 --- a/Code/CryEngine/CrySystem/SystemInit.cpp +++ b/Code/CryEngine/CrySystem/SystemInit.cpp @@ -852,16 +852,6 @@ bool CSystem::InitVTuneProfiler() return true; } -///////////////////////////////////////////////////////////////////////////////// -bool CSystem::InitShine([[maybe_unused]] const SSystemInitParams& initParams) -{ - LOADING_TIME_PROFILE_SECTION(GetISystem()); - - EBUS_EVENT(UiSystemBus, InitializeSystem); - - return true; -} - ////////////////////////////////////////////////////////////////////////// void CSystem::InitLocalization() { @@ -1550,20 +1540,6 @@ AZ_POP_DISABLE_WARNING } m_Time.ResetTimer(); - ////////////////////////////////////////////////////////////////////////// - // UI. Should be after input and hardware mouse - ////////////////////////////////////////////////////////////////////////// - if (!m_bDedicatedServer) - { - AZ_Printf(AZ_TRACE_SYSTEM_WINDOW, "UI system initialization"); - INDENT_LOG_DURING_SCOPE(); - if (!InitShine(startupParams)) - { - return false; - } - } - - InlineInitializationProcessing("CSystem::Init InitShine"); // CONSOLE ////////////////////////////////////////////////////////////////////////// if (!InitConsole()) diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp index 7a57f3aeb4..ff23f21945 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.cpp @@ -202,12 +202,6 @@ namespace LyShine LyShineAllocatorScope::DeactivateAllocators(); } - //////////////////////////////////////////////////////////////////////////////////////////////////// - void LyShineSystemComponent::InitializeSystem() - { - BroadcastCursorImagePathname(); - } - //////////////////////////////////////////////////////////////////////////////////////////////////// void LyShineSystemComponent::RegisterComponentTypeForMenuOrdering(const AZ::Uuid& typeUuid) { @@ -379,6 +373,8 @@ namespace LyShine #endif m_pLyShine = new CLyShine(gEnv->pSystem); gEnv->pLyShine = m_pLyShine; + + BroadcastCursorImagePathname(); } void LyShineSystemComponent::OnCrySystemShutdown([[maybe_unused]] ISystem& system) diff --git a/Gems/LyShine/Code/Source/LyShineSystemComponent.h b/Gems/LyShine/Code/Source/LyShineSystemComponent.h index f4bd478067..50a8ee5aba 100644 --- a/Gems/LyShine/Code/Source/LyShineSystemComponent.h +++ b/Gems/LyShine/Code/Source/LyShineSystemComponent.h @@ -60,7 +60,6 @@ namespace LyShine //////////////////////////////////////////////////////////////////////// // UiSystemBus interface implementation - void InitializeSystem() override; void RegisterComponentTypeForMenuOrdering(const AZ::Uuid& typeUuid) override; const AZStd::vector* GetComponentTypesForMenuOrdering() override; const AZStd::list* GetLyShineComponentDescriptors(); From 0ad6346e8b7c564a9dfe605c0f06143c6534f2ee Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Fri, 25 Jun 2021 02:41:52 -0700 Subject: [PATCH 09/16] [LYN-4718] [Forums]: [Bug] Editor crashes consistently when EmotionFX is open and Play Game is used (#1552) --- Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp b/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp index 0a1137d7d9..69cccace81 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Assets/ActorAsset.cpp @@ -63,6 +63,8 @@ namespace EMotionFX &actorSettings, ""); + // Set the is owned by runtime flag before finalizing the actor, as that uses the flag already. + assetData->m_emfxActor->SetIsOwnedByRuntime(true); assetData->m_emfxActor->Finalize(); // Clear out the EMFX raw asset data. @@ -74,8 +76,6 @@ namespace EMotionFX return false; } - assetData->m_emfxActor->SetIsOwnedByRuntime(true); - // Note: Render actor depends on the mesh asset, so we need to manually create it after mesh asset has been loaded. return static_cast(assetData->m_emfxActor); } From bf0816fb69098ca49da97572d8407b49400b85bf Mon Sep 17 00:00:00 2001 From: Benjamin Jillich <43751992+amzn-jillich@users.noreply.github.com> Date: Fri, 25 Jun 2021 02:47:09 -0700 Subject: [PATCH 10/16] [LYN-4574] [LYN-4603] [LYN-4669] Saving motions and actors to json-based .assetinfo files in the Animation Editor fails (#1509) * Fixes saving motions from within the Animation Editor * Fixes saving actors from within the Animation Editor * The motion event chunk of the .motion file format now also stores the event data as json (rather than XML) reducing motion file sizes (Example: 60KB motion went down to 49KB, containing only 4 motion events from 2 tracks). * Fully backward compatible * New motion meta data rule stores the event data directly rather than command strings or objects. This is the way that aligns with the Json paradigm and as side-effect bypasses the optionals that we use for the commands which fixes the issue. * [LYN-4574] Adding new motion event meta data rule that stores the event data directly rather than via commands to align with the Json paradigm * [LYN-4574] Preparing motion, event table and event track for Json serialization * [LYN-4574] New chunk to store motion event data in Json format (fully backward compatible to XML) * [LYN-4669] Json: Empty AZStd::vector> serializes into 1x element with nullptr as data * [LYN-4603] EMotion FX: Cannot save actors with physics or simulated object setup in Json format --- .../Serialization/Json/JsonSerializer.cpp | 3 + .../CommandSystem/Source/MetaData.cpp | 42 --------- .../EMotionFX/CommandSystem/Source/MetaData.h | 7 -- .../Exporter/MotionEventExport.cpp | 38 ++++++-- .../RCExt/Motion/MotionGroupExporter.cpp | 12 ++- .../Behaviors/MotionGroupBehavior.cpp | 15 ++-- .../Pipeline/SceneAPIExt/Rules/MetaDataRule.h | 2 +- .../SceneAPIExt/Rules/MotionMetaDataRule.cpp | 53 ++++++++++++ .../SceneAPIExt/Rules/MotionMetaDataRule.h | 51 +++++++++++ .../SceneAPIExt/sceneapi_ext_files.cmake | 2 + .../EMotionFX/Code/EMotionFX/Source/Event.cpp | 10 +++ Gems/EMotionFX/Code/EMotionFX/Source/Event.h | 13 +-- .../Source/Importer/ChunkProcessors.cpp | 63 +++++++++++++- .../Source/Importer/ChunkProcessors.h | 1 + .../EMotionFX/Source/Importer/Importer.cpp | 1 + .../Code/EMotionFX/Source/Motion.cpp | 37 ++------ Gems/EMotionFX/Code/EMotionFX/Source/Motion.h | 20 ++--- .../EMotionFX/Source/MotionEventTable.cpp | 20 +---- .../Code/EMotionFX/Source/MotionEventTable.h | 13 +-- .../EMotionFX/Source/MotionEventTrack.cpp | 86 ++++++++----------- .../Code/EMotionFX/Source/MotionEventTrack.h | 24 ++---- .../Code/EMotionFX/Source/PhysicsSetup.cpp | 10 ++- .../EMStudioSDK/Source/Commands.cpp | 58 ++++++++++++- .../Code/Tests/EventManagerTests.cpp | 4 +- 24 files changed, 372 insertions(+), 213 deletions(-) create mode 100644 Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp create mode 100644 Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h diff --git a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp index 51943536e8..057c0591b0 100644 --- a/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp +++ b/Code/Framework/AzCore/AzCore/Serialization/Json/JsonSerializer.cpp @@ -483,6 +483,9 @@ namespace AZ // tell the caller of this function to write the type id and provide a default object, if requested, for // the specific polymorphic instance the pointer is pointing to. const AZ::Uuid& actualClassId = rtti.GetActualUuid(object); + + // Note: If it is crashing here, it might be that you're serializing a pointer and forgot to initialize it with nullptr. + // Check the elementClassData to identify the causing element. const AZ::Uuid& actualDefaultClassId = rtti.GetActualUuid(defaultObject); if (actualClassId != rtti.GetTypeId()) diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp index 9409f1468d..0cc96d8a2e 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.cpp @@ -24,48 +24,6 @@ namespace CommandSystem { - - AZStd::vector MetaData::GenerateMotionMetaData(EMotionFX::Motion* motion) - { - AZStd::vector commands; - - if (!motion) - { - AZ_Error("EMotionFX", false, "Cannot generate meta data for motion. Motion invalid."); - return commands; - } - - // Save event tracks including motion events. - CommandAdjustMotion* adjustMotionCommand = aznew CommandAdjustMotion(); - adjustMotionCommand->SetMotionExtractionFlags(motion->GetMotionExtractionFlags()); - commands.emplace_back(adjustMotionCommand); - - const size_t eventTrackCount = motion->GetEventTable()->GetNumTracks(); - for (size_t trackIndex = 0; trackIndex < eventTrackCount; ++trackIndex) - { - const EMotionFX::MotionEventTrack* track = motion->GetEventTable()->GetTrack(trackIndex); - - CommandCreateMotionEventTrack* createMotionEventTrackCommand = aznew CommandCreateMotionEventTrack(); - createMotionEventTrackCommand->SetEventTrackName(track->GetName()); - commands.emplace_back(createMotionEventTrackCommand); - - const size_t eventCount = track->GetNumEvents(); - for (size_t eventIndex = 0; eventIndex < eventCount; ++eventIndex) - { - const EMotionFX::MotionEvent& event = track->GetEvent(eventIndex); - CommandCreateMotionEvent* createMotionEventCommand = aznew CommandCreateMotionEvent(); - commands.emplace_back(createMotionEventCommand); - createMotionEventCommand->SetEventTrackName(track->GetName()); - createMotionEventCommand->SetStartTime(event.GetStartTime()); - createMotionEventCommand->SetEndTime(event.GetEndTime()); - createMotionEventCommand->SetEventDatas(event.GetEventDatas()); - } - } - - return commands; - } - - bool MetaData::ApplyMetaDataOnMotion(EMotionFX::Motion* motion, const AZStd::vector& metaDataCommands) { for (MCore::Command* command : metaDataCommands) diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.h b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.h index c309bf04be..7fba241110 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.h +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/MetaData.h @@ -30,13 +30,6 @@ namespace CommandSystem class COMMANDSYSTEM_API MetaData { public: - /** - * Constructs a list of commands representing the changes the user did on the source asset and returns it as a string. - * @param motion The motion to read the changes from. - * @result A string containing a list of commands. - */ - static AZStd::vector GenerateMotionMetaData(EMotionFX::Motion* motion); - /** * Use the given list , prepare it for the given motion and apply the meta data. * @param motion The motion to apply the meta data on. diff --git a/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/MotionEventExport.cpp b/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/MotionEventExport.cpp index db2dcafbdc..78daf024f5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/MotionEventExport.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Exporters/ExporterLib/Exporter/MotionEventExport.cpp @@ -5,6 +5,13 @@ * */ +#include +#include +#include +#include +#include +#include +#include #include "Exporter.h" #include #include @@ -28,17 +35,38 @@ namespace ExporterLib return; } - AZ::Outcome serializedMotionEventTable = MCore::ReflectionSerializer::Serialize(motionEventTable); - if (!serializedMotionEventTable.IsSuccess()) + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!context) { + AZ_Error("EMotionFX", false, "Can't save motion events. Can't get serialize context from component application."); return; } - const size_t serializedTableSizeInBytes = serializedMotionEventTable.GetValue().size(); + + AZ::JsonSerializerSettings settings; + settings.m_serializeContext = context; + rapidjson::Document jsonDocument; + auto jsonResult = AZ::JsonSerialization::Store(jsonDocument, jsonDocument.GetAllocator(), *motionEventTable, settings); + if (jsonResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted) + { + AZ_Error("EMotionFX", false, "JSON serialization failed: %s", jsonResult.ToString("").c_str()); + return; + } + + AZStd::string serializedMotionEventTable; + auto writeToStringOutcome = AzFramework::FileFunc::WriteJsonToString(jsonDocument, serializedMotionEventTable); + if (!writeToStringOutcome.IsSuccess()) + { + AZ_Error("EMotionFX", false, "WriteJsonToString failed: %s", writeToStringOutcome.GetError().c_str()); + return; + } + + const size_t serializedTableSizeInBytes = serializedMotionEventTable.size(); // the motion event table chunk header EMotionFX::FileFormat::FileChunk chunkHeader; chunkHeader.mChunkID = EMotionFX::FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE; - chunkHeader.mVersion = 2; + chunkHeader.mVersion = 3; chunkHeader.mSizeInBytes = static_cast(serializedTableSizeInBytes + sizeof(EMotionFX::FileFormat::FileMotionEventTableSerialized)); @@ -51,6 +79,6 @@ namespace ExporterLib // save the chunk header and the chunk file->Write(&chunkHeader, sizeof(EMotionFX::FileFormat::FileChunk)); file->Write(&tableHeader, sizeof(EMotionFX::FileFormat::FileMotionEventTableSerialized)); - file->Write(serializedMotionEventTable.GetValue().c_str(), serializedTableSizeInBytes); + file->Write(serializedMotionEventTable.c_str(), serializedTableSizeInBytes); } } // namespace ExporterLib diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp index c077324ef1..b44f2c36b3 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -72,7 +73,7 @@ namespace EMotionFX result += SceneEvents::Process(dataBuilderContext, AZ::RC::Phase::Filling); result += SceneEvents::Process(dataBuilderContext, AZ::RC::Phase::Finalizing); - // Check if there is meta data and apply it to the motion. + // Legacy meta data: Check if there is legacy (XML) event data rule and apply it. AZStd::vector metaDataCommands; if (Rule::MetaDataRule::LoadMetaData(motionGroup, metaDataCommands)) { @@ -82,6 +83,15 @@ namespace EMotionFX } } + // Apply motion meta data. + EMotionFX::Pipeline::Rule::MotionMetaData motionMetaData; + if (EMotionFX::Pipeline::Rule::LoadFromGroup(motionGroup, motionMetaData)) + { + motion->SetEventTable(AZStd::unique_ptr(motionMetaData.m_motionEventTable)); + motion->GetEventTable()->InitAfterLoading(motion); + motion->SetMotionExtractionFlags(motionMetaData.m_motionExtractionFlags); + } + ExporterLib::SaveMotion(filename, motion, MCore::Endian::ENDIAN_LITTLE); static AZ::Data::AssetType emotionFXMotionAssetType("{00494B8E-7578-4BA2-8B28-272E90680787}"); // from MotionAsset.h in EMotionFX Gem context.m_products.AddProduct(AZStd::move(filename), context.m_group.GetId(), emotionFXMotionAssetType, diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionGroupBehavior.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionGroupBehavior.cpp index ceffaf29ea..42f369d992 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionGroupBehavior.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionGroupBehavior.cpp @@ -17,12 +17,13 @@ #include #include -#include +#include #include +#include +#include +#include #include #include -#include -#include namespace EMotionFX { @@ -35,11 +36,13 @@ namespace EMotionFX void MotionGroupBehavior::Reflect(AZ::ReflectContext* context) { Group::MotionGroup::Reflect(context); - Rule::MotionScaleRule::Reflect(context); - Rule::MotionCompressionSettingsRule::Reflect(context); - Rule::MorphTargetRuleReadOnly::Reflect(context); Rule::MotionAdditiveRule::Reflect(context); + Rule::MotionCompressionSettingsRule::Reflect(context); + Rule::MotionMetaData::Reflect(context); + Rule::MotionMetaDataRule::Reflect(context); Rule::MotionSamplingRule::Reflect(context); + Rule::MotionScaleRule::Reflect(context); + Rule::MorphTargetRuleReadOnly::Reflect(context); AZ::SerializeContext* serializeContext = azrtti_cast(context); if (serializeContext) diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MetaDataRule.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MetaDataRule.h index bc9a440cc2..58250174da 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MetaDataRule.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MetaDataRule.h @@ -57,7 +57,7 @@ namespace EMotionFX /** * Set the meta data string which contains a list of commands representing the changes the user did on the source asset. - * This string can be constructed using CommandSystem::GenerateMotionMetaData() and CommandSystem::GenerateActorMetaData(). + * This string can be constructed using CommandSystem::GenerateActorMetaData(). * @param metaData The meta data string containing a list of commands to be applied on the source asset. */ void SetMetaData(const AZStd::string& metaData); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp new file mode 100644 index 0000000000..f57e4ec268 --- /dev/null +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#include +#include +#include +#include +#include + +namespace EMotionFX::Pipeline::Rule +{ + void MotionMetaData::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (!serializeContext) + { + return; + } + + serializeContext->Class() + ->Version(1) + ->Field("motionEventTable", &MotionMetaData::m_motionEventTable) + ->Field("motionExtractionFlags", &MotionMetaData::m_motionExtractionFlags) + ; + } + + MotionMetaDataRule::MotionMetaDataRule() + : ExternalToolRule() + { + } + + MotionMetaDataRule::MotionMetaDataRule(const MotionMetaData& data) + : MotionMetaDataRule() + { + m_data = data; + } + + void MotionMetaDataRule::Reflect(AZ::ReflectContext* context) + { + AZ::SerializeContext* serializeContext = azrtti_cast(context); + if (serializeContext) + { + serializeContext->Class() + ->Version(1) + ->Field("data", &MotionMetaDataRule::m_data) + ; + } + } +} // EMotionFX::Pipeline::Rule diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h new file mode 100644 index 0000000000..099451ff7e --- /dev/null +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) Contributors to the Open 3D Engine Project + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + * + */ + +#pragma once + +#include +#include +#include +#include +#include + +namespace EMotionFX::Pipeline::Rule +{ + struct MotionMetaData + { + AZ_RTTI(EMotionFX::Pipeline::Rule::MotionMetaData, "{A381A915-3CB3-4F60-82B3-70865CFA1F4F}"); + AZ_CLASS_ALLOCATOR(MotionMetaData, AZ::SystemAllocator, 0) + + MotionMetaData() = default; + virtual ~MotionMetaData() = default; + + static void Reflect(AZ::ReflectContext* context); + + EMotionFX::MotionEventTable* m_motionEventTable = nullptr; + EMotionFX::EMotionExtractionFlags m_motionExtractionFlags; + }; + + class MotionMetaDataRule + : public ExternalToolRule + { + public: + AZ_RTTI(EMotionFX::Pipeline::Rule::MotionMetaDataRule, "{E68D0C3D-CBFF-4536-95C1-676474B351A5}", AZ::SceneAPI::DataTypes::IRule); + AZ_CLASS_ALLOCATOR(MotionMetaDataRule, AZ::SystemAllocator, 0) + + MotionMetaDataRule(); + MotionMetaDataRule(const MotionMetaData& data); + ~MotionMetaDataRule() final = default; + + const MotionMetaData& GetData() const override { return m_data; } + void SetData(const MotionMetaData& data) override { m_data = data; } + + static void Reflect(AZ::ReflectContext* context); + + private: + MotionMetaData m_data; + }; +} // EMotionFX::Pipeline::Rule diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/sceneapi_ext_files.cmake b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/sceneapi_ext_files.cmake index bf8977b317..211f85cb1c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/sceneapi_ext_files.cmake +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/sceneapi_ext_files.cmake @@ -37,6 +37,8 @@ set(FILES Rules/IMotionCompressionSettingsRule.h Rules/MotionCompressionSettingsRule.h Rules/MotionCompressionSettingsRule.cpp + Rules/MotionMetaDataRule.h + Rules/MotionMetaDataRule.cpp Rules/IMotionScaleRule.h Rules/MotionScaleRule.h Rules/MotionScaleRule.cpp diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Event.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Event.cpp index 62c3924d78..e69ef9f20e 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Event.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Event.cpp @@ -15,6 +15,16 @@ namespace EMotionFX { AZ_CLASS_ALLOCATOR_IMPL(Event, MotionEventAllocator, 0) + Event::Event(EventDataPtr&& data) + : m_eventDatas{ AZStd::move(data) } + { + } + + Event::Event(EventDataSet&& datas) + : m_eventDatas(AZStd::move(datas)) + { + } + void Event::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Event.h b/Gems/EMotionFX/Code/EMotionFX/Source/Event.h index 8ac3e48a8c..6665ef1ae3 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Event.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Event.h @@ -27,16 +27,9 @@ namespace EMotionFX AZ_RTTI(Event, "{67549E9F-8E3F-4336-BDB8-716AFCBD4985}"); AZ_CLASS_ALLOCATOR_DECL - Event(EventDataPtr&& data = nullptr) - : m_eventDatas{AZStd::move(data)} - { - } - - Event(EventDataSet&& datas) - : m_eventDatas(AZStd::move(datas)) - { - } - + Event() = default; + explicit Event(EventDataPtr&& data); + explicit Event(EventDataSet&& datas); virtual ~Event() = default; static void Reflect(AZ::ReflectContext* context); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp index 1ca657af5f..ac4a44b8c0 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp @@ -6,10 +6,17 @@ */ #include +#include +#include #include #include #include #include +#include +#include +#include +#include + #include #include #include @@ -1161,10 +1168,11 @@ namespace EMotionFX AZStd::vector buffer(fileEventTable.m_size); file->Read(&buffer[0], fileEventTable.m_size); - MotionEventTable* motionEventTable = AZ::Utils::LoadObjectFromBuffer(&buffer[0], buffer.size(), context); + auto motionEventTable = AZStd::unique_ptr(AZ::Utils::LoadObjectFromBuffer(&buffer[0], buffer.size(), context)); if (motionEventTable) { - motionEventTable->InitAfterLoading(motion); + motion->SetEventTable(AZStd::move(motionEventTable)); + motion->GetEventTable()->InitAfterLoading(motion); return true; } @@ -1173,6 +1181,57 @@ namespace EMotionFX //================================================================================================= + bool ChunkProcessorMotionEventTrackTable3::Process(MCore::File* file, Importer::ImportParameters& importParams) + { + Motion* motion = importParams.mMotion; + MCORE_ASSERT(motion); + + FileFormat::FileMotionEventTableSerialized fileEventTable; + file->Read(&fileEventTable, sizeof(FileFormat::FileMotionEventTableSerialized)); + + if (GetLogging()) + { + MCore::LogDetailedInfo("- Motion Event Table:"); + MCore::LogDetailedInfo(" + size = %d", fileEventTable.m_size); + } + + AZStd::vector buffer(fileEventTable.m_size); + file->Read(&buffer[0], fileEventTable.m_size); + AZStd::string_view bufferStringView(&buffer[0], buffer.size()); + + auto readJsonOutcome = AzFramework::FileFunc::ReadJsonFromString(bufferStringView); + AZStd::string errorMsg; + if (!readJsonOutcome.IsSuccess()) + { + AZ_Error("EMotionFX", false, "Loading motion event table failed due to ReadJsonFromString. %s", readJsonOutcome.TakeError().c_str()); + return false; + } + rapidjson::Document document = readJsonOutcome.TakeValue(); + + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!context) + { + return false; + } + + AZ::JsonDeserializerSettings settings; + settings.m_serializeContext = context; + + MotionEventTable* motionEventTable = motion->GetEventTable(); + AZ::JsonSerializationResult::ResultCode jsonResult = AZ::JsonSerialization::Load(*motionEventTable, document, settings); + if (jsonResult.GetProcessing() == AZ::JsonSerializationResult::Processing::Halted) + { + AZ_Error("EMotionFX", false, "Loading motion event table failed due to AZ::JsonSerialization::Load."); + return false; + } + + motionEventTable->InitAfterLoading(motion); + return true; + } + + //================================================================================================= + bool ChunkProcessorActorInfo::Process(MCore::File* file, Importer::ImportParameters& importParams) { const MCore::Endian::EEndianType endianType = importParams.mEndianType; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h index a319af42c8..057ebea83f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h @@ -312,6 +312,7 @@ namespace EMotionFX // shared file format chunk processors EMFX_CHUNKPROCESSOR(ChunkProcessorMotionEventTrackTable, FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE, 1) EMFX_CHUNKPROCESSOR(ChunkProcessorMotionEventTrackTable2, FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE, 2) + EMFX_CHUNKPROCESSOR(ChunkProcessorMotionEventTrackTable3, FileFormat::SHARED_CHUNK_MOTIONEVENTTABLE, 3) // Actor file format chunk processors EMFX_CHUNKPROCESSOR(ChunkProcessorActorInfo, FileFormat::ACTOR_CHUNK_INFO, 1) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp index 2e568d2539..2c74c5f4e9 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp @@ -1061,6 +1061,7 @@ namespace EMotionFX // shared processors RegisterChunkProcessor(aznew ChunkProcessorMotionEventTrackTable()); RegisterChunkProcessor(aznew ChunkProcessorMotionEventTrackTable2()); + RegisterChunkProcessor(aznew ChunkProcessorMotionEventTrackTable3()); // Actor file format RegisterChunkProcessor(aznew ChunkProcessorActorInfo()); diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp index 3c34fb83f0..bff1f855d6 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.cpp @@ -26,29 +26,20 @@ namespace EMotionFX { AZ_CLASS_ALLOCATOR_IMPL(Motion, MotionAllocator, 0) - - // constructor Motion::Motion(const char* name) : BaseObject() { - mCustomData = nullptr; - mNameID = MCORE_INVALIDINDEX32; - mID = MCore::GetIDGenerator().GenerateID(); - mEventTable = aznew MotionEventTable(); - mUnitType = GetEMotionFX().GetUnitType(); - mFileUnitType = mUnitType; - mExtractionFlags = static_cast(0); - m_motionData = nullptr; + mID = MCore::GetIDGenerator().GenerateID(); + m_eventTable = AZStd::make_unique(); + mUnitType = GetEMotionFX().GetUnitType(); + mFileUnitType = mUnitType; + mExtractionFlags = static_cast(0); if (name) { SetName(name); } - mMotionFPS = 30.0f; - mDirtyFlag = false; - mAutoUnregister = true; - #if defined(EMFX_DEVELOPMENT_BUILD) mIsOwnedByRuntime = false; #endif // EMFX_DEVELOPMENT_BUILD @@ -57,8 +48,6 @@ namespace EMotionFX GetMotionManager().AddMotion(this); } - - // destructor Motion::~Motion() { // trigger the OnDeleteMotion event @@ -70,11 +59,6 @@ namespace EMotionFX GetMotionManager().RemoveMotion(this, false); } - if (mEventTable) - { - mEventTable->Destroy(); - } - delete m_motionData; } @@ -208,19 +192,14 @@ namespace EMotionFX MotionEventTable* Motion::GetEventTable() const { - return mEventTable; + return m_eventTable.get(); } - void Motion::SetEventTable(MotionEventTable* newTable) + void Motion::SetEventTable(AZStd::unique_ptr eventTable) { - if (mEventTable && mEventTable != newTable) - { - mEventTable->Destroy(); - } - mEventTable = newTable; + m_eventTable = AZStd::move(eventTable); } - void Motion::SetID(uint32 id) { mID = id; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h index 7e66350cdc..e34e2ef7ab 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Motion.h @@ -7,7 +7,7 @@ #pragma once -// include the required headers +#include #include "EMotionFXConfig.h" #include "EMotionFXManager.h" #include "PlayBackInfo.h" @@ -115,7 +115,7 @@ namespace EMotionFX * Set the event table. * @param newTable The new motion event table for the Motion to use. */ - void SetEventTable(MotionEventTable* newTable); + void SetEventTable(AZStd::unique_ptr eventTable); /** * Set the motion framerate. @@ -249,19 +249,19 @@ namespace EMotionFX void SetMotionData(MotionData* motionData, bool delOldFromMem=true); protected: - MotionData* m_motionData; /**< The motion data, which can in theory be any data representation/compression. */ + MotionData* m_motionData = nullptr; /**< The motion data, which can in theory be any data representation/compression. */ AZStd::string mFileName; /**< The filename of the motion. */ PlayBackInfo m_defaultPlayBackInfo; /**< The default/fallback motion playback info which will be used when no playback info is passed to the Play() function. */ - MotionEventTable* mEventTable; /**< The event table, which contains all events, and will make sure events get executed. */ + AZStd::unique_ptr m_eventTable; /**< The event table, which contains all events, and will make sure events get executed. */ MCore::Distance::EUnitType mUnitType; /**< The type of units used. */ MCore::Distance::EUnitType mFileUnitType; /**< The type of units used, inside the file that got loaded. */ - void* mCustomData; /**< A pointer to custom user data that is linked with this motion object. */ - float mMotionFPS; /**< The number of keyframes per second. */ - uint32 mNameID; /**< The ID represention the name or description of this motion. */ - uint32 mID; /**< The unique identification number for the motion. */ + void* mCustomData = nullptr; /**< A pointer to custom user data that is linked with this motion object. */ + float mMotionFPS = 30.0f; /**< The number of keyframes per second. */ + uint32 mNameID = MCORE_INVALIDINDEX32; /**< The ID represention the name or description of this motion. */ + uint32 mID = MCORE_INVALIDINDEX32; /**< The unique identification number for the motion. */ EMotionExtractionFlags mExtractionFlags; /**< The motion extraction flags, which define behavior of the motion extraction system when applied to this motion. */ - bool mDirtyFlag; /**< The dirty flag which indicates whether the user has made changes to the motion since the last file save operation. */ - bool mAutoUnregister; /**< Automatically unregister the motion from the motion manager when this motion gets deleted? Default is true. */ + bool mDirtyFlag = false; /**< The dirty flag which indicates whether the user has made changes to the motion since the last file save operation. */ + bool mAutoUnregister = true; /**< Automatically unregister the motion from the motion manager when this motion gets deleted? Default is true. */ #if defined(EMFX_DEVELOPMENT_BUILD) bool mIsOwnedByRuntime; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.cpp index 2060203166..751f7e551a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.cpp @@ -5,7 +5,6 @@ * */ -// include the required headers #include "MotionEventTable.h" #include "MotionEvent.h" #include "MotionEventTrack.h" @@ -19,22 +18,11 @@ namespace EMotionFX { AZ_CLASS_ALLOCATOR_IMPL(MotionEventTable, MotionEventAllocator, 0) - - // constructor - MotionEventTable::MotionEventTable() - : BaseObject() - , m_syncTrack(nullptr) - { - } - - - // destructor MotionEventTable::~MotionEventTable() { RemoveAllTracks(); } - void MotionEventTable::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); @@ -56,7 +44,6 @@ namespace EMotionFX track->SetMotion(motion); } - motion->SetEventTable(this); AutoCreateSyncTrack(motion); } @@ -96,7 +83,7 @@ namespace EMotionFX { for (MotionEventTrack* track : m_tracks) { - track->Destroy(); + delete track; } } @@ -109,7 +96,7 @@ namespace EMotionFX { if (delFromMem) { - m_tracks[index]->Destroy(); + delete m_tracks[index]; } m_tracks.erase(AZStd::next(m_tracks.begin(), index)); @@ -196,9 +183,8 @@ namespace EMotionFX AnimGraphSyncTrack* syncTrack; if (!track) { - // create and add the sync track syncTrack = aznew AnimGraphSyncTrack("Sync", motion); - AddTrack(syncTrack); + InsertTrack(0, syncTrack); } else { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.h index 25726134ae..2101843a52 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTable.h @@ -7,9 +7,7 @@ #pragma once -// include the required headers #include "EMotionFXConfig.h" -#include "BaseObject.h" #include "AnimGraphSyncTrack.h" #include @@ -40,17 +38,15 @@ namespace EMotionFX * The handling of those events is done by the MotionEventHandler class that you specify to the MotionEventManager singleton. */ class EMFX_API MotionEventTable - : public BaseObject { friend class MotionEvent; public: AZ_CLASS_ALLOCATOR_DECL - AZ_RTTI(MotionEventTable, "{DB5BF142-99BE-4026-8D3E-3E5B30C14714}", BaseObject) + AZ_RTTI(MotionEventTable, "{DB5BF142-99BE-4026-8D3E-3E5B30C14714}") - MotionEventTable(); - - ~MotionEventTable(); + MotionEventTable() = default; + virtual ~MotionEventTable(); static void Reflect(AZ::ReflectContext* context); @@ -100,7 +96,6 @@ namespace EMotionFX AZStd::vector m_tracks; /// A shortcut to the track containing sync events. - AnimGraphSyncTrack* m_syncTrack; - + AnimGraphSyncTrack* m_syncTrack = nullptr; }; } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.cpp index ea984b82be..f1ec5950fb 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.cpp @@ -5,7 +5,6 @@ * */ -// include the required headers #include "MotionEventTrack.h" #include "MotionEvent.h" #include "EventManager.h" @@ -20,30 +19,19 @@ #include #include - namespace EMotionFX { AZ_CLASS_ALLOCATOR_IMPL(MotionEventTrack, MotionEventAllocator, 0) - // constructor MotionEventTrack::MotionEventTrack(Motion* motion) - : BaseObject() - , mMotion(motion) - , mNameID(MCORE_INVALIDINDEX32) - , mEnabled(true) - , mDeletable(true) + : mMotion(motion) { } - - // extended constructor MotionEventTrack::MotionEventTrack(const char* name, Motion* motion) - : BaseObject() - , mMotion(motion) - , mEnabled(true) - , mDeletable(true) + : mMotion(motion) + , m_name(name) { - SetName(name); } MotionEventTrack::MotionEventTrack(const MotionEventTrack& other) @@ -59,7 +47,7 @@ namespace EMotionFX } m_events = other.m_events; mMotion = other.mMotion; - mNameID = other.mNameID; + m_name = other.m_name; return *this; } @@ -72,8 +60,8 @@ namespace EMotionFX } serializeContext->Class() - ->Version(1) - ->Field("name", &MotionEventTrack::mNameID) + ->Version(2, VersionConverter) + ->Field("name", &MotionEventTrack::m_name) ->Field("enabled", &MotionEventTrack::mEnabled) ->Field("deletable", &MotionEventTrack::mDeletable) ->Field("events", &MotionEventTrack::m_events) @@ -94,6 +82,31 @@ namespace EMotionFX ; } + bool MotionEventTrack::VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement) + { + const unsigned int version = classElement.GetVersion(); + if (version < 2) + { + int nameElementIndex = classElement.FindElement(AZ_CRC_CE("name")); + if (nameElementIndex < 0) + { + return false; + } + AZ::SerializeContext::DataElementNode& nameElement = classElement.GetSubElement(nameElementIndex); + + MCore::StringIdPoolIndex oldName; + const bool result = nameElement.GetData(oldName); + + classElement.RemoveElement(nameElementIndex); + if (result) + { + AZStd::string newName = MCore::GetStringIdPool().GetName(oldName.m_index); + classElement.AddElementWithData(context, "name", newName); + } + } + return true; + } + // creation MotionEventTrack* MotionEventTrack::Create(Motion* motion) @@ -112,7 +125,7 @@ namespace EMotionFX // set the name of the motion event track void MotionEventTrack::SetName(const char* name) { - mNameID = MCore::GetStringIdPool().GenerateIdForString(name); + m_name = name; } @@ -362,60 +375,31 @@ namespace EMotionFX RemoveAllEvents(); } - - // get the name const char* MotionEventTrack::GetName() const { - if (mNameID == MCORE_INVALIDINDEX32) - { - return ""; - } - - return MCore::GetStringIdPool().GetName(mNameID).c_str(); + return m_name.c_str(); } - - // get the name as string object const AZStd::string& MotionEventTrack::GetNameString() const { - if (mNameID == MCORE_INVALIDINDEX32) - { - return MCore::GetStringIdPool().GetName(0); - } - - return MCore::GetStringIdPool().GetName(mNameID); + return m_name; } - // copy the track contents to a target track // this overwrites all existing contents of the target track void MotionEventTrack::CopyTo(MotionEventTrack* targetTrack) const { - targetTrack->mNameID = mNameID; + targetTrack->m_name = m_name; targetTrack->m_events = m_events; targetTrack->mEnabled = mEnabled; } - // reserve memory for a given amount of events void MotionEventTrack::ReserveNumEvents(size_t numEvents) { m_events.reserve(numEvents); } - - uint32 MotionEventTrack::GetNameID() const - { - return mNameID; - } - - - void MotionEventTrack::SetNameID(uint32 id) - { - mNameID = id; - } - - void MotionEventTrack::SetIsEnabled(bool enabled) { mEnabled = enabled; diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.h b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.h index 40e8f24405..b7cfc526cc 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/MotionEventTrack.h @@ -7,13 +7,10 @@ #pragma once -// include the required headers +#include #include "EMotionFXConfig.h" #include "BaseObject.h" #include "MotionEvent.h" -#include - -#include namespace AZ { @@ -38,15 +35,15 @@ namespace EMotionFX * The handling of those events is done by the MotionEventHandler class that you specify to the MotionEventManager singleton. */ class EMFX_API MotionEventTrack - : public BaseObject { friend class MotionEvent; public: - AZ_RTTI(MotionEventTrack, "{D142399D-C7DF-4E4A-A099-7E4E662F1E81}", BaseObject) + AZ_RTTI(MotionEventTrack, "{D142399D-C7DF-4E4A-A099-7E4E662F1E81}") AZ_CLASS_ALLOCATOR_DECL - MotionEventTrack() {} + MotionEventTrack() = default; + virtual ~MotionEventTrack() = default; /** * The constructor. @@ -167,8 +164,6 @@ namespace EMotionFX const char* GetName() const; const AZStd::string& GetNameString() const; - uint32 GetNameID() const; - void SetNameID(uint32 id); void SetIsEnabled(bool enabled); bool GetIsEnabled() const; @@ -182,23 +177,22 @@ namespace EMotionFX void ReserveNumEvents(size_t numEvents); protected: - /// The collection of motion events. AZStd::vector m_events; + AZStd::string m_name; /// The motion where this track belongs to. Motion* mMotion; - /// The name ID. - MCore::StringIdPoolIndex mNameID; - /// Is this track enabled? - bool mEnabled; - bool mDeletable; + bool mEnabled = true; + bool mDeletable = true; private: void ProcessEventsImpl(float startTime, float endTime, ActorInstance* actorInstance, const MotionInstance* motionInstance, const AZStd::function& processFunc); template void ExtractEvents(float startTime, float endTime, const MotionInstance* motionInstance, const Functor& processFunc, bool handleLoops = true) const; + + static bool VersionConverter(AZ::SerializeContext& context, AZ::SerializeContext::DataElementNode& classElement); }; } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/PhysicsSetup.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/PhysicsSetup.cpp index 9fab1b18c3..33e5e3dbc8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/PhysicsSetup.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/PhysicsSetup.cpp @@ -298,14 +298,20 @@ namespace EMotionFX { Physics::CapsuleShapeConfiguration* capsule = static_cast(collider.second.get()); capsule->m_height = boneDirection.GetLength(); - collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized()); + if (AZ::IsClose(localBoneDirection.GetLength(), 1.0f)) + { + collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized()); + } capsule->m_height = boneLength; const float radius = AZ::GetMin(rootMeanSquareDistanceFromBone, minRadiusRatio * boneLength); capsule->m_radius = radius; } else if (colliderType == azrtti_typeid()) { - collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized()); + if (AZ::IsClose(localBoneDirection.GetLength(), 1.0f)) + { + collider.first->m_rotation = AZ::Quaternion::CreateShortestArc(AZ::Vector3::CreateAxisZ(), localBoneDirection.GetNormalized()); + } Physics::BoxShapeConfiguration* box = static_cast(collider.second.get()); box->m_dimensions = AZ::Vector3(2.0f * rootMeanSquareDistanceFromBone, 2.0f * rootMeanSquareDistanceFromBone, boneLength); } diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp index c2b9babf70..920006b1d4 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -293,16 +294,65 @@ namespace EMStudio AZStd::string sourceAssetFilename; EBUS_EVENT_RESULT(fullPathFound, AzToolsFramework::AssetSystemRequestBus, GetFullSourcePathFromRelativeProductPath, productFilename, sourceAssetFilename); - // Generate meta data command for all changes being made to the motion. - const AZStd::vector metaData = CommandSystem::MetaData::GenerateMotionMetaData(motion); + // Load the manifest from disk. + AZStd::shared_ptr scene; + AZ::SceneAPI::Events::SceneSerializationBus::BroadcastResult(scene, &AZ::SceneAPI::Events::SceneSerializationBus::Events::LoadScene, sourceAssetFilename, AZ::Uuid::CreateNull()); + if (!scene) + { + AZ_Error("EMotionFX", false, "Unable to save meta data to manifest due to failed scene loading."); + return false; + } - // Save meta data commands to the manifest. - const bool saveResult = EMotionFX::Pipeline::Rule::MetaDataRule::SaveMetaDataToFile(sourceAssetFilename, groupName, metaData, outResult); + AZ::SceneAPI::Containers::SceneManifest& manifest = scene->GetManifest(); + auto values = manifest.GetValueStorage(); + auto groupView = AZ::SceneAPI::Containers::MakeDerivedFilterView(values); + for (EMotionFX::Pipeline::Group::MotionGroup& group : groupView) + { + // Non-case sensitive group name comparison. Product filenames are lower case only and might mismatch casing of the entered group name. + if (AzFramework::StringFunc::Equal(group.GetName().c_str(), groupName.c_str())) + { + // Remove legacy meta data rule. + EMotionFX::Pipeline::Rule::RemoveRuleFromGroup>(*scene, group); + + // Add motion meta data. + EMotionFX::Pipeline::Rule::MotionMetaData motionMetaData; + motionMetaData.m_motionEventTable = motion->GetEventTable(); + motionMetaData.m_motionExtractionFlags = motion->GetMotionExtractionFlags(); + EMotionFX::Pipeline::Rule::SaveToGroup(*scene, group, motionMetaData); + } + } + + const AZStd::string& manifestFilename = scene->GetManifestFilename(); + const bool fileExisted = AZ::IO::FileIOBase::GetInstance()->Exists(manifestFilename.c_str()); + + // Source Control: Checkout file. + if (fileExisted) + { + using ApplicationBus = AzToolsFramework::ToolsApplicationRequestBus; + bool checkoutResult = false; + ApplicationBus::BroadcastResult(checkoutResult, &ApplicationBus::Events::RequestEditForFileBlocking, manifestFilename.c_str(), "Checking out manifest from source control.", []([[maybe_unused]] int& current, [[maybe_unused]] int& max) {}); + if (!checkoutResult) + { + AZ_Error("EMotionFX", false, "Cannot checkout file '%s' from source control.", manifestFilename.c_str()); + return false; + } + } + + const bool saveResult = manifest.SaveToFile(manifestFilename.c_str()); if (saveResult) { motion->SetDirtyFlag(false); } + // Source Control: Add file in case it did not exist before (when saving it the first time). + if (saveResult && !fileExisted) + { + using ApplicationBus = AzToolsFramework::ToolsApplicationRequestBus; + bool checkoutResult = false; + ApplicationBus::BroadcastResult(checkoutResult, &ApplicationBus::Events::RequestEditForFileBlocking, manifestFilename.c_str(), "Adding manifest to source control.", []([[maybe_unused]] int& current, [[maybe_unused]] int& max) {}); + AZ_Error("EMotionFX", checkoutResult, "Cannot add file '%s' to source control.", manifestFilename.c_str()); + } + return saveResult; } diff --git a/Gems/EMotionFX/Code/Tests/EventManagerTests.cpp b/Gems/EMotionFX/Code/Tests/EventManagerTests.cpp index 6ab796691c..c717a1b27e 100644 --- a/Gems/EMotionFX/Code/Tests/EventManagerTests.cpp +++ b/Gems/EMotionFX/Code/Tests/EventManagerTests.cpp @@ -31,8 +31,8 @@ TEST_F(SystemComponentFixture, DISABLED_EventDataFactoryMakesUniqueData) EXPECT_EQ(loadedTrack->GetEvent(0).GetEventDatas()[0], track->GetEvent(0).GetEventDatas()[0]); EXPECT_EQ(loadedTrack->GetEvent(0).GetEventDatas()[0].use_count(), 2); - track->Destroy(); - loadedTrack->Destroy(); + delete track; + delete loadedTrack; } } // end namespace EMotionFX From a462df2991e4e5e76117c49148d76e4a4c7dbe03 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Fri, 25 Jun 2021 16:17:17 +0200 Subject: [PATCH 11/16] [LYN-4727] Version converter for motion group that ports XML serialized object-based commands to Json event data --- .../SceneAPIExt/Groups/MotionGroup.cpp | 58 ++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/MotionGroup.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/MotionGroup.cpp index d3b74dd72f..c699e12a0c 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/MotionGroup.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Groups/MotionGroup.cpp @@ -16,9 +16,11 @@ #include #include #include +#include #include #include +#include #include namespace EMotionFX @@ -89,7 +91,7 @@ namespace EMotionFX serializeContext->Class()->Version(1); - serializeContext->Class()->Version(5, VersionConverter) + serializeContext->Class()->Version(6, VersionConverter) ->Field("name", &MotionGroup::m_name) ->Field("selectedRootBone", &MotionGroup::m_selectedRootBone) ->Field("id", &MotionGroup::m_id) @@ -225,6 +227,60 @@ namespace EMotionFX } } + // Motion meta data introduced (no more string- or object-based commands stored in the former meta data rule) + if (version < 6) + { + AZ::SerializeContext::DataElementNode* ruleContainerNode = classElement.FindSubElement(AZ_CRC("rules", 0x899a993c)); + if (!ruleContainerNode) + { + AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Can't find rule container.\n"); + return false; + } + + AZ::SerializeContext::DataElementNode* rulesNode = ruleContainerNode->FindSubElement(AZ_CRC("rules", 0x899a993c)); + if (!rulesNode) + { + AZ_TracePrintf(AZ::SceneAPI::Utilities::ErrorWindow, "Can't find rules within rule container.\n"); + return false; + } + + const int numRules = rulesNode->GetNumSubElements(); + for (int i = 0; i < numRules; ++i) + { + AZ::SerializeContext::DataElementNode& sharedPointerNode = rulesNode->GetSubElement(i); + if (sharedPointerNode.GetNumSubElements() == 1) + { + AZ::SerializeContext::DataElementNode& currentRuleNode = sharedPointerNode.GetSubElement(0); + if (currentRuleNode.GetId() == azrtti_typeid()) + { + // Read the old, command-based meta data rule and retrieve the command objects. + Rule::MetaDataRule oldMetaDataRule; + currentRuleNode.GetData(oldMetaDataRule); + const AZStd::vector& commands = oldMetaDataRule.GetMetaData&>(); + + // Apply the commands onto a temporary motion. + auto motion = new EMotionFX::Motion(""); + motion->SetMotionData(aznew EMotionFX::NonUniformMotionData()); + CommandSystem::MetaData::ApplyMetaDataOnMotion(motion, commands); + + // Construct the new motion meta data rule. + auto metaData = AZStd::make_shared(motion->GetMotionExtractionFlags(), motion->GetEventTable()); + auto metaDataRule = AZStd::make_shared(metaData); + + // Add the new motion meta data rule. + AZ::SceneAPI::Containers::RuleContainer ruleContainer; + ruleContainerNode->GetDataHierarchy(context, ruleContainer); + ruleContainer.RemoveRule(i); + ruleContainer.AddRule(metaDataRule); + ruleContainerNode->SetData(context, ruleContainer); + + motion->Destroy(); + break; + } + } + } + } + return result; } } From 44c813824e0f08a74988d1e27d763cc692be8090 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Fri, 25 Jun 2021 16:18:12 +0200 Subject: [PATCH 12/16] [LYN-4727] Memory management improvements and clear ownership for motion meta data --- .../SceneAPIExt/Rules/MotionMetaDataRule.cpp | 38 +++++++++++++++++-- .../SceneAPIExt/Rules/MotionMetaDataRule.h | 22 +++++++---- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp index f57e4ec268..2bd7e2a57e 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp @@ -28,12 +28,44 @@ namespace EMotionFX::Pipeline::Rule ; } - MotionMetaDataRule::MotionMetaDataRule() - : ExternalToolRule() + MotionMetaData::MotionMetaData(EMotionFX::EMotionExtractionFlags extractionFlags, EMotionFX::MotionEventTable* eventTable) + : m_motionExtractionFlags(extractionFlags) + { + m_motionEventTable = CloneMotionEventTable(eventTable); + } + + MotionMetaData::MotionMetaData() + : m_motionExtractionFlags(static_cast(0)) { } - MotionMetaDataRule::MotionMetaDataRule(const MotionMetaData& data) + AZStd::unique_ptr MotionMetaData::GetClonedEventTable(EMotionFX::Motion* targetMotion) const + { + AZStd::unique_ptr clonedEventTable = AZStd::move(CloneMotionEventTable(m_motionEventTable.get())); + clonedEventTable->InitAfterLoading(targetMotion); + return AZStd::move(clonedEventTable); + } + + AZStd::unique_ptr MotionMetaData::CloneMotionEventTable(EMotionFX::MotionEventTable* sourceEventTable) + { + AZ::SerializeContext* serializeContext = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(serializeContext, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!serializeContext) + { + AZ_Error("EMotionFX", false, "Cannot clone motion event table for motion meta data. Can't get serialize context from component application."); + return {}; + } + + AZStd::unique_ptr clonedEventTable(serializeContext->CloneObject(sourceEventTable)); + return AZStd::move(clonedEventTable); + } + + MotionMetaDataRule::MotionMetaDataRule() + : ExternalToolRule>() + { + } + + MotionMetaDataRule::MotionMetaDataRule(const AZStd::shared_ptr& data) : MotionMetaDataRule() { m_data = data; diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h index 099451ff7e..8ede0e130f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -20,32 +21,39 @@ namespace EMotionFX::Pipeline::Rule AZ_RTTI(EMotionFX::Pipeline::Rule::MotionMetaData, "{A381A915-3CB3-4F60-82B3-70865CFA1F4F}"); AZ_CLASS_ALLOCATOR(MotionMetaData, AZ::SystemAllocator, 0) - MotionMetaData() = default; + MotionMetaData(); + MotionMetaData(EMotionFX::EMotionExtractionFlags extractionFlags, EMotionFX::MotionEventTable* eventTable); virtual ~MotionMetaData() = default; + EMotionFX::EMotionExtractionFlags GetMotionExtractionFlags() const { return m_motionExtractionFlags; } + AZStd::unique_ptr GetClonedEventTable(EMotionFX::Motion* targetMotion) const; + static void Reflect(AZ::ReflectContext* context); - EMotionFX::MotionEventTable* m_motionEventTable = nullptr; + private: + static AZStd::unique_ptr CloneMotionEventTable(EMotionFX::MotionEventTable* sourceEventTable); + EMotionFX::EMotionExtractionFlags m_motionExtractionFlags; + AZStd::unique_ptr m_motionEventTable; }; class MotionMetaDataRule - : public ExternalToolRule + : public ExternalToolRule> { public: AZ_RTTI(EMotionFX::Pipeline::Rule::MotionMetaDataRule, "{E68D0C3D-CBFF-4536-95C1-676474B351A5}", AZ::SceneAPI::DataTypes::IRule); AZ_CLASS_ALLOCATOR(MotionMetaDataRule, AZ::SystemAllocator, 0) MotionMetaDataRule(); - MotionMetaDataRule(const MotionMetaData& data); + MotionMetaDataRule(const AZStd::shared_ptr& data); ~MotionMetaDataRule() final = default; - const MotionMetaData& GetData() const override { return m_data; } - void SetData(const MotionMetaData& data) override { m_data = data; } + const AZStd::shared_ptr& GetData() const override { return m_data; } + void SetData(const AZStd::shared_ptr& data) override { m_data = data; } static void Reflect(AZ::ReflectContext* context); private: - MotionMetaData m_data; + AZStd::shared_ptr m_data; }; } // EMotionFX::Pipeline::Rule From b80f0782ef673598d57159d44cc308fa21e3f9d4 Mon Sep 17 00:00:00 2001 From: Terry Michaels Date: Fri, 25 Jun 2021 10:04:08 -0500 Subject: [PATCH 13/16] Removed old code referencing removed classes (#1587) --- Code/Sandbox/Editor/MainWindow.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Code/Sandbox/Editor/MainWindow.cpp b/Code/Sandbox/Editor/MainWindow.cpp index 71b31102fd..b4cf317c26 100644 --- a/Code/Sandbox/Editor/MainWindow.cpp +++ b/Code/Sandbox/Editor/MainWindow.cpp @@ -1350,10 +1350,6 @@ void MainWindow::RegisterStdViewClasses() AzAssetBrowserWindow::RegisterViewClass(); AssetEditorWindow::RegisterViewClass(); - //These view dialogs aren't used anymore so they became disabled. - //CLightmapCompilerDialog::RegisterViewClass(); - //CLightmapCompilerDialog::RegisterViewClass(); - // Notify that views can now be registered AzToolsFramework::EditorEvents::Bus::Broadcast( &AzToolsFramework::EditorEvents::Bus::Events::NotifyRegisterViews); From 9b6ef150ff17cdf4a253e838b0b59093fdf3f71c Mon Sep 17 00:00:00 2001 From: Danilo Aimini <82231674+AMZN-daimini@users.noreply.github.com> Date: Fri, 25 Jun 2021 08:53:25 -0700 Subject: [PATCH 14/16] LYN-2480 | Minor fixes to the Prefab system (#1581) Remove warning when entities that aren't registered to instances get passed to the Prefab Undo Cache (just ignore them to avoid noise in the console). Also avoid marking templates dirty when they are added. --- .../AzToolsFramework/Prefab/PrefabSystemComponent.cpp | 1 - .../AzToolsFramework/Prefab/PrefabUndoCache.cpp | 5 +---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp index c58379ea3e..9d1e95657d 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabSystemComponent.cpp @@ -414,7 +414,6 @@ namespace AzToolsFramework } m_templateFilePathToIdMap.emplace(AZStd::make_pair(filePath, newTemplateId)); - newTemplate.MarkAsDirty(true); return newTemplateId; } diff --git a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoCache.cpp b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoCache.cpp index bc48846585..dcf2a57c64 100644 --- a/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoCache.cpp +++ b/Code/Framework/AzToolsFramework/AzToolsFramework/Prefab/PrefabUndoCache.cpp @@ -130,10 +130,7 @@ namespace AzToolsFramework if (!instanceOptionalReference.has_value()) { - AZ_Warning( - "Undo", false, - "PrefabUndoCache was told to update the cache for entity of id %p (%s), but that entity does not have an owning instance.", - entityId, entity->GetName().c_str()); + // This is not an error, we just don't handle this entity. return; } From acce801b41fd593285da90f3221eaa6006c2aea4 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Fri, 25 Jun 2021 09:23:27 -0700 Subject: [PATCH 15/16] SPEC-7435 Vegetation Tests Reference Missing File: Mocks/MockSpawnableEntitiesInterface.h --- scripts/build/Platform/Mac/build_mac.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/scripts/build/Platform/Mac/build_mac.sh b/scripts/build/Platform/Mac/build_mac.sh index f8ed570ed3..00254a2974 100755 --- a/scripts/build/Platform/Mac/build_mac.sh +++ b/scripts/build/Platform/Mac/build_mac.sh @@ -31,6 +31,11 @@ else RUN_CONFIGURE=1 fi fi + +# temporarily enabling cmake regeneration for this platform +# We have observed cases where continous integration has not regenerated but a regeneration was required, leaving the build in a bad state +RUN_CONFIGURE=1 + if [[ ! -z "$RUN_CONFIGURE" ]]; then # have to use eval since $CMAKE_OPTIONS (${EXTRA_CMAKE_OPTIONS}) contains quotes that need to be processed echo [ci_build] ${CONFIGURE_CMD} From a3d314d0593eb8d80126bfa8e79a8e5d8ed5092b Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Fri, 25 Jun 2021 16:18:54 +0200 Subject: [PATCH 16/16] [LYN-4727] Adapting the motion group exporter and the save commands to the motion meta data changes --- .../Pipeline/RCExt/Motion/MotionGroupExporter.cpp | 9 ++++----- .../Pipeline/SceneAPIExt/Rules/ExternalToolRule.inl | 2 +- .../Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp | 9 ++++----- .../Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp | 6 ++---- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp index b44f2c36b3..c4ed3307ae 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/RCExt/Motion/MotionGroupExporter.cpp @@ -84,12 +84,11 @@ namespace EMotionFX } // Apply motion meta data. - EMotionFX::Pipeline::Rule::MotionMetaData motionMetaData; - if (EMotionFX::Pipeline::Rule::LoadFromGroup(motionGroup, motionMetaData)) + AZStd::shared_ptr motionMetaData; + if (EMotionFX::Pipeline::Rule::LoadFromGroup(motionGroup, motionMetaData)) { - motion->SetEventTable(AZStd::unique_ptr(motionMetaData.m_motionEventTable)); - motion->GetEventTable()->InitAfterLoading(motion); - motion->SetMotionExtractionFlags(motionMetaData.m_motionExtractionFlags); + motion->SetEventTable(motionMetaData->GetClonedEventTable(motion)); + motion->SetMotionExtractionFlags(motionMetaData->GetMotionExtractionFlags()); } ExporterLib::SaveMotion(filename, motion, MCore::Endian::ENDIAN_LITTLE); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/ExternalToolRule.inl b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/ExternalToolRule.inl index e98e2e7187..da97743229 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/ExternalToolRule.inl +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/ExternalToolRule.inl @@ -35,7 +35,7 @@ namespace EMotionFX return false; } - outData = rule->GetData(); + outData = AZStd::move(rule->GetData()); return true; } diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp index 2bd7e2a57e..40648a7f8f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Rules/MotionMetaDataRule.cpp @@ -41,9 +41,9 @@ namespace EMotionFX::Pipeline::Rule AZStd::unique_ptr MotionMetaData::GetClonedEventTable(EMotionFX::Motion* targetMotion) const { - AZStd::unique_ptr clonedEventTable = AZStd::move(CloneMotionEventTable(m_motionEventTable.get())); + AZStd::unique_ptr clonedEventTable = CloneMotionEventTable(m_motionEventTable.get()); clonedEventTable->InitAfterLoading(targetMotion); - return AZStd::move(clonedEventTable); + return clonedEventTable; } AZStd::unique_ptr MotionMetaData::CloneMotionEventTable(EMotionFX::MotionEventTable* sourceEventTable) @@ -57,7 +57,7 @@ namespace EMotionFX::Pipeline::Rule } AZStd::unique_ptr clonedEventTable(serializeContext->CloneObject(sourceEventTable)); - return AZStd::move(clonedEventTable); + return clonedEventTable; } MotionMetaDataRule::MotionMetaDataRule() @@ -66,9 +66,8 @@ namespace EMotionFX::Pipeline::Rule } MotionMetaDataRule::MotionMetaDataRule(const AZStd::shared_ptr& data) - : MotionMetaDataRule() + : m_data(data) { - m_data = data; } void MotionMetaDataRule::Reflect(AZ::ReflectContext* context) diff --git a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp index 920006b1d4..8c22d657c3 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Tools/EMotionStudio/EMStudioSDK/Source/Commands.cpp @@ -315,10 +315,8 @@ namespace EMStudio EMotionFX::Pipeline::Rule::RemoveRuleFromGroup>(*scene, group); // Add motion meta data. - EMotionFX::Pipeline::Rule::MotionMetaData motionMetaData; - motionMetaData.m_motionEventTable = motion->GetEventTable(); - motionMetaData.m_motionExtractionFlags = motion->GetMotionExtractionFlags(); - EMotionFX::Pipeline::Rule::SaveToGroup(*scene, group, motionMetaData); + auto motionMetaData = AZStd::make_shared(motion->GetMotionExtractionFlags(), motion->GetEventTable()); + EMotionFX::Pipeline::Rule::SaveToGroup>(*scene, group, motionMetaData); } }