From 11eb920e400b0252fda27b1f6b39cf1f6c0ea1d5 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 12 Jul 2021 15:29:56 -0700 Subject: [PATCH 01/58] Removal of dead code and bug fixes for reflection Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp | 2 +- .../Code/Source/Shape/PolygonPrismShapeComponent.cpp | 2 +- .../Include/ScriptCanvas/Data/BehaviorContextObject.h | 8 +++++++- .../Code/Source/Framework/ScriptCanvasTestFixture.h | 5 ----- .../Code/Source/Framework/ScriptCanvasTestUtilities.cpp | 8 -------- 5 files changed, 9 insertions(+), 16 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index 39f6c02bde..a40dd2daac 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -38,7 +38,7 @@ namespace AZ { struct SymbolStorageDynamicallyLoadedModules { size_t m_size; - DynamicallyLoadedModuleInfo m_modules[256]; + DynamicallyLoadedModuleInfo m_modules[1028]; SymbolStorageDynamicallyLoadedModules() : m_size(0) diff --git a/Gems/LmbrCentral/Code/Source/Shape/PolygonPrismShapeComponent.cpp b/Gems/LmbrCentral/Code/Source/Shape/PolygonPrismShapeComponent.cpp index 22b0cbfb03..6bb4c1238c 100644 --- a/Gems/LmbrCentral/Code/Source/Shape/PolygonPrismShapeComponent.cpp +++ b/Gems/LmbrCentral/Code/Source/Shape/PolygonPrismShapeComponent.cpp @@ -98,7 +98,7 @@ namespace LmbrCentral if (AZ::BehaviorContext* behaviorContext = azrtti_cast(context)) { behaviorContext->EBus("PolygonPrismShapeComponentRequestBus") - ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Common) ->Attribute(AZ::Edit::Attributes::Category, "Shape") ->Attribute(AZ::Script::Attributes::Module, "shape") ->Event("GetPolygonPrism", &PolygonPrismShapeComponentRequestBus::Events::GetPolygonPrism) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h index 29831e20f9..4980fdd37b 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h @@ -115,7 +115,6 @@ namespace ScriptCanvas AZ_FORCE_INLINE BehaviorContextObject() = default; BehaviorContextObject& operator=(const BehaviorContextObject&) = delete; - BehaviorContextObject(const BehaviorContextObject&) = delete; // copy ctor AZ_FORCE_INLINE BehaviorContextObject(const void* source, const AnyTypeInfo& typeInfo, AZ::u32 flags); @@ -134,6 +133,13 @@ namespace ScriptCanvas AZ_FORCE_INLINE void add_ref(); void release(); + + public: + // no copying allowed, this is here to allow compile time compatibility with storage in of BehaviorContextObjectPtr AZStd::any, only + AZ_FORCE_INLINE BehaviorContextObject(const BehaviorContextObject&) + { + AZ_Assert(false, "no copying allowed, this is here to allow storage in of BehaviorContextObjectPtr AZStd::any, only"); + } }; AZ_FORCE_INLINE BehaviorContextObject::BehaviorContextObject(const void* value, const AnyTypeInfo& typeInfo, AZ::u32 flags) diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h index 0a4408b689..403a1623d6 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestFixture.h @@ -135,11 +135,6 @@ namespace ScriptCanvasTests // don't hang on to dangling assets AZ::Data::AssetManager::Instance().DispatchEvents(); - if (AZ::IO::FileIOBase* fileIO = AZ::IO::FileIOBase::GetInstance()) - { - fileIO->DestroyPath(k_tempCoreAssetDir); - } - if (s_application) { s_application->Stop(); diff --git a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp index 03ecba29be..8b231d5fdc 100644 --- a/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp +++ b/Gems/ScriptCanvasTesting/Code/Source/Framework/ScriptCanvasTestUtilities.cpp @@ -33,14 +33,6 @@ namespace ScriptCanvasTests { using namespace ScriptCanvas; -#define SC_CORE_UNIT_TEST_DIR "@engroot@/LY_SC_UnitTest_ScriptCanvas_CoreCPP_Temporary" -#define SC_CORE_UNIT_TEST_NAME "serializationTest.scriptcanvas_compiled" - const char* k_tempCoreAssetDir = SC_CORE_UNIT_TEST_DIR; - const char* k_tempCoreAssetName = SC_CORE_UNIT_TEST_NAME; - const char* k_tempCoreAssetPath = SC_CORE_UNIT_TEST_DIR "/" SC_CORE_UNIT_TEST_NAME; -#undef SC_CORE_UNIT_TEST_DIR -#undef SC_CORE_UNIT_TEST_NAME - void ExpectParse(AZStd::string_view graphPath) { AZ_TEST_START_TRACE_SUPPRESSION; From 539fb8200990a876a6ba921e6122c99e1ac26845 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 13 Jul 2021 17:40:49 -0700 Subject: [PATCH 02/58] remove smoke tag from scriptcanvas tests Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index 83a3456a1c..9b01064e31 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -112,7 +112,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests - TEST_SUITE smoke ) endif() From 41dd7054b7a43c3a2c429fdb616746262716d9ea Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 13 Jul 2021 17:52:06 -0700 Subject: [PATCH 03/58] Restore BCO destructor delete Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../ScriptCanvas/Data/BehaviorContextObject.h | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h index 4980fdd37b..51d61f9934 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Data/BehaviorContextObject.h @@ -36,8 +36,7 @@ namespace ScriptCanvas static void Reflect(AZ::ReflectContext* reflection); static BehaviorContextObjectPtr Create(const AZ::BehaviorClass& behaviorClass, const void* value = nullptr); - static BehaviorContextObjectPtr CreateDeepCopy(const AZ::BehaviorClass& behaviorClass, const BehaviorContextObject* value = nullptr); - + template AZ_INLINE static BehaviorContextObjectPtr Create(const t_Value& value, const AZ::BehaviorClass& behaviorClass); @@ -116,6 +115,8 @@ namespace ScriptCanvas BehaviorContextObject& operator=(const BehaviorContextObject&) = delete; + BehaviorContextObject(const BehaviorContextObject&) = delete; + // copy ctor AZ_FORCE_INLINE BehaviorContextObject(const void* source, const AnyTypeInfo& typeInfo, AZ::u32 flags); @@ -133,13 +134,6 @@ namespace ScriptCanvas AZ_FORCE_INLINE void add_ref(); void release(); - - public: - // no copying allowed, this is here to allow compile time compatibility with storage in of BehaviorContextObjectPtr AZStd::any, only - AZ_FORCE_INLINE BehaviorContextObject(const BehaviorContextObject&) - { - AZ_Assert(false, "no copying allowed, this is here to allow storage in of BehaviorContextObjectPtr AZStd::any, only"); - } }; AZ_FORCE_INLINE BehaviorContextObject::BehaviorContextObject(const void* value, const AnyTypeInfo& typeInfo, AZ::u32 flags) From 7dcdd3cb465c09e71f1f5dc5d788a8d8b7849742 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 13 Jul 2021 21:20:52 -0700 Subject: [PATCH 04/58] remove the deliberate failure test Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index db3d2223d6..fedb1fc4d1 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -83,11 +83,6 @@ public: } }; -TEST_F(ScriptCanvasTestFixture, ProveError) -{ - EXPECT_TRUE(false); -} - TEST_F(ScriptCanvasTestFixture, ParseErrorOnKnownNull) { ExpectParseError("LY_SC_UnitTest_ParseErrorOnKnownNull"); From c6f03cbb098a474a17a78cee4205f1248e7c7d9b Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 14 Jul 2021 12:50:15 -0700 Subject: [PATCH 05/58] Removed superflous translation asset registration Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/GraphCanvas/Code/Source/GraphCanvas.cpp | 29 -------------------- Gems/GraphCanvas/Code/Source/GraphCanvas.h | 1 - 2 files changed, 30 deletions(-) diff --git a/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp b/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp index 011548ce5a..be44908cb8 100644 --- a/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp +++ b/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp @@ -190,7 +190,6 @@ namespace GraphCanvas void GraphCanvasSystemComponent::Activate() { - RegisterAssetHandler(); RegisterTranslationBuilder(); AzFramework::AssetCatalogEventBus::Handler::BusConnect(); @@ -385,34 +384,6 @@ namespace GraphCanvas AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, collectAssetsCb, postEnumerateCb); } - void GraphCanvasSystemComponent::RegisterAssetHandler() - { - AZ::Data::AssetType assetType(azrtti_typeid()); - if (AZ::Data::AssetManager::Instance().GetHandler(assetType)) - { - return; // Asset Type already handled - } - - auto* catalogBus = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); - if (catalogBus) - { - // Register asset types the asset DB should query our catalog for. - catalogBus->AddAssetType(assetType); - - // Build the catalog (scan). - catalogBus->AddExtension(".names"); - } - - m_assetHandler = AZStd::make_unique(); - AZ::Data::AssetManager::Instance().RegisterHandler(m_assetHandler.get(), assetType); - - // Use AssetCatalog service to register ScriptEvent asset type and extension - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddAssetType, assetType); - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::EnableCatalogForAsset, assetType); - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, TranslationAsset::GetFileFilter()); - - } - void GraphCanvasSystemComponent::UnregisterAssetHandler() { if (m_assetHandler) diff --git a/Gems/GraphCanvas/Code/Source/GraphCanvas.h b/Gems/GraphCanvas/Code/Source/GraphCanvas.h index ddb29b18c0..2e5b200a1b 100644 --- a/Gems/GraphCanvas/Code/Source/GraphCanvas.h +++ b/Gems/GraphCanvas/Code/Source/GraphCanvas.h @@ -82,7 +82,6 @@ namespace GraphCanvas void RegisterTranslationBuilder(); - void RegisterAssetHandler(); void UnregisterAssetHandler(); TranslationAssetWorker m_translationAssetWorker; AZStd::vector m_translationAssets; From e2c147762900cec9c59302f950d4088e4eee8770 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 15 Jul 2021 09:46:51 -0700 Subject: [PATCH 06/58] fix for dependency job key on ScriptEvents from SC builder Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../AzCore/Debug/StackTracer_Windows.cpp | 2 +- .../Builder/ScriptCanvasBuilderWorker.cpp | 29 ++++++++++++++----- .../ScriptCanvasBuilderWorkerUtility.cpp | 2 +- .../ScriptCanvas/Core/SubgraphInterface.cpp | 6 ---- .../ScriptCanvas/Core/SubgraphInterface.h | 2 -- .../ScriptCanvas/Grammar/Primitives.cpp | 4 +-- .../Grammar/PrimitivesDeclarations.h | 2 +- .../Builder/ScriptEventsBuilderWorker.cpp | 2 +- .../Include/ScriptEvents/ScriptEventsAsset.h | 2 ++ 9 files changed, 29 insertions(+), 22 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index a40dd2daac..dcc55cfcf6 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -38,7 +38,7 @@ namespace AZ { struct SymbolStorageDynamicallyLoadedModules { size_t m_size; - DynamicallyLoadedModuleInfo m_modules[1028]; + DynamicallyLoadedModuleInfo m_modules[1024]; SymbolStorageDynamicallyLoadedModules() : m_size(0) diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp index b9d1dd5a7c..3377cea0e8 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorker.cpp @@ -82,23 +82,35 @@ namespace ScriptCanvasBuilder m_processEditorAssetDependencies.clear(); - auto assetFilter = [this, &response](const AZ::Data::AssetFilterInfo& filterInfo) + AZStd::unordered_multimap jobDependenciesByKey; + + auto assetFilter = [this, &jobDependenciesByKey](const AZ::Data::AssetFilterInfo& filterInfo) { // force load these before processing if (filterInfo.m_assetType == azrtti_typeid() - || filterInfo.m_assetType == azrtti_typeid()) + || filterInfo.m_assetType == azrtti_typeid()) { this->m_processEditorAssetDependencies.push_back(filterInfo); } // these trigger re-processing - if (filterInfo.m_assetType == azrtti_typeid() - || filterInfo.m_assetType == azrtti_typeid() - || filterInfo.m_assetType == azrtti_typeid()) + if (filterInfo.m_assetType == azrtti_typeid()) + { + AZ_Error("ScriptCanvas", false, "ScriptAsset Reference in a graph detected"); + } + + if (filterInfo.m_assetType == azrtti_typeid()) { AssetBuilderSDK::SourceFileDependency dependency; dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid; - response.m_sourceFileDependencyList.push_back(dependency); + jobDependenciesByKey.insert({ ScriptEvents::k_builderJobKey, dependency }); + } + + if (filterInfo.m_assetType == azrtti_typeid()) + { + AssetBuilderSDK::SourceFileDependency dependency; + dependency.m_sourceFileDependencyUUID = filterInfo.m_assetId.m_guid; + jobDependenciesByKey.insert({ s_scriptCanvasProcessJobKey, dependency }); } // Asset filter always returns false to prevent parsing dependencies, but makes note of the script canvas dependencies @@ -163,9 +175,10 @@ namespace ScriptCanvasBuilder jobDescriptor.m_additionalFingerprintInfo = AZStd::string(GetFingerprintString()).append("|").append(AZStd::to_string(static_cast(fingerprint))); // Graph process job needs to wait until its dependency asset job finished - for (const auto& processingDependency : response.m_sourceFileDependencyList) + for (const auto& processingDependency : jobDependenciesByKey) { - jobDescriptor.m_jobDependencyList.emplace_back(s_scriptCanvasProcessJobKey, info.m_identifier.c_str(), AssetBuilderSDK::JobDependencyType::Order, processingDependency); + response.m_sourceFileDependencyList.push_back(processingDependency.second); + jobDescriptor.m_jobDependencyList.emplace_back(processingDependency.first, info.m_identifier.c_str(), AssetBuilderSDK::JobDependencyType::Order, processingDependency.second); } response.m_createJobOutputs.push_back(jobDescriptor); diff --git a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp index 7f6269a698..375c773e7d 100644 --- a/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp +++ b/Gems/ScriptCanvas/Code/Builder/ScriptCanvasBuilderWorkerUtility.cpp @@ -97,7 +97,7 @@ namespace ScriptCanvasBuilder bool pathFound = false; AZStd::string relativePath; AzToolsFramework::AssetSystemRequestBus::BroadcastResult - (pathFound + ( pathFound , &AzToolsFramework::AssetSystem::AssetSystemRequest::GetRelativeProductPathFromFullSourceOrProductPath , fullPath.c_str(), relativePath); diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp index a6959ae209..3b7ec9c77f 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.cpp @@ -802,12 +802,6 @@ namespace ScriptCanvas m_namespacePath = namespacePath; } - void SubgraphInterface::TakeNamespacePath(NamespacePath&& namespacePath) - { - m_namespacePath = AZStd::move(namespacePath); - } - - AZStd::string SubgraphInterface::ToExecutionString() const { AZStd::string result; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h index 19ff2e1d65..6dac3cf7a4 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Core/SubgraphInterface.h @@ -235,8 +235,6 @@ namespace ScriptCanvas void SetNamespacePath(const NamespacePath& namespacePath); - void TakeNamespacePath(NamespacePath&& namespacePath); - AZStd::string ToExecutionString() const; private: diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp index aa11d01fdf..dca4f41933 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/Primitives.cpp @@ -234,7 +234,7 @@ namespace ScriptCanvas const VariableData Source::k_emptyVardata{}; Source::Source - (const Graph& graph + ( const Graph& graph , const AZ::Data::AssetId& id , const GraphData& graphData , const VariableData& variableData @@ -276,7 +276,7 @@ namespace ScriptCanvas AzFramework::StringFunc::Path::StripExtension(namespacePath); return AZ::Success(Source - (*request.graph + (*request.graph , request.scriptAssetId , *graphData , *sourceVariableData diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h index 12f4199bc4..0c245de2a5 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/PrimitivesDeclarations.h @@ -289,7 +289,7 @@ namespace ScriptCanvas Source() = default; Source - (const Graph& graph + ( const Graph& graph , const AZ::Data::AssetId& id , const GraphData& graphData , const VariableData& variableData diff --git a/Gems/ScriptEvents/Code/Builder/ScriptEventsBuilderWorker.cpp b/Gems/ScriptEvents/Code/Builder/ScriptEventsBuilderWorker.cpp index 2357fb38a5..8465b28936 100644 --- a/Gems/ScriptEvents/Code/Builder/ScriptEventsBuilderWorker.cpp +++ b/Gems/ScriptEvents/Code/Builder/ScriptEventsBuilderWorker.cpp @@ -120,7 +120,7 @@ namespace ScriptEventsBuilder AssetBuilderSDK::JobDescriptor jobDescriptor; jobDescriptor.m_priority = 2; jobDescriptor.m_critical = true; - jobDescriptor.m_jobKey = "Script Events"; + jobDescriptor.m_jobKey = ScriptEvents::k_builderJobKey; jobDescriptor.SetPlatformIdentifier(info.m_identifier.data()); jobDescriptor.m_additionalFingerprintInfo = GetFingerprintString(); diff --git a/Gems/ScriptEvents/Code/Include/ScriptEvents/ScriptEventsAsset.h b/Gems/ScriptEvents/Code/Include/ScriptEvents/ScriptEventsAsset.h index cfa8253923..8178f1c9e0 100644 --- a/Gems/ScriptEvents/Code/Include/ScriptEvents/ScriptEventsAsset.h +++ b/Gems/ScriptEvents/Code/Include/ScriptEvents/ScriptEventsAsset.h @@ -21,6 +21,8 @@ namespace ScriptEvents { + constexpr const char* k_builderJobKey = "Script Events"; + class ScriptEventsAsset : public AZ::Data::AssetData { From ab6a98db44013f6d4182d051dc009570f24f9231 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Thu, 15 Jul 2021 09:52:40 -0700 Subject: [PATCH 07/58] restoring smoke lable to SC unit tests pending Linux filename fix Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index 9b01064e31..83a3456a1c 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -112,6 +112,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests + TEST_SUITE smoke ) endif() From e28ff0beea17a3a63e3804ad11c8e16c6c2a4edb Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Fri, 16 Jul 2021 03:52:11 -0500 Subject: [PATCH 08/58] Adding rapidjson.natvis file to the AzCore project to Visualizers to VS By adding the natvis to a vcxproj Visual Studio automatically loads it when using the source engine Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../AzCore/Natvis/rapidjson.natvis | 38 +++++++++++++++++++ .../Windows/platform_windows_files.cmake | 1 + 2 files changed, 39 insertions(+) create mode 100644 Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis diff --git a/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis b/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis new file mode 100644 index 0000000000..5167714f20 --- /dev/null +++ b/Code/Framework/AzCore/Platform/Common/VisualStudio/AzCore/Natvis/rapidjson.natvis @@ -0,0 +1,38 @@ + + + + + null + true + false + {data_.ss.str} + {(const char*)((size_t)data_.s.str & 0x0000FFFFFFFFFFFF)} + {data_.n.i.i} + {data_.n.u.u} + {data_.n.i64} + {data_.n.u64} + {data_.n.d} + Object members={data_.o.size} + Array members={data_.a.size} + + data_.o.size + data_.o.capacity + + data_.o.size + + (rapidjson_ly::GenericMember<$T1,$T2>*)(((size_t)data_.o.members) & 0x0000FFFFFFFFFFFF) + + + data_.a.size + data_.a.capacity + + data_.a.size + + (rapidjson_ly::GenericValue<$T1,$T2>*)(((size_t)data_.a.elements) & 0x0000FFFFFFFFFFFF) + + + + + + + diff --git a/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake b/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake index 520c53f74c..97ab3c86d6 100644 --- a/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake +++ b/Code/Framework/AzCore/Platform/Windows/platform_windows_files.cmake @@ -29,6 +29,7 @@ set(FILES ../Common/VisualStudio/AzCore/Natvis/azcore.natvis ../Common/VisualStudio/AzCore/Natvis/azcore.natstepfilter ../Common/VisualStudio/AzCore/Natvis/azcore.natjmc + ../Common/VisualStudio/AzCore/Natvis/rapidjson.natvis AzCore/Debug/StackTracer_Windows.cpp ../Common/WinAPI/AzCore/Debug/Trace_WinAPI.cpp ../Common/WinAPI/AzCore/IO/Streamer/StreamerContext_WinAPI.cpp From 002a4a4a2120687773e0cb8a6986109818dbf58a Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Wed, 21 Jul 2021 14:50:23 -0500 Subject: [PATCH 09/58] AtomToolsApplication working with MatEditor Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.h | 92 ++++ .../Application/AtomToolsApplication.cpp | 428 ++++++++++++++++++ .../Code/atomtoolsframework_files.cmake | 2 + .../Code/Source/MaterialEditorApplication.cpp | 203 +-------- .../Code/Source/MaterialEditorApplication.h | 53 +-- .../ShaderManagementConsoleApplication.cpp | 170 +------ .../ShaderManagementConsoleApplication.h | 21 +- 7 files changed, 535 insertions(+), 434 deletions(-) create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h create mode 100644 Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h new file mode 100644 index 0000000000..dc34ad9a0a --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -0,0 +1,92 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace AtomToolsFramework +{ + class AtomToolsApplication + : public AzFramework::Application + , public AzQtComponents::AzQtApplication + , protected AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler + , protected AzFramework::AssetSystemStatusBus::Handler + , protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler + , protected AZ::Debug::TraceMessageBus::Handler + , protected AZ::UserSettingsOwnerRequestBus::Handler + { + public: + AZ_TYPE_INFO(AtomTools::AtomToolsApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); + + using Base = AzFramework::Application; + + AtomToolsApplication(int* argc, char*** argv); + + ////////////////////////////////////////////////////////////////////////// + // AzFramework::Application + void CreateReflectionManager() override; + void Reflect(AZ::ReflectContext* context) override; + void RegisterCoreComponents() override; + AZ::ComponentTypeList GetRequiredSystemComponents() const override; + void CreateStaticModules(AZStd::vector& outModules) override; + const char* GetCurrentConfigurationName() const override; + void StartCommon(AZ::Entity* systemEntity) override; + void Tick(float deltaOverride = -1.f) override; + void Stop() override; + + protected: + ////////////////////////////////////////////////////////////////////////// + // AssetDatabaseRequestsBus::Handler overrides... + bool GetAssetDatabaseLocation(AZStd::string& result) override; + ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// + // AzFramework::Application overrides... + void Destroy() override; + ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// + // AZ::ComponentApplication overrides... + void QueryApplicationType(AZ::ApplicationTypeQuery& appType) const override; + ////////////////////////////////////////////////////////////////////////// + + ////////////////////////////////////////////////////////////////////////// + // AZ::UserSettingsOwnerRequestBus::Handler overrides... + void SaveSettings() override; + ////////////////////////////////////////////////////////////////////////// + + virtual void LoadSettings(); + virtual void UnloadSettings(); + virtual void CompileCriticalAssets(); + virtual void ProcessCommandLine(const AZ::CommandLine& commandLine); + virtual bool LaunchDiscoveryService(); + virtual void StartInternal(); + + static void PyIdleWaitFrames(uint32_t frames); + + AzToolsFramework::TraceLogger m_traceLogger; + + //! Local user settings are used to store material browser tree expansion state + AZ::UserSettingsProvider m_localUserSettings; + + //! Are local settings loaded + bool m_activatedLocalUserSettings = false; + + QTimer m_timer; + + AtomToolsFramework::LocalSocket m_socket; + AtomToolsFramework::LocalServer m_server; + }; +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp new file mode 100644 index 0000000000..35a151e95b --- /dev/null +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -0,0 +1,428 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT +#include +#include +AZ_POP_DISABLE_WARNING + +namespace AtomToolsFramework +{ + //! This function returns the build system target name of "AtomTools +// AZStd::string_view GetBuildTargetName() +// { +//#if !defined(LY_CMAKE_TARGET) +//#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" +//#endif +// return AZStd::string_view{ LY_CMAKE_TARGET }; +// } + + const char* AtomToolsApplication::GetCurrentConfigurationName() const + { +#if defined(_RELEASE) + return "ReleaseAtomTools"; +#elif defined(_DEBUG) + return "DebugAtomTools"; +#else + return "ProfileAtomTools"; +#endif + } + + + AtomToolsApplication::AtomToolsApplication(int* argc, char*** argv) + : Application(argc, argv) + , AzQtApplication(*argc, *argv) + { + } + + void AtomToolsApplication::CreateReflectionManager() + { + Application::CreateReflectionManager(); + GetSerializeContext()->CreateEditContext(); + } + + void AtomToolsApplication::Reflect(AZ::ReflectContext* context) + { + Application::Reflect(context); + + AzToolsFramework::AssetBrowser::AssetBrowserEntry::Reflect(context); + AzToolsFramework::AssetBrowser::RootAssetBrowserEntry::Reflect(context); + AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry::Reflect(context); + AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry::Reflect(context); + AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry::Reflect(context); + + AzToolsFramework::QTreeViewWithStateSaving::Reflect(context); + AzToolsFramework::QWidgetSavedState::Reflect(context); + + if (auto behaviorContext = azrtti_cast(context)) + { + // this will put these methods into the 'azlmbr.AtomTools.general' module + auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) + { + methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) + ->Attribute(AZ::Script::Attributes::Category, "Editor") + ->Attribute(AZ::Script::Attributes::Module, "AtomTools.general"); + }; + // The reflection here is based on patterns in CryEditPythonHandler::Reflect + addGeneral(behaviorContext->Method( + "idle_wait_frames", &AtomToolsApplication::PyIdleWaitFrames, nullptr, + "Waits idling for a frames. Primarily used for auto-testing.")); + } + } + + void AtomToolsApplication::RegisterCoreComponents() + { + Application::RegisterCoreComponents(); + RegisterComponentDescriptor(AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor()); + RegisterComponentDescriptor(AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor()); + RegisterComponentDescriptor(AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor()); + RegisterComponentDescriptor(AzToolsFramework::AssetSystem::AssetSystemComponent::CreateDescriptor()); + RegisterComponentDescriptor(AzToolsFramework::PerforceComponent::CreateDescriptor()); + } + + AZ::ComponentTypeList AtomToolsApplication::GetRequiredSystemComponents() const + { + AZ::ComponentTypeList components = Application::GetRequiredSystemComponents(); + + components.insert( + components.end(), + { + azrtti_typeid(), + azrtti_typeid(), + azrtti_typeid(), + azrtti_typeid(), + }); + + return components; + } + + void AtomToolsApplication::CreateStaticModules(AZStd::vector& outModules) + { + Application::CreateStaticModules(outModules); + outModules.push_back(aznew AzToolsFramework::AzToolsFrameworkModule); + } + + void AtomToolsApplication::StartCommon(AZ::Entity* systemEntity) + { + AzFramework::AssetSystemStatusBus::Handler::BusConnect(); + AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect(); + + AzFramework::Application::StartCommon(systemEntity); + + StartInternal(); + + m_timer.start(); + } + + void AtomToolsApplication::Destroy() + { + AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); + AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); + AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); + + m_logFile = {}; + m_startupLogSink = {}; + + AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); + Application::Destroy(); + } + + void AtomToolsApplication::CompileCriticalAssets() + { + AZ_TracePrintf("AtomTools", "Compiling critical assets.\n"); + + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + const AZStd::string assetFiltersArray[] = { + "passes/", + "config/", + }; + + QStringList failedAssets; + + // Forced asset processor to synchronously process all critical assets + // Note: with AssetManager's current implementation, a compiled asset won't be added in asset registry until next system tick. + // So the asset id won't be found right after CompileAssetSync call. + for (const AZStd::string& assetFilters : assetFiltersArray) + { + AZ_TracePrintf("AtomTools", "Compiling critical asset matching: %s.\n", assetFilters.c_str()); + + // Wait for the asset be compiled + AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; + AzFramework::AssetSystemRequestBus::BroadcastResult( + status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilters); + if (status != AzFramework::AssetSystem::AssetStatus_Compiled) + { + failedAssets.append(assetFilters.c_str()); + } + } + + if (!failedAssets.empty()) + { + QMessageBox::critical( + activeWindow(), QString("Failed to compile critical assets"), + QString("Failed to compile the following critical assets:\n%1\n%2") + .arg(failedAssets.join(",\n")) + .arg("Make sure this is an Atom project.")); + ExitMainLoop(); + } + } + + void AtomToolsApplication::SaveSettings() + { + if (m_activatedLocalUserSettings) + { + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext); + AZ_Assert(context, "No serialize context"); + + char resolvedPath[AZ_MAX_PATH_LEN] = ""; + AZ::IO::FileIOBase::GetInstance()->ResolvePath( + "@user@/MaterialEditorUserSettings.xml", resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); + m_localUserSettings.Save(resolvedPath, context); + } + } + + + void AtomToolsApplication::LoadSettings() + { + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext); + AZ_Assert(context, "No serialize context"); + + char resolvedPath[AZ_MAX_PATH_LEN] = ""; + AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/EditorUserSettings.xml", resolvedPath, AZ_MAX_PATH_LEN); + + m_localUserSettings.Load(resolvedPath, context); + m_localUserSettings.Activate(AZ::UserSettings::CT_LOCAL); + AZ::UserSettingsOwnerRequestBus::Handler::BusConnect(AZ::UserSettings::CT_LOCAL); + m_activatedLocalUserSettings = true; + } + + void AtomToolsApplication::UnloadSettings() + { + if (m_activatedLocalUserSettings) + { + //SaveSettings(); + m_localUserSettings.Deactivate(); + AZ::UserSettingsOwnerRequestBus::Handler::BusDisconnect(); + m_activatedLocalUserSettings = false; + } + } + + void AtomToolsApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) + { + const AZStd::string exitAfterCommandsSwitchName = "exitaftercommands"; + if (commandLine.HasSwitch(exitAfterCommandsSwitchName)) + { + ExitMainLoop(); + } + } + + bool AtomToolsApplication::LaunchDiscoveryService() + { + // Determine if this is the first launch of the tool by attempting to connect to a running server + if (m_socket.Connect(QApplication::applicationName())) + { + // If the server was located, the application is already running. + // Forward commandline options to other application instance. + QByteArray buffer; + buffer.append("ProcessCommandLine:"); + + // Add the command line options from this process to the message, skipping the executable path + for (int argi = 1; argi < m_argC; ++argi) + { + buffer.append(QString(m_argV[argi]).append("\n").toUtf8()); + } + + // Inject command line option to always bring the main window to the foreground + buffer.append("--activatewindow\n"); + + m_socket.Send(buffer); + m_socket.Disconnect(); + return false; + } + + // Setup server to handle basic commands + m_server.SetReadHandler( + [this](const QByteArray& buffer) + { + // Handle commmand line params from connected socket + if (buffer.startsWith("ProcessCommandLine:")) + { + // Remove header and parse commands + AZStd::string params(buffer.data(), buffer.size()); + params = params.substr(strlen("ProcessCommandLine:")); + + AZStd::vector tokens; + AZ::StringFunc::Tokenize(params, tokens, "\n"); + + if (!tokens.empty()) + { + AZ::CommandLine commandLine; + commandLine.Parse(tokens); + ProcessCommandLine(commandLine); + } + } + }); + + // Launch local server + if (!m_server.Connect(QApplication::applicationName())) + { + return false; + } + + return true; + } + + void AtomToolsApplication::StartInternal() + { + if (WasExitMainLoopRequested()) + { + return; + } + + m_traceLogger.WriteStartupLog("AtomTools.log"); + + if (!LaunchDiscoveryService()) + { + ExitMainLoop(); + return; + } + + AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusConnect(); + AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast( + &AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); + + AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::LoadCatalog, "@assets@/assetcatalog.xml"); + + AZ::RPI::RPISystemInterface::Get()->InitializeSystemAssets(); + + LoadSettings(); + + auto editorPythonEventsInterface = AZ::Interface::Get(); + if (editorPythonEventsInterface) + { + // The PythonSystemComponent does not call StartPython to allow for lazy python initialization, so start it here + // The PythonSystemComponent will call StopPython when it deactivates, so we do not need our own corresponding call to + // StopPython + editorPythonEventsInterface->StartPython(); + } + + // Delay execution of commands and scripts post initialization + QTimer::singleShot( + 0, + [this]() + { + ProcessCommandLine(m_commandLine); + }); + } + + bool AtomToolsApplication::GetAssetDatabaseLocation(AZStd::string& result) + { + AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get(); + AZ::IO::FixedMaxPath assetDatabaseSqlitePath; + if (settingsRegistry && + settingsRegistry->Get(assetDatabaseSqlitePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheProjectRootFolder)) + { + assetDatabaseSqlitePath /= "assetdb.sqlite"; + result = AZStd::string_view(assetDatabaseSqlitePath.Native()); + return true; + } + + return false; + } + + void AtomToolsApplication::Tick(float deltaOverride) + { + TickSystem(); + Application::Tick(deltaOverride); + + if (WasExitMainLoopRequested()) + { + m_timer.disconnect(); + quit(); + } + } + + void AtomToolsApplication::Stop() + { + UnloadSettings(); + AzFramework::Application::Stop(); + } + + void AtomToolsApplication::QueryApplicationType(AZ::ApplicationTypeQuery& appType) const + { + appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Game; + } + + // Copied from PyIdleWaitFrames in CryEdit.cpp + void AtomToolsApplication::PyIdleWaitFrames(uint32_t frames) + { + struct Ticker : public AZ::TickBus::Handler + { + Ticker(QEventLoop* loop, uint32_t targetFrames) + : m_loop(loop) + , m_targetFrames(targetFrames) + { + AZ::TickBus::Handler::BusConnect(); + } + ~Ticker() + { + AZ::TickBus::Handler::BusDisconnect(); + } + + void OnTick(float deltaTime, AZ::ScriptTimePoint time) override + { + AZ_UNUSED(deltaTime); + AZ_UNUSED(time); + if (++m_elapsedFrames == m_targetFrames) + { + m_loop->quit(); + } + } + QEventLoop* m_loop = nullptr; + uint32_t m_elapsedFrames = 0; + uint32_t m_targetFrames = 0; + }; + + QEventLoop loop; + Ticker ticker(&loop, frames); + loop.exec(); + } + +} // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake index 817840221a..63bdbcd2ab 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/atomtoolsframework_files.cmake @@ -6,6 +6,7 @@ # set(FILES + Include/AtomToolsFramework/Application/AtomToolsApplication.h Include/AtomToolsFramework/Communication/LocalServer.h Include/AtomToolsFramework/Communication/LocalSocket.h Include/AtomToolsFramework/Debug/TraceRecorder.h @@ -22,6 +23,7 @@ set(FILES Include/AtomToolsFramework/Viewport/RenderViewportWidget.h Include/AtomToolsFramework/Viewport/ModularViewportCameraController.h Include/AtomToolsFramework/Viewport/ModularViewportCameraControllerRequestBus.h + Source/Application/AtomToolsApplication.cpp Source/Communication/LocalServer.cpp Source/Communication/LocalSocket.cpp Source/Debug/TraceRecorder.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index f880ad7680..324db34ee8 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -71,8 +71,8 @@ namespace MaterialEditor } MaterialEditorApplication::MaterialEditorApplication(int* argc, char*** argv) - : Application(argc, argv) - , AzQtApplication(*argc, *argv) + : AtomToolsApplication(argc, argv) + { QApplication::setApplicationName("O3DE Material Editor"); @@ -93,63 +93,6 @@ namespace MaterialEditor AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } - void MaterialEditorApplication::CreateReflectionManager() - { - Application::CreateReflectionManager(); - GetSerializeContext()->CreateEditContext(); - } - - void MaterialEditorApplication::Reflect(AZ::ReflectContext* context) - { - Application::Reflect(context); - - AzToolsFramework::AssetBrowser::AssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::RootAssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry::Reflect(context); - - AzToolsFramework::QTreeViewWithStateSaving::Reflect(context); - AzToolsFramework::QWidgetSavedState::Reflect(context); - - if (auto behaviorContext = azrtti_cast(context)) - { - // this will put these methods into the 'azlmbr.materialeditor.general' module - auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) - { - methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "materialeditor.general"); - }; - // The reflection here is based on patterns in CryEditPythonHandler::Reflect - addGeneral(behaviorContext->Method("idle_wait_frames", &MaterialEditorApplication::PyIdleWaitFrames, nullptr, "Waits idling for a frames. Primarily used for auto-testing.")); - } - } - - void MaterialEditorApplication::RegisterCoreComponents() - { - Application::RegisterCoreComponents(); - RegisterComponentDescriptor(AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::AssetSystem::AssetSystemComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::PerforceComponent::CreateDescriptor()); - } - - AZ::ComponentTypeList MaterialEditorApplication::GetRequiredSystemComponents() const - { - AZ::ComponentTypeList components = Application::GetRequiredSystemComponents(); - - components.insert(components.end(), { - azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), - }); - - return components; - } - void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) { Application::CreateStaticModules(outModules); @@ -269,20 +212,6 @@ namespace MaterialEditor } } - void MaterialEditorApplication::SaveSettings() - { - if (m_activatedLocalUserSettings) - { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext); - AZ_Assert(context, "No serialize context"); - - char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/MaterialEditorUserSettings.xml", resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); - m_localUserSettings.Save(resolvedPath, context); - } - } - bool MaterialEditorApplication::OnOutput(const char* window, const char* message) { // Suppress spam from the Source Control system @@ -355,86 +284,6 @@ namespace MaterialEditor } } - void MaterialEditorApplication::LoadSettings() - { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext); - AZ_Assert(context, "No serialize context"); - - char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/EditorUserSettings.xml", resolvedPath, AZ_MAX_PATH_LEN); - - m_localUserSettings.Load(resolvedPath, context); - m_localUserSettings.Activate(AZ::UserSettings::CT_LOCAL); - AZ::UserSettingsOwnerRequestBus::Handler::BusConnect(AZ::UserSettings::CT_LOCAL); - m_activatedLocalUserSettings = true; - } - - void MaterialEditorApplication::UnloadSettings() - { - if (m_activatedLocalUserSettings) - { - SaveSettings(); - m_localUserSettings.Deactivate(); - AZ::UserSettingsOwnerRequestBus::Handler::BusDisconnect(); - m_activatedLocalUserSettings = false; - } - } - - bool MaterialEditorApplication::LaunchDiscoveryService() - { - // Determine if this is the first launch of the tool by attempting to connect to a running server - if (m_socket.Connect(QApplication::applicationName())) - { - // If the server was located, the application is already running. - // Forward commandline options to other application instance. - QByteArray buffer; - buffer.append("ProcessCommandLine:"); - - // Add the command line options from this process to the message, skipping the executable path - for (int argi = 1; argi < m_argC; ++argi) - { - buffer.append(QString(m_argV[argi]).append("\n").toUtf8()); - } - - // Inject command line option to always bring the main window to the foreground - buffer.append("--activatewindow\n"); - - m_socket.Send(buffer); - m_socket.Disconnect(); - return false; - } - - // Setup server to handle basic commands - m_server.SetReadHandler([this](const QByteArray& buffer) { - // Handle commmand line params from connected socket - if (buffer.startsWith("ProcessCommandLine:")) - { - // Remove header and parse commands - AZStd::string params(buffer.data(), buffer.size()); - params = params.substr(strlen("ProcessCommandLine:")); - - AZStd::vector tokens; - AZ::StringFunc::Tokenize(params, tokens, "\n"); - - if (!tokens.empty()) - { - AZ::CommandLine commandLine; - commandLine.Parse(tokens); - ProcessCommandLine(commandLine); - } - } - }); - - // Launch local server - if (!m_server.Connect(QApplication::applicationName())) - { - return false; - } - - return true; - } - void MaterialEditorApplication::StartInternal() { if (WasExitMainLoopRequested()) @@ -476,20 +325,6 @@ namespace MaterialEditor QTimer::singleShot(0, [this]() { ProcessCommandLine(m_commandLine); }); } - bool MaterialEditorApplication::GetAssetDatabaseLocation(AZStd::string& result) - { - AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get(); - AZ::IO::FixedMaxPath assetDatabaseSqlitePath; - if (settingsRegistry && settingsRegistry->Get(assetDatabaseSqlitePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheProjectRootFolder)) - { - assetDatabaseSqlitePath /= "assetdb.sqlite"; - result = AZStd::string_view(assetDatabaseSqlitePath.Native()); - return true; - } - - return false; - } - void MaterialEditorApplication::Tick(float deltaOverride) { TickSystem(); @@ -545,38 +380,4 @@ namespace MaterialEditor { AZ_Error("MaterialEditor", false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); } - - // Copied from PyIdleWaitFrames in CryEdit.cpp - void MaterialEditorApplication::PyIdleWaitFrames(uint32_t frames) - { - struct Ticker : public AZ::TickBus::Handler - { - Ticker(QEventLoop* loop, uint32_t targetFrames) : m_loop(loop), m_targetFrames(targetFrames) - { - AZ::TickBus::Handler::BusConnect(); - } - ~Ticker() - { - AZ::TickBus::Handler::BusDisconnect(); - } - - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override - { - AZ_UNUSED(deltaTime); - AZ_UNUSED(time); - if (++m_elapsedFrames == m_targetFrames) - { - m_loop->quit(); - } - } - QEventLoop* m_loop = nullptr; - uint32_t m_elapsedFrames = 0; - uint32_t m_targetFrames = 0; - }; - - QEventLoop loop; - Ticker ticker(&loop, frames); - loop.exec(); - } - } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 284eddee93..86fce0c73b 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -30,29 +31,19 @@ namespace MaterialEditor class MaterialThumbnailRenderer; class MaterialEditorApplication - : public AzFramework::Application - , public AzQtComponents::AzQtApplication - , private AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler + : public AtomToolsFramework::AtomToolsApplication , private MaterialEditorWindowNotificationBus::Handler - , private AzFramework::AssetSystemStatusBus::Handler - , private AZ::UserSettingsOwnerRequestBus::Handler - , private AZ::Debug::TraceMessageBus::Handler - , private AzToolsFramework::EditorPythonConsoleNotificationBus::Handler { public: AZ_TYPE_INFO(MaterialEditor::MaterialEditorApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); - using Base = AzFramework::Application; + using Base = AtomToolsFramework::AtomToolsApplication; MaterialEditorApplication(int* argc, char*** argv); virtual ~MaterialEditorApplication(); ////////////////////////////////////////////////////////////////////////// // AzFramework::Application - void CreateReflectionManager() override; - void Reflect(AZ::ReflectContext* context) override; - void RegisterCoreComponents() override; - AZ::ComponentTypeList GetRequiredSystemComponents() const override; void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; void StartCommon(AZ::Entity* systemEntity) override; @@ -60,11 +51,6 @@ namespace MaterialEditor void Stop() override; private: - ////////////////////////////////////////////////////////////////////////// - // AssetDatabaseRequestsBus::Handler overrides... - bool GetAssetDatabaseLocation(AZStd::string& result) override; - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // MaterialEditorWindowNotificationBus::Handler overrides... void OnMaterialEditorWindowClosing() override; @@ -92,28 +78,14 @@ namespace MaterialEditor void AssetSystemAvailable() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AZ::UserSettingsOwnerRequestBus::Handler overrides... - void SaveSettings() override; - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // AZ::Debug::TraceMessageBus::Handler overrides... bool OnOutput(const char* window, const char* message) override; ////////////////////////////////////////////////////////////////////////// - void CompileCriticalAssets(); - - void ProcessCommandLine(const AZ::CommandLine& commandLine); - - void LoadSettings(); - void UnloadSettings(); - - bool LaunchDiscoveryService(); - - void StartInternal(); - - static void PyIdleWaitFrames(uint32_t frames); + void CompileCriticalAssets() override; + void ProcessCommandLine(const AZ::CommandLine& commandLine) override; + void StartInternal() override; struct LogMessage { @@ -123,18 +95,5 @@ namespace MaterialEditor AZStd::vector m_startupLogSink; AZStd::unique_ptr m_logFile; - - AzToolsFramework::TraceLogger m_traceLogger; - - //! Local user settings are used to store material browser tree expansion state - AZ::UserSettingsProvider m_localUserSettings; - - //! Are local settings loaded - bool m_activatedLocalUserSettings = false; - - QTimer m_timer; - - AtomToolsFramework::LocalSocket m_socket; - AtomToolsFramework::LocalServer m_server; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index d10893ff46..271a53d73c 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -67,77 +67,13 @@ namespace ShaderManagementConsole } ShaderManagementConsoleApplication::ShaderManagementConsoleApplication(int* argc, char*** argv) - : Application(argc, argv) - , AzQtApplication(*argc, *argv) + : AtomToolsApplication(argc, argv) { QApplication::setApplicationName("O3DE Shader Management Console"); // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); - - connect(&m_timer, &QTimer::timeout, this, [&]() - { - this->PumpSystemEventLoopUntilEmpty(); - this->Tick(); - }); - } - - void ShaderManagementConsoleApplication::CreateReflectionManager() - { - Application::CreateReflectionManager(); - GetSerializeContext()->CreateEditContext(); - } - - void ShaderManagementConsoleApplication::Reflect(AZ::ReflectContext* context) - { - Application::Reflect(context); - - AzToolsFramework::AssetBrowser::AssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::RootAssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::FolderAssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry::Reflect(context); - AzToolsFramework::AssetBrowser::ProductAssetBrowserEntry::Reflect(context); - - AzToolsFramework::QTreeViewWithStateSaving::Reflect(context); - AzToolsFramework::QWidgetSavedState::Reflect(context); - - if (auto behaviorContext = azrtti_cast(context)) - { - // this will put these methods into the 'azlmbr.shadermanagementconsole.general' module - auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) - { - methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) - ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "shadermanagementconsole.general"); - }; - // The reflection here is based on patterns in CryEditPythonHandler::Reflect - addGeneral(behaviorContext->Method("idle_wait_frames", &ShaderManagementConsoleApplication::PyIdleWaitFrames, nullptr, "Waits idling for a frames. Primarily used for auto-testing.")); - } - } - - void ShaderManagementConsoleApplication::RegisterCoreComponents() - { - Application::RegisterCoreComponents(); - RegisterComponentDescriptor(AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::AssetSystem::AssetSystemComponent::CreateDescriptor()); - RegisterComponentDescriptor(AzToolsFramework::PerforceComponent::CreateDescriptor()); - } - - AZ::ComponentTypeList ShaderManagementConsoleApplication::GetRequiredSystemComponents() const - { - AZ::ComponentTypeList components = Application::GetRequiredSystemComponents(); - - components.insert(components.end(), { - azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), - azrtti_typeid(), - }); - - return components; } void ShaderManagementConsoleApplication::CreateStaticModules(AZStd::vector& outModules) @@ -148,18 +84,6 @@ namespace ShaderManagementConsole outModules.push_back(aznew ShaderManagementConsoleWindowModule); } - void ShaderManagementConsoleApplication::StartCommon(AZ::Entity* systemEntity) - { - AzFramework::AssetSystemStatusBus::Handler::BusConnect(); - AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect(); - - AzFramework::Application::StartCommon(systemEntity); - - StartInternal(); - - m_timer.start(); - } - void ShaderManagementConsoleApplication::OnShaderManagementConsoleWindowClosing() { ExitMainLoop(); @@ -174,6 +98,7 @@ namespace ShaderManagementConsole ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); + m_traceLogger.~TraceLogger(); AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); @@ -254,20 +179,6 @@ namespace ShaderManagementConsole } } - void ShaderManagementConsoleApplication::SaveSettings() - { - if (m_activatedLocalUserSettings) - { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext); - AZ_Assert(context, "No serialize context"); - - char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/EditorUserSettings.xml", resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); - m_localUserSettings.Save(resolvedPath, context); - } - } - bool ShaderManagementConsoleApplication::OnPrintf(const char* window, const char* /*message*/) { // Suppress spam from the Source Control system @@ -303,32 +214,6 @@ namespace ShaderManagementConsole } } - void ShaderManagementConsoleApplication::LoadSettings() - { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationRequests::GetSerializeContext); - AZ_Assert(context, "No serialize context"); - - char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/EditorUserSettings.xml", resolvedPath, AZ_MAX_PATH_LEN); - - m_localUserSettings.Load(resolvedPath, context); - m_localUserSettings.Activate(AZ::UserSettings::CT_LOCAL); - AZ::UserSettingsOwnerRequestBus::Handler::BusConnect(AZ::UserSettings::CT_LOCAL); - m_activatedLocalUserSettings = true; - } - - void ShaderManagementConsoleApplication::UnloadSettings() - { - if (m_activatedLocalUserSettings) - { - SaveSettings(); - m_localUserSettings.Deactivate(); - AZ::UserSettingsOwnerRequestBus::Handler::BusDisconnect(); - m_activatedLocalUserSettings = false; - } - } - bool ShaderManagementConsoleApplication::LaunchDiscoveryService() { const QStringList arguments = { "-fail_silently" }; @@ -398,17 +283,6 @@ namespace ShaderManagementConsole } } - void ShaderManagementConsoleApplication::Stop() - { - UnloadSettings(); - AzFramework::Application::Stop(); - } - - void ShaderManagementConsoleApplication::QueryApplicationType(AZ::ApplicationTypeQuery& appType) const - { - appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Game; - } - void ShaderManagementConsoleApplication::OnTraceMessage([[maybe_unused]] AZStd::string_view message) { #if defined(AZ_ENABLE_TRACING) @@ -428,48 +302,8 @@ namespace ShaderManagementConsole #endif } - void ShaderManagementConsoleApplication::OnErrorMessage(AZStd::string_view message) - { - // Use AZ_TracePrintf instead of AZ_Error or AZ_Warning to avoid all the metadata noise - OnTraceMessage(message); - } - void ShaderManagementConsoleApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) { AZ_Error("Shader Management Console", false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); } - - // Copied from PyIdleWaitFrames in CryEdit.cpp - void ShaderManagementConsoleApplication::PyIdleWaitFrames(uint32_t frames) - { - struct Ticker : public AZ::TickBus::Handler - { - Ticker(QEventLoop* loop, uint32_t targetFrames) : m_loop(loop), m_targetFrames(targetFrames) - { - AZ::TickBus::Handler::BusConnect(); - } - ~Ticker() - { - AZ::TickBus::Handler::BusDisconnect(); - } - - void OnTick(float deltaTime, AZ::ScriptTimePoint time) override - { - AZ_UNUSED(deltaTime); - AZ_UNUSED(time); - if (++m_elapsedFrames == m_targetFrames) - { - m_loop->quit(); - } - } - QEventLoop* m_loop = nullptr; - uint32_t m_elapsedFrames = 0; - uint32_t m_targetFrames = 0; - }; - - QEventLoop loop; - Ticker ticker(&loop, frames); - loop.exec(); - } - } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index e74458b2e7..f6dd2f12ea 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -23,19 +23,17 @@ #include #include +#include #include namespace ShaderManagementConsole { class ShaderManagementConsoleApplication - : public AzFramework::Application - , public AzQtComponents::AzQtApplication - , private AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler + : public AtomToolsFramework::AtomToolsApplication , private ShaderManagementConsoleWindowNotificationBus::Handler , private AzFramework::AssetSystemStatusBus::Handler - , private AZ::UserSettingsOwnerRequestBus::Handler - , private AZ::Debug::TraceMessageBus::Handler + , private AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler , private AzToolsFramework::EditorPythonConsoleNotificationBus::Handler { public: @@ -113,18 +111,5 @@ namespace ShaderManagementConsole void StartInternal(); static void PyIdleWaitFrames(uint32_t frames); - - AzToolsFramework::TraceLogger m_traceLogger; - - //! Local user settings are used to store asset browser tree expansion state - AZ::UserSettingsProvider m_localUserSettings; - - //! Are local settings loaded - bool m_activatedLocalUserSettings = false; - - QTimer m_timer; - - bool m_started = false; - bool m_closing = false; }; } // namespace ShaderManagementConsole From c1998d8d3c2ca5adb024e7db6da81749319e9ee1 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Wed, 21 Jul 2021 16:47:06 -0500 Subject: [PATCH 10/58] AtomToolsApplication working with SMC Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.cpp | 3 -- .../Code/Source/MaterialEditorApplication.cpp | 5 --- .../Code/Source/MaterialEditorApplication.h | 5 --- .../ShaderManagementConsoleApplication.cpp | 21 ++++++------ .../ShaderManagementConsoleApplication.h | 32 ++----------------- 5 files changed, 12 insertions(+), 54 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 35a151e95b..464480ec53 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -154,9 +154,6 @@ namespace AtomToolsFramework AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - m_logFile = {}; - m_startupLogSink = {}; - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); Application::Destroy(); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 324db34ee8..4b233b0212 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -346,11 +346,6 @@ namespace MaterialEditor AzFramework::Application::Stop(); } - void MaterialEditorApplication::QueryApplicationType(AZ::ApplicationTypeQuery& appType) const - { - appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Game; - } - void MaterialEditorApplication::OnTraceMessage([[maybe_unused]] AZStd::string_view message) { #if defined(AZ_ENABLE_TRACING) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 86fce0c73b..d398f4406d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -61,11 +61,6 @@ namespace MaterialEditor void Destroy() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AZ::ComponentApplication overrides... - void QueryApplicationType(AZ::ApplicationTypeQuery& appType) const override; - ////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////// // EditorPythonConsoleNotificationBus::Handler overrides... void OnTraceMessage(AZStd::string_view message) override; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 271a53d73c..4a3f5dd02d 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -98,7 +98,7 @@ namespace ShaderManagementConsole ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); - m_traceLogger.~TraceLogger(); + AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); @@ -175,7 +175,7 @@ namespace ShaderManagementConsole QString("Failed to compile the following critical assets:\n%1\n%2") .arg(failedAssets.join(",\n")) .arg("Make sure this is an Atom project.")); - m_closing = true; + ExitMainLoop(); } } @@ -214,16 +214,9 @@ namespace ShaderManagementConsole } } - bool ShaderManagementConsoleApplication::LaunchDiscoveryService() - { - const QStringList arguments = { "-fail_silently" }; - - return AtomToolsFramework::LaunchTool("GridHub", AZ_TRAIT_SHADER_MANAGEMENT_CONSOLE_EXT, arguments); - } - void ShaderManagementConsoleApplication::StartInternal() { - if (m_closing) + if (WasExitMainLoopRequested()) { return; } @@ -276,7 +269,7 @@ namespace ShaderManagementConsole TickSystem(); Application::Tick(deltaOverride); - if (m_closing) + if (WasExitMainLoopRequested()) { m_timer.disconnect(); quit(); @@ -302,6 +295,12 @@ namespace ShaderManagementConsole #endif } + void ShaderManagementConsoleApplication::OnErrorMessage(AZStd::string_view message) + { + // Use AZ_TracePrintf instead of AZ_Error or AZ_Warning to avoid all the metadata noise + OnTraceMessage(message); + } + void ShaderManagementConsoleApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) { AZ_Error("Shader Management Console", false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index f6dd2f12ea..d99d814627 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -32,9 +32,6 @@ namespace ShaderManagementConsole class ShaderManagementConsoleApplication : public AtomToolsFramework::AtomToolsApplication , private ShaderManagementConsoleWindowNotificationBus::Handler - , private AzFramework::AssetSystemStatusBus::Handler - , private AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler - , private AzToolsFramework::EditorPythonConsoleNotificationBus::Handler { public: AZ_TYPE_INFO(ShaderManagementConsole::ShaderManagementConsoleApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); @@ -46,15 +43,9 @@ namespace ShaderManagementConsole ////////////////////////////////////////////////////////////////////////// // AzFramework::Application - void CreateReflectionManager() override; - void Reflect(AZ::ReflectContext* context) override; - void RegisterCoreComponents() override; - AZ::ComponentTypeList GetRequiredSystemComponents() const override; void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; - void StartCommon(AZ::Entity* systemEntity) override; void Tick(float deltaOverride = -1.f) override; - void Stop() override; private: ////////////////////////////////////////////////////////////////////////// @@ -72,11 +63,6 @@ namespace ShaderManagementConsole void Destroy() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AzFramework::ApplicationRequests::Bus overrides... - void QueryApplicationType(AZ::ApplicationTypeQuery& appType) const override; - ////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////// // EditorPythonConsoleNotificationBus::Handler overrides... void OnTraceMessage(AZStd::string_view message) override; @@ -89,27 +75,13 @@ namespace ShaderManagementConsole void AssetSystemAvailable() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AZ::UserSettingsOwnerRequestBus::Handler overrides... - void SaveSettings() override; - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // AZ::Debug::TraceMessageBus::Handler overrides... bool OnPrintf(const char* window, const char* message) override; ////////////////////////////////////////////////////////////////////////// - void CompileCriticalAssets(); - + void CompileCriticalAssets() override; void ProcessCommandLine(); - - void LoadSettings(); - void UnloadSettings(); - - bool LaunchDiscoveryService(); - - void StartInternal(); - - static void PyIdleWaitFrames(uint32_t frames); + void StartInternal() override; }; } // namespace ShaderManagementConsole From ecc26a24a5e13d7f4083f6e50c034fb507f7ec82 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Thu, 22 Jul 2021 11:27:23 -0500 Subject: [PATCH 11/58] //! Comment added Signed-off-by: Dayo Lawal --- .../AtomToolsFramework/Application/AtomToolsApplication.h | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index dc34ad9a0a..8d3c09385c 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -18,6 +18,7 @@ namespace AtomToolsFramework { + //!Base class for Atom tools to inherit from class AtomToolsApplication : public AzFramework::Application , public AzQtComponents::AzQtApplication From a3e90b878c6a33780425e6b27eaff4dc8286c7f0 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Mon, 26 Jul 2021 09:55:37 +0200 Subject: [PATCH 12/58] Removed legacy anim graph node parsers and legacy file format chunks Signed-off-by: Benjamin Jillich --- .../Source/Importer/AnimGraphFileFormat.cpp | 120 - .../Source/Importer/AnimGraphFileFormat.h | 231 - .../Importer/LegacyAnimGraphNodeParser.cpp | 4772 ----------------- .../Importer/LegacyAnimGraphNodeParser.h | 259 - .../Source/Importer/MotionSetFileFormat.h | 60 - 5 files changed, 5442 deletions(-) delete mode 100644 Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp delete mode 100644 Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h delete mode 100644 Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp delete mode 100644 Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h delete mode 100644 Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp deleted file mode 100644 index f79057dfa8..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - * 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 "AnimGraphFileFormat.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace EMotionFX -{ - namespace FileFormat - { - AZ::TypeId GetParameterTypeIdForInterfaceType(uint32 interfaceType) - { - switch (interfaceType) - { - case MCore::ATTRIBUTE_INTERFACETYPE_FLOATSPINNER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_FLOATSLIDER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_INTSPINNER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_INTSLIDER: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_CHECKBOX: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR2: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3GIZMO: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR4: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_COLOR: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_STRING: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3: - return azrtti_typeid(); - case MCore::ATTRIBUTE_INTERFACETYPE_TAG: - return azrtti_typeid(); - - case MCore::ATTRIBUTE_INTERFACETYPE_COMBOBOX: - case MCore::ATTRIBUTE_INTERFACETYPE_PROPERTYSET: - case MCore::ATTRIBUTE_INTERFACETYPE_DEFAULT: - default: - break; - } - return AZ::TypeId(); - } - - uint32 GetInterfaceTypeForParameterTypeId(const AZ::TypeId& parameterTypeId) - { - if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_FLOATSPINNER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_FLOATSLIDER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_INTSPINNER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_INTSLIDER; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_CHECKBOX; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR2; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3GIZMO; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR4; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_COLOR; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_STRING; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_VECTOR3; - } - else if (parameterTypeId == azrtti_typeid()) - { - return MCore::ATTRIBUTE_INTERFACETYPE_TAG; - } - return MCORE_INVALIDINDEX32; - } - } -} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h deleted file mode 100644 index 3b88c3605f..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/AnimGraphFileFormat.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * 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 - * - */ - -#pragma once - -#include "SharedFileFormatStructs.h" -#include "AzCore/RTTI/TypeInfo.h" - -namespace EMotionFX -{ - namespace FileFormat // so now we are in the namespace EMotionFX::FileFormat - { - // collection of animGraph chunk IDs - enum - { - ANIMGRAPH_CHUNK_BLENDNODE = 400, - ANIMGRAPH_CHUNK_STATETRANSITIONS = 401, - ANIMGRAPH_CHUNK_NODECONNECTIONS = 402, - ANIMGRAPH_CHUNK_PARAMETERS = 403, - ANIMGRAPH_CHUNK_NODEGROUPS = 404, - ANIMGRAPH_CHUNK_GROUPPARAMETERS = 405, - ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS = 406, - ANIMGRAPH_CHUNK_ADDITIONALINFO = 407, - ANIMGRAPH_FORCE_32BIT = 0xFFFFFFFF - }; - - enum - { - ANIMGRAPH_NODEFLAG_COLLAPSED = 1 << 0, - ANIMGRAPH_NODEFLAG_VISUALIZED = 1 << 1, - ANIMGRAPH_NODEFLAG_DISABLED = 1 << 2, - ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT = 1 << 3 - }; - - /* - AnimGraph_Header - - ANIMGRAPH_CHUNK_PARAMETERS: (global animgraph parameters) - uint32 numParameters - AnimGraph_ParamInfo[numParameters] - - ANIMGRAPH_CHUNK_BLENDNODE: - AnimGraph_NodeHeader - - ANIMGRAPH_CHUNK_NODECONNECTIONS: (for last loaded BLENDNODE) - uint32 numConnections - AnimGraph_NodeConnection[numConnections] - - ANIMGRAPH_CHUNK_STATETRANSITIONS: (for last loaded node, assumed to be a state machine) - uint32 numStateTransitions - uint32 blendNodeIndex (the state machine the transitions are for) - AnimGraph_StateTransition[numStateTransitions] - - ANIMGRAPH_CHUNK_NODEGROUPS: - uint32 numNodeGroups - AnimGraph_NodeGroup[numNodeGroups] - - ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS: - uint32 activePresetIndex - uint32 numPresets - AnimGraph_GameControllerPreset[numPresets] - */ - - // AnimGraph file header - struct AnimGraph_Header - { - char mFourCC[4]; - uint8 mEndianType; - uint32 mFileVersion; - uint32 mNumNodes; - uint32 mNumStateTransitions; - uint32 mNumNodeConnections; - uint32 mNumParameters; - - // followed by: - // string mName; - // string mCopyright; - // string mDescription; - // string mCompany; - // string mEMFXVersion; - // string mEMStudioBuildDate; - }; - - // additional info - struct AnimGraph_AdditionalInfo - { - uint8 mUnitType; - }; - - - // the node header - struct AnimGraph_NodeHeader - { - uint32 mTypeID; - uint32 mParentIndex; - uint32 mVersion; - uint32 mNumCustomDataBytes; // number of bytes of node custom data to follow - uint32 mNumChildNodes; - uint32 mNumAttributes; - int32 mVisualPosX; - int32 mVisualPosY; - uint32 mVisualizeColor; - uint8 mFlags; - - // followed by: - // string mName; - // animGraphNode->Save(...) or animGraphNode->Load(...), writing or reading mNumBytes bytes - }; - - - struct AnimGraph_ParameterInfo - { - uint32 mNumComboValues; - uint32 mInterfaceType; - uint32 mAttributeType; - uint16 mFlags; - char mHasMinMax; - - // followed by: - // string mName - // string mInternalName - // string mDescription - // if (mHasMinMax == 1) - // { - // AnimGraph_Attribute mMinValue - // AnimGraph_Attribute mMaxValue - // } - // AnimGraph_Attribute mDefaultValue - // string mComboValues[mNumComboValues] - }; - - - // a node connection - struct AnimGraph_NodeConnection - { - uint32 mSourceNode; - uint32 mTargetNode; - uint16 mSourceNodePort; - uint16 mTargetNodePort; - }; - - - // a state transition - struct AnimGraph_StateTransition - { - uint32 mSourceNode; - uint32 mDestNode; - int32 mStartOffsetX; - int32 mStartOffsetY; - int32 mEndOffsetX; - int32 mEndOffsetY; - uint32 mNumConditions; - - // followed by: - // AnimGraph_NodeHeader (and its followed by data, EXCEPT THE NAME STRING, which is skipped) - // AnimGraph_NodeHeader[mConditions] (and its followed by data, EXCEPT THE NAME STRING, which is skipped) - }; - - - // a node group - struct AnimGraph_NodeGroup - { - FileColor mColor; - uint8 mIsVisible; - uint32 mNumNodes; - - // followed by: - // string mName - // uint32[mNumNodes] (node indices that belong to the group) - }; - - - // a group parameter - struct AnimGraph_GroupParameter - { - uint32 mNumParameters; - uint8 mCollapsed; - - // followed by: - // string mName - // uint32[mNumParameters] (parameter indices that belong to the group) - }; - - - // a game controller parameter info - struct AnimGraph_GameControllerParameterInfo - { - uint8 mAxis; - uint8 mMode; - uint8 mInvert; - - // followed by: - // string mName - }; - - - // a game controller button info - struct AnimGraph_GameControllerButtonInfo - { - uint8 mButtonIndex; - uint8 mMode; - - // followed by: - // string mString - }; - - - // a game controller preset - struct AnimGraph_GameControllerPreset - { - uint32 mNumParameterInfos; - uint32 mNumButtonInfos; - - // followed by: - // string mName - // AnimGraph_GameControllerParameterInfo[mNumParameterInfos] - // AnimGraph_GameControllerButtonInfo[mNumButtonInfos] - }; - - // Conversion functions to support attributes with the old serialization. - // Once we deprecate the old format we can remove these two functions. - AZ::TypeId GetParameterTypeIdForInterfaceType(uint32 interfaceType); - uint32 GetInterfaceTypeForParameterTypeId(const AZ::TypeId& parameterTypeId); - - } // namespace FileFormat -} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp deleted file mode 100644 index db3db121dd..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.cpp +++ /dev/null @@ -1,4772 +0,0 @@ -/* - * 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 "LegacyAnimGraphNodeParser.h" -#include -#include -#include "../ConstraintTransformRotationAngles.h" -#include "ChunkProcessors.h" -#include "../AnimGraph.h" -#include "../AnimGraphStateMachine.h" -#include "../AnimGraphBindPoseNode.h" -#include "../AnimGraphHubNode.h" -#include "../AnimGraphParameterCondition.h" -#include "../AnimGraphVector2Condition.h" -#include "../AnimGraphMotionCondition.h" -#include "../AnimGraphStateCondition.h" -#include "../AnimGraphTimeCondition.h" -#include "../AnimGraphPlayTimeCondition.h" -#include "../AnimGraphTagCondition.h" -#include "../BlendTreeMotionFrameNode.h" -#include "../BlendTreeBlendNNode.h" -#include "../BlendTreeFloatConditionNode.h" -#include "../BlendTreeFloatSwitchNode.h" -#include "../BlendTreeBoolLogicNode.h" -#include "../AnimGraphMotionNode.h" -#include "../BlendTreeAccumTransformNode.h" -#include "../BlendTreeBlend2LegacyNode.h" -#include "../BlendTreeFloatConstantNode.h" -#include "../BlendTreeFloatMath1Node.h" -#include "../BlendTreeFloatMath2Node.h" -#include "../BlendTreeMorphTargetNode.h" -#include "../BlendTreeVector2ComposeNode.h" -#include "../BlendTreeVector3ComposeNode.h" -#include "../BlendTreeVector4ComposeNode.h" -#include "../BlendTreeVector3Math1Node.h" -#include "../BlendTreeVector3Math2Node.h" -#include "../BlendTreeSmoothingNode.h" -#include "../BlendTreeRangeRemapperNode.h" -#include "../BlendTreeTwoLinkIKNode.h" -#include "../BlendTreeLookAtNode.h" -#include "../BlendTreeTransformNode.h" -#include "../BlendTreeMaskLegacyNode.h" -#include "../BlendTreePoseSwitchNode.h" -#include "../BlendTreeVector2DecomposeNode.h" -#include "../BlendTreeVector3DecomposeNode.h" -#include "../BlendTreeVector4DecomposeNode.h" -#include "../BlendTreeDirectionToWeightNode.h" -#include "../BlendTreeMirrorPoseNode.h" -#include "../AnimGraphEntryNode.h" -#include "../AnimGraphExitNode.h" -#include "../BlendTreeParameterNode.h" -#include "../BlendSpace1DNode.h" -#include "../BlendSpace2DNode.h" -#include "../BlendTreeFinalNode.h" -#include "../BlendTree.h" -#include "../BlendSpaceNode.h" -#include "../AnimGraphStateTransition.h" -#include "../AnimGraphMotionCondition.h" -#include "../AnimGraphParameterCondition.h" -#include "../AnimGraphPlayTimeCondition.h" -#include "../AnimGraphStateCondition.h" -#include "../AnimGraphTagCondition.h" -#include "../AnimGraphTimeCondition.h" -#include "../AnimGraphVector2Condition.h" -#include "../BlendTreeFloatConstantNode.h" -#include "../BlendTreeMorphTargetNode.h" -#include "../BlendTreeVector2ComposeNode.h" -#include "../BlendTreeVector3ComposeNode.h" -#include "../BlendTreeVector4ComposeNode.h" -#include "../TwoStringEventData.h" - - -namespace EMotionFX -{ - const AZ::TypeId GetNewTypeIdByOldNodeTypeId(uint32 oldNodeTypeId) - { - switch (oldNodeTypeId) - { - case 0x00000017: return azrtti_typeid(); break; - case 0x00000005: return azrtti_typeid(); break; - case 0x00000002: return azrtti_typeid(); break; - case 0x38658581: return azrtti_typeid(); break; - case 0x32521069: return azrtti_typeid(); break; - case 0x38020071: return azrtti_typeid(); break; - case 0x00000006: return azrtti_typeid(); break; - case 0x00000001: return azrtti_typeid(); break; - case 0x00022100: return azrtti_typeid(); break; - case 0x00022200: return azrtti_typeid(); break; - case 0x00000004: return azrtti_typeid(); break; - case 0x00000013: return azrtti_typeid(); break; - case 0x00000007: return azrtti_typeid(); break; - case 0x00000008: return azrtti_typeid(); break; - case 0x00000009: return azrtti_typeid(); break; - case 0x00000010: return azrtti_typeid(); break; - case 0x00000148: return azrtti_typeid(); break; - case 0x00000012: return azrtti_typeid(); break; - case 0x00000011: return azrtti_typeid(); break; - case 0x00000014: return azrtti_typeid(); break; - case 0x00000016: return azrtti_typeid(); break; - case 0x00002445: return azrtti_typeid(); break; - case 0x00000018: return azrtti_typeid(); break; - case 0x00000020: return azrtti_typeid(); break; - case 0x00000021: return azrtti_typeid(); break; - case 0x00000126: return azrtti_typeid(); break; - case 0x00000227: return azrtti_typeid(); break; - case 0x00000129: return azrtti_typeid(); break; - case 0x00000228: return azrtti_typeid(); break; - case 0x00000128: return azrtti_typeid(); break; - case 0x00000229: return azrtti_typeid(); break; - case 0x00000456: return azrtti_typeid(); break; - case 0x02094017: return azrtti_typeid(); break; - case 0x38427080: return azrtti_typeid(); break; - case 0x00000214: return azrtti_typeid(); break; - case 0x00001286: return azrtti_typeid(); break; - case 0x00040360: return azrtti_typeid(); break; - case 0x00012345: return azrtti_typeid(); break; - case 0x00012346: return azrtti_typeid(); break; - case 0x00001000: return azrtti_typeid(); break; - case 0x00002000: return azrtti_typeid(); break; - case 0x00002123: return azrtti_typeid(); break; - case 0x00002001: return azrtti_typeid(); break; - case 0x09502005: return azrtti_typeid(); break; - case 0x00005210: return azrtti_typeid(); break; - case 0x00029610: return azrtti_typeid(); break; - case 0x00005321: return azrtti_typeid(); break; - default: return AZ::TypeId::CreateNull(); - }; - } - - class LegacyAttributeRotation - { - public: - LegacyAttributeRotation() - {} - - LegacyAttributeRotation(const LegacyAttributeRotation& src): - m_rotation(src.m_rotation), - m_degrees(src.m_degrees), - m_order(src.m_order) - {} - - LegacyAttributeRotation& operator=(const LegacyAttributeRotation& src) - { - m_rotation = src.m_rotation; - m_degrees = src.m_degrees; - m_order = src.m_order; - return *this; - } - - void SetRotation(const AZ::Quaternion& rotation) - { - m_rotation = rotation; - } - - void SetDegrees(const AZ::Vector3& degrees) - { - m_degrees = degrees; - } - - void SetOrder(LegacyERotationOrder order) - { - m_order = order; - } - - const AZ::Quaternion& GetRotation() const - { - return m_rotation; - } - - const AZ::Vector3& GetDegrees() const - { - return m_degrees; - } - - LegacyERotationOrder GetOrder() const - { - return m_order; - } - - private: - AZ::Quaternion m_rotation; /**< The unit quaternion rotation. */ - AZ::Vector3 m_degrees; /**< The rotation angles. As programmer you don't need to setup these values. They are only to display in the GUI. */ - LegacyERotationOrder m_order; /**< The rotation order, which defaults to ZYX. */ - }; - - class LegacyStateFilterLocal - { - public: - LegacyStateFilterLocal() { } - - LegacyStateFilterLocal(const LegacyStateFilterLocal& src) : - m_nodeNames(src.m_nodeNames), - m_groupNames(src.m_groupNames) - { } - - LegacyStateFilterLocal& operator=(const LegacyStateFilterLocal& src) - { - m_nodeNames = src.m_nodeNames; - m_groupNames = src.m_groupNames; - return *this; - } - - void SetNodeNmes(const AZStd::vector& nodeNames) - { - m_nodeNames = nodeNames; - } - - void SetGroupNames(const AZStd::vector& groupNames) - { - m_groupNames = groupNames; - } - - const AZStd::vector& GetNodeNames() const - { - return m_nodeNames; - } - - const AZStd::vector& GetGroupNames() const - { - return m_groupNames; - } - - private: - AZStd::vector m_nodeNames; - AZStd::vector m_groupNames; - }; - -bool LegacyAnimGraphNodeParser::Forward(MCore::File* stream, size_t numBytes) -{ - if(!stream->Forward(numBytes)) - { - AZ_Error("EMotionFX", false, "Unable to skip data in stream"); - return false; - } - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - AZStd::string motionId; - - AZ::u32 numCharacters; - if (stream->Read(&numCharacters, sizeof(AZ::u32)) != sizeof(AZ::u32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - - if (numCharacters > 0) - { - motionId.resize(numCharacters); - if (stream->Read(motionId.data(), numCharacters) != numCharacters) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - AZ::Vector2 position; - if (stream->Read(&position, MCore::AttributeVector2::sizeofVector2) != MCore::AttributeVector2::sizeofVector2) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - float x = position.GetX(); - float y = position.GetY(); - MCore::Endian::ConvertFloat(&x, endianType); - MCore::Endian::ConvertFloat(&y, endianType); - position.Set(x, y); - - - AZ::u8 streamTypeFlags; - if (stream->Read(&streamTypeFlags, sizeof(AZ::u8)) != sizeof(AZ::u8)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - BlendSpaceNode::BlendSpaceMotion::TypeFlags typeFlags = static_cast(streamTypeFlags); - m_value.Set(motionId, position, typeFlags); - return true; -} - -template<> -bool LegacyAttribute>::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of entries - uint32 numEntries; - if (stream->Read(&numEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numEntries, endianType); - - m_value.resize(numEntries); - for (uint32 i = 0; i < numEntries; ++i) - { - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "LegacyParameterMask: unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, endianType); - AZStd::string name; - if (numStringBytes > 0) - { - name.resize(numStringBytes); - // Read the string data - if (stream->Read(name.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "LegacyParameterMask: Unable to read data in stream"); - return false; - } - } - m_value[i] = name; - } - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the value - AZ::Vector2 streamValue; - if (stream->Read(&streamValue, MCore::AttributeVector2::sizeofVector2) != MCore::AttributeVector2::sizeofVector2) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertVector2(&streamValue, endianType); - m_value = streamValue; - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - uint8 version; - if(stream->Read(&version, sizeof(uint8)) != sizeof(uint8)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - switch (version) - { - case 1: - { - AZ::PackedVector3f streamValue; - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - - // Read only the degrees, automatically calculate the quaternion - m_value.SetDegrees(value); - const AZ::Quaternion rotation = MCore::AzEulerAnglesToAzQuat(MCore::Math::DegreesToRadians(value.GetX()), MCore::Math::DegreesToRadians(value.GetY()), MCore::Math::DegreesToRadians(value.GetZ())); - m_value.SetRotation(rotation); - } - break; - case 2: - { - AZ::PackedVector3f streamValue; - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - m_value.SetDegrees(value); - - AZ::Quaternion streamValueQ; - if (stream->Read(&streamValueQ, sizeof(AZ::Quaternion)) != sizeof(AZ::Quaternion)) - { - return false; - } - - // Convert endian - MCore::Endian::ConvertQuaternion(&streamValueQ, endianType); - m_value.SetRotation(streamValueQ); - } - break; - case 3: - { - // Read the value - AZ::PackedVector3f streamValue; - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - m_value.SetDegrees(value); - - // Read the quaternion - AZ::Quaternion streamValueQ; - if (stream->Read(&streamValueQ, sizeof(AZ::Quaternion)) != sizeof(AZ::Quaternion)) - { - return false; - } - - // Convert endian - MCore::Endian::ConvertQuaternion(&streamValueQ, endianType); - m_value.SetRotation(streamValueQ); - - // Read the rotation order - uint8 order = 0; - if (stream->Read(&order, sizeof(uint8)) != sizeof(uint8)) - { - return false; - } - - m_value.SetOrder(static_cast(order)); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unknown version %u parsing legacy attribute rotation", version); - return false; - } - break; - } - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Read the value - AZ::PackedVector3f streamValue(0.0f); - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) != sizeof(AZ::PackedVector3f)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - AZ::Vector3 value(streamValue); - MCore::Endian::ConvertVector3(&value, endianType); - - m_value = AZ::PackedVector3f(value.GetX(), value.GetY(), value.GetZ()); - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - AZ_UNUSED(endianType); - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - int8 streamValue; - if (stream->Read(&streamValue, sizeof(int8)) != sizeof(int8)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - m_value = (streamValue == 0) ? false : true; - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - AZStd::string nodeName; - // Read the character data - if (numCharacters > 0) - { - nodeName.resize(numCharacters); - if (stream->Read( nodeName.data(), sizeof(char) * numCharacters) != (sizeof(char) * numCharacters)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - // Read the parent depth - uint32 parentDepth; - if (stream->Read(&parentDepth, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertUnsignedInt32(&parentDepth, endianType); - m_value.first = nodeName; - m_value.second = parentDepth; - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType streamEndianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - AZ_Error("EMotionFX", false, "Unable to skip version for legacy attribute State Filter"); - return false; - } - - // Read the number of group entries - uint32 numGroupEntries; - if (stream->Read(&numGroupEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read num groups"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numGroupEntries, streamEndianType); - - // Read the number of node entries - uint32 numNodeEntries; - if (stream->Read(&numNodeEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read num nodes"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numNodeEntries, streamEndianType); - - // Read the group entries - AZStd::string convTemp; - - AZStd::vector groupNames; - groupNames.resize(numGroupEntries); - - for (uint32 i = 0; i < numGroupEntries; ++i) - { - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read group name size"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, streamEndianType); - - // Read the string data - if (numStringBytes > 0) - { - convTemp.resize(numStringBytes); - if (stream->Read(convTemp.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "Unable to read group name"); - return false; - } - } - else - { - convTemp.clear(); - } - - // Add the entry to the mask - groupNames[i] = convTemp; - } - - // Read the node entries - AZStd::vector nodeNames; - nodeNames.resize(numNodeEntries); - for (uint32 i = 0; i < numNodeEntries; ++i) - { - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read node name size"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, streamEndianType); - - // Read the string data - if (numStringBytes > 0) - { - convTemp.resize(numStringBytes); - if (stream->Read(convTemp.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "Unable to read node name"); - return false; - } - } - else - { - convTemp.clear(); - } - - // Add the entry to the mask - nodeNames[i] = convTemp; - } - m_value.SetNodeNmes(nodeNames); - m_value.SetGroupNames(groupNames); - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - int32 streamValue; - if (stream->Read(&streamValue, sizeof(int32)) != sizeof(int32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - MCore::Endian::ConvertSignedInt32(&streamValue, endianType); - m_value = streamValue; - return true; -} - -template<> -bool LegacyAttribute>::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of entries - uint32 numEntries; - if (stream->Read(&numEntries, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numEntries, endianType); - m_value.resize(numEntries); - // Read the entries - for (uint32 i = 0; i < numEntries; ++i) - { - // Read the weight - float weight; - if (stream->Read(&weight, sizeof(float)) != sizeof(float)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertFloat(&weight, endianType); - - // Read the number of string bytes to follow - uint32 numStringBytes; - if (stream->Read(&numStringBytes, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numStringBytes, endianType); - AZStd::string name; - - if (numStringBytes > 0) - { - name.resize(numStringBytes); - - // Read the string data - if (stream->Read(name.data(), numStringBytes) != numStringBytes) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - // Add the entry to the mask - m_value[i].first = name; - m_value[i].second = weight; - } - - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - // Read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - // Convert endian - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - if (numCharacters == 0) - { - m_value.clear(); - return true; - } - - m_value.resize(numCharacters); - if (stream->Read(m_value.data(), numCharacters) != numCharacters) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - return true; -} - -template<> -bool LegacyAttribute::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Skip the version (not used byt this legacy attribute) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint8))) - { - return false; - } - - float streamValue; - if (stream->Read(&streamValue, sizeof(float)) != sizeof(float)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - - MCore::Endian::ConvertFloat(&streamValue, endianType); - - m_value = streamValue; - return true; -} - -template -const T& LegacyAttribute::GetValue() const -{ - return m_value; -} - -bool LegacyAnimGraphNodeParser::GetBlendSpaceNodeEvaluatorTypeId(uint32 legacyIndex, AZ::TypeId& value) -{ - bool result = true; - switch (legacyIndex) - { - case 0: - { - value = azrtti_typeid(); - } - break; - case 1: - { - value = azrtti_typeid(); - } - break; - case 2: - { - value = azrtti_typeid(); - } - break; - case 3: - { - value = azrtti_typeid(); - } - break; - case 4: - { - value = azrtti_typeid(); - } - break; - case 5: - { - value = azrtti_typeid(); - } - break; - case 6: - { - value = azrtti_typeid(); - } - break; - case 7: - { - value = azrtti_typeid(); - } - break; - case 8: - { - value = azrtti_typeid(); - } - break; - default: - { - result = false; - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::GetBlendSpaceNodeEvaluatorTypeId: Unknown typeid index"); - } - break; - } - return result; -} - -bool LegacyAnimGraphNodeParser::InitializeNodeGeneralData(const char* nodeName, Importer::ImportParameters& importParams, FileFormat::AnimGraph_NodeHeader& nodeHeader, AnimGraphNode* node) -{ - AnimGraph* animGraph = importParams.mAnimGraph; - node->SetName(nodeName); - - node->SetVisualPos(nodeHeader.mVisualPosX, nodeHeader.mVisualPosY); - node->SetIsCollapsed(nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_COLLAPSED); - - const AZ::Color color( - MCore::ExtractRed(nodeHeader.mVisualizeColor)/255.0f, - MCore::ExtractGreen(nodeHeader.mVisualizeColor)/255.0f, - MCore::ExtractBlue(nodeHeader.mVisualizeColor)/255.0f, - 1.0f); - node->SetVisualizeColor(color); - - if (importParams.mAnimGraphSettings->mDisableNodeVisualization == false) - { - node->SetVisualization((nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VISUALIZED) != 0); - } - else - { - node->SetVisualization(false); - } - - node->ReserveChildNodes(nodeHeader.mNumChildNodes); - - if (node->GetSupportsDisable()) - { - node->SetIsEnabled(!(nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_DISABLED)); - } - - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - - // Add the new node to the list of loaded nodes - blendNodes.Add(node); - - AZStd::map& entryNodeIndexToStateMachineIdLookupTable = SharedHelperData::GetEntryStateToStateMachineTable(importParams.mSharedData); - - // Add the node to the anim graph - if (nodeHeader.mParentIndex == MCORE_INVALIDINDEX32) - { - AZ_Assert(azrtti_typeid(node) == azrtti_typeid(), ""); - AnimGraphStateMachine* stateMachine = static_cast(node); - - // Set the root state machine - if (animGraph->GetRootStateMachine() == nullptr) - { - animGraph->SetRootStateMachine(stateMachine); - } - else - { - AZ_Warning("EMotionFX", false, "Anim graph already contains a root state machine. Skipping additional root state machines."); - } - } - else - { - blendNodes[nodeHeader.mParentIndex]->AddChildNode(node); - - AZStd::rbtree_const_iterator> tableIter = entryNodeIndexToStateMachineIdLookupTable.find(AZ::u64(blendNodes[nodeHeader.mParentIndex]->GetId())); - if (tableIter != entryNodeIndexToStateMachineIdLookupTable.end()) - { - AnimGraphNode* animGraphNode = animGraph->RecursiveFindNodeById(AnimGraphNodeId((*tableIter).first)); - // The type id check will remove the pointer - if (!animGraphNode) - { - AZ_Error("EMotionFX", false, "Unable to find expected State Machine that needs a registered entry state"); - AZ_Assert(false, "Unable to find expected State Machine that needs a registered entry state"); - return false; - } - if (azrtti_typeid(animGraphNode) != azrtti_typeid()) - { - AZ_Error("EMotionFX", false, "Unexpected parent node type"); - AZ_Assert(false, "Unexpected parent node type"); - return false; - } - AnimGraphStateMachine& parentStateMachine = *(static_cast(animGraphNode)); - uint32 entryStateChildNodeIndex = (*tableIter).second; - if (entryStateChildNodeIndex < parentStateMachine.GetNumChildNodes()) - { - parentStateMachine.SetEntryStateId(parentStateMachine.GetChildNode(entryStateChildNodeIndex)->GetId()); - entryNodeIndexToStateMachineIdLookupTable.erase(tableIter); - } - } - - // Set the final node - if (azrtti_typeid(node) == azrtti_typeid()) - { - AZ_Assert(azrtti_typeid(blendNodes[nodeHeader.mParentIndex]) == azrtti_typeid(), ""); - BlendTree* blendTree = static_cast(blendNodes[nodeHeader.mParentIndex]); - blendTree->SetFinalNodeId(node->GetId()); - } - - // Update the virtual final output node - if (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT) - { - AZ_Assert(azrtti_typeid(blendNodes[nodeHeader.mParentIndex]) == azrtti_typeid(), ""); - BlendTree* blendTree = static_cast(blendNodes[nodeHeader.mParentIndex]); - blendTree->SetVirtualFinalNode(node); - } - return true; - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeMorphTargetNode& blendTreeMorphTargetNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttributeArray legacyAttributeArrayStrings; - if (!legacyAttributeArrayStrings.Parse(stream, endianType)) - { - return false; - } - AZStd::vector morphTargetNames; - morphTargetNames.resize(legacyAttributeArrayStrings.GetValue().size()); - for (int i = 0; i < legacyAttributeArrayStrings.GetValue().size(); i++) - { - morphTargetNames[i] = legacyAttributeArrayStrings.GetValue()[i].GetValue(); - } - blendTreeMorphTargetNode.SetMorphTargetNames(morphTargetNames); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatConstantNode& blendTreeFloatConstantNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConstantNode.SetValue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeLookAtNode& blendTreeLookAtNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeLookAtNode.SetTargetNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeLookAtNode.SetLimitMin(legacyAttribute.GetValue()); - } - break; - case 2: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeLookAtNode.SetLimitMax(legacyAttribute.GetValue()); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - - blendTreeLookAtNode.SetConstraintRotation(legacyAttribute.GetValue().GetRotation()); - } - break; - case 4: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - - blendTreeLookAtNode.SetPostRotation(legacyAttribute.GetValue().GetRotation()); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeLookAtNode.SetFollowSpeed(floatValue); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - ConstraintTransformRotationAngles::EAxis axis = static_cast(static_cast(floatValue)); - blendTreeLookAtNode.SetTwistAxis(axis); - } - break; - case 7: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool limitsEnabled = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeLookAtNode.SetLimitsEnabled(limitsEnabled); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeTwoLinkIKNode& blendTreeTwoLinkIKNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetEndNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetEndEffectorNodeName(legacyAttribute.GetValue()); - } - break; - case 2: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetAlignToNode(legacyAttribute.GetValue()); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTwoLinkIKNode.SetBendDirNodeName(legacyAttribute.GetValue()); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool boolValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeTwoLinkIKNode.SetRotationEnabled(boolValue); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool boolValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeTwoLinkIKNode.SetRelativeBendDir(boolValue); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool boolValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeTwoLinkIKNode.SetExtractBendDir(boolValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatMath1Node& blendTreeFloatMath1Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatMath1Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeFloatMath1Node.SetMathFunction(eMathFunction); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphStateTransition& animGraphStateTransition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0:// ATTRIB_DISABLED - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_DISABLED"); - return false; - } - bool isDisabled = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetIsDisabled(isDisabled); - } - break; - case 1:// ATTRIB_PRIORITY - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_PRIORITY"); - return false; - } - int32 intValue = static_cast(floatValue); - animGraphStateTransition.SetPriority(intValue); - } - break; - case 2:// ATTRIB_CANBEINTERRUPTED - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_CANBEINTERRUPTED"); - return false; - } - bool canBeInterrupted = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetCanBeInterrupted(canBeInterrupted); - } - break; - case 3:// ATTRIB_CANINTERRUPTOTHERTRANSITIONS - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_CANINTERRUPTOTHERTRANSITIONS"); - return false; - } - bool canInterruptOtherTransitions = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetCanInterruptOtherTransitions(canInterruptOtherTransitions); - } - break; - case 4:// ATTRIB_ALLOWSELFINTERRUPTION - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_ALLOWSELFINTERRUPTION"); - return false; - } - bool allowSelfInterruption = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateTransition.SetCanInterruptItself(allowSelfInterruption); - } - break; - case 5:// ATTRIB_ALLOWEDSTATES - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - AZ_Error("EMotionFX", false, "Unable to parse legacy attribute state filter"); - return false; - } - - animGraphStateTransition.SetGroups(legacyAttribute.GetValue().GetGroupNames()); - AZStd::vector nodeIDs; - nodeIDs.resize(legacyAttribute.GetValue().GetNodeNames().size()); - int index = 0; - for (int i = 0; i < legacyAttribute.GetValue().GetNodeNames().size(); i++) - { - AnimGraphNode* node = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().GetNodeNames()[i].c_str()); - if (!node) - { - AZ_Warning("EMotionFX", false, "Missing allowed wild card transition on node (%s): The state (%s) in the allowed source state list does not exist in the graph. Removing." - , animGraphStateTransition.GetTargetNode()->GetName(), legacyAttribute.GetValue().GetNodeNames()[i].c_str()); - } - else - { - nodeIDs[index++] = node->GetId(); - } - } - animGraphStateTransition.SetStateIds(nodeIDs); - } - break; - case 6:// ATTRIB_BLENDTIME - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_BLENDTIME"); - return false; - } - animGraphStateTransition.SetBlendTime(floatValue); - } - break; - case 7:// ATTRIB_SYNC - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_SYNC"); - return false; - } - AnimGraphStateTransition::ESyncMode eSyncMode = static_cast(static_cast(floatValue)); - animGraphStateTransition.SetSyncMode(eSyncMode); - } - break; - case 8:// ATTRIB_EVENTMODE - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_EVENTMODE"); - return false; - } - AnimGraphStateTransition::EEventMode eventMode = static_cast(static_cast(floatValue)); - animGraphStateTransition.SetEventFilterMode(eventMode); - } - break; - case 9:// ATTRIB_INTERPOLATIONTYPE - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_INTERPOLATIONTYPE"); - return false; - } - AnimGraphStateTransition::EInterpolationType interpolationType = static_cast(static_cast(floatValue)); - animGraphStateTransition.SetInterpolationType(interpolationType); - } - break; - case 10:// ATTRIB_EASEIN_SMOOTH - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_EASEIN_SMOOTH"); - return false; - } - animGraphStateTransition.SetEaseInSmoothness(floatValue); - } - break; - case 11:// ATTRIB_EASEOUT_SMOOTH - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "Unable to parse ATTRIB_EASEOUT_SMOOTH"); - return false; - } - animGraphStateTransition.SetEaseOutSmoothness(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count parsing AnimGraphStateTransition"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphStateMachine& animGraphStateMachine = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool alwaysStartInEntryState = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphStateMachine.SetAlwaysStartInEntryState(alwaysStartInEntryState); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeRangeRemapperNode& blendTreeRangeRemapperNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetInputMin(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetInputMax(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetOutputMin(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeRangeRemapperNode.SetOutputMax(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeSmoothingNode& blendTreeSmoothingNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeSmoothingNode.SetInterpolationSpeed(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool useStartValue = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeSmoothingNode.SetUseStartVAlue(useStartValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeSmoothingNode.SetStartVAlue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeVector3Math2Node& blendTreeVector3Math2Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeVector3Math2Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeVector3Math2Node.SetMathFunction(eMathFunction); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeVector3Math2Node.SetDefaultValue(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeVector3Math1Node& blendTreeVector3Math1Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeVector3Math1Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeVector3Math1Node.SetMathFunction(eMathFunction); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatMath2Node& blendTreeFloatMath2Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatMath2Node::EMathFunction eMathFunction = static_cast(static_cast(floatValue)); - blendTreeFloatMath2Node.SetMathFunction(eMathFunction); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatMath2Node.SetDefaultValue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeBlend2LegacyNode& blendTreeBlend2Node = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphObject::ESyncMode syncMode = static_cast(static_cast(floatValue)); - blendTreeBlend2Node.SetSyncMode(syncMode); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphObject::EEventMode eventMode = static_cast(static_cast(floatValue)); - blendTreeBlend2Node.SetEventMode(eventMode); - } - break; - case 2: - { - LegacyAttribute> legacyAttributeNodeMask; - if (!legacyAttributeNodeMask.Parse(stream, endianType)) - { - return false; - } - blendTreeBlend2Node.SetWeightedNodeMask(legacyAttributeNodeMask.GetValue()); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool isAdditive = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeBlend2Node.SetAdditiveBlending(isAdditive); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - - } - } - } - return true; -} - -bool LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(float value) -{ - return value > MCore::Math::epsilon; -} - -bool LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(MCore::File* stream - , MCore::Endian::EEndianType endianType - , const LegacyAttributeHeader& attributeHeader - , float& outputValue) -{ - bool result = true; - switch (attributeHeader.GetAttributeType()) - { - case EMotionFX::LegacyAttributeTypeId::ATTRIBUTE_BOOL_TYPE_ID: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - result = false; - } - else - { - outputValue = legacyAttribute.GetValue() ? 1.0f : 0.0f; - } - } - break; - case EMotionFX::LegacyAttributeTypeId::ATTRIBUTE_INT32_TYPE_ID: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - result = false; - } - else - { - outputValue = static_cast(legacyAttribute.GetValue()); - } - } - break; - case EMotionFX::LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - result = false; - } - outputValue = legacyAttribute.GetValue(); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute type"); - result = false; - } - break; - } - if (!result) - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::TryGetFloatFromAttribute Unable to parse attribute value"); - } - return result; -} - -bool LegacyAttributeHeader::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType, LegacyAttributeHeader& attributeHeader) -{ - AZStd::string name; - name.resize(32); - - // Read the attribute size - uint32 attribType; - if (stream->Read(&attribType, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attribType, endianType); - - // Read the attribute size - uint32 attributeSize; - if (stream->Read(&attributeSize, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attributeSize, endianType); - - // First read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numCharacters, endianType); - - // Read the string - if (numCharacters > 0) - { - name.resize(numCharacters); - if (stream->Read(name.data(), numCharacters) != numCharacters) - { - AZ_Error("EMotionFX", false, "Unable to read data in stream"); - return false; - } - } - - attributeHeader.m_attribType = attribType; - attributeHeader.m_attributeSize = attributeSize; - attributeHeader.m_name = name; - return true; -} - -template class LegacyAttribute> -bool LegacyAttributeArray::PopulateAttributeDynamicArray(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Read the number of values - uint32 numValues; - if (stream->Read(&numValues, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numValues, endianType); - - for (uint32 i = 0; i < numValues; ++i) - { - LegacyAttribute legacyAttribute; - legacyAttribute.Parse(stream, endianType); - m_attributes.push_back(legacyAttribute); - } - return true; -} - -template class LegacyAttribute> -bool LegacyAttributeArray::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Write the version of the attribute settings format - uint8 version; - if (stream->Read(&version, sizeof(uint8)) != sizeof(uint8)) - { - AZ_Error("EMotionFX", false, "LegacyAttributeArray::Parse - Failed to read the attribute version."); - return false; - } - if (version == 2) - { - // Read the attribute type id - uint32 attribType; - if (stream->Read(&attribType, sizeof(uint32)) != sizeof(uint32)) - { - AZ_Error("EMotionFX", false, "AttributeArray::ReadData() - Failed to read the attribute type ID."); - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attribType, endianType); - m_elementTypeId = attribType; - - if (!LegacyAttributeSettingsParser::Parse(stream, endianType)) - { - return false; - } - } - return PopulateAttributeDynamicArray(stream, endianType); -} - -template class LegacyAttribute> -const AZStd::vector< LegacyAttribute > & LegacyAttributeArray::GetValue() const -{ - return m_attributes; -} - -bool LegacyAttributeSettingsParser::Parse(MCore::File* stream, MCore::Endian::EEndianType endianType) -{ - // Write the version of the attribute settings format - uint8 version; - if (stream->Read(&version, sizeof(uint8)) != sizeof(uint8)) - { - AZ_Error("EMotionFX", false, "LegacyAttributeSettingsParser::Parse - Failed to read the attribute version."); - return false; - } - - if (version == 2) - { - // Read the flags (new in version 2) - uint16 flags = 0; - if (stream->Read(&flags, sizeof(uint16)) != sizeof(uint16)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt16(&flags, endianType); - } - - // Read the internal name - uint32 numChars; - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - - AZStd::string tempString; - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - - // Read the name - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - tempString.clear(); - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - - // Read the description - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - tempString.clear(); - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - - // Read the interface type - uint32 interfaceType; - if (stream->Read(&interfaceType, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&interfaceType, endianType); - - // Read the number of combobox values - uint32 numComboValues; - if (stream->Read(&numComboValues, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numComboValues, endianType); - - // Read the combo strings - for (uint32 i = 0; i < numComboValues; ++i) - { - tempString.clear(); - if (stream->Read(&numChars, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&numChars, endianType); - if (numChars > 0) - { - tempString.resize(numChars); - if (stream->Read(tempString.data(), numChars) != numChars) - { - return false; - } - } - } - - for (int skipCounter = 0; skipCounter < 3; ++skipCounter) - { - // Skipping attribute type (default value of settings) - if (!LegacyAnimGraphNodeParser::Forward(stream, sizeof(uint32))) - { - return false; - } - - // Read the attribute size - uint32 attributeSize; - if (stream->Read(&attributeSize, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - MCore::Endian::ConvertUnsignedInt32(&attributeSize, endianType); - // Skipping attribute content (default value of settings) - if (!LegacyAnimGraphNodeParser::Forward(stream, attributeSize)) - { - return false; - } - } - - return true; -} - -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute>; -template class LegacyAttribute>; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttribute; -template class LegacyAttributeArray; -template class LegacyAttributeArray; - - -bool LegacyAnimGraphNodeParser::ParseTransitionConditionChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphTransitionCondition*& transitionCondition) -{ - const AZ::TypeId conditionType = GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID); - if (conditionType.IsNull()) - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot convert legacy transition condition id '0x%x' to uuid.", nodeHeader.mTypeID); - return false; - } - - if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphMotionCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphParameterCondition"); - return false; - } - transitionCondition->SetAnimGraph(importParams.mAnimGraph); - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphPlayTimeCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphStateCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphTagCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphTimeCondition"); - return false; - } - } - else if (conditionType == azrtti_typeid()) - { - if (!ParseAnimGraphTransitionCondition(file, importParams, nodeHeader, transitionCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphVector2Condition"); - return false; - } - } - else - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot parse transition condition with uuid %s. No node parser available", conditionType.ToString().c_str()); - return false; - } - - return true; -} - - -bool LegacyAnimGraphNodeParser::ParseAnimGraphNodeChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const char* nodeName, - FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphNode*& node) -{ - const AZ::TypeId nodeType = GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID); - if (nodeType.IsNull()) - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot convert legacy node id '0x%x' to uuid.", nodeHeader.mTypeID); - return false; - } - - if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphBindPoseNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTree"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFinalNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMotionFrameNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeBlendNNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatConditionNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatSwitchNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeBoolLogicNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphMotionNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeAccumTransformNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeBlend2Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatMath1Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatMath2Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3Math1Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3Math2Node"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeSmoothingNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeRangeRemapperNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphStateMachine"); - return false; - } - - // Only for this node we need to read legacy Custom Data. - - // Read the entry state child node index - uint32 entryStateNodeIndex; - if (file->Read(&entryStateNodeIndex, sizeof(uint32)) != sizeof(uint32)) - { - return false; - } - - // Convert endian if needed - MCore::Endian::ConvertUnsignedInt32(&entryStateNodeIndex, importParams.mEndianType); - AZStd::map& entryNodeIndexToStateMachineIdLookupTable = SharedHelperData::GetEntryStateToStateMachineTable(importParams.mSharedData); - if (!entryNodeIndexToStateMachineIdLookupTable.insert(AZStd::pair(node->GetId(), entryStateNodeIndex)).second) - { - AZ_Assert(false, "Same entry state id for different state machines found"); - AZ_Error("EMotionFX", false, "Same entry state id for different state machines found"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeTwoLinkIKNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeLookAtNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeTransformNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMaskLegacyNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreePoseSwitchNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector2DecomposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3DecomposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector4DecomposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector2ComposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector3ComposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeVector4ComposeNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeDirectionToWeightNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMirrorPoseNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphEntryNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse AnimGraphExitNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeParameterNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendSpace1DNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendSpace2DNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeMorphTargetNode"); - return false; - } - } - else if (nodeType == azrtti_typeid()) - { - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNode(file, importParams, nodeName, nodeHeader, node)) - { - AZ_Error("EMotionFX", false, "Unable to parse BlendTreeFloatConstantNode"); - return false; - } - } - else - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser: Cannot parse node with uuid %s. No node parser available", nodeType.ToString().c_str()); - return false; - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphVector2Condition& animGraphVector2Condition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - animGraphVector2Condition.SetParameterName(legacyAttribute.GetValue()); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphVector2Condition::EOperation operation = static_cast(static_cast(floatValue)); - animGraphVector2Condition.SetOperation(operation); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphParameterCondition::EFunction function = static_cast(static_cast(floatValue)); - animGraphVector2Condition.SetFunction(function); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphVector2Condition.SetTestValue(floatValue); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphVector2Condition.SetRangeValue(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphTimeCondition& animGraphTimeCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphTimeCondition.SetCountDownTime(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - const bool useRandomization = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - animGraphTimeCondition.SetUseRandomization(useRandomization); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphTimeCondition.SetMinRandomTime(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphTimeCondition.SetMaxRandomTime(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphTagCondition& animGraphTagCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphTagCondition::EFunction function = static_cast(static_cast(floatValue)); - animGraphTagCondition.SetFunction(function); - } - break; - case 1: - { - LegacyAttributeArray legacyAttributeArrayStrings; - if (!legacyAttributeArrayStrings.Parse(stream, endianType)) - { - return false; - } - AZStd::vector tags; - tags.resize(legacyAttributeArrayStrings.GetValue().size()); - for (int i = 0; i < legacyAttributeArrayStrings.GetValue().size(); i++) - { - tags[i] = legacyAttributeArrayStrings.GetValue()[i].GetValue(); - } - animGraphTagCondition.SetTags(tags); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphStateCondition& animGraphStateCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AnimGraphNode* node = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().c_str()); - if (node) - { - animGraphStateCondition.SetStateId(node->GetId()); - } - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphStateCondition::TestFunction testFunction = static_cast(static_cast(floatValue)); - animGraphStateCondition.SetTestFunction(testFunction); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphStateCondition.SetPlayTime(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphPlayTimeCondition& animGraphPlayTimeCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AnimGraphNode* node = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().c_str()); - if (node) - { - animGraphPlayTimeCondition.SetNodeId(node->GetId()); - } - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphPlayTimeCondition.SetPlayTime(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphPlayTimeCondition::Mode mode = static_cast(static_cast(floatValue)); - animGraphPlayTimeCondition.SetMode(mode); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphParameterCondition& animGraphParameterCondition = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - animGraphParameterCondition.SetParameterName(legacyAttribute.GetValue()); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphParameterCondition.SetTestValue(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphParameterCondition.SetRangeValue(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphParameterCondition::EFunction function = static_cast(static_cast(floatValue)); - animGraphParameterCondition.SetFunction(function); - } - break; - case 4: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - animGraphParameterCondition.SetTestString(legacyAttribute.GetValue()); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphParameterCondition::EStringFunction stringFunction = static_cast(static_cast(floatValue)); - animGraphParameterCondition.SetStringFunction(stringFunction); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AnimGraphMotionCondition& animGraphMotionCondition = static_cast(animGraphObject); - - AZStd::string eventType; - AZStd::string eventParameter; - - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: // ATTRIB_MOTIONNODE - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AnimGraphNode* motionNode = importParams.mAnimGraph->RecursiveFindNodeByName(legacyAttribute.GetValue().c_str()); - if (motionNode) - { - animGraphMotionCondition.SetMotionNodeId(motionNode->GetId()); - } - } - break; - case 1: // ATTRIB_FUNCTION - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphMotionCondition::TestFunction testFunction = static_cast(static_cast(floatValue)); - animGraphMotionCondition.SetTestFunction(testFunction); - } - break; - case 2: // ATTRIB_NUMLOOPS - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AZ::u32 numLoops = static_cast(floatValue); - animGraphMotionCondition.SetNumLoops(numLoops); - } - break; - case 3: // ATTRIB_PLAYTIME - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - animGraphMotionCondition.SetPlayTime(floatValue); - } - break; - case 4: // ATTRIB_EVENTTYPE - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - eventType = legacyAttribute.GetValue(); - } - break; - case 5: // ATTRIB_EVENTPARAMETER - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - eventParameter = legacyAttribute.GetValue(); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes. Unexpected attribute count"); - return false; - } - break; - } - } - } - - AZStd::shared_ptr eventData = EMotionFX::GetEventManager().FindOrCreateEventData(eventType, eventParameter); - animGraphMotionCondition.SetEventDatas({eventData}); - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeBlendNNode& blendTreeBlendNNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - const AnimGraphObject::ESyncMode syncMode = static_cast(static_cast(floatValue)); - blendTreeBlendNNode.SetSyncMode(syncMode); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - const AnimGraphObject::EEventMode eventMode = static_cast(static_cast(floatValue)); - blendTreeBlendNNode.SetEventMode(eventMode); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeMaskLegacyNode& blendTreeMaskNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for(int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask0(maskStrings); - } - break; - case 1: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for (int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask1(maskStrings); - } - break; - case 2: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for (int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask2(maskStrings); - } - break; - case 3: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - AZStd::vector maskStrings(legacyAttribute.GetValue().size()); - for (int i = 0; i < legacyAttribute.GetValue().size(); i++) - { - maskStrings[i] = legacyAttribute.GetValue()[i].first; - } - blendTreeMaskNode.SetMask3(maskStrings); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents0(eventFlag); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents1(eventFlag); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents2(eventFlag); - } - break; - case 7: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool eventFlag = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeMaskNode.SetOutputEvents3(eventFlag); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count parsing BlendTreeTransformNode"); - return false; - } - break; - } - } - } - return true; -} - - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeTransformNode& blendTreeTransformNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetTargetNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMinTranslation(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - case 2: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMaxTranslation(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMinRotation(legacyAttribute.GetValue().GetDegrees()); - } - break; - case 4: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMaxRotation(legacyAttribute.GetValue().GetDegrees()); - } - break; - case 5: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMinScale(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - case 6: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeTransformNode.SetMaxScale(AZ::Vector3(legacyAttribute.GetValue())); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count parsing BlendTreeTransformNode"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeAccumTransformNode& blendTreeAccumTransformNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendTreeAccumTransformNode.SetTargetNodeName(legacyAttribute.GetValue()); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeAccumTransformNode::Axis axis = static_cast(static_cast(floatValue)); - blendTreeAccumTransformNode.SetTranslationAxis(axis); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeAccumTransformNode::Axis axis = static_cast(static_cast(floatValue)); - blendTreeAccumTransformNode.SetRotationAxis(axis); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeAccumTransformNode::ScaleAxis axis = static_cast(static_cast(floatValue)); - blendTreeAccumTransformNode.SetScaleAxis(axis); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeAccumTransformNode.SetTranslateSpeed(floatValue); - } - break; - case 5: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeAccumTransformNode.SetRotateSpeed(floatValue); - } - break; - case 6: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeAccumTransformNode.SetScaleSpeed(floatValue); - } - break; - case 7: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool translateInvert = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeAccumTransformNode.SetInvertTranslation(translateInvert); - } - break; - case 8: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool rotateInvert = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeAccumTransformNode.SetInvertRotation(rotateInvert); - } - break; - case 9: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - bool scaleInvert = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(floatValue); - blendTreeAccumTransformNode.SetInvertScale(scaleInvert); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: unexpected attributes count"); - return false; - } - break; - } - } - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - AnimGraphMotionNode& animGraphMotionNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttributeArray legacyAttributeArrayStrings; - if (!legacyAttributeArrayStrings.Parse(stream, endianType)) - { - return false; - } - const AZStd::vector > & stringAttributes = legacyAttributeArrayStrings.GetValue(); - AZStd::vector stringValues; - for (LegacyAttribute attrStr : stringAttributes) - { - stringValues.push_back(attrStr.GetValue()); - } - animGraphMotionNode.SetMotionIds(stringValues); - } - break; - case 1: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool loop = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetLoop(loop); - } - break; - case 2: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool retarget = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetRetarget(retarget); - } - break; - case 3: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool reverse = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetReverse(reverse); - } - break; - case 4: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool emitEvents = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetEmitEvents(emitEvents); - } - break; - case 5: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool mirror = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetMirrorMotion(mirror); - } - break; - case 6: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool motionExtraction = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetMotionExtraction(motionExtraction); - } - break; - case 7: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - animGraphMotionNode.SetMotionPlaySpeed(legacyAttributeFloat.GetValue()); - } - break; - case 8: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - AnimGraphMotionNode::EIndexMode eIndexMode = static_cast(static_cast(legacyAttributeFloat.GetValue())); - animGraphMotionNode.SetIndexMode(eIndexMode); - } - break; - case 9: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool nextMotionAfterLoop = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetNextMotionAfterLoop(nextMotionAfterLoop); - } - break; - case 10: - { - LegacyAttribute legacyAttributeFloat; - if (!legacyAttributeFloat.Parse(stream, endianType)) - { - return false; - } - bool nextMotionAfterLoop = LegacyAnimGraphNodeParser::ConvertFloatAttributeValueToBool(legacyAttributeFloat.GetValue()); - animGraphMotionNode.SetNextMotionAfterLoop(nextMotionAfterLoop); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: unexpected attributes count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendSpace2DNode& blendSpace2DNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "BlendSpace2DNode: Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: // ATTRIB_CALCULATION_METHOD_X - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - BlendSpaceNode::ECalculationMethod calculationMethod = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetCalculationMethodX(calculationMethod); - } - break; - case 1: // ATTRIB_EVALUATOR_X - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - uint32 evaluatorIndex = static_cast(floatValue); - AZ::TypeId evaluatorId; - if (!GetBlendSpaceNodeEvaluatorTypeId(evaluatorIndex, evaluatorId)) - { - return false; - } - blendSpace2DNode.SetEvaluatorTypeX(evaluatorId); - } - break; - case 2: // ATTRIB_CALCULATION_METHOD_Y - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - BlendSpaceNode::ECalculationMethod calculationMethod = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetCalculationMethodY(calculationMethod); - } - break; - case 3: // ATTRIB_EVALUATOR_Y - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - uint32 evaluatorIndex = static_cast(floatValue); - AZ::TypeId evaluatorId; - if (!GetBlendSpaceNodeEvaluatorTypeId(evaluatorIndex, evaluatorId)) - { - return false; - } - blendSpace2DNode.SetEvaluatorTypeY(evaluatorId); - } - break; - case 4: // ATTRIB_SYNC - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - AnimGraphObject::ESyncMode syncMode = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetSyncMode(syncMode); - } - break; - case 5: //ATTRIB_SYNC_LEADERMOTION - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendSpace2DNode.SetSyncLeaderMotionId(legacyAttribute.GetValue()); - } - break; - case 6: //ATTRIB_EVENTMODE - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return true; - } - BlendSpaceNode::EBlendSpaceEventMode eventMode = static_cast(static_cast(floatValue)); - blendSpace2DNode.SetEventFilterMode(eventMode); - } - break; - case 7: // ATTRIB_MOTIONS - { - // Parsing an array of string attributes - LegacyAttributeArray legacyAttributeArray; - if (!legacyAttributeArray.Parse(stream, endianType)) - { - return false; - } - // Get the attribute array and process it - AZStd::vector blendSpaceMotions; - blendSpaceMotions.resize(legacyAttributeArray.GetValue().size()); - int newVectorIndex = 0; - for (LegacyAttribute legacyAttribute : legacyAttributeArray.GetValue()) - { - blendSpaceMotions[newVectorIndex++] = legacyAttribute.GetValue(); - } - blendSpace2DNode.SetMotions(blendSpaceMotions); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected number of attributes"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendSpace1DNode& blendSpace1DNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "BlendSpace1DNode: Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "BlendSpace1DNode: Unable to parse calculation method"); - return false; - } - BlendSpaceNode::ECalculationMethod eCalculationMethod = static_cast(static_cast(floatValue)); - blendSpace1DNode.SetCalculationMethod(eCalculationMethod); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - AZ_Error("EMotionFX", false, "BlendSpace1DNode: Unable to parse evaluator"); - return false; - } - uint32 evaluatorIndex = static_cast(floatValue); - AZ::TypeId evaluatorUUid; - if (!GetBlendSpaceNodeEvaluatorTypeId(evaluatorIndex, evaluatorUUid)) - { - return false; - } - blendSpace1DNode.SetEvaluatorType(evaluatorUUid); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - AnimGraphNode::ESyncMode eSyncMmode = static_cast(static_cast(floatValue)); - blendSpace1DNode.SetSyncMode(eSyncMmode); - } - break; - case 3: - { - LegacyAttribute legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - return false; - } - blendSpace1DNode.SetSyncLeaderMotionId(legacyAttribute.GetValue()); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendSpaceNode::EBlendSpaceEventMode eventMode = static_cast(static_cast(floatValue)); - blendSpace1DNode.SetEventFilterMode(eventMode); - } - break; - case 5: - { - // Parsing an array of string attributes - LegacyAttributeArray legacyAttributeArray; - if (!legacyAttributeArray.Parse(stream, endianType)) - { - return false; - } - // Get the attribute array and process it - AZStd::vector blendSpaceMotions; - blendSpaceMotions.resize(legacyAttributeArray.GetValue().size()); - int newVectorIndex = 0; - for (LegacyAttribute legacyAttribute : legacyAttributeArray.GetValue()) - { - blendSpaceMotions[newVectorIndex++] = legacyAttribute.GetValue(); - } - blendSpace1DNode.SetMotions(blendSpaceMotions); - } - break; - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - BlendTreeParameterNode& blendTreeParameterNode = static_cast(animGraphObject); - - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(importParams.mAnimGraph); - // **************************************************************************************** - - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(nullptr); - // **************************************************************************************** - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - LegacyAttribute> legacyAttribute; - if (!legacyAttribute.Parse(stream, endianType)) - { - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(nullptr); - // **************************************************************************************** - - return false; - } - const AZStd::vector& parameterNames = legacyAttribute.GetValue(); - blendTreeParameterNode.SetParameters(parameterNames); - } - break; - default: - { - // **************************************************************************************** - // Please Note: this is a fix to enable a safe destruction of the node if the parser fails - // **************************************************************************************** - blendTreeParameterNode.SetAnimGraph(nullptr); - // **************************************************************************************** - - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected attribute count"); - return false; - } - break; - } - } - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(stream); - AZ_UNUSED(numAttributes); - AZ_UNUSED(endianType); - AZ_UNUSED(importParams); - AZ_UNUSED(animGraphObject); - // Do nothing - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeMotionFrameNode& blendTreeFloatConditionNode = static_cast(animGraphObject); - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - // This node needs only one attribute, if any more are found inthe file they will be skipped - if (parsedAttributeCount == 0) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConditionNode.SetNormalizedTimeValue(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes : Unexpected attribute count"); - return false; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatConditionNode& blendTreeFloatConditionNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - - BlendTreeFloatConditionNode::EFunction eFunction = (BlendTreeFloatConditionNode::EFunction)((uint32)floatValue); - blendTreeFloatConditionNode.SetFunction(eFunction); - break; - } - - case 1: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - - blendTreeFloatConditionNode.SetDefaultValue(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 2: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConditionNode.SetTrueResult(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 3: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatConditionNode.SetFalseResult(floatValue); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 4: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatConditionNode::EReturnMode returnMode = static_cast(static_cast(floatValue)); - blendTreeFloatConditionNode.SetFalseReturnMode(returnMode); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - case 5: - { - if (legacyAttributeHeader.GetAttributeType() == LegacyAttributeTypeId::ATTRIBUTE_FLOAT_TYPE_ID) - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeFloatConditionNode::EReturnMode returnMode = static_cast(static_cast(floatValue)); - blendTreeFloatConditionNode.SetTrueReturnMode(returnMode); - } - else - { - AZ_Error("EMotionFX", false, "Unexpected Attribute type in legacy data. Float expected found %u instead", legacyAttributeHeader.GetAttributeType()); - return false; - } - break; - } - - default: - { - AZ_Error("EMotionFX", false, "LegacyAnimGraphNodeParser::ParseLegacyAttributes: Unexpected State in Legacy Node parser"); - return false; - } - } - } - } - - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeFloatSwitchNode& blendTreeFloatSwitchNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue0(floatValue); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue1(floatValue); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue2(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue3(floatValue); - } - break; - case 4: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeFloatSwitchNode.SetValue4(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -template<> -bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, - uint32 numAttributes, - MCore::Endian::EEndianType endianType, - Importer::ImportParameters& importParams, - AnimGraphObject& animGraphObject) -{ - AZ_UNUSED(importParams); - BlendTreeBoolLogicNode& blendTreeBoolLogicNode = static_cast(animGraphObject); - // For all attributes - for (uint32 parsedAttributeCount = 0; parsedAttributeCount < numAttributes; ++parsedAttributeCount) - { - LegacyAttributeHeader legacyAttributeHeader; - if (!LegacyAttributeHeader::Parse(stream, endianType, legacyAttributeHeader)) - { - AZ_Error("EMotionFX", false, "Unable to parse attribute header"); - return false; - } - - if (legacyAttributeHeader.GetAttributeSize() > 0) - { - switch (parsedAttributeCount) - { - case 0: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - BlendTreeBoolLogicNode::EFunction function = static_cast(static_cast(floatValue)); - blendTreeBoolLogicNode.SetFunction(function); - } - break; - case 1: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeBoolLogicNode.SetDefaultValue(floatValue > MCore::Math::epsilon); - } - break; - case 2: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeBoolLogicNode.SetTrueResult(floatValue); - } - break; - case 3: - { - float floatValue; - if (!LegacyAnimGraphNodeParser::TryGetFloatFromAttribute(stream, endianType, legacyAttributeHeader, floatValue)) - { - return false; - } - blendTreeBoolLogicNode.SetFalseResult(floatValue); - } - break; - default: - { - AZ_Error("EMotionFX", false, "Unexpected attribute count"); - return false; - } - break; - } - } - } - return true; -} - -} diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h deleted file mode 100644 index 5207b0aa10..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/LegacyAnimGraphNodeParser.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * 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 - * - */ -#pragma once - -#include -#include -#include -#include -#include "Importer.h" -#include "AnimGraphFileFormat.h" -#include "../AnimGraphObject.h" -#include -#include -#include "../AnimGraphNode.h" - - -namespace EMotionFX -{ - class AnimGraphNode; - class AnimGraphStateMachine; - class AnimGraphStateTransition; - class AnimGraphTransitionCondition; - class BlendTreeVector4ComposeNode; - class BlendTreeVector3ComposeNode; - class BlendTreeVector2ComposeNode; - class BlendTreeMorphTargetNode; - class BlendTreeFloatConstantNode; - class BlendTreeLookAtNode; - class BlendTreeTwoLinkIKNode; - class BlendTreeFloatMath1Node; - class AnimGraphStateTransition; - class AnimGraphStateMachine; - class BlendTreeRangeRemapperNode; - class BlendTreeSmoothingNode; - class BlendTreeVector3Math2Node; - class BlendTreeVector3Math1Node; - class BlendTreeFloatMath2Node; - class BlendTreeBlend2LegacyNode; - class AnimGraphVector2Condition; - class AnimGraphTimeCondition; - class AnimGraphTagCondition; - class AnimGraphStateCondition; - class AnimGraphPlayTimeCondition; - class AnimGraphParameterCondition; - class AnimGraphMotionCondition; - class BlendTreeBlendNNode; - class BlendTreeMaskLegacyNode; - class BlendTreeTransformNode; - class BlendTreeAccumTransformNode; - class AnimGraphMotionNode; - class BlendTreeVector4DecomposeNode; - class BlendTreeVector3DecomposeNode; - class BlendTreeVector2DecomposeNode; - class BlendTree; - class BlendTreePoseSwitchNode; - class BlendSpace2DNode; - class BlendSpace1DNode; - class BlendTreeParameterNode; - class AnimGraphExitNode; - class AnimGraphEntryNode; - class BlendTreeMirrorPoseNode; - class BlendTreeDirectionToWeightNode; - class AnimGraphBindPoseNode; - class BlendTreeFinalNode; - class AnimGraphNode; - class BlendTreeMotionFrameNode; - class BlendTreeFloatConditionNode; - class BlendTreeFloatSwitchNode; - class BlendTreeBoolLogicNode; - - const AZ::TypeId GetNewTypeIdByOldNodeTypeId(uint32 oldNodeTypeId); - - enum LegacyAttributeTypeId - { - ATTRIBUTE_FLOAT_TYPE_ID = 0x00000001, - ATTRIBUTE_INT32_TYPE_ID = 0x00000002, - ATTRIBUTE_BOOL_TYPE_ID = 0x00000004 - }; - - enum LegacyERotationOrder - { - ROTATIONORDER_ZYX = 0, - ROTATIONORDER_ZXY = 1, - ROTATIONORDER_YZX = 2, - ROTATIONORDER_YXZ = 3, - ROTATIONORDER_XYZ = 4, - ROTATIONORDER_XZY = 5 - }; - - - class LegacyAttributeHeader - { - public: - LegacyAttributeHeader() { } - - AZ::u32 GetAttributeType() const - { - return m_attribType; - } - - AZ::u32 GetAttributeSize() const - { - return m_attributeSize; - } - - static bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType, LegacyAttributeHeader& attributeHeader); - private: - LegacyAttributeHeader(const LegacyAttributeHeader& src) : - m_attribType(src.m_attribType) - , m_attributeSize(src.m_attributeSize) - , m_name(src.m_name) - { } - - AZ::u32 m_attribType; - AZ::u32 m_attributeSize; - AZStd::string m_name; - }; - - template - class LegacyAttribute - { - public: - bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType); - const T& GetValue() const; - private: - T m_value; - }; - - class LegacyAnimGraphNodeParser - { - public: - static bool ParseAnimGraphNodeChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const char* nodeName, - FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphNode*& node); - - static bool ParseTransitionConditionChunk(MCore::File* file, - Importer::ImportParameters& importParams, - const FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphTransitionCondition*& transitionCondition); - - template - static bool ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - - static bool Forward(MCore::File* stream, size_t numBytes); - - private: - static bool InitializeNodeGeneralData(const char* nodeName, Importer::ImportParameters& importParams, FileFormat::AnimGraph_NodeHeader& nodeHeader, AnimGraphNode* node); - static bool GetBlendSpaceNodeEvaluatorTypeId(uint32 legacyIndex, AZ::TypeId& value); - static bool ConvertFloatAttributeValueToBool(float value); - static bool TryGetFloatFromAttribute(MCore::File* stream, MCore::Endian::EEndianType endianType, const LegacyAttributeHeader& attributeHeader, float& outputValue); - - template - static bool ParseAnimGraphNode(MCore::File* file, - Importer::ImportParameters& importParams, - const char* nodeName, - FileFormat::AnimGraph_NodeHeader& nodeHeader, - AnimGraphNode*& node) - { - node = aznew T(); - node->SetAnimGraph(importParams.mAnimGraph); - if (!InitializeNodeGeneralData(nodeName, importParams, nodeHeader, node)) - { - MCore::LogError("Error on initializing node general data"); - return false; - } - if (!ParseLegacyAttributes(file, nodeHeader.mNumAttributes, importParams.mEndianType, importParams, *node)) - { - MCore::LogError("Unable to parse node legacy attributes"); - return false; - } - return true; - } - - template - static bool ParseAnimGraphTransitionCondition(MCore::File* file, - Importer::ImportParameters& importParams, - const FileFormat::AnimGraph_NodeHeader& header, - AnimGraphTransitionCondition*& transitionCondition) - { - transitionCondition = aznew T(); - return ParseLegacyAttributes(file, header.mNumAttributes, importParams.mEndianType, importParams, *transitionCondition); - } - }; - - template class LegacyAttribute> - class LegacyAttributeArray - { - public: - bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType); - const AZStd::vector< LegacyAttribute >& GetValue() const; - private: - bool PopulateAttributeDynamicArray(MCore::File* stream, MCore::Endian::EEndianType endianType); - - AZStd::vector< LegacyAttribute > m_attributes; - // Used when reading version 2 attribute array - uint32 m_elementTypeId; - }; - - class LegacyAttributeSettingsParser - { - public: - static bool Parse(MCore::File* stream, MCore::Endian::EEndianType endianType); - }; - - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); - template<> bool LegacyAnimGraphNodeParser::ParseLegacyAttributes(MCore::File* stream, uint32 numAttributes, MCore::Endian::EEndianType endianType, Importer::ImportParameters& importParams, AnimGraphObject& animGraphObject); -} // Namespace EMotionFX diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h deleted file mode 100644 index 216188022e..0000000000 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/MotionSetFileFormat.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * 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 - * - */ - -#pragma once - -// include the shared structs -#include "SharedFileFormatStructs.h" - - -namespace EMotionFX -{ - namespace FileFormat - { - // the chunks - enum - { - CHUNK_MOTIONSET = 500 - }; - - - struct MotionSet_Header - { - uint8 mFourCC[4]; // must be "MOS " - uint8 mHiVersion; // high version (2 in case of v2.34) - uint8 mLoVersion; // low version (34 in case of v2.34) - uint8 mEndianType; // the endian in which the data is saved [0=little, 1=big] - }; - - - struct MotionSetsChunk - { - uint32 mNumSets; // the number of motion sets - - // followed by: - // motionSets[mNumSets] - }; - - - struct MotionSetChunk - { - uint32 mNumChildSets; // the number of child motion sets - uint32 mNumMotionEntries; // the number of motion entries - - // followed by: - // string : the name of the parent set - // string : the name of the motion set - // string : the filename and path information (e.g. "Root/Motions/Human_Male/" // obsolete, this got removed and is now just an empty string - // motionEntries[mNumMotionEntries]: motion entries - // MotionEntry: - // string : motion filename without path (e.g. "Walk.motion") - // string : motion set string id (e.g. "WALK") - }; - } // namespace FileFormat -} // namespace EMotionFX - From a287b67b43c69fe3979d93ab9bcb331daa7b6957 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Mon, 26 Jul 2021 09:57:01 +0200 Subject: [PATCH 13/58] Removed ReadDataSize/ReadData() helpers for attributes Used only by legacy binary file format Signed-off-by: Benjamin Jillich --- .../Source/AnimGraphAttributeTypes.h | 6 ---- .../Source/Importer/SharedFileFormatStructs.h | 28 ++------------- .../EMotionFX/Code/MCore/Source/Attribute.cpp | 29 +-------------- Gems/EMotionFX/Code/MCore/Source/Attribute.h | 23 ------------ .../Code/MCore/Source/AttributeBool.h | 18 ---------- .../Code/MCore/Source/AttributeColor.h | 22 ------------ .../Code/MCore/Source/AttributeFloat.h | 18 ---------- .../Code/MCore/Source/AttributeInt32.h | 18 ---------- .../Code/MCore/Source/AttributePointer.h | 13 ------- .../Code/MCore/Source/AttributeQuaternion.h | 21 ----------- .../Code/MCore/Source/AttributeString.h | 35 ------------------- .../Code/MCore/Source/AttributeVector2.h | 22 ------------ .../Code/MCore/Source/AttributeVector3.h | 22 ------------ .../Code/MCore/Source/AttributeVector4.h | 22 ------------ 14 files changed, 3 insertions(+), 294 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h b/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h index 9514ffdb20..9f7b33a66d 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/AnimGraphAttributeTypes.h @@ -79,9 +79,6 @@ namespace EMotionFX AttributePose(AnimGraphPose* pose) : MCore::Attribute(TYPE_ID) { mValue = pose; } ~AttributePose() {} - - uint32 GetDataSize() const override { return 0; } - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override { MCORE_UNUSED(stream); MCORE_UNUSED(streamEndianType); MCORE_UNUSED(version); return false; } // unsupported }; @@ -130,9 +127,6 @@ namespace EMotionFX AttributeMotionInstance(MotionInstance* motionInstance) : MCore::Attribute(TYPE_ID) { mValue = motionInstance; } ~AttributeMotionInstance() {} - - uint32 GetDataSize() const override { return 0; } - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override { MCORE_UNUSED(stream); MCORE_UNUSED(streamEndianType); MCORE_UNUSED(version); return false; } // unsupported }; class AnimGraphPropertyUtils diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h index 2355e7923d..082bcbf0ef 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/SharedFileFormatStructs.h @@ -7,6 +7,7 @@ */ #pragma once + #include namespace EMotionFX @@ -20,8 +21,6 @@ namespace EMotionFX SHARED_CHUNK_TIMESTAMP = 51 }; - - // a chunk struct FileChunk { uint32 mChunkID; // the chunk ID @@ -29,7 +28,6 @@ namespace EMotionFX uint32 mVersion; // the version of the chunk }; - // color [0..1] range struct FileColor { @@ -39,16 +37,12 @@ namespace EMotionFX float mA; // alpha }; - - // a 2D vector struct FileVector2 { float mX; float mY; }; - - // a 3D vector struct FileVector3 { float mX; // x+ = to the right @@ -56,7 +50,6 @@ namespace EMotionFX float mZ; // z+ = up }; - // a compressed 3D vector struct File16BitVector3 { @@ -65,7 +58,6 @@ namespace EMotionFX uint16 mZ; // z+ = up }; - // a compressed 3D vector struct File8BitVector3 { @@ -74,8 +66,6 @@ namespace EMotionFX uint8 mZ; // z+ = up }; - - // a quaternion struct FileQuaternion { float mX; @@ -84,7 +74,6 @@ namespace EMotionFX float mW; }; - // the 16 bit component quaternion struct File16BitQuaternion { @@ -94,7 +83,6 @@ namespace EMotionFX int16 mW; }; - // a time stamp chunk struct FileTime { @@ -105,17 +93,5 @@ namespace EMotionFX int8 mMinutes; int8 mSeconds; }; - - - // attribute - struct FileAttribute - { - uint32 mDataType; - uint32 mNumBytes; - uint32 mFlags; - - // followed by: - // uint8 mData[mNumBytes]; - }; } // namespace FileFormat -} // namespace EMotionFX +} // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp b/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp index e2b7e7164b..ed2bc1a535 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp +++ b/Gems/EMotionFX/Code/MCore/Source/Attribute.cpp @@ -6,7 +6,6 @@ * */ -// include required headers #include "Attribute.h" #include "AttributeFactory.h" #include "AttributeString.h" @@ -14,20 +13,15 @@ namespace MCore { - // constructor Attribute::Attribute(uint32 typeID) { mTypeID = typeID; } - - // destructor Attribute::~Attribute() { } - - // equal operator Attribute& Attribute::operator=(const Attribute& other) { if (&other != this) @@ -36,25 +30,4 @@ namespace MCore } return *this; } - - // read the attribute - bool Attribute::Read(Stream* stream, Endian::EEndianType sourceEndianType) - { - // read the version - uint8 version; - if (stream->Read(&version, sizeof(uint8)) == 0) - { - return false; - } - - // read the data - const bool result = ReadData(stream, sourceEndianType, version); - if (result == false) - { - return false; - } - - return true; - } - -} // namespace MCore +} // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/Attribute.h b/Gems/EMotionFX/Code/MCore/Source/Attribute.h index 06de883a98..c245e7d778 100644 --- a/Gems/EMotionFX/Code/MCore/Source/Attribute.h +++ b/Gems/EMotionFX/Code/MCore/Source/Attribute.h @@ -8,7 +8,6 @@ #pragma once -// include the required headers #include "StandardHeaders.h" #include "MemoryManager.h" #include "Endian.h" @@ -28,7 +27,6 @@ namespace MCore // forward declarations class AttributeSettings; - // the attribute interface types enum : uint32 { @@ -49,12 +47,6 @@ namespace MCore ATTRIBUTE_INTERFACETYPE_DEFAULT = 0xFFFFFFFF// use the default attribute type that the specific attribute class defines as default }; - - /** - * - * - * - */ class MCORE_API Attribute { friend class AttributeFactory; @@ -70,10 +62,6 @@ namespace MCore virtual uint32 GetClassSize() const = 0; virtual uint32 GetDefaultInterfaceType() const = 0; - // These two members and ReadData can go away once we put the old-format parser - bool Read(Stream* stream, MCore::Endian::EEndianType sourceEndianType); - virtual uint32 GetDataSize() const = 0; // data only - Attribute& operator=(const Attribute& other); virtual void NetworkSerialize(EMotionFX::Network::AnimGraphSnapshotChunkSerializer&) {}; @@ -82,16 +70,5 @@ namespace MCore uint32 mTypeID; /**< The unique type ID of the attribute class. */ Attribute(uint32 typeID); - - /** - * Read the attribute info and data from a given stream. - * Please note that the endian information of the actual data is not being converted. You have to handle that yourself. - * The data endian conversion could be done with for example the static Attribute::ConvertDataEndian method. - * @param stream The stream to read the info and data from. - * @param endianType The endian type in which the data is stored in the stream. - * @param version The version of the attribute. - * @result Returns true when successful, or false when reading failed. - */ - virtual bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) = 0; }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h b/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h index 6ef66c28c2..9a923b5fda 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeBool.h @@ -63,23 +63,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeBool() {} - - uint32 GetDataSize() const override { return sizeof(int8); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - MCORE_UNUSED(streamEndianType); - int8 streamValue; - if (stream->Read(&streamValue, sizeof(int8)) == 0) - { - return false; - } - - mValue = (streamValue == 0) ? false : true; - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h b/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h index 4abddf90cd..6287239bf8 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeColor.h @@ -79,27 +79,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeColor() {} - - uint32 GetDataSize() const override { return sizeof(RGBAColor); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - RGBAColor streamValue; - if (stream->Read(&streamValue, sizeof(RGBAColor)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertRGBAColor(&streamValue, streamEndianType); - mValue = streamValue; - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h b/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h index 2c9f26e90f..ef650a1430 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeFloat.h @@ -57,8 +57,6 @@ namespace MCore private: float mValue; /**< The float value. */ - uint32 GetDataSize() const override { return sizeof(float); } - AttributeFloat() : Attribute(TYPE_ID) , mValue(0.0f) {} @@ -66,21 +64,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeFloat() {} - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - float streamValue; - if (stream->Read(&streamValue, sizeof(float)) == 0) - { - return false; - } - - Endian::ConvertFloat(&streamValue, streamEndianType); - mValue = streamValue; - return true; - } }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h b/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h index 75e4f102e3..f13246d438 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeInt32.h @@ -64,23 +64,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeInt32() {} - - uint32 GetDataSize() const override { return sizeof(int32); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - int32 streamValue; - if (stream->Read(&streamValue, sizeof(int32)) == 0) - { - return false; - } - - Endian::ConvertSignedInt32(&streamValue, streamEndianType); - mValue = streamValue; - return true; - } }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h b/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h index becb6030b7..8f7a6cbc65 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributePointer.h @@ -66,18 +66,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(pointer) { } ~AttributePointer() {} - - uint32 GetDataSize() const override { return sizeof(void*); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(stream); - MCORE_UNUSED(streamEndianType); - MCORE_UNUSED(version); - - MCore::LogWarning("MCore::AttributePointer::ReadData() - Pointer attributes cannot be read from disk."); - return false; - } }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h b/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h index 4509c3a962..3380cac957 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeQuaternion.h @@ -82,26 +82,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) {} ~AttributeQuaternion() { } - - uint32 GetDataSize() const override { return sizeof(AZ::Quaternion); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::Quaternion streamValue; - if (stream->Read(&streamValue, sizeof(AZ::Quaternion)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertQuaternion(&streamValue, streamEndianType); - mValue = streamValue; - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeString.h b/Gems/EMotionFX/Code/MCore/Source/AttributeString.h index 5e030baf54..4f3f8df6f9 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeString.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeString.h @@ -72,40 +72,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeString() { mValue.clear(); } - - uint32 GetDataSize() const override - { - return sizeof(uint32) + static_cast(mValue.size()); - } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the number of characters - uint32 numCharacters; - if (stream->Read(&numCharacters, sizeof(uint32)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertUnsignedInt32(&numCharacters, streamEndianType); - if (numCharacters == 0) - { - mValue.clear(); - return true; - } - - mValue.resize(numCharacters); - if (stream->Read(mValue.data(), numCharacters) == 0) - { - return false; - } - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h b/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h index b69fd5ebcf..b82c7778f7 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeVector2.h @@ -78,27 +78,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeVector2() { } - - uint32 GetDataSize() const override { return sizeofVector2; } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::Vector2 streamValue; - if (stream->Read(&streamValue, sizeofVector2) == 0) - { - return false; - } - - // convert endian - Endian::ConvertVector2(&streamValue, streamEndianType); - mValue = streamValue; - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h b/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h index 0151de0d69..ea6b820944 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeVector3.h @@ -79,27 +79,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeVector3() { } - - uint32 GetDataSize() const override { return sizeof(AZ::Vector3); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::PackedVector3f streamValue(0.0f); - if (stream->Read(&streamValue, sizeof(AZ::PackedVector3f)) == 0) - { - return false; - } - - // convert endian - mValue = AZ::Vector3(streamValue.GetX(), streamValue.GetY(), streamValue.GetZ()); - Endian::ConvertVector3(&mValue, streamEndianType); - - return true; - } - }; } // namespace MCore diff --git a/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h b/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h index 0df42b6676..93dc4a527b 100644 --- a/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h +++ b/Gems/EMotionFX/Code/MCore/Source/AttributeVector4.h @@ -75,27 +75,5 @@ namespace MCore : Attribute(TYPE_ID) , mValue(value) { } ~AttributeVector4() { } - - uint32 GetDataSize() const override { return sizeof(AZ::Vector4); } - - // read from a stream - bool ReadData(MCore::Stream* stream, MCore::Endian::EEndianType streamEndianType, uint8 version) override - { - MCORE_UNUSED(version); - - // read the value - AZ::Vector4 streamValue; - if (stream->Read(&streamValue, sizeof(AZ::Vector4)) == 0) - { - return false; - } - - // convert endian - Endian::ConvertVector4(&streamValue, streamEndianType); - mValue = streamValue; - - return true; - } - }; } // namespace MCore From c097d192150e1787ee0864dd0989bedc2bee6027 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Mon, 26 Jul 2021 09:57:51 +0200 Subject: [PATCH 14/58] Removed legacy chunk processors for anim graphs and motion sets together with unused shared data Signed-off-by: Benjamin Jillich --- .../Source/Importer/ChunkProcessors.cpp | 935 +----------------- .../Source/Importer/ChunkProcessors.h | 50 - 2 files changed, 1 insertion(+), 984 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp index 87ab61bf59..e1a3e0bbfa 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -53,7 +54,6 @@ #include "../AnimGraphTransitionCondition.h" #include "../MCore/Source/Endian.h" #include "../NodeMap.h" -#include "LegacyAnimGraphNodeParser.h" #include #include @@ -245,14 +245,10 @@ namespace EMotionFX { mFileHighVersion = 1; mFileLowVersion = 0; - mIsUnicodeFile = true; // allocate the string buffer used for reading in variable sized strings mStringStorageSize = 256; mStringStorage = (char*)MCore::Allocate(mStringStorageSize, EMFX_MEMCATEGORY_IMPORTER); - mBlendNodes.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER); - mBlendNodes.Reserve(1024); - //mConvertString.Reserve( 256 ); } @@ -281,57 +277,8 @@ namespace EMotionFX mStringStorage = nullptr; mStringStorageSize = 0; - //mConvertString.Clear(); - - // get rid of the blend nodes array - mBlendNodes.Clear(); - - m_entryNodeIndexToStateMachineIdLookupTable.clear(); } - - // check if the strings in the file are encoded using unicode or multi-byte - bool SharedHelperData::GetIsUnicodeFile(const char* dateString, MCore::Array* sharedData) - { - // find the helper data - SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID); - SharedHelperData* helperData = static_cast(data); - - AZStd::vector dateParts; - AzFramework::StringFunc::Tokenize(dateString, dateParts, MCore::CharacterConstants::space, false /* keep empty strings */, true /* keep space strings */); - - // decode the month - int32 month = 0; - const AZStd::string& monthString = dateParts[0]; - const char* monthStrings[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - for (int32 i = 0; i < 12; ++i) - { - if (monthString == monthStrings[i]) - { - month = i + 1; - break; - } - } - - //int32 day = dateParts[1].ToInt(); - int32 year; - if (!AzFramework::StringFunc::LooksLikeInt(dateParts[2].c_str(), &year)) - { - return false; - } - - // set if the file contains unicode strings or not based on the compilcation date - if (year < 2012 || (year == 2012 && month < 11)) - { - helperData->mIsUnicodeFile = false; - } - - //LogInfo( "String: '%s', Decoded: %i.%i.%i - isUnicode=%i", dateString, day, month, year, helperData->mIsUnicodeFile ); - - return helperData->mIsUnicodeFile; - } - - const char* SharedHelperData::ReadString(MCore::Stream* file, MCore::Array* sharedData, MCore::Endian::EEndianType endianType) { MCORE_ASSERT(file); @@ -366,25 +313,6 @@ namespace EMotionFX return helperData->mStringStorage; } - - // get the array of anim graph nodes - MCore::Array& SharedHelperData::GetBlendNodes(MCore::Array* sharedData) - { - // find the helper data - SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID); - SharedHelperData* helperData = static_cast(data); - return helperData->mBlendNodes; - } - - // Get the table of entry state indices to state machines IDs - AZStd::map& SharedHelperData::GetEntryStateToStateMachineTable(MCore::Array* sharedData) - { - // Find the helper data - SharedData* data = Importer::FindSharedData(sharedData, SharedHelperData::TYPE_ID); - SharedHelperData* helperData = static_cast(data); - return helperData->m_entryNodeIndexToStateMachineIdLookupTable; - } - //----------------------------------------------------------------------------- // constructor @@ -1999,7 +1927,6 @@ namespace EMotionFX //---------------------------------------------------------------------------------------------------------- - // bool ChunkProcessorActorAttachmentNodes::Process(MCore::File* file, Importer::ImportParameters& importParams) { const MCore::Endian::EEndianType endianType = importParams.mEndianType; @@ -2055,866 +1982,6 @@ namespace EMotionFX return true; } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph state transitions - bool ChunkProcessorAnimGraphStateTransitions::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - // read the number of transitions to follow - uint32 numTransitions; - file->Read(&numTransitions, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numTransitions, importParams.mEndianType); - - // read the state machine index - uint32 stateMachineIndex; - file->Read(&stateMachineIndex, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&stateMachineIndex, importParams.mEndianType); - - // get the loaded anim graph nodes - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - if (stateMachineIndex >= blendNodes.GetLength()) - { - if (GetLogging()) - { - AZ_Error("EMotionFX", false, "State machine refers to invalid blend node, state machine index: %d, amount of blend node: %d", stateMachineIndex, blendNodes.GetLength()); - } - return false; - } - AZ_Assert(azrtti_typeid(blendNodes[stateMachineIndex]) == azrtti_typeid(), "ChunkProcessorAnimGraphStateTransitions::Process : Unexpected node type expected AnimGraphStateMachine. Found %u instead", azrtti_typeid(blendNodes[stateMachineIndex])); - AnimGraphStateMachine* stateMachine = static_cast(blendNodes[stateMachineIndex]); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num transitions for state machine '%s' = %d", blendNodes[stateMachineIndex]->GetName(), numTransitions); - } - - stateMachine->ReserveTransitions(numTransitions); - - // read the transitions - FileFormat::AnimGraph_StateTransition transition; - for (uint32 i = 0; i < numTransitions; ++i) - { - // read the transition - file->Read(&transition, sizeof(FileFormat::AnimGraph_StateTransition)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&transition.mSourceNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&transition.mDestNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&transition.mNumConditions, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mStartOffsetX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mStartOffsetY, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mEndOffsetX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&transition.mEndOffsetY, importParams.mEndianType); - - //---------------------------------------------- - // read the node header - FileFormat::AnimGraph_NodeHeader nodeHeader; - file->Read(&nodeHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mParentIndex, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumChildNodes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumAttributes, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosY, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVisualizeColor, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- State Transition Node:"); - MCore::LogDetailedInfo(" + Type = %d", nodeHeader.mTypeID); - MCore::LogDetailedInfo(" + Version = %d", nodeHeader.mVersion); - MCore::LogDetailedInfo(" + Num data bytes = %d", nodeHeader.mNumCustomDataBytes); - MCore::LogDetailedInfo(" + Num attributes = %d", nodeHeader.mNumAttributes); - MCore::LogDetailedInfo(" + Num conditions = %d", transition.mNumConditions); - MCore::LogDetailedInfo(" + Source node = %d", transition.mSourceNode); - MCore::LogDetailedInfo(" + Dest node = %d", transition.mDestNode); - } - - // create the transition object - AnimGraphStateTransition* emfxTransition = nullptr; - if (GetNewTypeIdByOldNodeTypeId(nodeHeader.mTypeID) == azrtti_typeid()) - { - emfxTransition = aznew AnimGraphStateTransition(); - } - - if (emfxTransition) - { - if (transition.mDestNode >= blendNodes.GetLength()) - { - if (GetLogging()) - { - AZ_Error("EMotionFX", false, "State machine transition refers to invalid destination blend node, transition index %d, blend node: %d", i, transition.mDestNode); - } - delete emfxTransition; - emfxTransition = nullptr; - } - // A source node index of MCORE_INVALIDINDEX32 indicates that the transition is a wildcard transition. Don't go into error state in this case. - else if (transition.mSourceNode != MCORE_INVALIDINDEX32 && transition.mSourceNode >= blendNodes.GetLength()) - { - if (GetLogging()) - { - AZ_Error("EMotionFX", false, "State machine transition refers to invalid source blend node, transition index %d, blend node: %d", i, transition.mSourceNode); - } - delete emfxTransition; - emfxTransition = nullptr; - } - else - { - AnimGraphNode* targetNode = blendNodes[transition.mDestNode]; - if (targetNode == nullptr) - { - delete emfxTransition; - emfxTransition = nullptr; - } - else - { - AZ_Assert(azrtti_istypeof(emfxTransition), "ChunkProcessorAnimGraphStateTransitions::Process : Unexpected node type expected AnimGraphStateTransition. Found %u instead", azrtti_typeid(blendNodes[stateMachineIndex])); - - // Now apply the transition settings - // Check if we are dealing with a wildcard transition - if (transition.mSourceNode == MCORE_INVALIDINDEX32) - { - emfxTransition->SetSourceNode(nullptr); - emfxTransition->SetIsWildcardTransition(true); - } - else - { - // set the source node - emfxTransition->SetSourceNode(blendNodes[transition.mSourceNode]); - } - - // set the destination node - emfxTransition->SetTargetNode(targetNode); - - emfxTransition->SetVisualOffsets(transition.mStartOffsetX, transition.mStartOffsetY, transition.mEndOffsetX, transition.mEndOffsetY); - - // now read the attributes - if (!LegacyAnimGraphNodeParser::ParseLegacyAttributes(file, nodeHeader.mNumAttributes, importParams.mEndianType, importParams, *emfxTransition)) - { - delete emfxTransition; - emfxTransition = nullptr; - AZ_Error("EMotionFX", false, "Unable to parse state transition"); - return false; - } - // add the transition to the state machine - stateMachine->AddTransition(emfxTransition); - } - } - } - - if (emfxTransition) - { - // iterate through all conditions - for (uint32 c = 0; c < transition.mNumConditions; ++c) - { - // read the condition node header - FileFormat::AnimGraph_NodeHeader conditionHeader; - file->Read(&conditionHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumAttributes, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo(" - Transition Condition:"); - MCore::LogDetailedInfo(" + Type = %d", conditionHeader.mTypeID); - MCore::LogDetailedInfo(" + Version = %d", conditionHeader.mVersion); - MCore::LogDetailedInfo(" + Num data bytes = %d", conditionHeader.mNumCustomDataBytes); - MCore::LogDetailedInfo(" + Num attributes = %d", conditionHeader.mNumAttributes); - } - - AnimGraphTransitionCondition* emfxCondition = nullptr; - if (!LegacyAnimGraphNodeParser::ParseTransitionConditionChunk(file, importParams, conditionHeader, emfxCondition)) - { - AZ_Error("EMotionFX", false, "Unable to parse Transition condition of type %u in legacy file", azrtti_typeid(emfxCondition)); - delete emfxCondition; - emfxCondition = nullptr; - return false; - } - // add the condition to the transition - emfxTransition->AddCondition(emfxCondition); - } - - //emfxTransition->Init( animGraph ); - } - // something went wrong with creating the transition - else - { - MCore::LogWarning("Cannot load and instantiate state transition. State transition from %d to %d will be skipped.", transition.mSourceNode, transition.mDestNode); - - // skip reading the attributes - if (!ForwardAttributes(file, importParams.mEndianType, nodeHeader.mNumAttributes)) - { - return false; - } - - // skip reading the node custom data - if (file->Forward(nodeHeader.mNumCustomDataBytes) == false) - { - return false; - } - - // iterate through all conditions and skip them as well - for (uint32 c = 0; c < transition.mNumConditions; ++c) - { - // read the condition node header - FileFormat::AnimGraph_NodeHeader conditionHeader; - file->Read(&conditionHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&conditionHeader.mNumAttributes, importParams.mEndianType); - - // skip reading the attributes - if (!ForwardAttributes(file, importParams.mEndianType, conditionHeader.mNumAttributes)) - { - return false; - } - - // skip reading the node custom data - if (file->Forward(conditionHeader.mNumCustomDataBytes) == false) - { - return false; - } - } - } - } - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph state transitions - bool ChunkProcessorAnimGraphAdditionalInfo::Process(MCore::File* file, Importer::ImportParameters& /*importParams*/) - { - return file->Forward(sizeof(FileFormat::AnimGraph_AdditionalInfo)); - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph node connections - bool ChunkProcessorAnimGraphNodeConnections::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - // read the number of transitions to follow - uint32 numConnections; - file->Read(&numConnections, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numConnections, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num node connections = %d", numConnections); - } - - // get the array of currently loaded nodes - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - - // read the connections - FileFormat::AnimGraph_NodeConnection connection; - for (uint32 i = 0; i < numConnections; ++i) - { - // read the transition - file->Read(&connection, sizeof(FileFormat::AnimGraph_NodeConnection)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&connection.mSourceNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&connection.mTargetNode, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt16(&connection.mSourceNodePort, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt16(&connection.mTargetNodePort, importParams.mEndianType); - - // log details - if (GetLogging()) - { - MCore::LogDetailedInfo(" + Connection #%d = From node %d (port id %d) into node %d (port id %d)", i, connection.mSourceNode, connection.mSourceNodePort, connection.mTargetNode, connection.mTargetNodePort); - } - - // get the source and the target node and check if they are valid - AnimGraphNode* sourceNode = blendNodes[connection.mSourceNode]; - AnimGraphNode* targetNode = blendNodes[connection.mTargetNode]; - if (sourceNode == nullptr || targetNode == nullptr) - { - MCore::LogWarning("EMotionFX::ChunkProcessorAnimGraphNodeConnections() - Connection cannot be created because the source or target node is invalid! (sourcePortID=%d targetPortID=%d sourceNode=%d targetNode=%d)", connection.mSourceNodePort, connection.mTargetNodePort, connection.mSourceNode, connection.mTargetNode); - continue; - } - - // create the connection - const uint32 sourcePort = blendNodes[connection.mSourceNode]->FindOutputPortByID(connection.mSourceNodePort); - const uint32 targetPort = blendNodes[connection.mTargetNode]->FindInputPortByID(connection.mTargetNodePort); - if (sourcePort != MCORE_INVALIDINDEX32 && targetPort != MCORE_INVALIDINDEX32) - { - blendNodes[connection.mTargetNode]->AddConnection(blendNodes[connection.mSourceNode], static_cast(sourcePort), static_cast(targetPort)); - } - else - { - MCore::LogWarning("EMotionFX::ChunkProcessorAnimGraphNodeConnections() - Connection cannot be created because the source or target port doesn't exist! (sourcePortID=%d targetPortID=%d sourceNode='%s' targetNode=%s')", connection.mSourceNodePort, connection.mTargetNodePort, blendNodes[connection.mSourceNode]->GetName(), blendNodes[connection.mTargetNode]->GetName()); - } - } - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph node - bool ChunkProcessorAnimGraphNode::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the node header - FileFormat::AnimGraph_NodeHeader nodeHeader; - file->Read(&nodeHeader, sizeof(FileFormat::AnimGraph_NodeHeader)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mTypeID, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mParentIndex, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVersion, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumCustomDataBytes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumChildNodes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mNumAttributes, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&nodeHeader.mVisualizeColor, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosX, importParams.mEndianType); - MCore::Endian::ConvertSignedInt32(&nodeHeader.mVisualPosY, importParams.mEndianType); - - const char* nodeName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - if (GetLogging()) - { - MCore::LogDetailedInfo("- Blend Node:"); - MCore::LogDetailedInfo(" + Name = %s", nodeName); - MCore::LogDetailedInfo(" + Parent index = %d", nodeHeader.mParentIndex); - MCore::LogDetailedInfo(" + Type = %d", nodeHeader.mTypeID); - MCore::LogDetailedInfo(" + Version = %d", nodeHeader.mVersion); - MCore::LogDetailedInfo(" + Num data bytes = %d", nodeHeader.mNumCustomDataBytes); - MCore::LogDetailedInfo(" + Num child nodes = %d", nodeHeader.mNumChildNodes); - MCore::LogDetailedInfo(" + Num attributes = %d", nodeHeader.mNumAttributes); - MCore::LogDetailedInfo(" + Visualize Color = %d, %d, %d", MCore::ExtractRed(nodeHeader.mVisualizeColor), MCore::ExtractGreen(nodeHeader.mVisualizeColor), MCore::ExtractBlue(nodeHeader.mVisualizeColor)); - MCore::LogDetailedInfo(" + Visual pos = (%d, %d)", nodeHeader.mVisualPosX, nodeHeader.mVisualPosY); - MCore::LogDetailedInfo(" + Collapsed = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_COLLAPSED) ? "Yes" : "No"); - MCore::LogDetailedInfo(" + Visualized = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VISUALIZED) ? "Yes" : "No"); - MCore::LogDetailedInfo(" + Disabled = %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_DISABLED) ? "Yes" : "No"); - MCore::LogDetailedInfo(" + Virtual FinalOut= %s", (nodeHeader.mFlags & FileFormat::ANIMGRAPH_NODEFLAG_VIRTUALFINALOUTPUT) ? "Yes" : "No"); - } - - AnimGraphNode* node = nullptr; - if (!LegacyAnimGraphNodeParser::ParseAnimGraphNodeChunk(file - , importParams - , nodeName - , nodeHeader - , node)) - { - if (importParams.mAnimGraph->GetRootStateMachine() == node) - { - importParams.mAnimGraph->SetRootStateMachine(nullptr); - } - - if (node) - { - AnimGraphNode* parentNode = node->GetParentNode(); - if (parentNode) - { - parentNode->RemoveChildNodeByPointer(node, false); - } - } - - delete node; - node = nullptr; - return false; - } - - EMotionFX::GetEventManager().OnCreatedNode(animGraph, node); - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - - // animGraph parameters - bool ChunkProcessorAnimGraphParameters::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the number of parameters - uint32 numParams; - file->Read(&numParams, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numParams, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num parameters = %d", numParams); - } - - // read all parameters - for (uint32 p = 0; p < numParams; ++p) - { - // read the parameter info header - FileFormat::AnimGraph_ParameterInfo paramInfo; - file->Read(¶mInfo, sizeof(FileFormat::AnimGraph_ParameterInfo)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(¶mInfo.mNumComboValues, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(¶mInfo.mInterfaceType, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(¶mInfo.mAttributeType, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt16(¶mInfo.mFlags, importParams.mEndianType); - - // check the attribute type - const uint32 attribType = paramInfo.mAttributeType; - if (attribType == 0) - { - MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to convert interface type %d to an attribute type.", attribType); - return false; - } - - const AZ::TypeId parameterTypeId = EMotionFX::FileFormat::GetParameterTypeIdForInterfaceType(paramInfo.mInterfaceType); - const AZStd::string name = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - AZStd::unique_ptr newParam(EMotionFX::ParameterFactory::Create(parameterTypeId)); - AZ_Assert(azrtti_istypeof(newParam.get()), "Expected a value parameter"); - - if (!newParam) - { - MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to create parameter: '%s'.", name.c_str()); - return false; - } - - // read the strings - newParam->SetName(name); - SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); // We dont use internal name anymore - newParam->SetDescription(SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType)); - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Parameter #%d:", p); - MCore::LogDetailedInfo(" + Name = %s", newParam->GetName().c_str()); - MCore::LogDetailedInfo(" + Description = %s", newParam->GetDescription().c_str()); - MCore::LogDetailedInfo(" + type = %s", newParam->RTTI_GetTypeName()); - MCore::LogDetailedInfo(" + Attribute type = %d", paramInfo.mAttributeType); - MCore::LogDetailedInfo(" + Has MinMax = %d", paramInfo.mHasMinMax); - MCore::LogDetailedInfo(" + Flags = %d", paramInfo.mFlags); - } - - MCore::Attribute* attr(MCore::GetAttributeFactory().CreateAttributeByType(attribType)); - EMotionFX::ValueParameter* valueParameter = static_cast(newParam.get()); - - // create the min, max and default value attributes - if (paramInfo.mHasMinMax == 1) - { - // min value - attr->Read(file, importParams.mEndianType); - valueParameter->SetMinValueFromAttribute(attr); - - // max value - attr->Read(file, importParams.mEndianType); - valueParameter->SetMaxValueFromAttribute(attr); - } - - // default value - attr->Read(file, importParams.mEndianType); - valueParameter->SetDefaultValueFromAttribute(attr); - delete attr; - - // Parameters were previously stored in "AttributeSettings". The calss supported - // multiple values, however, the UI did not, so this ended up not being used. - // Support for multiple values in parameters is possible, however we dont need it now. - // Leaving this code as reference - for (uint32 i = 0; i < paramInfo.mNumComboValues; ++i) - { - SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - } - - if (!animGraph->AddParameter(newParam.get())) - { - MCore::LogError("EMotionFX::ChunkProcessorAnimGraphParameters::Process() - Failed to add parameter: '%s'.", name.c_str()); - return false; - } - newParam.release(); // ownership moved to animGraph - } - - return true; - } - - - // animGraph node groups - bool ChunkProcessorAnimGraphNodeGroups::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the number of node groups - uint32 numNodeGroups; - file->Read(&numNodeGroups, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numNodeGroups, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num Node Groups = %d", numNodeGroups); - } - - // read all node groups - for (uint32 g = 0; g < numNodeGroups; ++g) - { - // read the node group header - FileFormat::AnimGraph_NodeGroup nodeGroupChunk; - file->Read(&nodeGroupChunk, sizeof(FileFormat::AnimGraph_NodeGroup)); - - MCore::RGBAColor emfxColor(nodeGroupChunk.mColor.mR, nodeGroupChunk.mColor.mG, nodeGroupChunk.mColor.mB, nodeGroupChunk.mColor.mA); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&nodeGroupChunk.mNumNodes, importParams.mEndianType); - MCore::Endian::ConvertRGBAColor(&emfxColor, importParams.mEndianType); - - const AZ::Color color128 = MCore::EmfxColorToAzColor(emfxColor); - const AZ::u32 color32 = color128.ToU32(); - - const char* groupName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - const uint32 numNodes = nodeGroupChunk.mNumNodes; - - // create and fill the new node group - AnimGraphNodeGroup* nodeGroup = aznew AnimGraphNodeGroup(groupName); - animGraph->AddNodeGroup(nodeGroup); - nodeGroup->SetIsVisible(nodeGroupChunk.mIsVisible != 0); - nodeGroup->SetColor(color32); - - // set the nodes of the node group - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(importParams.mSharedData); - nodeGroup->SetNumNodes(numNodes); - for (uint32 i = 0; i < numNodes; ++i) - { - // read the node index of the current node inside the group - uint32 nodeNr; - file->Read(&nodeNr, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&nodeNr, importParams.mEndianType); - - MCORE_ASSERT(nodeNr != MCORE_INVALIDINDEX32); - - // set the id of the given node to the group - if (nodeNr != MCORE_INVALIDINDEX32 && blendNodes[nodeNr]) - { - nodeGroup->SetNode(i, blendNodes[nodeNr]->GetId()); - } - else - { - nodeGroup->SetNode(i, AnimGraphNodeId::InvalidId); - } - } - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Node Group #%d:", g); - MCore::LogDetailedInfo(" + Name = %s", nodeGroup->GetName()); - MCore::LogDetailedInfo(" + Color = (%.2f, %.2f, %.2f, %.2f)", static_cast(color128.GetR()), static_cast(color128.GetG()), static_cast(color128.GetB()), static_cast(color128.GetA())); - MCore::LogDetailedInfo(" + Num Nodes = %i", nodeGroup->GetNumNodes()); - } - } - - return true; - } - - - // animGraph group parameters - bool ChunkProcessorAnimGraphGroupParameters::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // read the number of group parameters - uint32 numGroupParameters; - file->Read(&numGroupParameters, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(&numGroupParameters, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Num group parameters = %d", numGroupParameters); - } - - // Group parameters is going to re-shuffle the value parameter indices, therefore we - // need to update the connections downstream of parameter nodes. - EMotionFX::ValueParameterVector valueParametersBeforeChange = animGraph->RecursivelyGetValueParameters(); - - // Since relocating a parameter to another parent changes its index, we are going to - // compute all the relationships leaving the value parameters at the root, then relocate - // them. - AZStd::vector > parametersByGroup; - - // read all group parameters - for (uint32 g = 0; g < numGroupParameters; ++g) - { - // read the group parameter header - FileFormat::AnimGraph_GroupParameter groupChunk; - file->Read(&groupChunk, sizeof(FileFormat::AnimGraph_GroupParameter)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&groupChunk.mNumParameters, importParams.mEndianType); - - const char* groupName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - const uint32 numParameters = groupChunk.mNumParameters; - - // create and fill the new group parameter - AZStd::unique_ptr parameter(EMotionFX::ParameterFactory::Create(azrtti_typeid())); - parameter->SetName(groupName); - - // Previously collapsed/expanded state in group parameters was stored in the animgraph file. However, that - // would require to check out the animgraph file if you expand/collapse a group. Because this change was not - // done through commands, the dirty state was not properly restored. - // Collapsing state should be more of a setting per-user than something saved in the animgraph - //groupParameter->SetIsCollapsed(groupChunk.mCollapsed != 0); - - if (!animGraph->AddParameter(parameter.get())) - { - continue; - } - const EMotionFX::GroupParameter* groupParameter = static_cast(parameter.release()); - - parametersByGroup.emplace_back(groupParameter, EMotionFX::ParameterVector()); - AZStd::vector& parametersInGroup = parametersByGroup.back().second; - - // set the parameters of the group parameter - for (uint32 i = 0; i < numParameters; ++i) - { - // read the parameter index - uint32 parameterIndex; - file->Read(¶meterIndex, sizeof(uint32)); - MCore::Endian::ConvertUnsignedInt32(¶meterIndex, importParams.mEndianType); - - MCORE_ASSERT(parameterIndex != MCORE_INVALIDINDEX32); - if (parameterIndex != MCORE_INVALIDINDEX32) - { - const EMotionFX::Parameter* childParameter = animGraph->FindValueParameter(parameterIndex); - parametersInGroup.emplace_back(const_cast(childParameter)); - } - } - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Group parameter #%d:", g); - MCore::LogDetailedInfo(" + Name = %s", groupParameter->GetName().c_str()); - MCore::LogDetailedInfo(" + Num Parameters = %i", groupParameter->GetNumParameters()); - } - } - - // Now move the parameters to their groups - for (const AZStd::pair& groupAndParameters : parametersByGroup) - { - const EMotionFX::GroupParameter* groupParameter = groupAndParameters.first; - for (EMotionFX::Parameter* parameter : groupAndParameters.second) - { - animGraph->TakeParameterFromParent(parameter); - animGraph->AddParameter(const_cast(parameter), groupParameter); - } - } - - const EMotionFX::ValueParameterVector valueParametersAfterChange = animGraph->RecursivelyGetValueParameters(); - - AZStd::vector affectedObjects; - animGraph->RecursiveCollectObjectsOfType(azrtti_typeid(), affectedObjects); - - for (EMotionFX::AnimGraphObject* affectedObject : affectedObjects) - { - EMotionFX::ObjectAffectedByParameterChanges* affectedObjectByParameterChanges = azdynamic_cast(affectedObject); - affectedObjectByParameterChanges->ParameterOrderChanged(valueParametersBeforeChange, valueParametersAfterChange); - } - - return true; - } - - - // animGraph game controller settings - bool ChunkProcessorAnimGraphGameControllerSettings::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - uint32 i; - - AnimGraph* animGraph = importParams.mAnimGraph; - MCORE_ASSERT(animGraph); - - // get the game controller settings for the anim graph and clear it - AnimGraphGameControllerSettings& gameControllerSettings = animGraph->GetGameControllerSettings(); - gameControllerSettings.Clear(); - - // read the number of presets and the active preset index - uint32 activePresetIndex, numPresets; - file->Read(&activePresetIndex, sizeof(uint32)); - file->Read(&numPresets, sizeof(uint32)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&activePresetIndex, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&numPresets, importParams.mEndianType); - - if (GetLogging()) - { - MCore::LogDetailedInfo("- Game Controller Settings (NumPresets=%d, ActivePreset=%d)", numPresets, activePresetIndex); - } - - // preallocate memory for the presets - gameControllerSettings.SetNumPresets(numPresets); - - // read all presets - for (uint32 p = 0; p < numPresets; ++p) - { - // read the preset chunk - FileFormat::AnimGraph_GameControllerPreset presetChunk; - file->Read(&presetChunk, sizeof(FileFormat::AnimGraph_GameControllerPreset)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&presetChunk.mNumParameterInfos, importParams.mEndianType); - MCore::Endian::ConvertUnsignedInt32(&presetChunk.mNumButtonInfos, importParams.mEndianType); - - // read the preset name and get the number of parameter and button infos - const char* presetName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - const uint32 numParamInfos = presetChunk.mNumParameterInfos; - const uint32 numButtonInfos = presetChunk.mNumButtonInfos; - - // create and fill the new preset - AnimGraphGameControllerSettings::Preset* preset = aznew AnimGraphGameControllerSettings::Preset(presetName); - gameControllerSettings.SetPreset(p, preset); - - // read the parameter infos - preset->SetNumParamInfos(numParamInfos); - for (i = 0; i < numParamInfos; ++i) - { - // read the parameter info chunk - FileFormat::AnimGraph_GameControllerParameterInfo paramInfoChunk; - file->Read(¶mInfoChunk, sizeof(FileFormat::AnimGraph_GameControllerParameterInfo)); - - // read the parameter name - const char* parameterName = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - - // construct and fill the parameter info - AnimGraphGameControllerSettings::ParameterInfo* parameterInfo = aznew AnimGraphGameControllerSettings::ParameterInfo(parameterName); - parameterInfo->m_axis = paramInfoChunk.mAxis; - parameterInfo->m_invert = (paramInfoChunk.mInvert != 0); - parameterInfo->m_mode = (AnimGraphGameControllerSettings::ParameterMode)paramInfoChunk.mMode; - - preset->SetParamInfo(i, parameterInfo); - } - - // read the button infos - preset->SetNumButtonInfos(numButtonInfos); - for (i = 0; i < numButtonInfos; ++i) - { - // read the button info chunk - FileFormat::AnimGraph_GameControllerButtonInfo buttonInfoChunk; - file->Read(&buttonInfoChunk, sizeof(FileFormat::AnimGraph_GameControllerButtonInfo)); - - // read the button string - const char* buttonString = SharedHelperData::ReadString(file, importParams.mSharedData, importParams.mEndianType); - - // construct and fill the button info - AnimGraphGameControllerSettings::ButtonInfo* buttonInfo = aznew AnimGraphGameControllerSettings::ButtonInfo(buttonInfoChunk.mButtonIndex); - buttonInfo->m_mode = (AnimGraphGameControllerSettings::ButtonMode)buttonInfoChunk.mMode; - buttonInfo->m_string = buttonString; - - preset->SetButtonInfo(i, buttonInfo); - } - - // log the details - if (GetLogging()) - { - MCore::LogDetailedInfo("- Preset '%s':", preset->GetName()); - MCore::LogDetailedInfo(" + Num Param Infos = %d", preset->GetNumParamInfos()); - MCore::LogDetailedInfo(" + Num Button Infos = %d", preset->GetNumButtonInfos()); - } - } - - // set the active preset - if (activePresetIndex != MCORE_INVALIDINDEX32) - { - AnimGraphGameControllerSettings::Preset* activePreset = gameControllerSettings.GetPreset(activePresetIndex); - gameControllerSettings.SetActivePreset(activePreset); - } - - return true; - } - - //---------------------------------------------------------------------------------------------------------- - // MotionSet - //---------------------------------------------------------------------------------------------------------- - - // all submotions in one chunk - bool ChunkProcessorMotionSet::Process(MCore::File* file, Importer::ImportParameters& importParams) - { - const MCore::Endian::EEndianType endianType = importParams.mEndianType; - - FileFormat::MotionSetsChunk motionSetsChunk; - file->Read(&motionSetsChunk, sizeof(FileFormat::MotionSetsChunk)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&motionSetsChunk.mNumSets, endianType); - - // get the number of motion sets and iterate through them - const uint32 numMotionSets = motionSetsChunk.mNumSets; - for (uint32 i = 0; i < numMotionSets; ++i) - { - FileFormat::MotionSetChunk motionSetChunk; - file->Read(&motionSetChunk, sizeof(FileFormat::MotionSetChunk)); - - // convert endian - MCore::Endian::ConvertUnsignedInt32(&motionSetChunk.mNumChildSets, endianType); - MCore::Endian::ConvertUnsignedInt32(&motionSetChunk.mNumMotionEntries, endianType); - - // get the parent set - const char* parentSetName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - GetMotionManager().Lock(); - MotionSet* parentSet = GetMotionManager().FindMotionSetByName(parentSetName, importParams.m_isOwnedByRuntime); - GetMotionManager().Unlock(); - - // read the motion set name and create our new motion set - const char* motionSetName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - MotionSet* motionSet = aznew MotionSet(motionSetName, parentSet); - motionSet->SetIsOwnedByRuntime(importParams.m_isOwnedByRuntime); - - // set the root motion set to the importer params motion set, this will be returned by the Importer::LoadMotionSet() function - if (parentSet == nullptr) - { - assert(importParams.mMotionSet == nullptr); - importParams.mMotionSet = motionSet; - } - - // read the filename and set it - /*const char* motionSetFileName = */ SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - //motionSet->SetFileName( motionSetFileName ); - - // in case this is not a root motion set add the new motion set as child set to the parent set - if (parentSet) - { - parentSet->AddChildSet(motionSet); - } - - // Read all motion entries. - const uint32 numMotionEntries = motionSetChunk.mNumMotionEntries; - motionSet->ReserveMotionEntries(numMotionEntries); - AZStd::string nativeMotionFileName; - for (uint32 j = 0; j < numMotionEntries; ++j) - { - // read the motion entry - const char* motionFileName = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - nativeMotionFileName = motionFileName; - - // read the string id and set it - const char* motionStringID = SharedHelperData::ReadString(file, importParams.mSharedData, endianType); - - // add the motion entry to the motion set - MotionSet::MotionEntry* motionEntry = aznew MotionSet::MotionEntry(nativeMotionFileName.c_str(), motionStringID); - motionSet->AddMotionEntry(motionEntry); - } - } - - return true; - } - - - //---------------------------------------------------------------------------------------------------------- // NodeMap //---------------------------------------------------------------------------------------------------------- diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h index 3d0412eb3f..306e4af0c8 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/ChunkProcessors.h @@ -16,8 +16,6 @@ #include "SharedFileFormatStructs.h" #include "ActorFileFormat.h" #include "MotionFileFormat.h" -#include "AnimGraphFileFormat.h" -#include "MotionSetFileFormat.h" #include "NodeMapFileFormat.h" #include "Importer.h" #include @@ -32,7 +30,6 @@ namespace EMotionFX class Importer; class AnimGraphNode; - /** * Shared importer data class. * Chunks can load data, which might be shared between other chunks during import. @@ -57,20 +54,11 @@ namespace EMotionFX virtual void Reset() {} protected: - /** - * The constructor. - */ SharedData() : BaseObject() {} - - /** - * The destructor. - */ virtual ~SharedData() { Reset(); } }; - - /** * Helper class for reading strings from files and file information storage. */ @@ -108,34 +96,12 @@ namespace EMotionFX */ static const char* ReadString(MCore::Stream* file, MCore::Array* sharedData, MCore::Endian::EEndianType endianType); - /** - * Get the array of currently loaded anim graph nodes. - * @param sharedData The array which holds the shared data objects. - * @result The array of currently loaded anim graph nodes. - */ - static MCore::Array& GetBlendNodes(MCore::Array* sharedData); - - /** - * Get the table to look up a state machine that needs an entry state as they are created. - * @param sharedData The array which holds the shared data objects. - * @result The map whose keys are the indices of entry states and the values are the IDs of the state machines that need those as entry states. - */ - static AZStd::map& GetEntryStateToStateMachineTable(MCore::Array* sharedData); - - /** - * Checks if the strings in the file are encoded using unicode or multi-byte based on the exporter date. - * The first official EMotion FX version to use unicode was compiled on 26th November 2012. - */ - static bool GetIsUnicodeFile(const char* dateString, MCore::Array* sharedData); - public: uint32 mFileHighVersion; /**< The high file version. For example 3 in case of v3.10. */ uint32 mFileLowVersion; /**< The low file version. For example 10 in case of v3.10. */ uint32 mStringStorageSize; /**< The size of the string buffer. */ bool mIsUnicodeFile; /**< True in case strings in the file are saved using unicode character set, false in case they are saved using multi-byte. */ char* mStringStorage; /**< The shared string buffer. */ - MCore::Array mBlendNodes; /**< Array of read anim graph nodes. */ - AZStd::map m_entryNodeIndexToStateMachineIdLookupTable; protected: /** * The constructor. @@ -338,22 +304,6 @@ namespace EMotionFX EMFX_CHUNKPROCESSOR(ChunkProcessorMotionMorphSubMotions, FileFormat::MOTION_CHUNK_MORPHSUBMOTIONS, 1) EMFX_CHUNKPROCESSOR(ChunkProcessorMotionData, FileFormat::MOTION_CHUNK_MOTIONDATA, 1) - // Anim graph file format chunk processors - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphStateTransitions, FileFormat::ANIMGRAPH_CHUNK_STATETRANSITIONS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNodeConnections, FileFormat::ANIMGRAPH_CHUNK_NODECONNECTIONS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphParameters, FileFormat::ANIMGRAPH_CHUNK_PARAMETERS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNodeGroups, FileFormat::ANIMGRAPH_CHUNK_NODEGROUPS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphGroupParameters, FileFormat::ANIMGRAPH_CHUNK_GROUPPARAMETERS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphGameControllerSettings, FileFormat::ANIMGRAPH_CHUNK_GAMECONTROLLERSETTINGS, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphNode, FileFormat::ANIMGRAPH_CHUNK_BLENDNODE, 1) - EMFX_CHUNKPROCESSOR(ChunkProcessorAnimGraphAdditionalInfo, FileFormat::ANIMGRAPH_CHUNK_ADDITIONALINFO, 1) - - // motion set file format chunk processors - EMFX_CHUNKPROCESSOR(ChunkProcessorMotionSet, FileFormat::CHUNK_MOTIONSET, 1) - // node map file format chunk processors EMFX_CHUNKPROCESSOR(ChunkProcessorNodeMap, FileFormat::CHUNK_NODEMAP, 1) - - - //------------------------------------------------------------------------------------------------- } // namespace EMotionFX From abc501e535dcf8a3ea009df921d97284b53c573f Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Mon, 26 Jul 2021 09:58:24 +0200 Subject: [PATCH 15/58] Removed legacy file format loading for anim graphs and motion sets Signed-off-by: Benjamin Jillich --- .../EMotionFX/Source/Importer/Importer.cpp | 520 ++---------------- .../Code/EMotionFX/Source/Importer/Importer.h | 65 +-- 2 files changed, 36 insertions(+), 549 deletions(-) diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp index 6ac4493275..67cbb91c06 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.cpp @@ -156,85 +156,6 @@ namespace EMotionFX return true; } - - // check if we can process the given motion set file - bool Importer::CheckIfIsValidMotionSetFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const - { - MCORE_ASSERT(f->GetIsOpen()); - - // verify if we actually are dealing with a valid actor file - FileFormat::MotionSet_Header header; - if (f->Read(&header, sizeof(FileFormat::MotionSet_Header)) == 0) - { - MCore::LogError("Failed to read the motion set file header!"); - return false; - } - - // check the FOURCC - if (header.mFourCC[0] != 'M' || header.mFourCC[1] != 'O' || header.mFourCC[2] != 'S' || header.mFourCC[3] != ' ') - { - return false; - } - - // read the chunks - switch (header.mEndianType) - { - case 0: - *outEndianType = MCore::Endian::ENDIAN_LITTLE; - break; - case 1: - *outEndianType = MCore::Endian::ENDIAN_BIG; - break; - default: - MCore::LogError("Unsupported endian type used! (endian type = %d)", header.mEndianType); - return false; - } - ; - - // yes, it is a valid motionset file! - return true; - } - - - - // check if we can process the given anim graph file - bool Importer::CheckIfIsValidAnimGraphFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const - { - MCORE_ASSERT(f->GetIsOpen()); - - // verify if we actually are dealing with a valid actor file - FileFormat::AnimGraph_Header header; - if (f->Read(&header, sizeof(FileFormat::AnimGraph_Header)) == 0) - { - return false; - } - - // check the FOURCC - if (header.mFourCC[0] != 'A' || header.mFourCC[1] != 'N' || header.mFourCC[2] != 'G' || header.mFourCC[3] != 'R') - { - return false; - } - - // read the chunks - switch (header.mEndianType) - { - case 0: - *outEndianType = MCore::Endian::ENDIAN_LITTLE; - break; - case 1: - *outEndianType = MCore::Endian::ENDIAN_BIG; - break; - default: - MCore::LogError("Unsupported endian type used! (endian type = %d)", header.mEndianType); - return false; - } - ; - - // yes, it is a valid anim graph file! - return true; - } - - // check if we can process the given node map file bool Importer::CheckIfIsValidNodeMapFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const { @@ -599,125 +520,32 @@ namespace EMotionFX //------------------------------------------------------------------------------------------------- - // try to load a motion set from disk MotionSet* Importer::LoadMotionSet(AZStd::string filename, MotionSetSettings* settings, const AZ::ObjectStream::FilterDescriptor& loadFilter) { EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePathKeepCase, filename); - const bool isLegacyFile = Importer::CheckFileType(filename.c_str()) == Importer::EFileType::FILETYPE_MOTIONSET; - if (!isLegacyFile) + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!context) { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - if (!context) - { - AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); - return nullptr; - } - - EMotionFX::MotionSet* motionSet = EMotionFX::MotionSet::LoadFromFile(filename, context, loadFilter); - if (motionSet) - { - motionSet->SetFilename(filename.c_str()); - } - return motionSet; - } - - ////////////////////////////////////////// - // Legacy file type loading - ////////////////////////////////////////// - - // check if we want to load the motion set even if a motion set with the given filename is already inside the motion manager - if (settings == nullptr || settings->mForceLoading == false) - { - // search the motion set inside the motion manager and return it if it already got loaded - MotionSet* motionSet = GetMotionManager().FindMotionSetByFileName(filename.c_str()); - if (motionSet) - { - MCore::LogInfo(" + Motion set '%s' already loaded, returning already loaded motion set from the MotionManager.", filename.c_str()); - return motionSet; - } - } - - if (GetLogging()) - { - MCore::LogInfo("- Trying to load motion set from file '%s'...", filename.c_str()); - } - - // try to open the file from disk - MCore::DiskFile f; - if (f.Open(filename.c_str(), MCore::DiskFile::READ) == false) - { - if (GetLogging()) - { - MCore::LogError(" + Failed to open the file for motion set."); - } + AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); return nullptr; } - // retrieve the filesize - const size_t fileSize = f.GetFileSize(); - - // create a temporary buffer for the file - uint8* fileBuffer = (uint8*)MCore::Allocate(fileSize, EMFX_MEMCATEGORY_IMPORTER); - - // read in the complete file - f.Read(fileBuffer, fileSize); - - // close the file again - f.Close(); - - // create the motion set reading from memory - MotionSet* result = LoadMotionSet(fileBuffer, fileSize, settings); - if (result) + EMotionFX::MotionSet* motionSet = EMotionFX::MotionSet::LoadFromFile(filename, context, loadFilter); + if (motionSet) { - result->SetFilename(filename.c_str()); - } - - // delete the filebuffer again - MCore::Free(fileBuffer); - - // check if it worked :) - if (result == nullptr) - { - if (GetLogging()) - { - MCore::LogError(" + Failed to load motion set from file '%s'.", filename.c_str()); - } - } - else - { - if (GetLogging()) - { - MCore::LogInfo(" + Loading successfully finished."); - } - } - - // return the result - return result; - } - - - MotionSet* Importer::LoadMotionSet(uint8* memoryStart, size_t lengthInBytes, MotionSetSettings* settings) - { - // Legacy file type loading. - MCore::MemoryFile memFile; - memFile.Open(memoryStart, lengthInBytes); - - const bool isLegacyFile = Importer::CheckFileType(&memFile) == Importer::EFileType::FILETYPE_MOTIONSET; - if (isLegacyFile) - { - // Open the memory file again as CheckFileType() is closing it at the end. - memFile.Open(memoryStart, lengthInBytes); - EMotionFX::MotionSet* motionSet = LoadMotionSet(&memFile, settings); + motionSet->SetFilename(filename.c_str()); if (settings) { motionSet->SetIsOwnedByRuntime(settings->m_isOwnedByRuntime); } - return motionSet; } + return motionSet; + } - + MotionSet* Importer::LoadMotionSet(uint8* memoryStart, size_t lengthInBytes, MotionSetSettings* settings) + { AZ::SerializeContext* context = nullptr; AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); if (!context) @@ -734,58 +562,6 @@ namespace EMotionFX return motionSet; } - - // try to load a motion set from a file - MotionSet* Importer::LoadMotionSet(MCore::File* f, MotionSetSettings* settings) - { - MCORE_ASSERT(f); - MCORE_ASSERT(f->GetIsOpen()); - - // create the shared data - MCore::Array sharedData; - sharedData.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER); - PrepareSharedData(sharedData); - - // load the file header - FileFormat::MotionSet_Header fileHeader; - f->Read(&fileHeader, sizeof(FileFormat::MotionSet_Header)); - if (fileHeader.mFourCC[0] != 'M' || fileHeader.mFourCC[1] != 'O' || fileHeader.mFourCC[2] != 'S' || fileHeader.mFourCC[3] != ' ') - { - MCore::LogError("The motion set file is not a valid file."); - f->Close(); - return nullptr; - } - - // get the endian type - MCore::Endian::EEndianType endianType = (MCore::Endian::EEndianType)fileHeader.mEndianType; - - // init the import parameters - ImportParameters params; - params.mSharedData = &sharedData; - params.mEndianType = endianType; - params.m_isOwnedByRuntime = settings ? settings->m_isOwnedByRuntime : false; - - // read the chunks - while (ProcessChunk(f, params)) - { - } - - // close the file and return a pointer to the actor we loaded - f->Close(); - - // get rid of shared data - ResetSharedData(sharedData); - sharedData.Clear(); - - // check if the motion set got set - if (params.mMotionSet == nullptr) - { - return nullptr; - } - - return params.mMotionSet; - } - //------------------------------------------------------------------------------------------------- // load a node map by filename @@ -1087,19 +863,6 @@ namespace EMotionFX RegisterChunkProcessor(aznew ChunkProcessorMotionMorphSubMotions()); RegisterChunkProcessor(aznew ChunkProcessorMotionData()); - // AnimGraph file format - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphParameters()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphNodeGroups()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphNode()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphStateTransitions()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphNodeConnections()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphGroupParameters()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphGameControllerSettings()); - RegisterChunkProcessor(aznew ChunkProcessorAnimGraphAdditionalInfo()); - - // motion set file format - RegisterChunkProcessor(aznew ChunkProcessorMotionSet()); - // node map RegisterChunkProcessor(aznew ChunkProcessorNodeMap()); } @@ -1232,6 +995,18 @@ namespace EMotionFX return FILETYPE_UNKNOWN; } + AZStd::string fileExtension; + AZ::StringFunc::Path::GetExtension(filename, fileExtension); + + if (fileExtension == ".animgraph") + { + return FILETYPE_ANIMGRAPH; + } + if (fileExtension == ".motionset") + { + return FILETYPE_MOTIONSET; + } + // try to open the file from disk MCore::MemoryFile memoryFile; memoryFile.Open(); @@ -1272,14 +1047,6 @@ namespace EMotionFX return FILETYPE_MOTION; } - // check for motion set - file->Seek(0); - if (CheckIfIsValidMotionSetFile(file, &endianType)) - { - file->Close(); - return FILETYPE_MOTIONSET; - } - // check for node map file->Seek(0); if (CheckIfIsValidNodeMapFile(file, &endianType)) @@ -1288,14 +1055,6 @@ namespace EMotionFX return FILETYPE_NODEMAP; } - // check for anim graph - file->Seek(0); - if (CheckIfIsValidAnimGraphFile(file, &endianType)) - { - file->Close(); - return FILETYPE_ANIMGRAPH; - } - // close the file again file->Close(); @@ -1304,124 +1063,30 @@ namespace EMotionFX //--------------------------------------------------------- - - // load anim graph by filename - AnimGraph* Importer::LoadAnimGraph(AZStd::string filename, AnimGraphSettings* settings, const AZ::ObjectStream::FilterDescriptor& loadFilter) + AnimGraph* Importer::LoadAnimGraph(AZStd::string filename, const AZ::ObjectStream::FilterDescriptor& loadFilter) { EBUS_EVENT(AzFramework::ApplicationRequests::Bus, NormalizePathKeepCase, filename); - const bool isLegacyFile = Importer::CheckFileType(filename.c_str()) == Importer::EFileType::FILETYPE_ANIMGRAPH; - if (!isLegacyFile) + AZ::SerializeContext* context = nullptr; + AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); + if (!context) { - AZ::SerializeContext* context = nullptr; - AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); - if (!context) - { - AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); - return nullptr; - } - - EMotionFX::AnimGraph* animGraph = EMotionFX::AnimGraph::LoadFromFile(filename, context, loadFilter); - if (animGraph) - { - animGraph->SetFileName(filename.c_str()); - animGraph->RemoveInvalidConnections(); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. - } - - return animGraph; - } - - ////////////////////////////////////////// - // Legacy file type loading - ////////////////////////////////////////// - - // check if we want to load the anim graph even if a anim graph with the given filename is already inside the anim graph manager - if (settings == nullptr || settings->mForceLoading == false) - { - // search the anim graph inside the anim graph manager and return it if it already got loaded - AnimGraph* animGraph = GetAnimGraphManager().FindAnimGraphByFileName(filename.c_str()); - if (animGraph) - { - MCore::LogInfo(" + Anim graph '%s' already loaded, returning already loaded anim graph from the AnimGraphManager.", filename.c_str()); - return animGraph; - } - } - - if (GetLogging()) - { - MCore::LogInfo("- Trying to load anim graph from file '%s'...", filename.c_str()); - } - - // try to open the file from disk - MCore::DiskFile f; - if (!f.Open(filename.c_str(), MCore::DiskFile::READ)) - { - if (GetLogging()) - { - MCore::LogError(" + Failed to open the file for anim graph '%s', anim graph not loaded!", filename.c_str()); - } + AZ_Error("EMotionFX", false, "Can't get serialize context from component application."); return nullptr; } - // retrieve the filesize - const size_t fileSize = f.GetFileSize(); - - // create a temporary buffer for the file - uint8* fileBuffer = (uint8*)MCore::Allocate(fileSize, EMFX_MEMCATEGORY_IMPORTER); - - // read in the complete file - f.Read(fileBuffer, fileSize); - - // close the file again - f.Close(); - - // create the actor reading from memory - AnimGraph* result = LoadAnimGraph(fileBuffer, fileSize, settings); - if (result) + EMotionFX::AnimGraph* animGraph = EMotionFX::AnimGraph::LoadFromFile(filename, context, loadFilter); + if (animGraph) { - result->SetFileName(filename.c_str()); - result->RemoveInvalidConnections(); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. + animGraph->SetFileName(filename.c_str()); + animGraph->RemoveInvalidConnections(); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. } - // delete the filebuffer again - MCore::Free(fileBuffer); - - // check if it worked - if (result == nullptr) - { - if (GetLogging()) - { - MCore::LogError(" + Failed to load anim graph from file '%s'", filename.c_str()); - } - } - else - { - if (GetLogging()) - { - MCore::LogInfo(" + Loading successfully finished"); - } - } - - // return the result - return result; + return animGraph; } - - // load the anim graph from memory - AnimGraph* Importer::LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes, AnimGraphSettings* settings) + AnimGraph* Importer::LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes) { - // Legacy file type loading. - MCore::MemoryFile memFile; - memFile.Open(memoryStart, lengthInBytes); - - const bool isLegacyFile = Importer::CheckFileType(&memFile) == Importer::EFileType::FILETYPE_ANIMGRAPH; - if (isLegacyFile) - { - // Open the memory file again as CheckFileType() is closing it at the end. - memFile.Open(memoryStart, lengthInBytes); - return LoadAnimGraph(&memFile, settings); - } - AZ::SerializeContext* context = nullptr; AZ::ComponentApplicationBus::BroadcastResult(context, &AZ::ComponentApplicationBus::Events::GetSerializeContext); if (!context) @@ -1434,123 +1099,6 @@ namespace EMotionFX return animGraph; } - - // load a anim graph from a file object - AnimGraph* Importer::LoadAnimGraph(MCore::File* f, AnimGraphSettings* settings) - { - MCORE_ASSERT(f); - MCORE_ASSERT(f->GetIsOpen()); - - // execute the pre-passes - if (f->GetType() != MCore::MemoryFile::TYPE_ID) - { - MCore::LogError("Given file is not a memory file. Cannot process pre-passes."); - return nullptr; - } - - // copy over the actor settings, or use defaults - AnimGraphSettings animGraphSettings; - if (settings) - { - animGraphSettings = *settings; - } - - // create the shared data - MCore::Array sharedData; - sharedData.SetMemoryCategory(EMFX_MEMCATEGORY_IMPORTER); - PrepareSharedData(sharedData); - - //----------------------------------------------- - - // load the file header - FileFormat::AnimGraph_Header fileHeader; - f->Read(&fileHeader, sizeof(FileFormat::AnimGraph_Header)); - if (fileHeader.mFourCC[0] != 'A' || fileHeader.mFourCC[1] != 'N' || fileHeader.mFourCC[2] != 'G' || fileHeader.mFourCC[3] != 'R') - { - MCore::LogError("The anim graph file is not a valid anim graph file."); - f->Close(); - return nullptr; - } - - // get the endian type - MCore::Endian::EEndianType endianType = (MCore::Endian::EEndianType)fileHeader.mEndianType; - - // convert endian of the integer values - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mFileVersion, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumNodes, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumStateTransitions, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumNodeConnections, endianType); - MCore::Endian::ConvertUnsignedInt32(&fileHeader.mNumParameters, endianType); - - // read the anim graph name, create it, and read the other remaining info strings - SharedHelperData::ReadString(f, &sharedData, endianType); - AnimGraph* animGraph = aznew AnimGraph(); - - if (GetLogDetails()) - { - MCore::LogDetailedInfo("Anim Graph:"); - - SharedHelperData::ReadString(f, &sharedData, endianType); // copyright - SharedHelperData::ReadString(f, &sharedData, endianType); // description - MCore::LogDetailedInfo(" + Company = %s", SharedHelperData::ReadString(f, &sharedData, endianType)); // company - MCore::LogDetailedInfo(" + EMotion FX Version= %s", SharedHelperData::ReadString(f, &sharedData, endianType)); // emfx version - MCore::LogDetailedInfo(" + EMStudio Build = %s", SharedHelperData::ReadString(f, &sharedData, endianType)); // emstudio build - MCore::LogDetailedInfo(" + Num nodes = %d", fileHeader.mNumNodes); - MCore::LogDetailedInfo(" + Num transitions = %d", fileHeader.mNumStateTransitions); - MCore::LogDetailedInfo(" + Num connections = %d", fileHeader.mNumNodeConnections); - MCore::LogDetailedInfo(" + Num parameters = %d", fileHeader.mNumParameters); - MCore::LogDetailedInfo(" + File version = %d", fileHeader.mFileVersion); - MCore::LogDetailedInfo(" + Endian type = %d", fileHeader.mEndianType); - } - else - { - SharedHelperData::ReadString(f, &sharedData, endianType); // copyright - SharedHelperData::ReadString(f, &sharedData, endianType); // description - SharedHelperData::ReadString(f, &sharedData, endianType); // company - SharedHelperData::ReadString(f, &sharedData, endianType); // emfx version - SharedHelperData::ReadString(f, &sharedData, endianType); // emstudio build - } - - // init the import parameters - ImportParameters params; - params.mSharedData = &sharedData; - params.mEndianType = endianType; - params.mAnimGraph = animGraph; - params.mAnimGraphSettings = &animGraphSettings; - - // pre-allocate the blend nodes array to prevent reallocs - MCore::Array& blendNodes = SharedHelperData::GetBlendNodes(params.mSharedData); - blendNodes.Reserve(fileHeader.mNumNodes); - - // process all chunks - while (ProcessChunk(f, params)) - { - } - - // close the file and return a pointer to the actor we loaded - f->Close(); - - // get rid of shared data - ResetSharedData(sharedData); - sharedData.Clear(); - - // recursively update attributes of all state machines and blend tree nodes - if (animGraph->GetRootStateMachine()) - { - animGraph->InitAfterLoading(); - animGraph->RemoveInvalidConnections(true); // Remove connections that have nullptr source node's, which happens when connections point to unknown nodes. - } - else - { - delete animGraph; - animGraph = nullptr; - } - - // return the created actor - return animGraph; - } - - // extract the file information from an actor file bool Importer::ExtractActorFileInfo(FileInfo* outInfo, const char* filename) const { diff --git a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h index 83121a405a..2b12f93a1a 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h +++ b/Gems/EMotionFX/Code/EMotionFX/Source/Importer/Importer.h @@ -108,18 +108,15 @@ namespace EMotionFX MCore::Array mChunkIDsToIgnore; /**< Add the ID's of the chunks you wish to ignore. */ }; - /** * The motion set import options. * This can be used in combination with the LoadMotionSet method. */ struct EMFX_API MotionSetSettings { - bool mForceLoading = false; /**< Set to true in case you want to load the motion set even if a motion set with the given filename is already inside the motion manager. */ bool m_isOwnedByRuntime = false; }; - /** * The node map import options. * This can be used in combination with the LoadNodeMap method. @@ -130,30 +127,15 @@ namespace EMotionFX bool mLoadNodes = true; /**< Add nodes to the map? (default=true) */ }; - - /** - * The anim graph import settings. - */ - struct EMFX_API AnimGraphSettings - { - bool mForceLoading = false; /**< Set to true in case you want to load the anim graph even if an anim graph with the given filename is already inside the anim graph manager. */ - bool mDisableNodeVisualization = true; /**< Force disabling of node visualization code execution inside the anim graph nodes? */ - }; - - struct EMFX_API ImportParameters { Actor* mActor = nullptr; Motion* mMotion = nullptr; - MotionSet* mMotionSet = nullptr; Importer::ActorSettings* mActorSettings = nullptr; Importer::MotionSettings* mMotionSettings = nullptr; MCore::Array* mSharedData = nullptr; MCore::Endian::EEndianType mEndianType = MCore::Endian::ENDIAN_LITTLE; - AnimGraph* mAnimGraph = nullptr; - Importer::AnimGraphSettings* mAnimGraphSettings = nullptr; - NodeMap* mNodeMap = nullptr; Importer::NodeMapSettings* mNodeMapSettings = nullptr; bool m_isOwnedByRuntime = false; @@ -250,43 +232,24 @@ namespace EMotionFX //------------------------------------------------------------------------------------------------- - /** - * Load a anim graph file from a given file object. - * @param f The file object. - * @param settings The importer settings, or nullptr to use default settings. - * @result The anim graph object, or nullptr when failed. - */ - AnimGraph* LoadAnimGraph(MCore::File* f, AnimGraphSettings* settings = nullptr); - /** * Load a anim graph file by filename. * @param filename The filename to load from. - * @param settings The anim graph importer settings, or nullptr to use default settings. * @param loadFilter The filter descriptor for loading anim graph from file * @result The anim graph object, or nullptr in case loading failed. */ - AnimGraph* LoadAnimGraph(AZStd::string, AnimGraphSettings* settings = nullptr, const AZ::ObjectStream::FilterDescriptor& loadFilter = AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); + AnimGraph* LoadAnimGraph(AZStd::string, const AZ::ObjectStream::FilterDescriptor& loadFilter = AZ::ObjectStream::FilterDescriptor(nullptr, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES)); /** * Load a anim graph file from a memory location. * @param memoryStart The start address of the file in memory. * @param lengthInBytes The length of the file, in bytes. - * @param settings The settings to use during loading, or nullptr when you want to use default settings, which would load everything. * @result The anim graph object, or nullptr in case loading failed. */ - AnimGraph* LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes, AnimGraphSettings* settings = nullptr); + AnimGraph* LoadAnimGraph(uint8* memoryStart, size_t lengthInBytes); //------------------------------------------------------------------------------------------------- - /** - * Load a motion set from a given file. - * A file does not have to be stored on disk, but can also be in memory or in an archive or on some network stream. Anything is possible. - * @param f The file to load the motion set from (after load, the file will be closed). - * @param settings The motion set importer settings, or nullptr to use default settings. - * @result The motion set object, or nullptr in case loading failed. - */ - MotionSet* LoadMotionSet(MCore::File* f, MotionSetSettings* settings = nullptr); - /** * Loads a motion set from a file on disk. * @param filename The name of the file on disk. @@ -430,30 +393,6 @@ namespace EMotionFX */ bool CheckIfIsValidMotionFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const; - /** - * Verify if the given file is a valid motion set file that can be processed by the importer. - * Please note that the specified must already been opened and must also be pointing to the location where the - * XPM file header will be stored (the start of the file). The file will not be closed after this method! - * The endian type of the file will be written inside the outEndianType parameter. - * Also note that the file position (read position / cursor) will point after the header after this function has been executed. - * @param f The file to perform the check on. - * @param outEndianType The value that will contain the endian type used by the file. - * @result Returns true when the file is a valid actor file that can be processed by the importer. Otherwise false is returned. - */ - bool CheckIfIsValidMotionSetFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const; - - /** - * Verify if the given file is a valid anim graph file that can be processed by the importer. - * Please note that the specified must already been opened and must also be pointing to the location where the - * XPM file header will be stored (the start of the file). The file will not be closed after this method! - * The endian type of the file will be written inside the outEndianType parameter. - * Also note that the file position (read position / cursor) will point after the header after this function has been executed. - * @param f The file to perform the check on. - * @param outEndianType The value that will contain the endian type used by the file. - * @result Returns true when the file is a valid actor file that can be processed by the importer. Otherwise false is returned. - */ - bool CheckIfIsValidAnimGraphFile(MCore::File* f, MCore::Endian::EEndianType* outEndianType) const; - /** * Verify if the given file is a valid node map file that can be processed by the importer. * Please note that the specified must already been opened and must also be pointing to the location where the From ff2649d0c8ef0db3ea1bd75b2585ae9b0bc9aec9 Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Mon, 26 Jul 2021 09:59:19 +0200 Subject: [PATCH 16/58] Adapted loading calls to removed legacy file loading Signed-off-by: Benjamin Jillich --- Gems/EMotionFX/Code/CMakeLists.txt | 2 -- .../EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp | 4 +--- .../Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp | 2 +- Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake | 5 ----- .../Code/Source/Integration/Assets/AnimGraphAsset.cpp | 3 +-- 5 files changed, 3 insertions(+), 13 deletions(-) diff --git a/Gems/EMotionFX/Code/CMakeLists.txt b/Gems/EMotionFX/Code/CMakeLists.txt index 5c38faf2a6..ed5447ba25 100644 --- a/Gems/EMotionFX/Code/CMakeLists.txt +++ b/Gems/EMotionFX/Code/CMakeLists.txt @@ -219,8 +219,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/AnimGraphExampleNoDependency.animgraph ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/EmptyAnimGraphExample.animgraph ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/EmptyMotionSetExample.motionset - ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph - ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/MotionSetExample.motionset ${CMAKE_CURRENT_SOURCE_DIR}/Tests/TestAssets/EMotionFXBuilderTestAssets/MotionSetExampleNoDependency.motionset OUTPUT_SUBDIRECTORY diff --git a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp index a04f6a327d..fdc4e4d0e5 100644 --- a/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/CommandSystem/Source/AnimGraphCommands.cpp @@ -93,9 +93,7 @@ namespace CommandSystem } // load anim graph from file - EMotionFX::Importer::AnimGraphSettings settings; - settings.mDisableNodeVisualization = false; - EMotionFX::AnimGraph* animGraph = EMotionFX::GetImporter().LoadAnimGraph(filename.c_str(), &settings); + EMotionFX::AnimGraph* animGraph = EMotionFX::GetImporter().LoadAnimGraph(filename.c_str()); if (!animGraph) { outResult = AZStd::string::format("Failed to load anim graph from %s.", filename.c_str()); diff --git a/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp b/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp index 927ba67b76..cd81d81170 100644 --- a/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp +++ b/Gems/EMotionFX/Code/EMotionFX/Pipeline/EMotionFXBuilder/AnimGraphBuilderWorker.cpp @@ -97,7 +97,7 @@ namespace EMotionFX AZ_UNUSED(sourceFile); AZ::ObjectStream::FilterDescriptor loadFilter = AZ::ObjectStream::FilterDescriptor(&AZ::Data::AssetFilterNoAssetLoading, AZ::ObjectStream::FILTERFLAG_IGNORE_UNKNOWN_CLASSES); - AZStd::unique_ptr animGraph(GetImporter().LoadAnimGraph(fullPath, nullptr, loadFilter)); + AZStd::unique_ptr animGraph(GetImporter().LoadAnimGraph(fullPath, loadFilter)); if (!animGraph) { diff --git a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake index 7942a5525f..b12cbe102f 100644 --- a/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake +++ b/Gems/EMotionFX/Code/EMotionFX/emotionfx_files.cmake @@ -364,16 +364,11 @@ set(FILES Source/TwoStringEventData.h Source/Importer/ChunkProcessors.cpp Source/Importer/ChunkProcessors.h - Source/Importer/LegacyAnimGraphNodeParser.cpp - Source/Importer/LegacyAnimGraphNodeParser.h Source/Importer/Importer.cpp Source/Importer/Importer.h - Source/Importer/MotionSetFileFormat.h Source/Importer/NodeMapFileFormat.h Source/Importer/SharedFileFormatStructs.h Source/Importer/ActorFileFormat.h - Source/Importer/AnimGraphFileFormat.cpp - Source/Importer/AnimGraphFileFormat.h Source/Importer/MotionFileFormat.h Source/Parameter/BoolParameter.cpp Source/Parameter/BoolParameter.h diff --git a/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp b/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp index d3e39840ab..3e459d31d6 100644 --- a/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp +++ b/Gems/EMotionFX/Code/Source/Integration/Assets/AnimGraphAsset.cpp @@ -53,8 +53,7 @@ namespace EMotionFX AnimGraphAsset* assetData = asset.GetAs(); assetData->m_emfxAnimGraph.reset(EMotionFX::GetImporter().LoadAnimGraph( assetData->m_emfxNativeData.data(), - assetData->m_emfxNativeData.size(), - nullptr)); + assetData->m_emfxNativeData.size())); if (assetData->m_emfxAnimGraph) { From 96aa9fde0638f8dccdeae8e705d25d8436365eab Mon Sep 17 00:00:00 2001 From: Benjamin Jillich Date: Mon, 26 Jul 2021 10:00:07 +0200 Subject: [PATCH 17/58] Removed legacy loading automated tests and ported file format for anim graph for remaining automated tests Signed-off-by: Benjamin Jillich --- .../Code/Tests/EMotionFXBuilderTests.cpp | 20 ------------------- .../LegacyAnimGraphExample.animgraph | 3 --- .../LegacyMotionSetExample.motionset | 3 --- .../Code/Tests/TestAssets/Rin/rin.animgraph | 4 ++-- 4 files changed, 2 insertions(+), 28 deletions(-) delete mode 100644 Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph delete mode 100644 Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset diff --git a/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp b/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp index 3e63af8d63..acdd78fc0f 100644 --- a/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp +++ b/Gems/EMotionFX/Code/Tests/EMotionFXBuilderTests.cpp @@ -97,16 +97,6 @@ namespace EMotionFX ASSERT_EQ(productDependencies.size(), 0); } - TEST_F(EMotionFXBuilderTests, TestLegacyAnimGraphAsset_NoDependency_OutputNoProductDependencies) - { - const AZStd::string fileName = "@devroot@/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph"; - AZStd::vector productDependencies; - EMotionFXBuilder::AnimGraphBuilderWorker builderWorker; - - ASSERT_TRUE(builderWorker.ParseProductDependencies(ResolvePath(fileName.c_str()), fileName, productDependencies)); - ASSERT_EQ(productDependencies.size(), 0); - } - TEST_F(EMotionFXBuilderTests, TestMotionSetAsset_HasReferenceNode_OutputProductDependencies) { const AZStd::string fileName = "@devroot@/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/MotionSetExample.motionset"; @@ -150,14 +140,4 @@ namespace EMotionFX AZ_TEST_STOP_ASSERTTEST(2); ASSERT_EQ(productDependencies.size(), 0); } - - TEST_F(EMotionFXBuilderTests, TestLegacyMotionSetAsset_ReferenceMotionAssets_OutputProductDependencies) - { - const AZStd::string fileName = "@devroot@/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset"; - ProductPathDependencySet productDependencies; - EMotionFXBuilder::MotionSetBuilderWorker builderWorker; - - ASSERT_TRUE(builderWorker.ParseProductDependencies(ResolvePath(fileName.c_str()), fileName, productDependencies)); - ASSERT_EQ(productDependencies.size(), 25); - } } // namespace EMotionFX diff --git a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph b/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph deleted file mode 100644 index 5138720283..0000000000 --- a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyAnimGraphExample.animgraph +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:33ff8a4f75b5ad918a833113fb45a21e9075b66a9d0ed8563ee34d93ae905aaf -size 50863 diff --git a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset b/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset deleted file mode 100644 index e5339745ca..0000000000 --- a/Gems/EMotionFX/Code/Tests/TestAssets/EMotionFXBuilderTestAssets/LegacyMotionSetExample.motionset +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8ed5c6c8376df150ebddc8b16714012991c1892a94d2b8ad943a7f96563771e0 -size 2518 diff --git a/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph b/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph index 5138720283..ac370ff38d 100644 --- a/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph +++ b/Gems/EMotionFX/Code/Tests/TestAssets/Rin/rin.animgraph @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:33ff8a4f75b5ad918a833113fb45a21e9075b66a9d0ed8563ee34d93ae905aaf -size 50863 +oid sha256:8825feb4f0946979f8a1258cdf20bb71e358b7597eca1aaed552c2b0a17b2bd9 +size 464733 From 78b07a0869563e48cf04d258de5ddf3ac959fe65 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Mon, 26 Jul 2021 12:51:07 -0500 Subject: [PATCH 18/58] Fixing errors and streamlining more to base class Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.h | 22 ++- .../Application/AtomToolsApplication.cpp | 135 ++++++++----- .../Code/Source/MaterialEditorApplication.cpp | 187 +++--------------- .../Code/Source/MaterialEditorApplication.h | 38 +--- .../ShaderManagementConsoleApplication.cpp | 112 ++--------- .../ShaderManagementConsoleApplication.h | 30 +-- 6 files changed, 144 insertions(+), 380 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 8d3c09385c..73ba062328 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -1,3 +1,10 @@ +/* + * 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 + * + */ + #pragma once #include @@ -25,11 +32,10 @@ namespace AtomToolsFramework , protected AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler , protected AzFramework::AssetSystemStatusBus::Handler , protected AzToolsFramework::EditorPythonConsoleNotificationBus::Handler - , protected AZ::Debug::TraceMessageBus::Handler , protected AZ::UserSettingsOwnerRequestBus::Handler { public: - AZ_TYPE_INFO(AtomTools::AtomToolsApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); + AZ_TYPE_INFO(AtomTools::AtomToolsApplication, "{A0DF25BA-6F74-4F11-9F85-0F99278D5986}"); using Base = AzFramework::Application; @@ -68,14 +74,24 @@ namespace AtomToolsFramework void SaveSettings() override; ////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////// + // EditorPythonConsoleNotificationBus::Handler overrides... + void OnTraceMessage(AZStd::string_view message) override; + void OnErrorMessage(AZStd::string_view message) override; + void OnExceptionMessage(AZStd::string_view message) override; + //////////////////////////////////////////////////////////////////////// + virtual void LoadSettings(); virtual void UnloadSettings(); - virtual void CompileCriticalAssets(); + virtual void CompileCriticalAssets(const AZStd::vector &assetFiltersArray); virtual void ProcessCommandLine(const AZ::CommandLine& commandLine); virtual bool LaunchDiscoveryService(); virtual void StartInternal(); static void PyIdleWaitFrames(uint32_t frames); + void setTargetName(AZStd::string newTargetName); + + AZStd::string targetName = "AtomTools"; AzToolsFramework::TraceLogger m_traceLogger; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 464480ec53..93ea6ca499 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -1,12 +1,18 @@ /* - * 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. + * 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 +#include + +#include +#include + #include +#include #include #include #include @@ -26,15 +32,6 @@ #include #include -#include - -#include -#include - -#include - -#include - AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include #include @@ -42,15 +39,6 @@ AZ_POP_DISABLE_WARNING namespace AtomToolsFramework { - //! This function returns the build system target name of "AtomTools -// AZStd::string_view GetBuildTargetName() -// { -//#if !defined(LY_CMAKE_TARGET) -//#error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" -//#endif -// return AZStd::string_view{ LY_CMAKE_TARGET }; -// } - const char* AtomToolsApplication::GetCurrentConfigurationName() const { #if defined(_RELEASE) @@ -62,7 +50,6 @@ namespace AtomToolsFramework #endif } - AtomToolsApplication::AtomToolsApplication(int* argc, char*** argv) : Application(argc, argv) , AzQtApplication(*argc, *argv) @@ -152,22 +139,14 @@ namespace AtomToolsFramework { AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); Application::Destroy(); } - void AtomToolsApplication::CompileCriticalAssets() + void AtomToolsApplication::CompileCriticalAssets(const AZStd::vector &assetFiltersArray) { - AZ_TracePrintf("AtomTools", "Compiling critical assets.\n"); - - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::string assetFiltersArray[] = { - "passes/", - "config/", - }; + AZ_TracePrintf(targetName.c_str(), "Compiling critical assets.\n"); QStringList failedAssets; @@ -208,13 +187,14 @@ namespace AtomToolsFramework AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; + AZStd::string fileName = "@user@/" + targetName + "UserSettings.xml"; + AZ::IO::FileIOBase::GetInstance()->ResolvePath( - "@user@/MaterialEditorUserSettings.xml", resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); + fileName.c_str(), resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); m_localUserSettings.Save(resolvedPath, context); } } - void AtomToolsApplication::LoadSettings() { AZ::SerializeContext* context = nullptr; @@ -222,7 +202,9 @@ namespace AtomToolsFramework AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZ::IO::FileIOBase::GetInstance()->ResolvePath("@user@/EditorUserSettings.xml", resolvedPath, AZ_MAX_PATH_LEN); + AZStd::string fileName = "@user@/" + targetName + "UserSettings.xml"; + + AZ::IO::FileIOBase::GetInstance()->ResolvePath(fileName.c_str(), resolvedPath, AZ_MAX_PATH_LEN); m_localUserSettings.Load(resolvedPath, context); m_localUserSettings.Activate(AZ::UserSettings::CT_LOCAL); @@ -234,7 +216,7 @@ namespace AtomToolsFramework { if (m_activatedLocalUserSettings) { - //SaveSettings(); + SaveSettings(); m_localUserSettings.Deactivate(); AZ::UserSettingsOwnerRequestBus::Handler::BusDisconnect(); m_activatedLocalUserSettings = false; @@ -243,6 +225,34 @@ namespace AtomToolsFramework void AtomToolsApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) { + const AZStd::string timeoputSwitchName = "timeout"; + if (commandLine.HasSwitch(timeoputSwitchName)) + { + const AZStd::string& timeoutValue = commandLine.GetSwitchValue(timeoputSwitchName, 0); + const uint32_t timeoutInMs = atoi(timeoutValue.c_str()); + AZ_Printf(targetName.c_str(), "Timeout scheduled, shutting down in %u ms", timeoutInMs); + QTimer::singleShot( + timeoutInMs, + [this] + { + AZ_Printf(targetName.c_str(), "Timeout reached, shutting down"); + ExitMainLoop(); + }); + } + + // Process command line options for running one or more python scripts on startup + const AZStd::string runPythonScriptSwitchName = "runpython"; + size_t runPythonScriptCount = commandLine.GetNumSwitchValues(runPythonScriptSwitchName); + for (size_t runPythonScriptIndex = 0; runPythonScriptIndex < runPythonScriptCount; ++runPythonScriptIndex) + { + const AZStd::string runPythonScriptPath = commandLine.GetSwitchValue(runPythonScriptSwitchName, runPythonScriptIndex); + AZStd::vector runPythonArgs; + + AZ_Printf(targetName.c_str(), "Launching script: %s", runPythonScriptPath.c_str()); + AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast( + &AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, runPythonScriptPath, runPythonArgs); + } + const AZStd::string exitAfterCommandsSwitchName = "exitaftercommands"; if (commandLine.HasSwitch(exitAfterCommandsSwitchName)) { @@ -313,7 +323,9 @@ namespace AtomToolsFramework return; } - m_traceLogger.WriteStartupLog("AtomTools.log"); + AZStd::string fileName = targetName + ".log"; + + m_traceLogger.WriteStartupLog(fileName.c_str()); if (!LaunchDiscoveryService()) { @@ -330,23 +342,6 @@ namespace AtomToolsFramework AZ::RPI::RPISystemInterface::Get()->InitializeSystemAssets(); LoadSettings(); - - auto editorPythonEventsInterface = AZ::Interface::Get(); - if (editorPythonEventsInterface) - { - // The PythonSystemComponent does not call StartPython to allow for lazy python initialization, so start it here - // The PythonSystemComponent will call StopPython when it deactivates, so we do not need our own corresponding call to - // StopPython - editorPythonEventsInterface->StartPython(); - } - - // Delay execution of commands and scripts post initialization - QTimer::singleShot( - 0, - [this]() - { - ProcessCommandLine(m_commandLine); - }); } bool AtomToolsApplication::GetAssetDatabaseLocation(AZStd::string& result) @@ -387,6 +382,34 @@ namespace AtomToolsFramework appType.m_maskValue = AZ::ApplicationTypeQuery::Masks::Game; } + void AtomToolsApplication::OnTraceMessage([[maybe_unused]] AZStd::string_view message) + { +#if defined(AZ_ENABLE_TRACING) + AZStd::vector lines; + AzFramework::StringFunc::Tokenize( + message, lines, "\n", + false, // Keep empty strings + false // Keep space strings + ); + + for (auto& line : lines) + { + AZ_TracePrintf(targetName.c_str(), "Python: %s\n", line.c_str()); + } +#endif + } + + void AtomToolsApplication::OnErrorMessage(AZStd::string_view message) + { + // Use AZ_TracePrintf instead of AZ_Error or AZ_Warning to avoid all the metadata noise + OnTraceMessage(message); + } + + void AtomToolsApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) + { + AZ_Error(targetName.c_str(), false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); + } + // Copied from PyIdleWaitFrames in CryEdit.cpp void AtomToolsApplication::PyIdleWaitFrames(uint32_t frames) { @@ -421,5 +444,9 @@ namespace AtomToolsFramework Ticker ticker(&loop, frames); loop.exec(); } - + + void AtomToolsApplication::setTargetName(AZStd::string newTargetName) + { + targetName = newTargetName; + } } // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 4b233b0212..5e08b1e8ba 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -5,7 +5,22 @@ * */ +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include + #include +#include #include #include #include @@ -25,24 +40,9 @@ #include #include -#include - -#include -#include - #include #include -#include -#include - -#include - -#include -#include -#include -#include - AZ_PUSH_DISABLE_WARNING(4251 4800, "-Wunknown-warning-option") // disable warnings spawned by QT #include #include @@ -75,6 +75,7 @@ namespace MaterialEditor { QApplication::setApplicationName("O3DE Material Editor"); + setTargetName("MaterialEditor"); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); @@ -95,8 +96,7 @@ namespace MaterialEditor void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) { - Application::CreateStaticModules(outModules); - outModules.push_back(aznew AzToolsFramework::AzToolsFrameworkModule); + Base::CreateStaticModules(outModules); outModules.push_back(aznew MaterialDocumentModule); outModules.push_back(aznew MaterialViewportModule); outModules.push_back(aznew MaterialEditorWindowModule); @@ -108,14 +108,7 @@ namespace MaterialEditor //[GFX TODO][ATOM-408] This needs to be updated in some way to support the MaterialViewport render widget } - AzFramework::AssetSystemStatusBus::Handler::BusConnect(); - AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect(); - - AzFramework::Application::StartCommon(systemEntity); - - StartInternal(); - - m_timer.start(); + Base::StartCommon(systemEntity); } void MaterialEditorApplication::OnMaterialEditorWindowClosing() @@ -129,16 +122,9 @@ namespace MaterialEditor MaterialEditor::MaterialEditorWindowFactoryRequestBus::Broadcast( &MaterialEditor::MaterialEditorWindowFactoryRequestBus::Handler::DestroyMaterialEditorWindow); - AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); MaterialEditorWindowNotificationBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); - m_logFile = {}; - m_startupLogSink = {}; - - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); - Application::Destroy(); + Base::Destroy(); } void MaterialEditorApplication::AssetSystemAvailable() @@ -160,75 +146,17 @@ namespace MaterialEditor }; AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); - if (connectedToAssetProcessor) - { - CompileCriticalAssets(); - } - - AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); - } - - - void MaterialEditorApplication::CompileCriticalAssets() - { - AZ_TracePrintf("MaterialEditor", "Compiling critical assets.\n"); // List of common asset filters for things that need to be compiled to run the material editor // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::string assetFiltersArray[] = + const AZStd::vector assetFiltersArray = { "passes/", "config/", "MaterialEditor/" }; + + if (connectedToAssetProcessor) { - "passes/", - "config/", - "MaterialEditor/", - }; - - QStringList failedAssets; - - // Forced asset processor to synchronously process all critical assets - // Note: with AssetManager's current implementation, a compiled asset won't be added in asset registry until next system tick. - // So the asset id won't be found right after CompileAssetSync call. - for (const AZStd::string& assetFilters : assetFiltersArray) - { - AZ_TracePrintf("MaterialEditor", "Compiling critical asset matching: %s.\n", assetFilters.c_str()); - - // Wait for the asset be compiled - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilters); - if (status != AzFramework::AssetSystem::AssetStatus_Compiled) - { - failedAssets.append(assetFilters.c_str()); - } + CompileCriticalAssets(assetFiltersArray); } - if (!failedAssets.empty()) - { - QMessageBox::critical(activeWindow(), - QString("Failed to compile critical assets"), - QString("Failed to compile the following critical assets:\n%1\n%2") - .arg(failedAssets.join(",\n")) - .arg("Make sure this is an Atom project.")); - ExitMainLoop(); - } - } - - bool MaterialEditorApplication::OnOutput(const char* window, const char* message) - { - // Suppress spam from the Source Control system - if (0 == strncmp(window, AzToolsFramework::SCC_WINDOW, AZ_ARRAY_SIZE(AzToolsFramework::SCC_WINDOW))) - { - return true; - } - - if (m_logFile) - { - m_logFile->AppendLog(AzFramework::LogFile::SEV_NORMAL, window, message); - } - else - { - m_startupLogSink.push_back({ window, message }); - } - return false; + AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); } void MaterialEditorApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) @@ -286,27 +214,7 @@ namespace MaterialEditor void MaterialEditorApplication::StartInternal() { - if (WasExitMainLoopRequested()) - { - return; - } - - m_traceLogger.WriteStartupLog("MaterialEditor.log"); - - if (!LaunchDiscoveryService()) - { - ExitMainLoop(); - return; - } - - AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast(&AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); - - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::LoadCatalog, "@assets@/assetcatalog.xml"); - - AZ::RPI::RPISystemInterface::Get()->InitializeSystemAssets(); - - LoadSettings(); + Base::StartInternal(); MaterialEditorWindowNotificationBus::Handler::BusConnect(); @@ -325,54 +233,11 @@ namespace MaterialEditor QTimer::singleShot(0, [this]() { ProcessCommandLine(m_commandLine); }); } - void MaterialEditorApplication::Tick(float deltaOverride) - { - TickSystem(); - Application::Tick(deltaOverride); - - if (WasExitMainLoopRequested()) - { - m_timer.disconnect(); - quit(); - } - } - void MaterialEditorApplication::Stop() { MaterialEditor::MaterialEditorWindowFactoryRequestBus::Broadcast( &MaterialEditor::MaterialEditorWindowFactoryRequestBus::Handler::DestroyMaterialEditorWindow); - UnloadSettings(); - AzFramework::Application::Stop(); - } - - void MaterialEditorApplication::OnTraceMessage([[maybe_unused]] AZStd::string_view message) - { -#if defined(AZ_ENABLE_TRACING) - AZStd::vector lines; - AzFramework::StringFunc::Tokenize( - message, - lines, - "\n", - false, // Keep empty strings - false // Keep space strings - ); - - for (auto& line : lines) - { - AZ_TracePrintf("MaterialEditor", "Python: %s\n", line.c_str()); - } -#endif - } - - void MaterialEditorApplication::OnErrorMessage(AZStd::string_view message) - { - // Use AZ_TracePrintf instead of AZ_Error or AZ_Warning to avoid all the metadata noise - OnTraceMessage(message); - } - - void MaterialEditorApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) - { - AZ_Error("MaterialEditor", false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); + Base::Stop(); } } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index d398f4406d..92f4223f99 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -9,19 +9,6 @@ #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -47,7 +34,6 @@ namespace MaterialEditor void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; void StartCommon(AZ::Entity* systemEntity) override; - void Tick(float deltaOverride = -1.f) override; void Stop() override; private: @@ -61,34 +47,12 @@ namespace MaterialEditor void Destroy() override; ////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////// - // EditorPythonConsoleNotificationBus::Handler overrides... - void OnTraceMessage(AZStd::string_view message) override; - void OnErrorMessage(AZStd::string_view message) override; - void OnExceptionMessage(AZStd::string_view message) override; - //////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // AzFramework::AssetSystemStatusBus::Handler overrides... void AssetSystemAvailable() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AZ::Debug::TraceMessageBus::Handler overrides... - bool OnOutput(const char* window, const char* message) override; - ////////////////////////////////////////////////////////////////////////// - - void CompileCriticalAssets() override; void ProcessCommandLine(const AZ::CommandLine& commandLine) override; void StartInternal() override; - - struct LogMessage - { - AZStd::string window; - AZStd::string message; - }; - - AZStd::vector m_startupLogSink; - AZStd::unique_ptr m_logFile; - }; + }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 4a3f5dd02d..2ad61b9e3f 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -70,6 +70,7 @@ namespace ShaderManagementConsole : AtomToolsApplication(argc, argv) { QApplication::setApplicationName("O3DE Shader Management Console"); + setTargetName("ShaderManagementConsole"); // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( @@ -98,7 +99,6 @@ namespace ShaderManagementConsole ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); - AZ::Debug::TraceMessageBus::Handler::BusDisconnect(); AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); @@ -129,66 +129,28 @@ namespace ShaderManagementConsole }; AzFramework::AssetSystemRequestBus::Broadcast(ConnectToAssetProcessorWithIdentifier); + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + const AZStd::vector assetFiltersArray = { "passes/", "config/"}; + if (connected) { - CompileCriticalAssets(); + CompileCriticalAssets(assetFiltersArray); } AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); } - void ShaderManagementConsoleApplication::CompileCriticalAssets() - { - AZ_TracePrintf("Shader Management Console", "Compiling critical assets.\n"); - - // List of common asset filters for things that need to be compiled to run - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::string assetFilterss[] = - { - "passes/", - "config/", - }; - - QStringList failedAssets; - - // Forced asset processor to synchronously process all critical assets - // Note: with AssetManager's current implementation, a compiled asset won't be added in asset registry until next system tick. - // So the asset id won't be found right after CompileAssetSync call. - for (const AZStd::string& assetFilters : assetFilterss) - { - AZ_TracePrintf("Shader Management Console", "Compiling critical asset matching: %s.\n", assetFilters.c_str()); - - // Wait for the asset be compiled - AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; - AzFramework::AssetSystemRequestBus::BroadcastResult( - status, &AzFramework::AssetSystemRequestBus::Events::CompileAssetSync, assetFilters); - if (status != AzFramework::AssetSystem::AssetStatus_Compiled) - { - failedAssets.append(assetFilters.c_str()); - } - } - - if (!failedAssets.empty()) - { - QMessageBox::critical(activeWindow(), - QString("Failed to compile critical assets"), - QString("Failed to compile the following critical assets:\n%1\n%2") - .arg(failedAssets.join(",\n")) - .arg("Make sure this is an Atom project.")); - ExitMainLoop(); - } - } - - bool ShaderManagementConsoleApplication::OnPrintf(const char* window, const char* /*message*/) - { - // Suppress spam from the Source Control system - if (0 == strncmp(window, AzToolsFramework::SCC_WINDOW, AZ_ARRAY_SIZE(AzToolsFramework::SCC_WINDOW))) - { - return true; - } - - return false; - } +// bool ShaderManagementConsoleApplication::OnPrintf(const char* window, const char* /*message*/) +// { +// // Suppress spam from the Source Control system +// if (0 == strncmp(window, AzToolsFramework::SCC_WINDOW, AZ_ARRAY_SIZE(AzToolsFramework::SCC_WINDOW))) +// { +// return true; +// } +// +// return false; +// } void ShaderManagementConsoleApplication::ProcessCommandLine() { @@ -263,46 +225,4 @@ namespace ShaderManagementConsole return false; } - - void ShaderManagementConsoleApplication::Tick(float deltaOverride) - { - TickSystem(); - Application::Tick(deltaOverride); - - if (WasExitMainLoopRequested()) - { - m_timer.disconnect(); - quit(); - } - } - - void ShaderManagementConsoleApplication::OnTraceMessage([[maybe_unused]] AZStd::string_view message) - { -#if defined(AZ_ENABLE_TRACING) - AZStd::vector lines; - AzFramework::StringFunc::Tokenize( - message, - lines, - "\n", - false, // Keep empty strings - false // Keep space strings - ); - - for (auto& line : lines) - { - AZ_TracePrintf("Shader Management Console", "Python: %s\n", line.c_str()); - } -#endif - } - - void ShaderManagementConsoleApplication::OnErrorMessage(AZStd::string_view message) - { - // Use AZ_TracePrintf instead of AZ_Error or AZ_Warning to avoid all the metadata noise - OnTraceMessage(message); - } - - void ShaderManagementConsoleApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) - { - AZ_Error("Shader Management Console", false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); - } } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index d99d814627..7c4f53f4e9 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -7,22 +7,8 @@ #pragma once -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - #include #include - -#include #include #include @@ -34,7 +20,7 @@ namespace ShaderManagementConsole , private ShaderManagementConsoleWindowNotificationBus::Handler { public: - AZ_TYPE_INFO(ShaderManagementConsole::ShaderManagementConsoleApplication, "{30F90CA5-1253-49B5-8143-19CEE37E22BB}"); + AZ_TYPE_INFO(ShaderManagementConsole::ShaderManagementConsoleApplication, "{A31B1AEB-4DA3-49CD-884A-CC998FF7546F}"); using Base = AzFramework::Application; @@ -45,7 +31,6 @@ namespace ShaderManagementConsole // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; - void Tick(float deltaOverride = -1.f) override; private: ////////////////////////////////////////////////////////////////////////// @@ -63,24 +48,11 @@ namespace ShaderManagementConsole void Destroy() override; ////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////// - // EditorPythonConsoleNotificationBus::Handler overrides... - void OnTraceMessage(AZStd::string_view message) override; - void OnErrorMessage(AZStd::string_view message) override; - void OnExceptionMessage(AZStd::string_view message) override; - //////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // AzFramework::AssetSystemStatusBus::Handler overrides... void AssetSystemAvailable() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AZ::Debug::TraceMessageBus::Handler overrides... - bool OnPrintf(const char* window, const char* message) override; - ////////////////////////////////////////////////////////////////////////// - - void CompileCriticalAssets() override; void ProcessCommandLine(); void StartInternal() override; }; From 4306b57230ca1830f41e645cf021e305b6518e12 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Mon, 26 Jul 2021 13:08:59 -0500 Subject: [PATCH 19/58] More replacement with target name Signed-off-by: Dayo Lawal --- .../AtomToolsFramework/Application/AtomToolsApplication.h | 2 ++ .../Code/Source/MaterialEditorApplication.cpp | 2 +- .../Code/Source/ShaderManagementConsoleApplication.cpp | 8 ++------ 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 73ba062328..1ee73ee9fb 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -81,6 +81,8 @@ namespace AtomToolsFramework void OnExceptionMessage(AZStd::string_view message) override; //////////////////////////////////////////////////////////////////////// + virtual AZStd::string_view GetBuildTargetName() {return targetName;}; + virtual void LoadSettings(); virtual void UnloadSettings(); virtual void CompileCriticalAssets(const AZStd::vector &assetFiltersArray); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 5e08b1e8ba..038005891d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -139,7 +139,7 @@ namespace MaterialEditor AzFramework::AssetSystem::ConnectionSettings connectionSettings; AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); connectionSettings.m_connectionDirection = AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; - connectionSettings.m_connectionIdentifier = "MaterialEditor"; + connectionSettings.m_connectionIdentifier = targetName.c_str(); connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) { AZ_TracePrintf("Material Editor", "%.*s", aznumeric_cast(logData.size()), logData.data()); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 2ad61b9e3f..48c246f938 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -79,8 +79,7 @@ namespace ShaderManagementConsole void ShaderManagementConsoleApplication::CreateStaticModules(AZStd::vector& outModules) { - Application::CreateStaticModules(outModules); - outModules.push_back(aznew AzToolsFramework::AzToolsFrameworkModule); + Base::CreateStaticModules(outModules); outModules.push_back(aznew ShaderManagementConsoleDocumentModule); outModules.push_back(aznew ShaderManagementConsoleWindowModule); } @@ -98,11 +97,8 @@ namespace ShaderManagementConsole ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Broadcast(&ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Handler::DestroyShaderManagementConsoleWindow); ShaderManagementConsoleWindowNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); - AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); - - Application::Destroy(); + Base::Destroy(); } void ShaderManagementConsoleApplication::AssetSystemAvailable() From a87318c52a3df6148cece8eb431fdc21cc964d51 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 26 Jul 2021 11:31:34 -0700 Subject: [PATCH 20/58] temporarily disable SC unit tests on Linux until a file case issue is solved Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Framework/ScriptCanvasGraphUtilities.inl | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl index 96febf8553..8bb2fe8c29 100644 --- a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl +++ b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl @@ -20,6 +20,7 @@ #include #include #include +#include namespace ScriptCanvasEditor { @@ -223,6 +224,22 @@ namespace ScriptCanvasEditor if (!dependencies.empty()) { + +#if defined(LINUX) ////////////////////////////////////////////////////////////////////////// + + // Temporarily disable testing on the Linux build until the casing discrepancy + // is sorted out through the SC build and testing pipeline. + + auto graphEntityId = AZ::Entity::MakeId(); + reporter.SetGraph(graphEntityId); + loadResult.m_entity->Activate(); + ScriptCanvas::UnitTesting::EventSender::MarkComplete(graphEntityId, ""); + loadResult.m_entity->Deactivate(); + reporter.FinishReport(); + ScriptCanvas::SystemRequestBus::Broadcast(&ScriptCanvas::SystemRequests::MarkScriptUnitTestEnd); + return; +#else /////////////////////////////////////////////////////////////////////////////////////// + // #functions2_recursive_unit_tests eventually, this will need to be recursive, or the full asset handling system will need to be integrated into the testing framework // in order to test functionality with a dependency stack greater than 2 @@ -256,6 +273,7 @@ namespace ScriptCanvasEditor Execution::Context::InitializeActivationData(dependencyData); Execution::InitializeInterpretedStatics(dependencyData); } +#endif ////////////////////////////////////////////////////////////////////////////////////// } loadResult.m_scriptAsset = luaAssetResult.m_scriptAsset; From 91e84f15884db4408ca235bd7ffe58c9b736063a Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 26 Jul 2021 11:37:38 -0700 Subject: [PATCH 21/58] remove smoke tag now that Linux tests are disabled Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index dada433772..23c9627e83 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -113,7 +113,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests - TEST_SUITE smoke ) endif() From 3ad8f0dbf9dbb075c00bfff3bdbfb27104ac3bf1 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Mon, 26 Jul 2021 13:20:08 -0700 Subject: [PATCH 22/58] adjust location of disabling SC unit tests on Linux Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Framework/ScriptCanvasGraphUtilities.inl | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl index 2048fea08a..4b22864b6e 100644 --- a/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl +++ b/Gems/ScriptCanvas/Code/Editor/Framework/ScriptCanvasGraphUtilities.inl @@ -218,19 +218,14 @@ namespace ScriptCanvasEditor if (!reporter.IsProcessOnly()) { - dependencies = LoadInterpretedDepencies(luaAssetResult.m_dependencies.source.userSubgraphs); - RuntimeDataOverrides runtimeDataOverrides; runtimeDataOverrides.m_runtimeAsset = loadResult.m_runtimeAsset; - if (!dependencies.empty()) - { - #if defined(LINUX) ////////////////////////////////////////////////////////////////////////// - - // Temporarily disable testing on the Linux build until the casing discrepancy - // is sorted out through the SC build and testing pipeline. - + // Temporarily disable testing on the Linux build until the file name casing discrepancy + // is sorted out through the SC build and testing pipeline. + if (!luaAssetResult.m_dependencies.source.userSubgraphs.empty()) + { auto graphEntityId = AZ::Entity::MakeId(); reporter.SetGraph(graphEntityId); loadResult.m_entity->Activate(); @@ -239,8 +234,13 @@ namespace ScriptCanvasEditor reporter.FinishReport(); ScriptCanvas::SystemRequestBus::Broadcast(&ScriptCanvas::SystemRequests::MarkScriptUnitTestEnd); return; + } #else /////////////////////////////////////////////////////////////////////////////////////// + dependencies = LoadInterpretedDepencies(luaAssetResult.m_dependencies.source.userSubgraphs); + + if (!dependencies.empty()) + { // #functions2_recursive_unit_tests eventually, this will need to be recursive, or the full asset handling system will need to be integrated into the testing framework // in order to test functionality with a dependency stack greater than 2 @@ -274,8 +274,8 @@ namespace ScriptCanvasEditor Execution::Context::InitializeActivationData(dependencyData); Execution::InitializeInterpretedStatics(dependencyData); } -#endif ////////////////////////////////////////////////////////////////////////////////////// } +#endif ////////////////////////////////////////////////////////////////////////////////////// loadResult.m_scriptAsset = luaAssetResult.m_scriptAsset; loadResult.m_runtimeAsset.Get()->GetData().m_script = loadResult.m_scriptAsset; From 50f6ea83852a821ef86e8f9cc5d1ec586a8fe89f Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Mon, 26 Jul 2021 16:22:34 -0500 Subject: [PATCH 23/58] Using GetBuildTargetName() and other fixes Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.h | 7 +-- .../Application/AtomToolsApplication.cpp | 33 ++++++------- .../Code/Source/MaterialEditorApplication.cpp | 47 ++++--------------- .../Code/Source/MaterialEditorApplication.h | 1 + .../ShaderManagementConsoleApplication.cpp | 23 +++------ .../ShaderManagementConsoleApplication.h | 1 + 6 files changed, 32 insertions(+), 80 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 1ee73ee9fb..daec30f7d7 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -11,11 +11,9 @@ #include #include #include -#include #include #include #include -#include #include #include #include @@ -81,7 +79,7 @@ namespace AtomToolsFramework void OnExceptionMessage(AZStd::string_view message) override; //////////////////////////////////////////////////////////////////////// - virtual AZStd::string_view GetBuildTargetName() {return targetName;}; + virtual AZStd::string_view GetBuildTargetName() {return m_targetName;}; virtual void LoadSettings(); virtual void UnloadSettings(); @@ -91,9 +89,8 @@ namespace AtomToolsFramework virtual void StartInternal(); static void PyIdleWaitFrames(uint32_t frames); - void setTargetName(AZStd::string newTargetName); - AZStd::string targetName = "AtomTools"; + AZStd::string m_targetName = "AtomTools"; AzToolsFramework::TraceLogger m_traceLogger; diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 93ea6ca499..c8f1bebe3a 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -119,7 +119,7 @@ namespace AtomToolsFramework void AtomToolsApplication::CreateStaticModules(AZStd::vector& outModules) { - Application::CreateStaticModules(outModules); + Base::CreateStaticModules(outModules); outModules.push_back(aznew AzToolsFramework::AzToolsFrameworkModule); } @@ -128,7 +128,7 @@ namespace AtomToolsFramework AzFramework::AssetSystemStatusBus::Handler::BusConnect(); AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusConnect(); - AzFramework::Application::StartCommon(systemEntity); + Base::StartCommon(systemEntity); StartInternal(); @@ -141,12 +141,12 @@ namespace AtomToolsFramework AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusDisconnect(); AzFramework::AssetSystemRequestBus::Broadcast(&AzFramework::AssetSystem::AssetSystemRequests::StartDisconnectingAssetProcessor); - Application::Destroy(); + Base::Destroy(); } void AtomToolsApplication::CompileCriticalAssets(const AZStd::vector &assetFiltersArray) { - AZ_TracePrintf(targetName.c_str(), "Compiling critical assets.\n"); + AZ_TracePrintf(m_targetName.c_str(), "Compiling critical assets.\n"); QStringList failedAssets; @@ -155,7 +155,7 @@ namespace AtomToolsFramework // So the asset id won't be found right after CompileAssetSync call. for (const AZStd::string& assetFilters : assetFiltersArray) { - AZ_TracePrintf("AtomTools", "Compiling critical asset matching: %s.\n", assetFilters.c_str()); + AZ_TracePrintf(m_targetName.c_str(), "Compiling critical asset matching: %s.\n", assetFilters.c_str()); // Wait for the asset be compiled AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; @@ -187,7 +187,7 @@ namespace AtomToolsFramework AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZStd::string fileName = "@user@/" + targetName + "UserSettings.xml"; + AZStd::string fileName = "@user@/" + m_targetName + "UserSettings.xml"; AZ::IO::FileIOBase::GetInstance()->ResolvePath( fileName.c_str(), resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); @@ -202,7 +202,7 @@ namespace AtomToolsFramework AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZStd::string fileName = "@user@/" + targetName + "UserSettings.xml"; + AZStd::string fileName = "@user@/" + m_targetName + "UserSettings.xml"; AZ::IO::FileIOBase::GetInstance()->ResolvePath(fileName.c_str(), resolvedPath, AZ_MAX_PATH_LEN); @@ -230,12 +230,12 @@ namespace AtomToolsFramework { const AZStd::string& timeoutValue = commandLine.GetSwitchValue(timeoputSwitchName, 0); const uint32_t timeoutInMs = atoi(timeoutValue.c_str()); - AZ_Printf(targetName.c_str(), "Timeout scheduled, shutting down in %u ms", timeoutInMs); + AZ_Printf(m_targetName.c_str(), "Timeout scheduled, shutting down in %u ms", timeoutInMs); QTimer::singleShot( timeoutInMs, [this] { - AZ_Printf(targetName.c_str(), "Timeout reached, shutting down"); + AZ_Printf(m_targetName.c_str(), "Timeout reached, shutting down"); ExitMainLoop(); }); } @@ -248,7 +248,7 @@ namespace AtomToolsFramework const AZStd::string runPythonScriptPath = commandLine.GetSwitchValue(runPythonScriptSwitchName, runPythonScriptIndex); AZStd::vector runPythonArgs; - AZ_Printf(targetName.c_str(), "Launching script: %s", runPythonScriptPath.c_str()); + AZ_Printf(m_targetName.c_str(), "Launching script: %s", runPythonScriptPath.c_str()); AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast( &AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, runPythonScriptPath, runPythonArgs); } @@ -323,7 +323,7 @@ namespace AtomToolsFramework return; } - AZStd::string fileName = targetName + ".log"; + AZStd::string fileName = m_targetName + ".log"; m_traceLogger.WriteStartupLog(fileName.c_str()); @@ -374,7 +374,7 @@ namespace AtomToolsFramework void AtomToolsApplication::Stop() { UnloadSettings(); - AzFramework::Application::Stop(); + Base::Stop(); } void AtomToolsApplication::QueryApplicationType(AZ::ApplicationTypeQuery& appType) const @@ -394,7 +394,7 @@ namespace AtomToolsFramework for (auto& line : lines) { - AZ_TracePrintf(targetName.c_str(), "Python: %s\n", line.c_str()); + AZ_TracePrintf(m_targetName.c_str(), "Python: %s\n", line.c_str()); } #endif } @@ -407,7 +407,7 @@ namespace AtomToolsFramework void AtomToolsApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) { - AZ_Error(targetName.c_str(), false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); + AZ_Error(m_targetName.c_str(), false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); } // Copied from PyIdleWaitFrames in CryEdit.cpp @@ -444,9 +444,4 @@ namespace AtomToolsFramework Ticker ticker(&loop, frames); loop.exec(); } - - void AtomToolsApplication::setTargetName(AZStd::string newTargetName) - { - targetName = newTargetName; - } } // namespace AtomToolsFramework diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 038005891d..0b4165cce0 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -51,7 +51,7 @@ AZ_POP_DISABLE_WARNING namespace MaterialEditor { //! This function returns the build system target name of "MaterialEditor - AZStd::string_view GetBuildTargetName() + AZStd::string_view MaterialEditorApplication::GetBuildTargetName() { #if !defined (LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" @@ -75,7 +75,7 @@ namespace MaterialEditor { QApplication::setApplicationName("O3DE Material Editor"); - setTargetName("MaterialEditor"); + m_targetName = GetBuildTargetName(); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); @@ -139,7 +139,7 @@ namespace MaterialEditor AzFramework::AssetSystem::ConnectionSettings connectionSettings; AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); connectionSettings.m_connectionDirection = AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; - connectionSettings.m_connectionIdentifier = targetName.c_str(); + connectionSettings.m_connectionIdentifier = GetBuildTargetName(); connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) { AZ_TracePrintf("Material Editor", "%.*s", aznumeric_cast(logData.size()), logData.data()); @@ -147,12 +147,12 @@ namespace MaterialEditor AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::vector assetFiltersArray = { "passes/", "config/", "MaterialEditor/" }; - if (connectedToAssetProcessor) { + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + const AZStd::vector assetFiltersArray = { "passes/", "config/", "MaterialEditor/" }; + CompileCriticalAssets(assetFiltersArray); } @@ -168,33 +168,6 @@ namespace MaterialEditor &MaterialEditor::MaterialEditorWindowRequestBus::Handler::ActivateWindow); } - const AZStd::string timeoputSwitchName = "timeout"; - if (commandLine.HasSwitch(timeoputSwitchName)) - { - const AZStd::string& timeoutValue = commandLine.GetSwitchValue(timeoputSwitchName, 0); - const uint32_t timeoutInMs = atoi(timeoutValue.c_str()); - AZ_Printf("MaterialEditor", "Timeout scheduled, shutting down in %u ms", timeoutInMs); - QTimer::singleShot(timeoutInMs, [this] { - AZ_Printf("MaterialEditor", "Timeout reached, shutting down"); - ExitMainLoop(); - }); - } - - // Process command line options for running one or more python scripts on startup - const AZStd::string runPythonScriptSwitchName = "runpython"; - size_t runPythonScriptCount = commandLine.GetNumSwitchValues(runPythonScriptSwitchName); - for (size_t runPythonScriptIndex = 0; runPythonScriptIndex < runPythonScriptCount; ++runPythonScriptIndex) - { - const AZStd::string runPythonScriptPath = commandLine.GetSwitchValue(runPythonScriptSwitchName, runPythonScriptIndex); - AZStd::vector runPythonArgs; - - AZ_Printf("MaterialEditor", "Launching script: %s", runPythonScriptPath.c_str()); - AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast( - &AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, - runPythonScriptPath, - runPythonArgs); - } - // Process command line options for opening one or more material documents on startup size_t openDocumentCount = commandLine.GetNumMiscValues(); for (size_t openDocumentIndex = 0; openDocumentIndex < openDocumentCount; ++openDocumentIndex) @@ -205,11 +178,7 @@ namespace MaterialEditor MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); } - const AZStd::string exitAfterCommandsSwitchName = "exitaftercommands"; - if (commandLine.HasSwitch(exitAfterCommandsSwitchName)) - { - ExitMainLoop(); - } + Base::ProcessCommandLine(commandLine); } void MaterialEditorApplication::StartInternal() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 92f4223f99..0739fa6ae1 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -54,5 +54,6 @@ namespace MaterialEditor void ProcessCommandLine(const AZ::CommandLine& commandLine) override; void StartInternal() override; + AZStd::string_view GetBuildTargetName() override; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 48c246f938..5cb98a4345 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -47,7 +47,7 @@ AZ_POP_DISABLE_WARNING namespace ShaderManagementConsole { - AZStd::string_view GetBuildTargetName() + AZStd::string_view ShaderManagementConsoleApplication::GetBuildTargetName() { #if !defined (LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" @@ -70,7 +70,7 @@ namespace ShaderManagementConsole : AtomToolsApplication(argc, argv) { QApplication::setApplicationName("O3DE Shader Management Console"); - setTargetName("ShaderManagementConsole"); + m_targetName = GetBuildTargetName(); // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( @@ -125,29 +125,18 @@ namespace ShaderManagementConsole }; AzFramework::AssetSystemRequestBus::Broadcast(ConnectToAssetProcessorWithIdentifier); - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::vector assetFiltersArray = { "passes/", "config/"}; - if (connected) { + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + const AZStd::vector assetFiltersArray = { "passes/", "config/" }; + CompileCriticalAssets(assetFiltersArray); } AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); } -// bool ShaderManagementConsoleApplication::OnPrintf(const char* window, const char* /*message*/) -// { -// // Suppress spam from the Source Control system -// if (0 == strncmp(window, AzToolsFramework::SCC_WINDOW, AZ_ARRAY_SIZE(AzToolsFramework::SCC_WINDOW))) -// { -// return true; -// } -// -// return false; -// } - void ShaderManagementConsoleApplication::ProcessCommandLine() { // Process command line options for running one or more python scripts on startup diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 7c4f53f4e9..277d3ef1e3 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -55,5 +55,6 @@ namespace ShaderManagementConsole void ProcessCommandLine(); void StartInternal() override; + AZStd::string_view GetBuildTargetName() override; }; } // namespace ShaderManagementConsole From 7122f1b7618d0e22dccaab8852252c77d2c0b229 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Mon, 26 Jul 2021 17:41:10 -0500 Subject: [PATCH 24/58] More refractoring Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.h | 4 +- .../Application/AtomToolsApplication.cpp | 42 +++++++++++++---- .../Code/Source/MaterialEditorApplication.cpp | 25 +--------- .../Code/Source/MaterialEditorApplication.h | 3 +- .../ShaderManagementConsoleApplication.cpp | 46 +------------------ .../ShaderManagementConsoleApplication.h | 9 +--- 6 files changed, 40 insertions(+), 89 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index daec30f7d7..9d412ec477 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -79,7 +79,7 @@ namespace AtomToolsFramework void OnExceptionMessage(AZStd::string_view message) override; //////////////////////////////////////////////////////////////////////// - virtual AZStd::string_view GetBuildTargetName() {return m_targetName;}; + virtual AZStd::string GetBuildTargetName(); virtual void LoadSettings(); virtual void UnloadSettings(); @@ -90,8 +90,6 @@ namespace AtomToolsFramework static void PyIdleWaitFrames(uint32_t frames); - AZStd::string m_targetName = "AtomTools"; - AzToolsFramework::TraceLogger m_traceLogger; //! Local user settings are used to store material browser tree expansion state diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index c8f1bebe3a..1ad2048ae4 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -39,6 +39,11 @@ AZ_POP_DISABLE_WARNING namespace AtomToolsFramework { + AZStd::string AtomToolsApplication::GetBuildTargetName() + { + return AZStd::string("AtomTools"); + } + const char* AtomToolsApplication::GetCurrentConfigurationName() const { #if defined(_RELEASE) @@ -146,7 +151,7 @@ namespace AtomToolsFramework void AtomToolsApplication::CompileCriticalAssets(const AZStd::vector &assetFiltersArray) { - AZ_TracePrintf(m_targetName.c_str(), "Compiling critical assets.\n"); + AZ_TracePrintf(GetBuildTargetName().c_str(), "Compiling critical assets.\n"); QStringList failedAssets; @@ -155,7 +160,7 @@ namespace AtomToolsFramework // So the asset id won't be found right after CompileAssetSync call. for (const AZStd::string& assetFilters : assetFiltersArray) { - AZ_TracePrintf(m_targetName.c_str(), "Compiling critical asset matching: %s.\n", assetFilters.c_str()); + AZ_TracePrintf(GetBuildTargetName().c_str(), "Compiling critical asset matching: %s.\n", assetFilters.c_str()); // Wait for the asset be compiled AzFramework::AssetSystem::AssetStatus status = AzFramework::AssetSystem::AssetStatus_Unknown; @@ -187,7 +192,7 @@ namespace AtomToolsFramework AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZStd::string fileName = "@user@/" + m_targetName + "UserSettings.xml"; + AZStd::string fileName = "@user@/" + GetBuildTargetName() + "UserSettings.xml"; AZ::IO::FileIOBase::GetInstance()->ResolvePath( fileName.c_str(), resolvedPath, AZ_ARRAY_SIZE(resolvedPath)); @@ -202,7 +207,7 @@ namespace AtomToolsFramework AZ_Assert(context, "No serialize context"); char resolvedPath[AZ_MAX_PATH_LEN] = ""; - AZStd::string fileName = "@user@/" + m_targetName + "UserSettings.xml"; + AZStd::string fileName = "@user@/" + GetBuildTargetName() + "UserSettings.xml"; AZ::IO::FileIOBase::GetInstance()->ResolvePath(fileName.c_str(), resolvedPath, AZ_MAX_PATH_LEN); @@ -230,12 +235,12 @@ namespace AtomToolsFramework { const AZStd::string& timeoutValue = commandLine.GetSwitchValue(timeoputSwitchName, 0); const uint32_t timeoutInMs = atoi(timeoutValue.c_str()); - AZ_Printf(m_targetName.c_str(), "Timeout scheduled, shutting down in %u ms", timeoutInMs); + AZ_Printf(GetBuildTargetName().c_str(), "Timeout scheduled, shutting down in %u ms", timeoutInMs); QTimer::singleShot( timeoutInMs, [this] { - AZ_Printf(m_targetName.c_str(), "Timeout reached, shutting down"); + AZ_Printf(GetBuildTargetName().c_str(), "Timeout reached, shutting down"); ExitMainLoop(); }); } @@ -248,7 +253,7 @@ namespace AtomToolsFramework const AZStd::string runPythonScriptPath = commandLine.GetSwitchValue(runPythonScriptSwitchName, runPythonScriptIndex); AZStd::vector runPythonArgs; - AZ_Printf(m_targetName.c_str(), "Launching script: %s", runPythonScriptPath.c_str()); + AZ_Printf(GetBuildTargetName().c_str(), "Launching script: %s", runPythonScriptPath.c_str()); AzToolsFramework::EditorPythonRunnerRequestBus::Broadcast( &AzToolsFramework::EditorPythonRunnerRequestBus::Events::ExecuteByFilenameWithArgs, runPythonScriptPath, runPythonArgs); } @@ -323,7 +328,7 @@ namespace AtomToolsFramework return; } - AZStd::string fileName = m_targetName + ".log"; + AZStd::string fileName = GetBuildTargetName() + ".log"; m_traceLogger.WriteStartupLog(fileName.c_str()); @@ -342,6 +347,23 @@ namespace AtomToolsFramework AZ::RPI::RPISystemInterface::Get()->InitializeSystemAssets(); LoadSettings(); + + auto editorPythonEventsInterface = AZ::Interface::Get(); + if (editorPythonEventsInterface) + { + // The PythonSystemComponent does not call StartPython to allow for lazy python initialization, so start it here + // The PythonSystemComponent will call StopPython when it deactivates, so we do not need our own corresponding call to + // StopPython + editorPythonEventsInterface->StartPython(); + } + + // Delay execution of commands and scripts post initialization + QTimer::singleShot( + 0, + [this]() + { + ProcessCommandLine(m_commandLine); + }); } bool AtomToolsApplication::GetAssetDatabaseLocation(AZStd::string& result) @@ -394,7 +416,7 @@ namespace AtomToolsFramework for (auto& line : lines) { - AZ_TracePrintf(m_targetName.c_str(), "Python: %s\n", line.c_str()); + AZ_TracePrintf(GetBuildTargetName().c_str(), "Python: %s\n", line.c_str()); } #endif } @@ -407,7 +429,7 @@ namespace AtomToolsFramework void AtomToolsApplication::OnExceptionMessage([[maybe_unused]] AZStd::string_view message) { - AZ_Error(m_targetName.c_str(), false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); + AZ_Error(GetBuildTargetName().c_str(), false, "Python: " AZ_STRING_FORMAT, AZ_STRING_ARG(message)); } // Copied from PyIdleWaitFrames in CryEdit.cpp diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 0b4165cce0..6832ca683c 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -51,12 +51,12 @@ AZ_POP_DISABLE_WARNING namespace MaterialEditor { //! This function returns the build system target name of "MaterialEditor - AZStd::string_view MaterialEditorApplication::GetBuildTargetName() + AZStd::string MaterialEditorApplication::GetBuildTargetName() { #if !defined (LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" #endif - return AZStd::string_view{ LY_CMAKE_TARGET }; + return AZStd::string{ LY_CMAKE_TARGET }; } const char* MaterialEditorApplication::GetCurrentConfigurationName() const @@ -75,7 +75,6 @@ namespace MaterialEditor { QApplication::setApplicationName("O3DE Material Editor"); - m_targetName = GetBuildTargetName(); AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); @@ -102,15 +101,6 @@ namespace MaterialEditor outModules.push_back(aznew MaterialEditorWindowModule); } - void MaterialEditorApplication::StartCommon(AZ::Entity* systemEntity) - { - { - //[GFX TODO][ATOM-408] This needs to be updated in some way to support the MaterialViewport render widget - } - - Base::StartCommon(systemEntity); - } - void MaterialEditorApplication::OnMaterialEditorWindowClosing() { ExitMainLoop(); @@ -189,17 +179,6 @@ namespace MaterialEditor MaterialEditor::MaterialEditorWindowFactoryRequestBus::Broadcast( &MaterialEditor::MaterialEditorWindowFactoryRequestBus::Handler::CreateMaterialEditorWindow); - - auto editorPythonEventsInterface = AZ::Interface::Get(); - if (editorPythonEventsInterface) - { - // The PythonSystemComponent does not call StartPython to allow for lazy python initialization, so start it here - // The PythonSystemComponent will call StopPython when it deactivates, so we do not need our own corresponding call to StopPython - editorPythonEventsInterface->StartPython(); - } - - // Delay execution of commands and scripts post initialization - QTimer::singleShot(0, [this]() { ProcessCommandLine(m_commandLine); }); } void MaterialEditorApplication::Stop() diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 0739fa6ae1..1139a73827 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -33,7 +33,6 @@ namespace MaterialEditor // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; const char* GetCurrentConfigurationName() const override; - void StartCommon(AZ::Entity* systemEntity) override; void Stop() override; private: @@ -54,6 +53,6 @@ namespace MaterialEditor void ProcessCommandLine(const AZ::CommandLine& commandLine) override; void StartInternal() override; - AZStd::string_view GetBuildTargetName() override; + AZStd::string GetBuildTargetName() override; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 5cb98a4345..6d5e331c75 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -47,7 +47,7 @@ AZ_POP_DISABLE_WARNING namespace ShaderManagementConsole { - AZStd::string_view ShaderManagementConsoleApplication::GetBuildTargetName() + AZStd::string ShaderManagementConsoleApplication::GetBuildTargetName() { #if !defined (LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" @@ -70,7 +70,6 @@ namespace ShaderManagementConsole : AtomToolsApplication(argc, argv) { QApplication::setApplicationName("O3DE Shader Management Console"); - m_targetName = GetBuildTargetName(); // The settings registry has been created at this point, so add the CMake target AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( @@ -163,51 +162,10 @@ namespace ShaderManagementConsole void ShaderManagementConsoleApplication::StartInternal() { - if (WasExitMainLoopRequested()) - { - return; - } - - m_traceLogger.WriteStartupLog("ShaderManagementConsole.log"); - - //[GFX TODO][ATOM-415] Try to factor out some of this stuff with AtomSampleViewerApplication - AzToolsFramework::AssetDatabase::AssetDatabaseRequestsBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotificationBus::Broadcast(&AzToolsFramework::AssetBrowser::AssetDatabaseLocationNotifications::OnDatabaseInitialized); - - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::LoadCatalog, "@assets@/assetcatalog.xml"); - - AZ::RPI::RPISystemInterface::Get()->InitializeSystemAssets(); - - LoadSettings(); - - LaunchDiscoveryService(); + Base::StartInternal(); ShaderManagementConsoleWindowNotificationBus::Handler::BusConnect(); ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Broadcast(&ShaderManagementConsole::ShaderManagementConsoleWindowRequestBus::Handler::CreateShaderManagementConsoleWindow); - - auto editorPythonEventsInterface = AZ::Interface::Get(); - if (editorPythonEventsInterface) - { - // The PythonSystemComponent does not call StartPython to allow for lazy python initialization, so start it here - // The PythonSystemComponent will call StopPython when it deactivates, so we do not need our own corresponding call to StopPython - editorPythonEventsInterface->StartPython(); - } - - ProcessCommandLine(); - } - - bool ShaderManagementConsoleApplication::GetAssetDatabaseLocation(AZStd::string& result) - { - AZ::SettingsRegistryInterface* settingsRegistry = AZ::SettingsRegistry::Get(); - AZ::IO::FixedMaxPath assetDatabaseSqlitePath; - if (settingsRegistry && settingsRegistry->Get(assetDatabaseSqlitePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_CacheProjectRootFolder)) - { - assetDatabaseSqlitePath /= "assetdb.sqlite"; - result = AZStd::string_view(assetDatabaseSqlitePath.Native()); - return true; - } - - return false; } } // namespace ShaderManagementConsole diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 277d3ef1e3..42817040ce 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -22,7 +22,7 @@ namespace ShaderManagementConsole public: AZ_TYPE_INFO(ShaderManagementConsole::ShaderManagementConsoleApplication, "{A31B1AEB-4DA3-49CD-884A-CC998FF7546F}"); - using Base = AzFramework::Application; + using Base = AtomToolsFramework::AtomToolsApplication; ShaderManagementConsoleApplication(int* argc, char*** argv); virtual ~ShaderManagementConsoleApplication() = default; @@ -33,11 +33,6 @@ namespace ShaderManagementConsole const char* GetCurrentConfigurationName() const override; private: - ////////////////////////////////////////////////////////////////////////// - // AssetDatabaseRequestsBus::Handler overrides... - bool GetAssetDatabaseLocation(AZStd::string& result) override; - ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// // ShaderManagementConsoleWindowNotificationBus::Handler overrides... void OnShaderManagementConsoleWindowClosing() override; @@ -55,6 +50,6 @@ namespace ShaderManagementConsole void ProcessCommandLine(); void StartInternal() override; - AZStd::string_view GetBuildTargetName() override; + AZStd::string GetBuildTargetName() override; }; } // namespace ShaderManagementConsole From 4baea40a75985314cca06a9a154299cf5de12ecc Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Mon, 26 Jul 2021 17:48:22 -0500 Subject: [PATCH 25/58] Reflect() fix Signed-off-by: Dayo Lawal --- .../Code/Source/Application/AtomToolsApplication.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 1ad2048ae4..0ee06d3fc2 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -82,12 +82,13 @@ namespace AtomToolsFramework if (auto behaviorContext = azrtti_cast(context)) { + AZStd::string fileName = GetBuildTargetName() + ".general"; // this will put these methods into the 'azlmbr.AtomTools.general' module - auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) + auto addGeneral = [fileName](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) { methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "AtomTools.general"); + ->Attribute(AZ::Script::Attributes::Module, fileName); }; // The reflection here is based on patterns in CryEditPythonHandler::Reflect addGeneral(behaviorContext->Method( From 23fb27e2a4786cc00ce2c81d077ff216fbfb68d4 Mon Sep 17 00:00:00 2001 From: kberg-amzn Date: Mon, 26 Jul 2021 19:40:39 -0700 Subject: [PATCH 26/58] New AzNetworking metrics display plus connection quality debug widgets using ImGui Signed-off-by: kberg-amzn --- .../ConnectionLayer/ConnectionMetrics.cpp | 18 ++ .../ConnectionLayer/ConnectionMetrics.h | 28 +- .../ConnectionLayer/ConnectionMetrics.inl | 29 ++ .../ConnectionLayer/IConnection.h | 16 +- .../ConnectionLayer/IConnection.inl | 10 + .../TcpTransport/TcpConnection.cpp | 13 +- .../AzNetworking/TcpTransport/TcpConnection.h | 1 - .../UdpTransport/UdpConnection.cpp | 10 +- .../AzNetworking/UdpTransport/UdpConnection.h | 8 - .../UdpTransport/UdpConnection.inl | 10 - .../UdpTransport/UdpNetworkInterface.cpp | 3 +- .../AzNetworking/UdpTransport/UdpSocket.cpp | 8 +- .../Debug/MultiplayerDebugSystemComponent.cpp | 302 ++++++++++++------ 13 files changed, 310 insertions(+), 146 deletions(-) diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.cpp b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.cpp index cc0851e53d..3a3ab06d02 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.cpp @@ -22,6 +22,7 @@ namespace AzNetworking const AZ::TimeMs deltaTimeMs = currentTimeMs - m_lastLoggedTimeMs; m_atoms[m_activeAtom].m_bytesTransmitted += byteCount; + m_atoms[m_activeAtom].m_packetsSent++; m_atoms[m_activeAtom].m_timeAccumulatorMs += deltaTimeMs; if (m_atoms[m_activeAtom].m_timeAccumulatorMs >= m_maxSampleTimeMs) @@ -32,6 +33,11 @@ namespace AzNetworking m_lastLoggedTimeMs = currentTimeMs; } + void DatarateMetrics::LogPacketLost() + { + m_atoms[m_activeAtom].m_packetsLost++; + } + float DatarateMetrics::GetBytesPerSecond() const { const uint32_t sampleAtom = 1 - m_activeAtom; @@ -47,6 +53,18 @@ namespace AzNetworking return (bytesLogged * 1000.0f) / sampleTime; // (* 1000) to convert from bytes per millisecond to bytes per second } + float DatarateMetrics::GetLossRatePercent() const + { + const uint32_t sampleAtom = 1 - m_activeAtom; + + if (m_atoms[sampleAtom].m_packetsSent == 0) + { + return 0.0f; + } + + return float(m_atoms[sampleAtom].m_packetsLost) / float(m_atoms[sampleAtom].m_packetsSent); + } + void ConnectionComputeRtt::LogPacketSent(PacketId packetId, AZ::TimeMs currentTimeMs) { for (uint32_t i = 0; i < MaxTrackableEntries; i++) diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.h index c2227b07b6..b576c64e86 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.h @@ -19,8 +19,10 @@ namespace AzNetworking { DatarateAtom() = default; + AZ::TimeMs m_timeAccumulatorMs = AZ::TimeMs{ 0 }; uint32_t m_bytesTransmitted = 0; - AZ::TimeMs m_timeAccumulatorMs = AZ::TimeMs{0}; + uint32_t m_packetsSent = 0; + uint32_t m_packetsLost = 0; }; //! @class DatarateMetrics @@ -40,19 +42,26 @@ namespace AzNetworking //! @param currentTimeMs current process time in milliseconds void LogPacket(uint32_t byteCount, AZ::TimeMs currentTimeMs); + //! Invoked whenever a packet has determined to be lost. + void LogPacketLost(); + //! Retrieve a sample of the datarate being incurred by this connection in bytes per second. //! @return datarate for traffic sent to or from the connection in bytes per second float GetBytesPerSecond() const; + //! Returns the estimated packet loss rate as a percentage of packets. + //! @return the estimated percentage loss rate + float GetLossRatePercent() const; + private: //! Used internally to swap buffers used for metric gathering. void SwapBuffers(); - static constexpr AZ::TimeMs MaxSampleTimeMs = AZ::TimeMs{500}; + static constexpr AZ::TimeMs MaxSampleTimeMs = AZ::TimeMs{ 2000 }; - AZ::TimeMs m_maxSampleTimeMs = MaxSampleTimeMs; - AZ::TimeMs m_lastLoggedTimeMs = MaxSampleTimeMs; + AZ::TimeMs m_maxSampleTimeMs = MaxSampleTimeMs; + AZ::TimeMs m_lastLoggedTimeMs = MaxSampleTimeMs; uint32_t m_activeAtom = 0; DatarateAtom m_atoms[2]; }; @@ -69,7 +78,7 @@ namespace AzNetworking ConnectionPacketEntry(PacketId packetId, AZ::TimeMs sendTimeMs); PacketId m_packetId = InvalidPacketId; - AZ::TimeMs m_sendTimeMs = AZ::TimeMs{0}; + AZ::TimeMs m_sendTimeMs = AZ::TimeMs{0}; }; //! @class ConnectionComputeRtt @@ -100,8 +109,8 @@ namespace AzNetworking private: - static constexpr uint32_t MaxTrackableEntries = 4; - static constexpr float InitialRoundTripTime = 0.1f; //< Start off with a 100 millisecond estimate for Rtt + static constexpr uint32_t MaxTrackableEntries = 8; + static constexpr float InitialRoundTripTime = 0.1f; //< Start off with a 100 millisecond estimate for Rtt float m_roundTripTime = InitialRoundTripTime; ConnectionPacketEntry m_entries[MaxTrackableEntries]; @@ -117,6 +126,11 @@ namespace AzNetworking //! Resets all internal metrics to defaults. void Reset(); + void LogPacketSent(uint32_t byteCount, AZ::TimeMs currentTimeMs); + void LogPacketRecv(uint32_t byteCount, AZ::TimeMs currentTimeMs); + void LogPacketLost(); + void LogPacketAcked(); + uint32_t m_packetsSent = 0; uint32_t m_packetsRecv = 0; uint32_t m_packetsLost = 0; diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.inl b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.inl index 5d7d18f709..5f196c4ed1 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.inl +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/ConnectionMetrics.inl @@ -40,4 +40,33 @@ namespace AzNetworking { *this = ConnectionMetrics(); } + + inline void ConnectionMetrics::LogPacketSent(uint32_t byteCount, AZ::TimeMs currentTimeMs) + { + if (byteCount > 0) + { + m_packetsSent++; + } + m_sendDatarate.LogPacket(byteCount, currentTimeMs); + } + + inline void ConnectionMetrics::LogPacketRecv(uint32_t byteCount, AZ::TimeMs currentTimeMs) + { + if (byteCount > 0) + { + m_packetsRecv++; + } + m_recvDatarate.LogPacket(byteCount, currentTimeMs); + } + + inline void ConnectionMetrics::LogPacketLost() + { + m_packetsLost++; + m_sendDatarate.LogPacketLost(); + } + + inline void ConnectionMetrics::LogPacketAcked() + { + m_packetsAcked++; + } } diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h index 1034f17585..363fd1d37b 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.h @@ -95,11 +95,6 @@ namespace AzNetworking //! @return the max transmission unit for this connection virtual uint32_t GetConnectionMtu() const = 0; - //! Sets connection quality values for testing poor connection conditions. - //! Currently unsupported on TcpConnections - //! @param connectionQuality simulated connection quality values to use - virtual void SetConnectionQuality(const ConnectionQuality& connectionQuality) = 0; - //! Returns the connection identifier for this connection instance. //! @return the connection identifier for this connection instance ConnectionId GetConnectionId() const; @@ -128,12 +123,23 @@ namespace AzNetworking //! @return reference to the connection metric info ConnectionMetrics& GetMetrics(); + //! Retrieves debug connection quality settings. + //! Currently unsupported on TcpConnections + //! @return connection quality structure for this connection + const ConnectionQuality& GetConnectionQuality() const; + + //! Retrieves debug connection quality settings, non-const. + //! Currently unsupported on TcpConnections + //! @return connection quality structure for this connection + ConnectionQuality& GetConnectionQuality(); + private: // The following data members are here in the interface for performance reasons ConnectionId m_connectionId = InvalidConnectionId; IpAddress m_remoteAddress; ConnectionMetrics m_connectionMetrics; + ConnectionQuality m_connectionQuality; void* m_userData = nullptr; }; } diff --git a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.inl b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.inl index 646afac8f0..61e92010c7 100644 --- a/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.inl +++ b/Code/Framework/AzNetworking/AzNetworking/ConnectionLayer/IConnection.inl @@ -59,4 +59,14 @@ namespace AzNetworking { return m_connectionMetrics; } + + inline const ConnectionQuality& IConnection::GetConnectionQuality() const + { + return m_connectionQuality; + } + + inline ConnectionQuality& IConnection::GetConnectionQuality() + { + return m_connectionQuality; + } } diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp index ea746b9d00..1beb83e19f 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.cpp @@ -122,7 +122,7 @@ namespace AzNetworking bool TcpConnection::UpdateRecv() { const AZ::TimeMs startTimeMs = AZ::GetElapsedTimeMs(); - GetMetrics().m_recvDatarate.LogPacket(0, startTimeMs); + GetMetrics().LogPacketRecv(0, startTimeMs); // Read new data off the input socket { @@ -261,11 +261,6 @@ namespace AzNetworking return 0; // do nothing, unsupported on TCP connections } - void TcpConnection::SetConnectionQuality([[maybe_unused]] const ConnectionQuality& connectionQuality) - { - ; // do nothing, unsupported on TCP connections - } - bool TcpConnection::SendPacketInternal(PacketType packetType, TcpPacketEncodingBuffer& payloadBuffer, AZ::TimeMs currentTimeMs) { AZ_Assert(payloadBuffer.GetCapacity() < AZStd::numeric_limits::max(), "Buffer capacity should be representable using 2 bytes or less"); @@ -333,8 +328,7 @@ namespace AzNetworking } m_sendRingbuffer.AdvanceWriteBuffer(headerSize + payloadSize); - GetMetrics().m_packetsSent++; - GetMetrics().m_sendDatarate.LogPacket(headerSize + payloadSize, currentTimeMs); + GetMetrics().LogPacketSent(headerSize + payloadSize, currentTimeMs); m_networkInterface.GetMetrics().m_sendPackets++; UpdateSend(); return true; @@ -379,8 +373,7 @@ namespace AzNetworking memcpy(dstData, srcData, packetSize); m_recvRingbuffer.AdvanceReadBuffer(serializer.GetReadSize() + packetSize); - GetMetrics().m_packetsRecv++; - GetMetrics().m_recvDatarate.LogPacket(packetSize, currentTimeMs); + GetMetrics().LogPacketRecv(packetSize, currentTimeMs); m_networkInterface.GetMetrics().m_recvPackets++; return true; } diff --git a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.h b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.h index af2c69292c..b769aea086 100644 --- a/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/TcpTransport/TcpConnection.h @@ -102,7 +102,6 @@ namespace AzNetworking bool Disconnect(DisconnectReason reason, TerminationEndpoint endpoint) override; void SetConnectionMtu(uint32_t connectionMtu) override; uint32_t GetConnectionMtu() const override; - void SetConnectionQuality(const ConnectionQuality& connectionQuality) override; // @} //! Sets the registered socket file descriptor for this TcpConnection in the associated ConnectionSet instance. diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.cpp index 798116d180..3efc6a51a8 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.cpp @@ -152,7 +152,7 @@ namespace AzNetworking void UdpConnection::ProcessAcked(PacketId packetId, AZ::TimeMs currentTimeMs) { - GetMetrics().m_packetsAcked++; + GetMetrics().LogPacketAcked(); m_reliableQueue.OnPacketAcked(m_networkInterface, *this, packetId); // Compute Rtt adjustments @@ -172,8 +172,7 @@ namespace AzNetworking GetMetrics().m_connectionRtt.LogPacketSent(packetId, currentTimeMs); } - GetMetrics().m_packetsSent++; - GetMetrics().m_sendDatarate.LogPacket(packetSize, currentTimeMs); + GetMetrics().LogPacketSent(packetSize, currentTimeMs); m_lastSentPacketMs = currentTimeMs; m_unackedPacketCount = 0; } @@ -193,7 +192,7 @@ namespace AzNetworking return PacketTimeoutResult::Acked; case PacketAckState::Nacked: - GetMetrics().m_packetsLost++; + GetMetrics().LogPacketLost(); if (reliability == ReliabilityType::Reliable) { m_reliableQueue.OnPacketLost(m_networkInterface, *this, packetId); @@ -224,8 +223,7 @@ namespace AzNetworking return false; } - GetMetrics().m_packetsRecv++; - GetMetrics().m_recvDatarate.LogPacket(packetSize, currentTimeMs); + GetMetrics().LogPacketRecv(packetSize, currentTimeMs); if (header.GetIsReliable() && !m_reliableQueue.OnPacketReceived(header)) { diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.h b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.h index c8e0c2cdc9..67d626d6cb 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.h +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.h @@ -66,13 +66,8 @@ namespace AzNetworking bool Disconnect(DisconnectReason reason, TerminationEndpoint endpoint) override; void SetConnectionMtu(uint32_t connectionMtu) override; uint32_t GetConnectionMtu() const override; - void SetConnectionQuality(const ConnectionQuality& connectionQuality) override; // @} - //! Gets connection quality values for testing poor connection conditions. - //! @return connection quality values for this IConnection instance - const ConnectionQuality& GetConnectionQuality() const; - //! Returns a suitable encryption endpoint for this connection type. //! @return reference to the connections encryption endpoint DtlsEndpoint& GetDtlsEndpoint(); @@ -146,8 +141,6 @@ namespace AzNetworking UdpFragmentQueue m_fragmentQueue; ConnectionState m_state = ConnectionState::Disconnected; ConnectionRole m_connectionRole = ConnectionRole::Connector; - - ConnectionQuality m_connectionQuality; DtlsEndpoint m_dtlsEndpoint; AZ::TimeMs m_lastSentPacketMs; @@ -160,4 +153,3 @@ namespace AzNetworking } #include - diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.inl b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.inl index 1ab273d53d..b31595263d 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.inl +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpConnection.inl @@ -10,16 +10,6 @@ namespace AzNetworking { - inline void UdpConnection::SetConnectionQuality(const ConnectionQuality& connectionQuality) - { - m_connectionQuality = connectionQuality; - } - - inline const ConnectionQuality& UdpConnection::GetConnectionQuality() const - { - return m_connectionQuality; - } - inline DtlsEndpoint& UdpConnection::GetDtlsEndpoint() { return m_dtlsEndpoint; diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp index 1a29dd4cae..a3ddb856d2 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpNetworkInterface.cpp @@ -224,8 +224,7 @@ namespace AzNetworking continue; } - connection->GetMetrics().m_recvDatarate.LogPacket(packet.m_receivedBytes + UdpPacketHeaderSize, currentTimeMs); - connection->GetMetrics().m_packetsRecv++; + connection->GetMetrics().LogPacketRecv(packet.m_receivedBytes + UdpPacketHeaderSize, currentTimeMs); // Decode the packet flag bitset first since it's always uncompressed UdpPacketHeader header; diff --git a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp index bb0b6d0fff..29a99f96a1 100644 --- a/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp +++ b/Code/Framework/AzNetworking/AzNetworking/UdpTransport/UdpSocket.cpp @@ -126,7 +126,7 @@ namespace AzNetworking #ifdef ENABLE_LATENCY_DEBUG if (connectionQuality.m_lossPercentage > 0) { - if (int32_t(m_random.GetRandom() % 100) < (connectionQuality.m_lossPercentage / 2)) + if (int32_t(m_random.GetRandom() % 100) < (connectionQuality.m_lossPercentage)) { // Pretend we sent, but don't actually send return true; @@ -157,9 +157,11 @@ namespace AzNetworking #ifdef ENABLE_LATENCY_DEBUG else if ((connectionQuality.m_latencyMs > AZ::TimeMs{ 0 }) || (connectionQuality.m_varianceMs > AZ::TimeMs{ 0 })) { - const AZ::TimeMs jitterMs = aznumeric_cast(m_random.GetRandom()) % (connectionQuality.m_varianceMs / aznumeric_cast(2)); + const AZ::TimeMs jitterMs = aznumeric_cast(m_random.GetRandom()) % (connectionQuality.m_varianceMs > AZ::TimeMs{ 0 } + ? connectionQuality.m_varianceMs + : AZ::TimeMs{ 1 }); const AZ::TimeMs currTimeMs = AZ::GetElapsedTimeMs(); - const AZ::TimeMs deferTimeMs = (connectionQuality.m_latencyMs / aznumeric_cast(2)) + jitterMs; + const AZ::TimeMs deferTimeMs = (connectionQuality.m_latencyMs) + jitterMs; DeferredData deferred = DeferredData(address, data, size, encrypt, dtlsEndpoint); AZ::Interface::Get()->AddCallback([&, deferredData = deferred] diff --git a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp index 1611a3213d..4d2d47444c 100644 --- a/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/Debug/MultiplayerDebugSystemComponent.cpp @@ -23,36 +23,30 @@ namespace Multiplayer ->Version(1); } } - void MultiplayerDebugSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) { provided.push_back(AZ_CRC_CE("MultiplayerDebugSystemComponent")); } - void MultiplayerDebugSystemComponent::GetRequiredServices([[maybe_unused]] AZ::ComponentDescriptor::DependencyArrayType& required) { ; } - void MultiplayerDebugSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatbile) { incompatbile.push_back(AZ_CRC_CE("MultiplayerDebugSystemComponent")); } - void MultiplayerDebugSystemComponent::Activate() { #ifdef IMGUI_ENABLED ImGui::ImGuiUpdateListenerBus::Handler::BusConnect(); #endif } - void MultiplayerDebugSystemComponent::Deactivate() { #ifdef IMGUI_ENABLED ImGui::ImGuiUpdateListenerBus::Handler::BusDisconnect(); #endif } - #ifdef IMGUI_ENABLED void MultiplayerDebugSystemComponent::OnImGuiMainMenuUpdate() { @@ -63,7 +57,6 @@ namespace Multiplayer ImGui::EndMenu(); } } - void AccumulatePerSecondValues(const MultiplayerStats& stats, const MultiplayerStats::Metric& metric, float& outCallsPerSecond, float& outBytesPerSecond) { uint64_t summedCalls = 0; @@ -80,8 +73,9 @@ namespace Multiplayer bool DrawMetricsRow(const char* name, bool expandable, uint64_t totalCalls, uint64_t totalBytes, float callsPerSecond, float bytesPerSecond) { - const ImGuiTreeNodeFlags flags = expandable ? ImGuiTreeNodeFlags_SpanFullWidth - : (ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth); + const ImGuiTreeNodeFlags flags = expandable + ? ImGuiTreeNodeFlags_SpanFullWidth + : (ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth); ImGui::TableNextRow(); ImGui::TableNextColumn(); const bool open = ImGui::TreeNodeEx(name, flags); @@ -95,14 +89,12 @@ namespace Multiplayer ImGui::Text("%11.2f", bytesPerSecond); return open; } - bool DrawSummaryRow(const char* name, const MultiplayerStats& stats) { const MultiplayerStats::Metric propertyUpdatesSent = stats.CalculateTotalPropertyUpdateSentMetrics(); const MultiplayerStats::Metric propertyUpdatesRecv = stats.CalculateTotalPropertyUpdateRecvMetrics(); const MultiplayerStats::Metric rpcsSent = stats.CalculateTotalRpcsSentMetrics(); const MultiplayerStats::Metric rpcsRecv = stats.CalculateTotalRpcsRecvMetrics(); - const uint64_t totalCalls = propertyUpdatesSent.m_totalCalls + propertyUpdatesRecv.m_totalCalls + rpcsSent.m_totalCalls + rpcsRecv.m_totalCalls; const uint64_t totalBytes = propertyUpdatesSent.m_totalBytes + propertyUpdatesRecv.m_totalBytes + rpcsSent.m_totalBytes + rpcsRecv.m_totalBytes; float callsPerSecond = 0.0f; @@ -111,17 +103,14 @@ namespace Multiplayer AccumulatePerSecondValues(stats, propertyUpdatesRecv, callsPerSecond, bytesPerSecond); AccumulatePerSecondValues(stats, rpcsSent, callsPerSecond, bytesPerSecond); AccumulatePerSecondValues(stats, rpcsRecv, callsPerSecond, bytesPerSecond); - return DrawMetricsRow(name, true, totalCalls, totalBytes, callsPerSecond, bytesPerSecond); } - bool DrawComponentRow(const char* name, const MultiplayerStats& stats, NetComponentId netComponentId) { const MultiplayerStats::Metric propertyUpdatesSent = stats.CalculateComponentPropertyUpdateSentMetrics(netComponentId); const MultiplayerStats::Metric propertyUpdatesRecv = stats.CalculateComponentPropertyUpdateRecvMetrics(netComponentId); const MultiplayerStats::Metric rpcsSent = stats.CalculateComponentRpcsSentMetrics(netComponentId); const MultiplayerStats::Metric rpcsRecv = stats.CalculateComponentRpcsRecvMetrics(netComponentId); - const uint64_t totalCalls = propertyUpdatesSent.m_totalCalls + propertyUpdatesRecv.m_totalCalls + rpcsSent.m_totalCalls + rpcsRecv.m_totalCalls; const uint64_t totalBytes = propertyUpdatesSent.m_totalBytes + propertyUpdatesRecv.m_totalBytes + rpcsSent.m_totalBytes + rpcsRecv.m_totalBytes; float callsPerSecond = 0.0f; @@ -130,10 +119,8 @@ namespace Multiplayer AccumulatePerSecondValues(stats, propertyUpdatesRecv, callsPerSecond, bytesPerSecond); AccumulatePerSecondValues(stats, rpcsSent, callsPerSecond, bytesPerSecond); AccumulatePerSecondValues(stats, rpcsRecv, callsPerSecond, bytesPerSecond); - return DrawMetricsRow(name, true, totalCalls, totalBytes, callsPerSecond, bytesPerSecond); } - void DrawComponentDetails(const MultiplayerStats& stats, NetComponentId netComponentId) { MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry(); @@ -158,7 +145,6 @@ namespace Multiplayer ImGui::TreePop(); } } - { const MultiplayerStats::Metric metric = stats.CalculateComponentPropertyUpdateRecvMetrics(netComponentId); float callsPerSecond = 0.0f; @@ -180,7 +166,6 @@ namespace Multiplayer ImGui::TreePop(); } } - { const MultiplayerStats::Metric metric = stats.CalculateComponentRpcsSentMetrics(netComponentId); float callsPerSecond = 0.0f; @@ -202,7 +187,6 @@ namespace Multiplayer ImGui::TreePop(); } } - { const MultiplayerStats::Metric metric = stats.CalculateComponentRpcsRecvMetrics(netComponentId); float callsPerSecond = 0.0f; @@ -226,45 +210,218 @@ namespace Multiplayer } } - void MultiplayerDebugSystemComponent::OnImGuiUpdate() + void DrawNetworkingStats() { const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x; const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing(); + const ImGuiTableFlags flags = ImGuiTableFlags_BordersV + | ImGuiTableFlags_BordersOuterH + | ImGuiTableFlags_Resizable + | ImGuiTableFlags_RowBg + | ImGuiTableFlags_NoBordersInBody; + + const ImGuiTreeNodeFlags nodeFlags = (ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_SpanFullWidth); + + AzNetworking::INetworking* networking = AZ::Interface::Get(); + + ImGui::Text("Total sockets monitored by TcpListenThread: %u", networking->GetTcpListenThreadSocketCount()); + ImGui::Text("Total time spent updating TcpListenThread: %lld", aznumeric_cast(networking->GetTcpListenThreadUpdateTime())); + ImGui::Text("Total sockets monitored by UdpReaderThread: %u", networking->GetUdpReaderThreadSocketCount()); + ImGui::Text("Total time spent updating UdpReaderThread: %lld", aznumeric_cast(networking->GetUdpReaderThreadUpdateTime())); + ImGui::NewLine(); + + for (auto& networkInterface : networking->GetNetworkInterfaces()) + { + if (ImGui::CollapsingHeader(networkInterface.second->GetName().GetCStr())) + { + const char* protocol = networkInterface.second->GetType() == AzNetworking::ProtocolType::Tcp ? "Tcp" : "Udp"; + const char* trustZone = networkInterface.second->GetTrustZone() == AzNetworking::TrustZone::ExternalClientToServer ? "ExternalClientToServer" : "InternalServerToServer"; + const uint32_t port = aznumeric_cast(networkInterface.second->GetPort()); + ImGui::Text("%sNetworkInterface open to %s on port %u", protocol, trustZone, port); + + if (ImGui::BeginTable("", 2, flags)) + { + const AzNetworking::NetworkInterfaceMetrics& metrics = networkInterface.second->GetMetrics(); + ImGui::TableSetupColumn("Stat", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableHeadersRow(); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total time spent updating (ms)"); + ImGui::TableNextColumn(); + ImGui::Text("%lld", aznumeric_cast(metrics.m_updateTimeMs)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total number of connections"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_connectionCount)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total send time (ms)"); + ImGui::TableNextColumn(); + ImGui::Text("%lld", aznumeric_cast(metrics.m_sendTimeMs)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total sent packets"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_sendPackets)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total sent bytes after compression"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_sendBytes)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total sent bytes before compression"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_sendBytesUncompressed)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total sent compressed packets without benefit"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_sendCompressedPacketsNoGain)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total gain from packet compression"); + ImGui::TableNextColumn(); + ImGui::Text("%lld", aznumeric_cast(metrics.m_sendBytesCompressedDelta)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total packets resent"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_resentPackets)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total receive time (ms)"); + ImGui::TableNextColumn(); + ImGui::Text("%lld", aznumeric_cast(metrics.m_recvTimeMs)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total received packets"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_recvPackets)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total received bytes after compression"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_recvBytes)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total received bytes before compression"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_recvBytesUncompressed)); + ImGui::TableNextRow(); ImGui::TableNextColumn(); + ImGui::Text("Total packets discarded due to load"); + ImGui::TableNextColumn(); + ImGui::Text("%llu", aznumeric_cast(metrics.m_discardedPackets)); + ImGui::EndTable(); + } + + if (ImGui::BeginTable("", 7, flags)) + { + // The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On + ImGui::TableSetupColumn("RemoteAddr", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("Conn. Id", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 6.0f); + ImGui::TableSetupColumn("Send (Bps)", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 10.0f); + ImGui::TableSetupColumn("Recv (Bps)", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 10.0f); + ImGui::TableSetupColumn("RTT (ms)", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 8.0f); + ImGui::TableSetupColumn("% Lost", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 8.0f); + ImGui::TableSetupColumn("Debug Settings", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 32.0f); + ImGui::TableHeadersRow(); + + auto displayConnectionRow = [](AzNetworking::IConnection& connection) + { + ImGui::PushID(&connection); + + const AzNetworking::ConnectionMetrics& metrics = connection.GetMetrics(); + const AzNetworking::IpAddress::IpString remoteAddr = connection.GetRemoteAddress().GetString(); + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::TreeNodeEx(remoteAddr.c_str(), nodeFlags); + ImGui::TableNextColumn(); + ImGui::Text("%5llu", aznumeric_cast(connection.GetConnectionId())); + ImGui::TableNextColumn(); + ImGui::Text("%9.2f", metrics.m_sendDatarate.GetBytesPerSecond()); + ImGui::TableNextColumn(); + ImGui::Text("%9.2f", metrics.m_recvDatarate.GetBytesPerSecond()); + ImGui::TableNextColumn(); + ImGui::Text("%7.2f", metrics.m_connectionRtt.GetRoundTripTimeSeconds() * 1000.0f); + ImGui::TableNextColumn(); + ImGui::Text("%7.2f", metrics.m_sendDatarate.GetLossRatePercent()); + ImGui::TableNextColumn(); + + { + AzNetworking::ConnectionQuality& quality = connection.GetConnectionQuality(); + int32_t latency = aznumeric_cast(quality.m_latencyMs); + int32_t variance = aznumeric_cast(quality.m_varianceMs); + ImGui::SliderInt("Loss %", &quality.m_lossPercentage, 0, 100); + if (ImGui::SliderInt("Latency(ms)", &latency, 0, 3000)) + { + quality.m_latencyMs = AZ::TimeMs{ latency }; + } + if (ImGui::SliderInt("Jitter(ms)", &variance, 0, 1000)) + { + quality.m_varianceMs = AZ::TimeMs{ variance }; + } + } + ImGui::PopID(); + }; + networkInterface.second->GetConnectionSet().VisitConnections(displayConnectionRow); + ImGui::EndTable(); + } + } + ImGui::NewLine(); + } + ImGui::End(); + } + + void DrawMultiplayerStats() + { + const float TEXT_BASE_WIDTH = ImGui::CalcTextSize("A").x; + const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing(); + + IMultiplayer* multiplayer = AZ::Interface::Get(); + MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry(); + const Multiplayer::MultiplayerStats& stats = multiplayer->GetStats(); + ImGui::Text("Multiplayer operating in %s mode", GetEnumString(multiplayer->GetAgentType())); + ImGui::Text("Total networked entities: %llu", aznumeric_cast(stats.m_entityCount)); + ImGui::Text("Total client connections: %llu", aznumeric_cast(stats.m_clientConnectionCount)); + ImGui::Text("Total server connections: %llu", aznumeric_cast(stats.m_serverConnectionCount)); + ImGui::NewLine(); + + static ImGuiTableFlags flags = ImGuiTableFlags_BordersV + | ImGuiTableFlags_BordersOuterH + | ImGuiTableFlags_Resizable + | ImGuiTableFlags_RowBg + | ImGuiTableFlags_NoBordersInBody; + + if (ImGui::BeginTable("", 5, flags)) + { + // The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On + ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch); + ImGui::TableSetupColumn("Total Calls", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableSetupColumn("Total Bytes", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableSetupColumn("Calls/Sec", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableSetupColumn("Bytes/Sec", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); + ImGui::TableHeadersRow(); + + if (DrawSummaryRow("Totals", stats)) + { + for (AZStd::size_t index = 0; index < stats.m_componentStats.size(); ++index) + { + const NetComponentId netComponentId = aznumeric_cast(index); + using StringLabel = AZStd::fixed_string<128>; + const StringLabel gemName = componentRegistry->GetComponentGemName(netComponentId); + const StringLabel componentName = componentRegistry->GetComponentName(netComponentId); + const StringLabel label = gemName + "::" + componentName; + if (DrawComponentRow(label.c_str(), stats, netComponentId)) + { + DrawComponentDetails(stats, netComponentId); + ImGui::TreePop(); + } + } + } + ImGui::EndTable(); + ImGui::NewLine(); + } + ImGui::End(); + } + + void MultiplayerDebugSystemComponent::OnImGuiUpdate() + { if (m_displayNetworkingStats) { if (ImGui::Begin("Networking Stats", &m_displayNetworkingStats, ImGuiWindowFlags_None)) { - AzNetworking::INetworking* networking = AZ::Interface::Get(); - - ImGui::Text("Total sockets monitored by TcpListenThread: %u", networking->GetTcpListenThreadSocketCount()); - ImGui::Text("Total time spent updating TcpListenThread: %lld", aznumeric_cast(networking->GetTcpListenThreadUpdateTime())); - ImGui::Text("Total sockets monitored by UdpReaderThread: %u", networking->GetUdpReaderThreadSocketCount()); - ImGui::Text("Total time spent updating UdpReaderThread: %lld", aznumeric_cast(networking->GetUdpReaderThreadUpdateTime())); - - for (auto& networkInterface : networking->GetNetworkInterfaces()) - { - const char* protocol = networkInterface.second->GetType() == AzNetworking::ProtocolType::Tcp ? "Tcp" : "Udp"; - const char* trustZone = networkInterface.second->GetTrustZone() == AzNetworking::TrustZone::ExternalClientToServer ? "ExternalClientToServer" : "InternalServerToServer"; - const uint32_t port = aznumeric_cast(networkInterface.second->GetPort()); - ImGui::Text("%sNetworkInterface: %s - open to %s on port %u", protocol, networkInterface.second->GetName().GetCStr(), trustZone, port); - - const AzNetworking::NetworkInterfaceMetrics& metrics = networkInterface.second->GetMetrics(); - ImGui::Text(" - Total time spent updating in milliseconds: %lld", aznumeric_cast(metrics.m_updateTimeMs)); - ImGui::Text(" - Total number of connections: %llu", aznumeric_cast(metrics.m_connectionCount)); - ImGui::Text(" - Total send time in milliseconds: %lld", aznumeric_cast(metrics.m_sendTimeMs)); - ImGui::Text(" - Total sent packets: %llu", aznumeric_cast(metrics.m_sendPackets)); - ImGui::Text(" - Total sent bytes after compression: %llu", aznumeric_cast(metrics.m_sendBytes)); - ImGui::Text(" - Total sent bytes before compression: %llu", aznumeric_cast(metrics.m_sendBytesUncompressed)); - ImGui::Text(" - Total sent compressed packets without benefit: %llu", aznumeric_cast(metrics.m_sendCompressedPacketsNoGain)); - ImGui::Text(" - Total gain from packet compression: %lld", aznumeric_cast(metrics.m_sendBytesCompressedDelta)); - ImGui::Text(" - Total packets resent: %llu", aznumeric_cast(metrics.m_resentPackets)); - ImGui::Text(" - Total receive time in milliseconds: %lld", aznumeric_cast(metrics.m_recvTimeMs)); - ImGui::Text(" - Total received packets: %llu", aznumeric_cast(metrics.m_recvPackets)); - ImGui::Text(" - Total received bytes after compression: %llu", aznumeric_cast(metrics.m_recvBytes)); - ImGui::Text(" - Total received bytes before compression: %llu", aznumeric_cast(metrics.m_recvBytesUncompressed)); - ImGui::Text(" - Total packets discarded due to load: %llu", aznumeric_cast(metrics.m_discardedPackets)); - } + DrawNetworkingStats(); } } @@ -272,50 +429,7 @@ namespace Multiplayer { if (ImGui::Begin("Multiplayer Stats", &m_displayMultiplayerStats, ImGuiWindowFlags_None)) { - IMultiplayer* multiplayer = AZ::Interface::Get(); - MultiplayerComponentRegistry* componentRegistry = GetMultiplayerComponentRegistry(); - const Multiplayer::MultiplayerStats& stats = multiplayer->GetStats(); - ImGui::Text("Multiplayer operating in %s mode", GetEnumString(multiplayer->GetAgentType())); - ImGui::Text("Total networked entities: %llu", aznumeric_cast(stats.m_entityCount)); - ImGui::Text("Total client connections: %llu", aznumeric_cast(stats.m_clientConnectionCount)); - ImGui::Text("Total server connections: %llu", aznumeric_cast(stats.m_serverConnectionCount)); - ImGui::NewLine(); - - static ImGuiTableFlags flags = ImGuiTableFlags_BordersV - | ImGuiTableFlags_BordersOuterH - | ImGuiTableFlags_Resizable - | ImGuiTableFlags_RowBg - | ImGuiTableFlags_NoBordersInBody; - - if (ImGui::BeginTable("", 5, flags)) - { - // The first column will use the default _WidthStretch when ScrollX is Off and _WidthFixed when ScrollX is On - ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch); - ImGui::TableSetupColumn("Total Calls", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); - ImGui::TableSetupColumn("Total Bytes", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); - ImGui::TableSetupColumn("Calls/Sec", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); - ImGui::TableSetupColumn("Bytes/Sec", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 12.0f); - ImGui::TableHeadersRow(); - - if (DrawSummaryRow("Totals", stats)) - { - for (AZStd::size_t index = 0; index < stats.m_componentStats.size(); ++index) - { - const NetComponentId netComponentId = aznumeric_cast(index); - using StringLabel = AZStd::fixed_string<128>; - const StringLabel gemName = componentRegistry->GetComponentGemName(netComponentId); - const StringLabel componentName = componentRegistry->GetComponentName(netComponentId); - const StringLabel label = gemName + "::" + componentName; - if (DrawComponentRow(label.c_str(), stats, netComponentId)) - { - DrawComponentDetails(stats, netComponentId); - ImGui::TreePop(); - } - } - } - ImGui::EndTable(); - } - ImGui::End(); + DrawMultiplayerStats(); } } } From 4b97a416a39b9dfe87b9c05b2fa9486b23534406 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 02:06:33 -0500 Subject: [PATCH 27/58] GetCriticalAssetFilters() Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.h | 8 +++- .../Application/AtomToolsApplication.cpp | 45 ++++++++++++++++--- .../Code/Source/MaterialEditorApplication.cpp | 37 +++------------ .../Code/Source/MaterialEditorApplication.h | 8 +--- .../ShaderManagementConsoleApplication.cpp | 39 +++------------- .../ShaderManagementConsoleApplication.h | 8 +--- 6 files changed, 62 insertions(+), 83 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 9d412ec477..08eac727a3 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -62,6 +62,11 @@ namespace AtomToolsFramework void Destroy() override; ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// + // AzFramework::AssetSystemStatusBus::Handler overrides... + void AssetSystemAvailable() override; + ////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////// // AZ::ComponentApplication overrides... void QueryApplicationType(AZ::ApplicationTypeQuery& appType) const override; @@ -79,7 +84,8 @@ namespace AtomToolsFramework void OnExceptionMessage(AZStd::string_view message) override; //////////////////////////////////////////////////////////////////////// - virtual AZStd::string GetBuildTargetName(); + virtual AZStd::string GetBuildTargetName() const; + virtual AZStd::vector GetCriticalAssetFilters() const; virtual void LoadSettings(); virtual void UnloadSettings(); diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 0ee06d3fc2..2aeb53db90 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -39,7 +39,7 @@ AZ_POP_DISABLE_WARNING namespace AtomToolsFramework { - AZStd::string AtomToolsApplication::GetBuildTargetName() + AZStd::string AtomToolsApplication::GetBuildTargetName() const { return AZStd::string("AtomTools"); } @@ -69,7 +69,7 @@ namespace AtomToolsFramework void AtomToolsApplication::Reflect(AZ::ReflectContext* context) { - Application::Reflect(context); + Base::Reflect(context); AzToolsFramework::AssetBrowser::AssetBrowserEntry::Reflect(context); AzToolsFramework::AssetBrowser::RootAssetBrowserEntry::Reflect(context); @@ -82,13 +82,12 @@ namespace AtomToolsFramework if (auto behaviorContext = azrtti_cast(context)) { - AZStd::string fileName = GetBuildTargetName() + ".general"; // this will put these methods into the 'azlmbr.AtomTools.general' module - auto addGeneral = [fileName](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) + auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) { methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, fileName); + ->Attribute(AZ::Script::Attributes::Module, "AtomTools"); }; // The reflection here is based on patterns in CryEditPythonHandler::Reflect addGeneral(behaviorContext->Method( @@ -150,6 +149,42 @@ namespace AtomToolsFramework Base::Destroy(); } + AZStd::vector AtomToolsApplication::GetCriticalAssetFilters() const + { + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + return AZStd::vector({ "passes/", "config/" }); + } + + void AtomToolsApplication::AssetSystemAvailable() + { + bool connectedToAssetProcessor = false; + + // When the AssetProcessor is already launched it should take less than a second to perform a connection + // but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize + // and able to negotiate a connection when running a debug build + // and to negotiate a connection + + AzFramework::AssetSystem::ConnectionSettings connectionSettings; + AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); + connectionSettings.m_connectionDirection = + AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; + connectionSettings.m_connectionIdentifier = GetBuildTargetName(); + connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) + { + AZ_TracePrintf("Atom Tools", "%.*s", aznumeric_cast(logData.size()), logData.data()); + }; + AzFramework::AssetSystemRequestBus::BroadcastResult( + connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); + + if (connectedToAssetProcessor) + { + CompileCriticalAssets(GetCriticalAssetFilters()); + } + + AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); + } + void AtomToolsApplication::CompileCriticalAssets(const AZStd::vector &assetFiltersArray) { AZ_TracePrintf(GetBuildTargetName().c_str(), "Compiling critical assets.\n"); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 6832ca683c..57313c6694 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -51,7 +51,7 @@ AZ_POP_DISABLE_WARNING namespace MaterialEditor { //! This function returns the build system target name of "MaterialEditor - AZStd::string MaterialEditorApplication::GetBuildTargetName() + AZStd::string MaterialEditorApplication::GetBuildTargetName() const { #if !defined (LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" @@ -117,36 +117,11 @@ namespace MaterialEditor Base::Destroy(); } - void MaterialEditorApplication::AssetSystemAvailable() + AZStd::vector MaterialEditorApplication::GetCriticalAssetFilters() const { - bool connectedToAssetProcessor = false; - - // When the AssetProcessor is already launched it should take less than a second to perform a connection - // but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize - // and able to negotiate a connection when running a debug build - // and to negotiate a connection - - AzFramework::AssetSystem::ConnectionSettings connectionSettings; - AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); - connectionSettings.m_connectionDirection = AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; - connectionSettings.m_connectionIdentifier = GetBuildTargetName(); - connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) - { - AZ_TracePrintf("Material Editor", "%.*s", aznumeric_cast(logData.size()), logData.data()); - }; - AzFramework::AssetSystemRequestBus::BroadcastResult(connectedToAssetProcessor, - &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); - - if (connectedToAssetProcessor) - { - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::vector assetFiltersArray = { "passes/", "config/", "MaterialEditor/" }; - - CompileCriticalAssets(assetFiltersArray); - } - - AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + return AZStd::vector({ "passes/", "config/", "MaterialEditor" }); } void MaterialEditorApplication::ProcessCommandLine(const AZ::CommandLine& commandLine) @@ -164,7 +139,7 @@ namespace MaterialEditor { const AZStd::string openDocumentPath = commandLine.GetMiscValue(openDocumentIndex); - AZ_Printf("MaterialEditor", "Opening document: %s", openDocumentPath.c_str()); + AZ_Printf(GetBuildTargetName().c_str(), "Opening document: %s", openDocumentPath.c_str()); MaterialDocumentSystemRequestBus::Broadcast(&MaterialDocumentSystemRequestBus::Events::OpenDocument, openDocumentPath); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 1139a73827..0177013a3d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -46,13 +46,9 @@ namespace MaterialEditor void Destroy() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AzFramework::AssetSystemStatusBus::Handler overrides... - void AssetSystemAvailable() override; - ////////////////////////////////////////////////////////////////////////// - void ProcessCommandLine(const AZ::CommandLine& commandLine) override; void StartInternal() override; - AZStd::string GetBuildTargetName() override; + AZStd::string GetBuildTargetName() const override; + AZStd::vector GetCriticalAssetFilters() const override; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 6d5e331c75..6f6ee697d5 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -47,7 +47,7 @@ AZ_POP_DISABLE_WARNING namespace ShaderManagementConsole { - AZStd::string ShaderManagementConsoleApplication::GetBuildTargetName() + AZStd::string ShaderManagementConsoleApplication::GetBuildTargetName() const { #if !defined (LY_CMAKE_TARGET) #error "LY_CMAKE_TARGET must be defined in order to add this source file to a CMake executable target" @@ -100,40 +100,11 @@ namespace ShaderManagementConsole Base::Destroy(); } - void ShaderManagementConsoleApplication::AssetSystemAvailable() + AZStd::vector ShaderManagementConsoleApplication::GetCriticalAssetFilters() const { - // Try connect to AP first before try to launch it manually. - bool connected = false; - auto ConnectToAssetProcessorWithIdentifier = [&connected](AzFramework::AssetSystem::AssetSystemRequests* assetSystemRequests) - { - // When the AssetProcessor is already launched it should take less than a second to perform a connection - // but when the AssetProcessor needs to be launch it could take up to 15 seconds to have the AssetProcessor initialize - // and able to negotiate a connection when running a debug build - // and to negotiate a connection - - AzFramework::AssetSystem::ConnectionSettings connectionSettings; - AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); - connectionSettings.m_connectionDirection = AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; - connectionSettings.m_connectionIdentifier = "Shader Management Console"; - connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) - { - AZ_TracePrintf("Shader Management Console", "%.*s", aznumeric_cast(logData.size()), logData.data()); - }; - - connected = assetSystemRequests->EstablishAssetProcessorConnection(connectionSettings); - }; - AzFramework::AssetSystemRequestBus::Broadcast(ConnectToAssetProcessorWithIdentifier); - - if (connected) - { - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - const AZStd::vector assetFiltersArray = { "passes/", "config/" }; - - CompileCriticalAssets(assetFiltersArray); - } - - AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); + // List of common asset filters for things that need to be compiled to run the material editor + // Some of these things will not be necessary once we have proper support for queued asset loading and reloading + return AZStd::vector({ "passes/", "config/" }); } void ShaderManagementConsoleApplication::ProcessCommandLine() diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 42817040ce..6229f5d77d 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -43,13 +43,9 @@ namespace ShaderManagementConsole void Destroy() override; ////////////////////////////////////////////////////////////////////////// - ////////////////////////////////////////////////////////////////////////// - // AzFramework::AssetSystemStatusBus::Handler overrides... - void AssetSystemAvailable() override; - ////////////////////////////////////////////////////////////////////////// - void ProcessCommandLine(); void StartInternal() override; - AZStd::string GetBuildTargetName() override; + AZStd::string GetBuildTargetName() const override; + AZStd::vector GetCriticalAssetFilters() const override; }; } // namespace ShaderManagementConsole From 61038ccd0316bdc9dfec5ecdd0f0b4828e9af179 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 02:09:45 -0500 Subject: [PATCH 28/58] Reflect() Signed-off-by: Dayo Lawal --- .../Code/Source/Application/AtomToolsApplication.cpp | 4 ++-- .../MaterialEditor/Code/Source/MaterialEditorApplication.cpp | 5 +++++ .../MaterialEditor/Code/Source/MaterialEditorApplication.h | 1 + .../Code/Source/ShaderManagementConsoleApplication.cpp | 5 +++++ .../Code/Source/ShaderManagementConsoleApplication.h | 1 + 5 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 2aeb53db90..5e817f0125 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -98,7 +98,7 @@ namespace AtomToolsFramework void AtomToolsApplication::RegisterCoreComponents() { - Application::RegisterCoreComponents(); + Base::RegisterCoreComponents(); RegisterComponentDescriptor(AzToolsFramework::AssetBrowser::AssetBrowserComponent::CreateDescriptor()); RegisterComponentDescriptor(AzToolsFramework::Thumbnailer::ThumbnailerComponent::CreateDescriptor()); RegisterComponentDescriptor(AzToolsFramework::Components::PropertyManagerComponent::CreateDescriptor()); @@ -108,7 +108,7 @@ namespace AtomToolsFramework AZ::ComponentTypeList AtomToolsApplication::GetRequiredSystemComponents() const { - AZ::ComponentTypeList components = Application::GetRequiredSystemComponents(); + AZ::ComponentTypeList components = Base::GetRequiredSystemComponents(); components.insert( components.end(), diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 57313c6694..02c2af2266 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -93,6 +93,11 @@ namespace MaterialEditor AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } + void MaterialEditorApplication::Reflect(AZ::ReflectContext* context) + { + Base::Reflect(); + } + void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) { Base::CreateStaticModules(outModules); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 0177013a3d..bbe5a26141 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -32,6 +32,7 @@ namespace MaterialEditor ////////////////////////////////////////////////////////////////////////// // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; + void Reflect(AZ::ReflectContext* context) override; const char* GetCurrentConfigurationName() const override; void Stop() override; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 6f6ee697d5..8532ad1f81 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -83,6 +83,11 @@ namespace ShaderManagementConsole outModules.push_back(aznew ShaderManagementConsoleWindowModule); } + void ShaderManagementConsoleApplication::Reflect(AZ::ReflectContext* context) + { + Base::Reflect(); + } + void ShaderManagementConsoleApplication::OnShaderManagementConsoleWindowClosing() { ExitMainLoop(); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 6229f5d77d..26dd93c08a 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -30,6 +30,7 @@ namespace ShaderManagementConsole ////////////////////////////////////////////////////////////////////////// // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; + void Reflect(AZ::ReflectContext* context) override; const char* GetCurrentConfigurationName() const override; private: From e3083c7310e27f5b4df0dc4d8f527d46b97b0d19 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 02:11:58 -0500 Subject: [PATCH 29/58] Reflect() fix Signed-off-by: Dayo Lawal --- .../MaterialEditor/Code/Source/MaterialEditorApplication.cpp | 2 +- .../Code/Source/ShaderManagementConsoleApplication.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 02c2af2266..03a80e797d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -95,7 +95,7 @@ namespace MaterialEditor void MaterialEditorApplication::Reflect(AZ::ReflectContext* context) { - Base::Reflect(); + Base::Reflect(context); } void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 8532ad1f81..de499deeaa 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -85,7 +85,7 @@ namespace ShaderManagementConsole void ShaderManagementConsoleApplication::Reflect(AZ::ReflectContext* context) { - Base::Reflect(); + Base::Reflect(context); } void ShaderManagementConsoleApplication::OnShaderManagementConsoleWindowClosing() From 485f6338acd4a2a6da2c3c5d250994b19744c144 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 02:19:26 -0500 Subject: [PATCH 30/58] CreateReflectionManager() Signed-off-by: Dayo Lawal --- .../Code/Source/Application/AtomToolsApplication.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 5e817f0125..865bd37955 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -63,7 +63,7 @@ namespace AtomToolsFramework void AtomToolsApplication::CreateReflectionManager() { - Application::CreateReflectionManager(); + Base::CreateReflectionManager(); GetSerializeContext()->CreateEditContext(); } From 06b3f7d964254e948f3678474a32488d82362f99 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 12:18:12 -0500 Subject: [PATCH 31/58] Undoing adding reflect and adding target names to functions Signed-off-by: Dayo Lawal --- .../Code/Source/Application/AtomToolsApplication.cpp | 12 ++++++++---- .../Code/Source/MaterialEditorApplication.cpp | 5 ----- .../Code/Source/MaterialEditorApplication.h | 1 - .../Source/ShaderManagementConsoleApplication.cpp | 5 ----- .../Code/Source/ShaderManagementConsoleApplication.h | 1 - 5 files changed, 8 insertions(+), 16 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 865bd37955..f968584998 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -82,12 +82,14 @@ namespace AtomToolsFramework if (auto behaviorContext = azrtti_cast(context)) { + auto targetName = GetBuildTargetName(); + // this will put these methods into the 'azlmbr.AtomTools.general' module - auto addGeneral = [](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) + auto addGeneral = [targetName](AZ::BehaviorContext::GlobalMethodBuilder methodBuilder) { methodBuilder->Attribute(AZ::Script::Attributes::Scope, AZ::Script::Attributes::ScopeFlags::Automation) ->Attribute(AZ::Script::Attributes::Category, "Editor") - ->Attribute(AZ::Script::Attributes::Module, "AtomTools"); + ->Attribute(AZ::Script::Attributes::Module, targetName); }; // The reflection here is based on patterns in CryEditPythonHandler::Reflect addGeneral(behaviorContext->Method( @@ -165,14 +167,16 @@ namespace AtomToolsFramework // and able to negotiate a connection when running a debug build // and to negotiate a connection + auto targetName = GetBuildTargetName(); + AzFramework::AssetSystem::ConnectionSettings connectionSettings; AzFramework::AssetSystem::ReadConnectionSettingsFromSettingsRegistry(connectionSettings); connectionSettings.m_connectionDirection = AzFramework::AssetSystem::ConnectionSettings::ConnectionDirection::ConnectToAssetProcessor; connectionSettings.m_connectionIdentifier = GetBuildTargetName(); - connectionSettings.m_loggingCallback = []([[maybe_unused]] AZStd::string_view logData) + connectionSettings.m_loggingCallback = [targetName]([[maybe_unused]] AZStd::string_view logData) { - AZ_TracePrintf("Atom Tools", "%.*s", aznumeric_cast(logData.size()), logData.data()); + AZ_TracePrintf(targetName.c_str(), "%.*s", aznumeric_cast(logData.size()), logData.data()); }; AzFramework::AssetSystemRequestBus::BroadcastResult( connectedToAssetProcessor, &AzFramework::AssetSystemRequestBus::Events::EstablishAssetProcessorConnection, connectionSettings); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 03a80e797d..57313c6694 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -93,11 +93,6 @@ namespace MaterialEditor AzToolsFramework::EditorPythonConsoleNotificationBus::Handler::BusDisconnect(); } - void MaterialEditorApplication::Reflect(AZ::ReflectContext* context) - { - Base::Reflect(context); - } - void MaterialEditorApplication::CreateStaticModules(AZStd::vector& outModules) { Base::CreateStaticModules(outModules); diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index bbe5a26141..0177013a3d 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -32,7 +32,6 @@ namespace MaterialEditor ////////////////////////////////////////////////////////////////////////// // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; - void Reflect(AZ::ReflectContext* context) override; const char* GetCurrentConfigurationName() const override; void Stop() override; diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index de499deeaa..6f6ee697d5 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -83,11 +83,6 @@ namespace ShaderManagementConsole outModules.push_back(aznew ShaderManagementConsoleWindowModule); } - void ShaderManagementConsoleApplication::Reflect(AZ::ReflectContext* context) - { - Base::Reflect(context); - } - void ShaderManagementConsoleApplication::OnShaderManagementConsoleWindowClosing() { ExitMainLoop(); diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h index 26dd93c08a..6229f5d77d 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.h @@ -30,7 +30,6 @@ namespace ShaderManagementConsole ////////////////////////////////////////////////////////////////////////// // AzFramework::Application void CreateStaticModules(AZStd::vector& outModules) override; - void Reflect(AZ::ReflectContext* context) override; const char* GetCurrentConfigurationName() const override; private: From 5cb001dffd1cc81af6f47ab7e492c0bb37a3961e Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 12:51:38 -0500 Subject: [PATCH 32/58] More fixes Signed-off-by: Dayo Lawal --- .../Application/AtomToolsApplication.h | 2 +- .../Source/Application/AtomToolsApplication.cpp | 15 ++++++++++----- .../Code/Source/MaterialEditorApplication.cpp | 6 ------ 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 08eac727a3..3b2e5a7e8a 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -89,7 +89,7 @@ namespace AtomToolsFramework virtual void LoadSettings(); virtual void UnloadSettings(); - virtual void CompileCriticalAssets(const AZStd::vector &assetFiltersArray); + virtual void CompileCriticalAssets(); virtual void ProcessCommandLine(const AZ::CommandLine& commandLine); virtual bool LaunchDiscoveryService(); virtual void StartInternal(); diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index f968584998..0dc579b017 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -59,6 +59,11 @@ namespace AtomToolsFramework : Application(argc, argv) , AzQtApplication(*argc, *argv) { + connect(&m_timer, &QTimer::timeout, this, [&]() + { + this->PumpSystemEventLoopUntilEmpty(); + this->Tick(); + }); } void AtomToolsApplication::CreateReflectionManager() @@ -155,7 +160,7 @@ namespace AtomToolsFramework { // List of common asset filters for things that need to be compiled to run the material editor // Some of these things will not be necessary once we have proper support for queued asset loading and reloading - return AZStd::vector({ "passes/", "config/" }); + return AZStd::vector({}); } void AtomToolsApplication::AssetSystemAvailable() @@ -183,13 +188,13 @@ namespace AtomToolsFramework if (connectedToAssetProcessor) { - CompileCriticalAssets(GetCriticalAssetFilters()); + CompileCriticalAssets(); } AzFramework::AssetSystemStatusBus::Handler::BusDisconnect(); } - void AtomToolsApplication::CompileCriticalAssets(const AZStd::vector &assetFiltersArray) + void AtomToolsApplication::CompileCriticalAssets() { AZ_TracePrintf(GetBuildTargetName().c_str(), "Compiling critical assets.\n"); @@ -198,7 +203,7 @@ namespace AtomToolsFramework // Forced asset processor to synchronously process all critical assets // Note: with AssetManager's current implementation, a compiled asset won't be added in asset registry until next system tick. // So the asset id won't be found right after CompileAssetSync call. - for (const AZStd::string& assetFilters : assetFiltersArray) + for (const AZStd::string& assetFilters : GetCriticalAssetFilters()) { AZ_TracePrintf(GetBuildTargetName().c_str(), "Compiling critical asset matching: %s.\n", assetFilters.c_str()); @@ -424,7 +429,7 @@ namespace AtomToolsFramework void AtomToolsApplication::Tick(float deltaOverride) { TickSystem(); - Application::Tick(deltaOverride); + Base::Tick(deltaOverride); if (WasExitMainLoopRequested()) { diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 57313c6694..09c7588de9 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -78,12 +78,6 @@ namespace MaterialEditor AZ::SettingsRegistryMergeUtils::MergeSettingsToRegistry_AddBuildSystemTargetSpecialization( *AZ::SettingsRegistry::Get(), GetBuildTargetName()); - - connect(&m_timer, &QTimer::timeout, this, [&]() - { - this->PumpSystemEventLoopUntilEmpty(); - this->Tick(); - }); } MaterialEditorApplication::~MaterialEditorApplication() From 76a3195487e0c0a3f4cd9f01b089653b0336093d Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 27 Jul 2021 10:52:22 -0700 Subject: [PATCH 33/58] remove null data check from connected slots Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 545500c57e..883e15cd29 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -4343,6 +4343,9 @@ namespace ScriptCanvas execution->AddInput({ &input, inputVariable, DebugDataSource::FromSelfSlot(input, inputVariable->m_datum.GetType()) }); } + + // Check for known null reads + CheckForKnownNullDereference(execution, execution->GetInput(execution->GetInputCount() - 1), input); } else { @@ -4374,9 +4377,6 @@ namespace ScriptCanvas return; } } - - // Check for known null reads - CheckForKnownNullDereference(execution, execution->GetInput(execution->GetInputCount() - 1), input); } bool AbstractCodeModel::ParseInputThisPointer(ExecutionTreePtr execution) From 33c408f65424358c7bfb0c1db44081fea4c31d73 Mon Sep 17 00:00:00 2001 From: Ken Pruiksma Date: Tue, 27 Jul 2021 13:31:05 -0500 Subject: [PATCH 34/58] Expose shadow bias to component & feature processors. (#2406) * Expose shadow bias to component & feature processors. Shadow bias now works more consistently with various near / far shadow planes and caster positions. Bias now also affects esm shadows which helps eliminate acne in certain situations. Signed-off-by: Ken Pruiksma * Adding jira comment to light configuration serialization version. Improved comment on final adjustment to bias before its sent to the shader. Signed-off-by: Ken Pruiksma * Hooking up bias to behavior context. Signed-off-by: Ken Pruiksma --- .../Features/Shadow/ProjectedShadow.azsli | 13 +- .../DiskLightFeatureProcessorInterface.h | 2 + .../PointLightFeatureProcessorInterface.h | 2 + ...ProjectedShadowFeatureProcessorInterface.h | 2 + .../CoreLights/DiskLightFeatureProcessor.cpp | 5 + .../CoreLights/DiskLightFeatureProcessor.h | 1 + .../CoreLights/PointLightFeatureProcessor.cpp | 5 + .../CoreLights/PointLightFeatureProcessor.h | 1 + .../ProjectedShadowFeatureProcessor.cpp | 37 ++-- .../Shadows/ProjectedShadowFeatureProcessor.h | 2 + .../CommonFeatures/CoreLights/AreaLightBus.h | 6 + .../CoreLights/AreaLightComponentConfig.h | 1 + .../CoreLights/AreaLightComponentConfig.cpp | 3 +- .../AreaLightComponentController.cpp | 18 ++ .../CoreLights/AreaLightComponentController.h | 2 + .../Source/CoreLights/DiskLightDelegate.cpp | 8 + .../Source/CoreLights/DiskLightDelegate.h | 1 + .../CoreLights/EditorAreaLightComponent.cpp | 9 + .../Source/CoreLights/LightDelegateBase.h | 1 + .../CoreLights/LightDelegateInterface.h | 4 +- .../Source/CoreLights/SphereLightDelegate.cpp | 167 +++++++++--------- .../Source/CoreLights/SphereLightDelegate.h | 1 + 22 files changed, 186 insertions(+), 105 deletions(-) diff --git a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli index 97862b6f6e..2fea4650b3 100644 --- a/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli +++ b/Gems/Atom/Feature/Common/Assets/ShaderLib/Atom/Features/Shadow/ProjectedShadow.azsli @@ -62,6 +62,7 @@ class ProjectedShadow float3 m_lightDirection; float3 m_normalVector; float3 m_shadowPosition; + float m_bias; }; float ProjectedShadow::GetVisibility( @@ -238,7 +239,7 @@ float ProjectedShadow::GetVisibilityEsm() } const float3 atlasPosition = GetAtlasPosition(m_shadowPosition.xy); const float depth = PerspectiveDepthToLinear( - m_shadowPosition.z, + m_shadowPosition.z - m_bias, coefficients); const float occluder = shadowmap.SampleLevel( PassSrg::LinearSampler, @@ -280,7 +281,7 @@ float ProjectedShadow::GetVisibilityEsmPcf() } const float3 atlasPosition = GetAtlasPosition(m_shadowPosition.xy); const float depth = PerspectiveDepthToLinear( - m_shadowPosition.z, + m_shadowPosition.z - m_bias, coefficients); const float occluder = shadowmap.SampleLevel( PassSrg::LinearSampler, @@ -346,7 +347,7 @@ float ProjectedShadow::SamplePcfBicubic() param.shadowPos = float3(atlasPosition.xy * ViewSrg::m_invShadowmapAtlasSize, atlasPosition.z); param.shadowMapSize = ViewSrg::m_shadowmapAtlasSize; param.invShadowMapSize = ViewSrg::m_invShadowmapAtlasSize; - param.comparisonValue = m_shadowPosition.z - ViewSrg::m_projectedShadows[m_shadowIndex].m_bias; + param.comparisonValue = m_shadowPosition.z - m_bias; param.samplerState = SceneSrg::m_hwPcfSampler; if (filteringSampleCount <= 4) @@ -384,8 +385,8 @@ bool ProjectedShadow::IsShadowed(float3 shadowPosition) PassSrg::LinearSampler, float3(atlasPosition.xy * invAtlasSize, atlasPosition.z), /*LOD=*/0).r; const float depthDiff = depthInShadowmap - shadowPosition.z; - float bias = ViewSrg::m_projectedShadows[m_shadowIndex].m_bias; - if (depthDiff < -bias) + + if (depthDiff < -m_bias) { return true; } @@ -428,6 +429,8 @@ void ProjectedShadow::SetShadowPosition() const float4x4 depthBiasMatrix = ViewSrg::m_projectedShadows[m_shadowIndex].m_depthBiasMatrix; float4 shadowPositionHomogeneous = mul(depthBiasMatrix, float4(m_worldPosition, 1)); m_shadowPosition = shadowPositionHomogeneous.xyz / shadowPositionHomogeneous.w; + + m_bias = ViewSrg::m_projectedShadows[m_shadowIndex].m_bias / shadowPositionHomogeneous.w; } float3 ProjectedShadow::GetAtlasPosition(float2 texturePosition) diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h index 9248add6f5..e4986eee93 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/DiskLightFeatureProcessorInterface.h @@ -84,6 +84,8 @@ namespace AZ //! Sets if shadows are enabled virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0; + //! Sets the shadow bias + virtual void SetShadowBias(LightHandle handle, float bias) = 0; //! Sets the shadowmap size (width and height) of the light. virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0; //! Specifies filter method of shadows. diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h index 8ad4fb89de..3383378dc7 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/CoreLights/PointLightFeatureProcessorInterface.h @@ -66,6 +66,8 @@ namespace AZ virtual void SetShadowsEnabled(LightHandle handle, bool enabled) = 0; //! Sets the shadowmap size (width and height) of the light. virtual void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) = 0; + //! Sets the shadow bias + virtual void SetShadowBias(LightHandle handle, float bias) = 0; //! Specifies filter method of shadows. virtual void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) = 0; //! Specifies the width of boundary between shadowed area and lit area in radians. The degree ofshadowed gradually changes on diff --git a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Shadows/ProjectedShadowFeatureProcessorInterface.h b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Shadows/ProjectedShadowFeatureProcessorInterface.h index c0cfff3dd5..6cbb0cfef1 100644 --- a/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Shadows/ProjectedShadowFeatureProcessorInterface.h +++ b/Gems/Atom/Feature/Common/Code/Include/Atom/Feature/Shadows/ProjectedShadowFeatureProcessorInterface.h @@ -50,6 +50,8 @@ namespace AZ::Render virtual void SetFieldOfViewY(ShadowId id, float fieldOfView) = 0; //! Sets the maximum resolution of the shadow map virtual void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) = 0; + //! Sets the shadow bias + virtual void SetShadowBias(ShadowId id, float bias) = 0; //! Sets the shadowmap Pcf method. virtual void SetPcfMethod(ShadowId id, PcfMethod method) = 0; //! Sets the shadow filter method diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp index 54410544a7..55be9d232e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.cpp @@ -308,6 +308,11 @@ namespace AZ AZStd::invoke(AZStd::forward(functor), m_shadowFeatureProcessor, shadowId, AZStd::forward(param)); } } + + void DiskLightFeatureProcessor::SetShadowBias(LightHandle handle, float bias) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowBias, bias); + } void DiskLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) { diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h index 0ff8efb1b1..2e97ae1ded 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/DiskLightFeatureProcessor.h @@ -50,6 +50,7 @@ namespace AZ void SetConstrainToConeLight(LightHandle handle, bool useCone) override; void SetConeAngles(LightHandle handle, float innerDegrees, float outerDegrees) override; void SetShadowsEnabled(LightHandle handle, bool enabled) override; + void SetShadowBias(LightHandle handle, float bias) override; void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override; void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override; void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override; diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp index 2b54b6ede1..9baa2ae1c2 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.cpp @@ -277,6 +277,11 @@ namespace AZ } } } + + void PointLightFeatureProcessor::SetShadowBias(LightHandle handle, float bias) + { + SetShadowSetting(handle, &ProjectedShadowFeatureProcessor::SetShadowBias, bias); + } void PointLightFeatureProcessor::SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) { diff --git a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h index d7bb25c71c..b7b644da9e 100644 --- a/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/CoreLights/PointLightFeatureProcessor.h @@ -47,6 +47,7 @@ namespace AZ void SetAttenuationRadius(LightHandle handle, float attenuationRadius) override; void SetBulbRadius(LightHandle handle, float bulbRadius) override; void SetShadowsEnabled(LightHandle handle, bool enabled) override; + void SetShadowBias(LightHandle handle, float bias) override; void SetShadowmapMaxResolution(LightHandle handle, ShadowmapSize shadowmapSize) override; void SetShadowFilterMethod(LightHandle handle, ShadowFilterMethod method) override; void SetSofteningBoundaryWidthAngle(LightHandle handle, float boundaryWidthRadians) override; diff --git a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp index 10dcffcf74..03ee176fd0 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.cpp @@ -143,7 +143,15 @@ namespace AZ::Render shadowProperty.m_desc.m_fieldOfViewYRadians = fieldOfViewYRadians; UpdateShadowView(shadowProperty); } - + + void ProjectedShadowFeatureProcessor::SetShadowBias(ShadowId id, float bias) + { + AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetShadowBias()."); + + ShadowProperty& shadowProperty = GetShadowPropertyFromShadowId(id); + shadowProperty.m_bias = bias; + } + void ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) { AZ_Assert(id.IsValid(), "Invalid ShadowId passed to ProjectedShadowFeatureProcessor::SetShadowmapMaxResolution()."); @@ -265,23 +273,20 @@ namespace AZ::Render view->SetCameraTransform(Matrix3x4::CreateFromTransform(desc.m_transform)); ShadowData& shadowData = m_shadowData.GetElement(shadowProperty.m_shadowId.GetIndex()); - shadowData.m_bias = (nearDist / farDist) * 0.1f; + + // Adjust the manually set bias to a more appropriate range for the shader. Scale the bias by the + // near plane so that the bias appears consistent as other light properties change. + shadowData.m_bias = nearDist * shadowProperty.m_bias * 0.01f; FilterParameter& esmData = m_shadowData.GetElement(shadowProperty.m_shadowId.GetIndex()); - if (FilterMethodIsEsm(shadowData)) - { - // Set parameters to calculate linear depth if ESM is used. - m_filterParameterNeedsUpdate = true; - esmData.m_isEnabled = true; - esmData.m_n_f_n = nearDist / (farDist - nearDist); - esmData.m_n_f = nearDist - farDist; - esmData.m_f = farDist; - } - else - { - // Reset enabling flag if ESM is not used. - esmData.m_isEnabled = false; - } + + // Set parameters to calculate linear depth if ESM is used. + esmData.m_n_f_n = nearDist / (farDist - nearDist); + esmData.m_n_f = nearDist - farDist; + esmData.m_f = farDist; + + esmData.m_isEnabled = FilterMethodIsEsm(shadowData); + m_filterParameterNeedsUpdate = m_filterParameterNeedsUpdate || esmData.m_isEnabled; for (EsmShadowmapsPass* esmPass : m_esmShadowmapsPasses) { diff --git a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h index 4da4e2ff1e..3dbf88addb 100644 --- a/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h +++ b/Gems/Atom/Feature/Common/Code/Source/Shadows/ProjectedShadowFeatureProcessor.h @@ -47,6 +47,7 @@ namespace AZ::Render void SetAspectRatio(ShadowId id, float aspectRatio) override; void SetFieldOfViewY(ShadowId id, float fieldOfViewYRadians) override; void SetShadowmapMaxResolution(ShadowId id, ShadowmapSize size) override; + void SetShadowBias(ShadowId id, float bias) override; void SetPcfMethod(ShadowId id, PcfMethod method); void SetEsmExponent(ShadowId id, float exponent); void SetShadowFilterMethod(ShadowId id, ShadowFilterMethod method) override; @@ -79,6 +80,7 @@ namespace AZ::Render { ProjectedShadowDescriptor m_desc; RPI::ViewPtr m_shadowmapView; + float m_bias = 0.1f; ShadowId m_shadowId; }; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightBus.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightBus.h index 9286db2817..06b00a6b84 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightBus.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightBus.h @@ -101,6 +101,12 @@ namespace AZ //! Sets if shadows should be enabled. virtual void SetEnableShadow(bool enabled) = 0; + + //! Returns the shadow bias. + virtual float GetShadowBias() const = 0; + + //! Sets the shadow bias. + virtual void SetShadowBias(float bias) = 0; //! Returns the maximum width and height of shadowmap. virtual ShadowmapSize GetShadowmapMaxSize() const = 0; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h index 8a3bb337a2..b890b3e264 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Include/AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h @@ -56,6 +56,7 @@ namespace AZ // Shadows (only used for supported shapes) bool m_enableShadow = false; + float m_bias = 0.1f; ShadowmapSize m_shadowmapMaxSize = ShadowmapSize::Size256; ShadowFilterMethod m_shadowFilterMethod = ShadowFilterMethod::None; PcfMethod m_pcfMethod = PcfMethod::Bicubic; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp index c442ee39ae..b9da5ccff4 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentConfig.cpp @@ -18,7 +18,7 @@ namespace AZ if (auto serializeContext = azrtti_cast(context)) { serializeContext->Class() - ->Version(6) // ATOM-15654 + ->Version(7) // ATOM-16034 ->Field("LightType", &AreaLightComponentConfig::m_lightType) ->Field("Color", &AreaLightComponentConfig::m_color) ->Field("IntensityMode", &AreaLightComponentConfig::m_intensityMode) @@ -33,6 +33,7 @@ namespace AZ ->Field("OuterShutterAngleDegrees", &AreaLightComponentConfig::m_outerShutterAngleDegrees) // Shadows ->Field("Enable Shadow", &AreaLightComponentConfig::m_enableShadow) + ->Field("Shadow Bias", &AreaLightComponentConfig::m_bias) ->Field("Shadowmap Max Size", &AreaLightComponentConfig::m_shadowmapMaxSize) ->Field("Shadow Filter Method", &AreaLightComponentConfig::m_shadowFilterMethod) ->Field("Softening Boundary Width", &AreaLightComponentConfig::m_boundaryWidthInDegrees) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.cpp index a6bf66d20e..b90b145320 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.cpp @@ -68,6 +68,8 @@ namespace AZ::Render ->Event("GetEnableShadow", &AreaLightRequestBus::Events::GetEnableShadow) ->Event("SetEnableShadow", &AreaLightRequestBus::Events::SetEnableShadow) + ->Event("GetShadowBias", &AreaLightRequestBus::Events::GetShadowBias) + ->Event("SetShadowBias", &AreaLightRequestBus::Events::SetShadowBias) ->Event("GetShadowmapMaxSize", &AreaLightRequestBus::Events::GetShadowmapMaxSize) ->Event("SetShadowmapMaxSize", &AreaLightRequestBus::Events::SetShadowmapMaxSize) ->Event("GetShadowFilterMethod", &AreaLightRequestBus::Events::GetShadowFilterMethod) @@ -94,6 +96,7 @@ namespace AZ::Render ->VirtualProperty("OuterShutterAngle", "GetOuterShutterAngle", "SetOuterShutterAngle") ->VirtualProperty("ShadowsEnabled", "GetEnableShadow", "SetEnableShadow") + ->VirtualProperty("ShadowBias", "GetShadowBias", "SetShadowBias") ->VirtualProperty("ShadowmapMaxSize", "GetShadowmapMaxSize", "SetShadowmapMaxSize") ->VirtualProperty("ShadowFilterMethod", "GetShadowFilterMethod", "SetShadowFilterMethod") ->VirtualProperty("SofteningBoundaryWidthAngle", "GetSofteningBoundaryWidthAngle", "SetSofteningBoundaryWidthAngle") @@ -307,6 +310,7 @@ namespace AZ::Render m_lightShapeDelegate->SetEnableShadow(m_configuration.m_enableShadow); if (m_configuration.m_enableShadow) { + m_lightShapeDelegate->SetShadowBias(m_configuration.m_bias); m_lightShapeDelegate->SetShadowmapMaxSize(m_configuration.m_shadowmapMaxSize); m_lightShapeDelegate->SetShadowFilterMethod(m_configuration.m_shadowFilterMethod); m_lightShapeDelegate->SetSofteningBoundaryWidthAngle(m_configuration.m_boundaryWidthInDegrees); @@ -467,6 +471,20 @@ namespace AZ::Render m_lightShapeDelegate->SetEnableShadow(enabled); } } + + float AreaLightComponentController::GetShadowBias() const + { + return m_configuration.m_bias; + } + + void AreaLightComponentController::SetShadowBias(float bias) + { + m_configuration.m_bias = bias; + if (m_lightShapeDelegate) + { + m_lightShapeDelegate->SetShadowBias(bias); + } + } ShadowmapSize AreaLightComponentController::GetShadowmapMaxSize() const { diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.h index 0a835a75d0..d290beb81d 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/AreaLightComponentController.h @@ -76,6 +76,8 @@ namespace AZ bool GetEnableShadow() const override; void SetEnableShadow(bool enabled) override; + float GetShadowBias() const override; + void SetShadowBias(float bias) override; ShadowmapSize GetShadowmapMaxSize() const override; void SetShadowmapMaxSize(ShadowmapSize size) override; ShadowFilterMethod GetShadowFilterMethod() const override; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.cpp index 06d0b39981..c6e4441d57 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.cpp @@ -123,6 +123,14 @@ namespace AZ::Render } } + void DiskLightDelegate::SetShadowBias(float bias) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) + { + GetFeatureProcessor()->SetShadowBias(GetLightHandle(), bias); + } + } + void DiskLightDelegate::SetShadowmapMaxSize(ShadowmapSize size) { if (GetShadowsEnabled() && GetLightHandle().IsValid()) diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.h index 53ddae669b..6931068635 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/DiskLightDelegate.h @@ -41,6 +41,7 @@ namespace AZ void SetShutterAngles(float innerAngleDegrees, float outerAngleDegrees) override; void SetEnableShadow(bool enabled) override; + void SetShadowBias(float bias) override; void SetShadowmapMaxSize(ShadowmapSize size) override; void SetShadowFilterMethod(ShadowFilterMethod method) override; void SetSofteningBoundaryWidthAngle(float widthInDegrees) override; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp index b58ca6448a..e45f460f18 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/EditorAreaLightComponent.cpp @@ -131,6 +131,15 @@ namespace AZ ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled) + ->DataElement(Edit::UIHandlers::Slider, &AreaLightComponentConfig::m_bias, "Bias", "How deep in shadow a surface must be before being affected by it.") + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute(Edit::Attributes::Min, 0.0f) + ->Attribute(Edit::Attributes::Max, 100.0f) + ->Attribute(Edit::Attributes::SoftMin, 0.0f) + ->Attribute(Edit::Attributes::SoftMax, 1.0f) + ->Attribute(Edit::Attributes::ChangeNotify, Edit::PropertyRefreshLevels::ValuesOnly) + ->Attribute(Edit::Attributes::Visibility, &AreaLightComponentConfig::SupportsShadows) + ->Attribute(Edit::Attributes::ReadOnly, &AreaLightComponentConfig::ShadowsDisabled) ->DataElement(Edit::UIHandlers::ComboBox, &AreaLightComponentConfig::m_shadowFilterMethod, "Shadow filter method", "Filtering method of edge-softening of shadows.\n" " None: no filtering\n" diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.h index 18d88b72af..415878081c 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateBase.h @@ -53,6 +53,7 @@ namespace AZ void SetShutterAngles([[maybe_unused]]float innerAngleDegrees, [[maybe_unused]]float outerAngleDegrees) override {}; void SetEnableShadow(bool enabled) override { m_shadowsEnabled = enabled; }; + void SetShadowBias([[maybe_unused]] float bias) override {}; void SetShadowmapMaxSize([[maybe_unused]] ShadowmapSize size) override {}; void SetShadowFilterMethod([[maybe_unused]] ShadowFilterMethod method) override {}; void SetSofteningBoundaryWidthAngle([[maybe_unused]] float widthInDegrees) override {}; diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateInterface.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateInterface.h index 52f9958d40..f18c3ef9af 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateInterface.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/LightDelegateInterface.h @@ -67,8 +67,10 @@ namespace AZ // Shadows - //! Sets if shadows should be enabled + //! Sets if shadows should be enabled virtual void SetEnableShadow(bool enabled) = 0; + //! Sets the shadow bias + virtual void SetShadowBias(float bias) = 0; //! Sets the maximum resolution of the shadow map virtual void SetShadowmapMaxSize(ShadowmapSize size) = 0; //! Sets the filter method for the shadow diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp index 1da6847269..edf08ba8c9 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.cpp @@ -11,121 +11,124 @@ #include #include -namespace AZ +namespace AZ::Render { - namespace Render + SphereLightDelegate::SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible) + : LightDelegateBase(entityId, isVisible) + , m_shapeBus(shapeBus) { - SphereLightDelegate::SphereLightDelegate(LmbrCentral::SphereShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible) - : LightDelegateBase(entityId, isVisible) - , m_shapeBus(shapeBus) - { - InitBase(entityId); - } + InitBase(entityId); + } - float SphereLightDelegate::CalculateAttenuationRadius(float lightThreshold) const - { - // Calculate the radius at which the irradiance will be equal to cutoffIntensity. - float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen); - return sqrt(intensity / lightThreshold); - } + float SphereLightDelegate::CalculateAttenuationRadius(float lightThreshold) const + { + // Calculate the radius at which the irradiance will be equal to cutoffIntensity. + float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen); + return sqrt(intensity / lightThreshold); + } - void SphereLightDelegate::HandleShapeChanged() + void SphereLightDelegate::HandleShapeChanged() + { + if (GetLightHandle().IsValid()) { - if (GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation()); - GetFeatureProcessor()->SetBulbRadius(GetLightHandle(), GetRadius()); - } + GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation()); + GetFeatureProcessor()->SetBulbRadius(GetLightHandle(), GetRadius()); } + } - float SphereLightDelegate::GetSurfaceArea() const - { - float radius = GetRadius(); - return 4.0f * Constants::Pi * radius * radius; - } + float SphereLightDelegate::GetSurfaceArea() const + { + float radius = GetRadius(); + return 4.0f * Constants::Pi * radius * radius; + } - float SphereLightDelegate::GetRadius() const - { - return m_shapeBus->GetRadius() * GetTransform().GetUniformScale(); - } + float SphereLightDelegate::GetRadius() const + { + return m_shapeBus->GetRadius() * GetTransform().GetUniformScale(); + } - void SphereLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const + void SphereLightDelegate::DrawDebugDisplay(const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const + { + if (isSelected) { - if (isSelected) - { - debugDisplay.SetColor(color); + debugDisplay.SetColor(color); - // Draw a sphere for the attenuation radius - debugDisplay.DrawWireSphere(transform.GetTranslation(), GetConfig()->m_attenuationRadius); - } + // Draw a sphere for the attenuation radius + debugDisplay.DrawWireSphere(transform.GetTranslation(), GetConfig()->m_attenuationRadius); } + } - void SphereLightDelegate::SetEnableShadow(bool enabled) + void SphereLightDelegate::SetEnableShadow(bool enabled) + { + Base::SetEnableShadow(enabled); + + if (GetLightHandle().IsValid()) { - Base::SetEnableShadow(enabled); - - if (GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled); - } + GetFeatureProcessor()->SetShadowsEnabled(GetLightHandle(), enabled); } - - void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size) + } + + void SphereLightDelegate::SetShadowBias(float bias) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size); - } + GetFeatureProcessor()->SetShadowBias(GetLightHandle(), bias); } + } - void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method) + void SphereLightDelegate::SetShadowmapMaxSize(ShadowmapSize size) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method); - } + GetFeatureProcessor()->SetShadowmapMaxResolution(GetLightHandle(), size); } + } - void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees) + void SphereLightDelegate::SetShadowFilterMethod(ShadowFilterMethod method) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees)); - } + GetFeatureProcessor()->SetShadowFilterMethod(GetLightHandle(), method); } + } - void SphereLightDelegate::SetPredictionSampleCount(uint32_t count) + void SphereLightDelegate::SetSofteningBoundaryWidthAngle(float widthInDegrees) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count); - } + GetFeatureProcessor()->SetSofteningBoundaryWidthAngle(GetLightHandle(), DegToRad(widthInDegrees)); } + } - void SphereLightDelegate::SetFilteringSampleCount(uint32_t count) + void SphereLightDelegate::SetPredictionSampleCount(uint32_t count) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count); - } + GetFeatureProcessor()->SetPredictionSampleCount(GetLightHandle(), count); } + } - void SphereLightDelegate::SetPcfMethod(PcfMethod method) + void SphereLightDelegate::SetFilteringSampleCount(uint32_t count) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method); - } + GetFeatureProcessor()->SetFilteringSampleCount(GetLightHandle(), count); } + } - void SphereLightDelegate::SetEsmExponent(float esmExponent) + void SphereLightDelegate::SetPcfMethod(PcfMethod method) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) { - if (GetShadowsEnabled() && GetLightHandle().IsValid()) - { - GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), esmExponent); - } + GetFeatureProcessor()->SetPcfMethod(GetLightHandle(), method); } + } - - } // namespace Render -} // namespace AZ + void SphereLightDelegate::SetEsmExponent(float esmExponent) + { + if (GetShadowsEnabled() && GetLightHandle().IsValid()) + { + GetFeatureProcessor()->SetEsmExponent(GetLightHandle(), esmExponent); + } + } +} // namespace AZ::Render diff --git a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h index 6dd872d693..984af56c17 100644 --- a/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h +++ b/Gems/AtomLyIntegration/CommonFeatures/Code/Source/CoreLights/SphereLightDelegate.h @@ -31,6 +31,7 @@ namespace AZ float GetSurfaceArea() const override; float GetEffectiveSolidAngle() const override { return PhotometricValue::OmnidirectionalSteradians; } void SetEnableShadow(bool enabled) override; + void SetShadowBias(float bias) override; void SetShadowmapMaxSize(ShadowmapSize size) override; void SetShadowFilterMethod(ShadowFilterMethod method) override; void SetSofteningBoundaryWidthAngle(float widthInDegrees) override; From 4b0527c07f27b3bbdd7f29757e3369b487128b49 Mon Sep 17 00:00:00 2001 From: Dayo Lawal Date: Tue, 27 Jul 2021 13:42:48 -0500 Subject: [PATCH 35/58] Moving comments Signed-off-by: Dayo Lawal --- .../AtomToolsFramework/Application/AtomToolsApplication.h | 2 +- .../Code/Source/Application/AtomToolsApplication.cpp | 2 -- .../MaterialEditor/Code/Source/MaterialEditorApplication.cpp | 2 -- .../MaterialEditor/Code/Source/MaterialEditorApplication.h | 3 +++ .../Code/Source/ShaderManagementConsoleApplication.cpp | 2 -- 5 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h index 3b2e5a7e8a..bceea24aad 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Include/AtomToolsFramework/Application/AtomToolsApplication.h @@ -23,7 +23,7 @@ namespace AtomToolsFramework { - //!Base class for Atom tools to inherit from + //! Base class for Atom tools to inherit from class AtomToolsApplication : public AzFramework::Application , public AzQtComponents::AzQtApplication diff --git a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp index 0dc579b017..3a542db1a4 100644 --- a/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp +++ b/Gems/Atom/Tools/AtomToolsFramework/Code/Source/Application/AtomToolsApplication.cpp @@ -158,8 +158,6 @@ namespace AtomToolsFramework AZStd::vector AtomToolsApplication::GetCriticalAssetFilters() const { - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading return AZStd::vector({}); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp index 09c7588de9..4dd6b6d9dc 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.cpp @@ -113,8 +113,6 @@ namespace MaterialEditor AZStd::vector MaterialEditorApplication::GetCriticalAssetFilters() const { - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading return AZStd::vector({ "passes/", "config/", "MaterialEditor" }); } diff --git a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h index 0177013a3d..5f3b71a5aa 100644 --- a/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h +++ b/Gems/Atom/Tools/MaterialEditor/Code/Source/MaterialEditorApplication.h @@ -49,6 +49,9 @@ namespace MaterialEditor void ProcessCommandLine(const AZ::CommandLine& commandLine) override; void StartInternal() override; AZStd::string GetBuildTargetName() const override; + + //! List of common asset filters for things that need to be compiled to run the material editor + //! Some of these things will not be necessary once we have proper support for queued asset loading and reloading AZStd::vector GetCriticalAssetFilters() const override; }; } // namespace MaterialEditor diff --git a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp index 6f6ee697d5..96046bf98e 100644 --- a/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp +++ b/Gems/Atom/Tools/ShaderManagementConsole/Code/Source/ShaderManagementConsoleApplication.cpp @@ -102,8 +102,6 @@ namespace ShaderManagementConsole AZStd::vector ShaderManagementConsoleApplication::GetCriticalAssetFilters() const { - // List of common asset filters for things that need to be compiled to run the material editor - // Some of these things will not be necessary once we have proper support for queued asset loading and reloading return AZStd::vector({ "passes/", "config/" }); } From a20588952e05f7d3ea3a5a2270f2afeeb946ec36 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Tue, 27 Jul 2021 15:41:17 -0700 Subject: [PATCH 36/58] disable vcpkg for every project (#2507) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/Platform/Common/Directory.Build.props | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmake/Platform/Common/Directory.Build.props b/cmake/Platform/Common/Directory.Build.props index 1adf33ee89..73aa984073 100644 --- a/cmake/Platform/Common/Directory.Build.props +++ b/cmake/Platform/Common/Directory.Build.props @@ -10,7 +10,10 @@ SPDX-License-Identifier: Apache-2.0 OR MIT true true + @VCPKG_CONFIGURATION_MAPPING@ + + false From 9742626aba3b763bfb1383e0c1a86f951a2c25ee Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 27 Jul 2021 15:59:28 -0700 Subject: [PATCH 37/58] Make SC unit tests run serially Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index 23c9627e83..8f3ba103e7 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -113,6 +113,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests + TEST_SERIAL true ) endif() From 7b7adb8573122ad3b9b4bcffa46b4629e45bb959 Mon Sep 17 00:00:00 2001 From: amzn-phist <52085794+amzn-phist@users.noreply.github.com> Date: Tue, 27 Jul 2021 18:18:03 -0500 Subject: [PATCH 38/58] Don't require a specific version of Wwise SDK, allow for later versions to be used (#2484) * Updates the Wwise SDK detection in CMake Parses AkWwiseSDKVersion.h to obtain the version instead of requiring an exact version to be installed. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Updates readme.md information about Wwise Rewrite some of the setup info about Wwise, mention the two ways in which Wwise can be found via CMake and that users can install later versions than the one specified. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Remove unnecessary parts of Wwise version detect Don't need to parse the file contents, it was only being used to print a message to CMake. Simplify the validation to just checking that the SDK version header exists. Maybe in the future we can reinstate better version checking to make sure the version falls within a range. Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> * Updates capitalization of Audiokinetic name Signed-off-by: amzn-phist <52085794+amzn-phist@users.noreply.github.com> --- Gems/AudioEngineWwise/gem.json | 2 +- README.md | 13 +++++++------ cmake/3rdParty/FindWwise.cmake | 30 +++++++++--------------------- 3 files changed, 17 insertions(+), 28 deletions(-) diff --git a/Gems/AudioEngineWwise/gem.json b/Gems/AudioEngineWwise/gem.json index dc5f968bc7..699ed8419a 100644 --- a/Gems/AudioEngineWwise/gem.json +++ b/Gems/AudioEngineWwise/gem.json @@ -8,5 +8,5 @@ "canonical_tags": ["Gem"], "user_tags": ["Audio", "Utility", "Tools"], "icon_path": "preview.png", - "requirements": "Users will need to download WWise from the AudioKinetic web site: https://www.audiokinetic.com/download/" + "requirements": "Users will need to download Wwise from the Audiokinetic web site: https://www.audiokinetic.com/download/" } diff --git a/README.md b/README.md index 6b88097739..c129fffb6c 100644 --- a/README.md +++ b/README.md @@ -41,11 +41,13 @@ git clone https://github.com/o3de/o3de.git #### Optional -* Wwise - 2021.1.1.7601 minimum: [https://www.audiokinetic.com/download/](https://www.audiokinetic.com/download/) +* Wwise version 2021.1.1.7601 minimum: [https://www.audiokinetic.com/download/](https://www.audiokinetic.com/download/) * Note: This requires registration and installation of a client application to download - * Make sure to select the SDK(C++) component during installation of Wwise - * You will also need to set an environment variable: `set LY_WWISE_INSTALL_PATH=` - * For example: `set LY_WWISE_INSTALL_PATH="C:\Program Files (x86)\Audiokinetic\Wwise 2021.1.1.7601"` + * Note: It is generally okay to use a more recent version of Wwise, but some SDK updates will require code changes + * Make sure to select the `SDK(C++)` component during installation of Wwise + * CMake can find the Wwise install location in two ways: + * The `LY_WWISE_INSTALL_PATH` CMake cache variable -- this is checked first + * The `WWISEROOT` environment variable which is set when installing Wwise SDK ### Quick Start Build Steps @@ -54,8 +56,7 @@ git clone https://github.com/o3de/o3de.git 1. Install the following redistributables to the following: - Visual Studio and VC++ redistributable can be installed to any location - CMake can be installed to any location, as long as it's available in the system path - - (Optional) Wwise can be installed anywhere, but you will need to set an environment variable for CMake to detect it: `set LY_WWISE_INSTALL_PATH=` - + 1. Configure the source into a solution using this command line, replacing and <3rdParty cache path> to a path you've created: ``` cmake -B -S -G "Visual Studio 16" -DLY_3RDPARTY_PATH=<3rdParty cache path> -DLY_UNITY_BUILD=ON -DLY_PROJECTS=AutomatedTesting diff --git a/cmake/3rdParty/FindWwise.cmake b/cmake/3rdParty/FindWwise.cmake index 8cd6db31dd..4cb95da319 100644 --- a/cmake/3rdParty/FindWwise.cmake +++ b/cmake/3rdParty/FindWwise.cmake @@ -6,25 +6,16 @@ # # -# The current supported version of Wwise -set(WWISE_VERSION 2021.1.1.7601) - # Wwise Install Path -# Initialize to the default 3rdParty path -set(LY_WWISE_INSTALL_PATH "" CACHE PATH "Path to Wwise version ${WWISE_VERSION} installation.") +set(LY_WWISE_INSTALL_PATH "" CACHE PATH "Path to Wwise installation.") +# Check for a known file in the SDK path to verify the path function(is_valid_sdk sdk_path is_valid) set(${is_valid} FALSE PARENT_SCOPE) if(EXISTS ${sdk_path}) set(sdk_version_file ${sdk_path}/SDK/include/AK/AkWwiseSDKVersion.h) if(EXISTS ${sdk_version_file}) - string(FIND ${sdk_path} ${WWISE_VERSION} index) - if(NOT index EQUAL -1) - set(${is_valid} TRUE PARENT_SCOPE) - else() - # The install path doesn't contain the WWISE_VERSION string. - # The path could still be correct, but it would require parsing the AkWwiseSDKVersion.h to verify. - endif() + set(${is_valid} TRUE PARENT_SCOPE) endif() endif() endfunction() @@ -32,19 +23,17 @@ endfunction() # Paths that will be checked, in order: # - CMake cache variable # - WWISEROOT Environment Variable -# - Standard 3rdParty path set(WWISE_SDK_PATHS "${LY_WWISE_INSTALL_PATH}" "$ENV{WWISEROOT}" - "${LY_3RDPARTY_PATH}/Wwise/${WWISE_VERSION}" ) set(found_sdk FALSE) -foreach(test_path ${WWISE_SDK_PATHS}) - is_valid_sdk(${test_path} found_sdk) +foreach(candidate_path ${WWISE_SDK_PATHS}) + is_valid_sdk(${candidate_path} found_sdk) if(found_sdk) - # Update the Wwise Install Path cache variable - set(LY_WWISE_INSTALL_PATH "${test_path}") + # Update the Wwise Install Path variable internally + set(LY_WWISE_INSTALL_PATH "${candidate_path}") break() endif() endforeach() @@ -112,15 +101,14 @@ set(WWISE_COMPILE_DEFINITIONS ) -# The default install path might look different than the standard 3rdParty format (${LY_3RDPARTY_PATH}//). # Use these to get the parent path and folder name before adding the external 3p target. -get_filename_component(WWISE_3P_ROOT ${LY_WWISE_INSTALL_PATH} DIRECTORY) +get_filename_component(WWISE_INSTALL_ROOT ${LY_WWISE_INSTALL_PATH} DIRECTORY) get_filename_component(WWISE_FOLDER ${LY_WWISE_INSTALL_PATH} NAME) ly_add_external_target( NAME Wwise VERSION "${WWISE_FOLDER}" - 3RDPARTY_ROOT_DIRECTORY "${WWISE_3P_ROOT}" + 3RDPARTY_ROOT_DIRECTORY "${WWISE_INSTALL_ROOT}" INCLUDE_DIRECTORIES SDK/include COMPILE_DEFINITIONS ${WWISE_COMPILE_DEFINITIONS} ) From c177fe3c040e585a0ae64504c96f6fcdd84aeff8 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 27 Jul 2021 16:27:36 -0700 Subject: [PATCH 39/58] use work around for missing SERIAL tag for ly_add_googletest() Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index 8f3ba103e7..7291cd65eb 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -113,8 +113,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests - TEST_SERIAL true ) + set_tests_properties(Gem::ScriptCanvasTesting.Editor.Tests.main::TEST_RUN PROPERTIES RUN_SERIAL true) endif() From 2174f8415ab4233cd87a135301c24dc36422457e Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 27 Jul 2021 18:32:00 -0700 Subject: [PATCH 40/58] making azcore tests serialized as a sanity check Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Code/Framework/AzCore/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Code/Framework/AzCore/CMakeLists.txt b/Code/Framework/AzCore/CMakeLists.txt index ea7cc27af5..0a03b6b77c 100644 --- a/Code/Framework/AzCore/CMakeLists.txt +++ b/Code/Framework/AzCore/CMakeLists.txt @@ -130,6 +130,7 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_googletest( NAME AZ::AzCore.Tests ) + set_tests_properties(AZ::AzCore.Tests.main::TEST_RUN PROPERTIES RUN_SERIAL true) ly_add_googlebenchmark( NAME AZ::AzCore.Benchmarks TARGET AZ::AzCore.Tests From 0cfac06c699c909626d0b7dcb41b44d301f6381b Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Tue, 27 Jul 2021 18:55:40 -0700 Subject: [PATCH 41/58] making azcore tests serialized as a sanity check only on non android Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Code/Framework/AzCore/CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Code/Framework/AzCore/CMakeLists.txt b/Code/Framework/AzCore/CMakeLists.txt index 0a03b6b77c..785352cf05 100644 --- a/Code/Framework/AzCore/CMakeLists.txt +++ b/Code/Framework/AzCore/CMakeLists.txt @@ -130,7 +130,9 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_googletest( NAME AZ::AzCore.Tests ) - set_tests_properties(AZ::AzCore.Tests.main::TEST_RUN PROPERTIES RUN_SERIAL true) + if(PAL_TRAIT_TEST_GOOGLE_TEST_SUPPORTED) + set_tests_properties(AZ::AzCore.Tests.main::TEST_RUN PROPERTIES RUN_SERIAL true) + endif() ly_add_googlebenchmark( NAME AZ::AzCore.Benchmarks TARGET AZ::AzCore.Tests From 6868a48bb08a39cb7ea380b0f57974ad93934dfd Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Tue, 27 Jul 2021 22:04:37 -0500 Subject: [PATCH 42/58] Adding o3de.py subcommands for engine.json and gem.json modification (#2411) The new commands are edit-engine-properties and edit-gem-properties They can modify specific fields within these manifest files, that should affect build system. More importantly, this commands can be used to modify the "engine_name" field in the engine.json and the "gem_name" field in the gem.json Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- scripts/o3de.py | 12 +- scripts/o3de/o3de/engine_properties.py | 82 +++++++++ scripts/o3de/o3de/gem_properties.py | 163 ++++++++++++++++++ scripts/o3de/o3de/project_properties.py | 6 +- scripts/o3de/tests/CMakeLists.txt | 14 ++ .../o3de/tests/unit_test_engine_properties.py | 72 ++++++++ .../o3de/tests/unit_test_gem_properties.py | 99 +++++++++++ .../tests/unit_test_project_properties.py | 3 +- 8 files changed, 444 insertions(+), 7 deletions(-) create mode 100644 scripts/o3de/o3de/engine_properties.py create mode 100644 scripts/o3de/o3de/gem_properties.py create mode 100644 scripts/o3de/tests/unit_test_engine_properties.py create mode 100644 scripts/o3de/tests/unit_test_gem_properties.py diff --git a/scripts/o3de.py b/scripts/o3de.py index 06873e1de2..03f737643f 100755 --- a/scripts/o3de.py +++ b/scripts/o3de.py @@ -28,7 +28,7 @@ def add_args(parser, subparsers) -> None: o3de_package_dir = (script_dir / 'o3de').resolve() # add the scripts/o3de directory to the front of the sys.path sys.path.insert(0, str(o3de_package_dir)) - from o3de import engine_template, global_project, register, print_registration, get_registration, \ + from o3de import engine_properties, engine_template, gem_properties, global_project, register, print_registration, get_registration, \ enable_gem, disable_gem, project_properties, sha256 # Remove the temporarily added path sys.path = sys.path[1:] @@ -52,9 +52,15 @@ def add_args(parser, subparsers) -> None: # remove a gem from a project disable_gem.add_args(subparsers) - - # modify project properties + + # modify engine properties + engine_properties.add_args(subparsers) + + # modify project properties project_properties.add_args(subparsers) + + # modify gem properties + gem_properties.add_args(subparsers) # sha256 sha256.add_args(subparsers) diff --git a/scripts/o3de/o3de/engine_properties.py b/scripts/o3de/o3de/engine_properties.py new file mode 100644 index 0000000000..92930dbb1c --- /dev/null +++ b/scripts/o3de/o3de/engine_properties.py @@ -0,0 +1,82 @@ +# +# 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 +# +# + +import argparse +import json +import os +import pathlib +import sys +import logging + +from o3de import manifest, utils + +logger = logging.getLogger() +logging.basicConfig() + +def edit_engine_props(engine_path: pathlib.Path = None, + engine_name: str = None, + new_name: str = None, + new_version: str = None) -> int: + if not engine_path and not engine_name: + logger.error(f'Either a engine path or a engine name must be supplied to lookup engine.json') + return 1 + if not engine_path: + engine_path = manifest.get_registered(engine_name=engine_name) + + if not engine_path: + logger.error(f'Error unable locate engine path: No engine with name {engine_name} is registered in any manifest') + return 1 + + engine_json_data = manifest.get_engine_json_data(engine_path=engine_path) + if not engine_json_data: + return 1 + + if new_name: + if not utils.validate_identifier(new_name): + logger.error(f'Engine name must be fewer than 64 characters, contain only alphanumeric, "_" or "-"' + f' characters, and start with a letter. {new_name}') + return 1 + engine_json_data['engine_name'] = new_name + if new_version: + engine_json_data['O3DEVersion'] = new_version + + return 0 if manifest.save_o3de_manifest(engine_json_data, pathlib.Path(engine_path) / 'engine.json') else 1 + +def _edit_engine_props(args: argparse) -> int: + return edit_engine_props(args.engine_path, + args.engine_name, + args.engine_new_name, + args.engine_version) + +def add_parser_args(parser): + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-ep', '--engine-path', type=pathlib.Path, required=False, + help='The path to the engine.') + group.add_argument('-en', '--engine-name', type=str, required=False, + help='The name of the engine.') + group = parser.add_argument_group('properties', 'arguments for modifying individual engine properties.') + group.add_argument('-enn', '--engine-new-name', type=str, required=False, + help='Sets the name for the engine.') + group.add_argument('-ev', '--engine-version', type=str, required=False, + help='Sets the version for the engine.') + parser.set_defaults(func=_edit_engine_props) + +def add_args(subparsers) -> None: + enable_engine_props_subparser = subparsers.add_parser('edit-engine-properties') + add_parser_args(enable_engine_props_subparser) + + +def main(): + the_parser = argparse.ArgumentParser() + add_parser_args(the_parser) + the_args = the_parser.parse_args() + ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1 + sys.exit(ret) + +if __name__ == "__main__": + main() diff --git a/scripts/o3de/o3de/gem_properties.py b/scripts/o3de/o3de/gem_properties.py new file mode 100644 index 0000000000..c97e5db89d --- /dev/null +++ b/scripts/o3de/o3de/gem_properties.py @@ -0,0 +1,163 @@ +# +# 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 +# +# + +import argparse +import json +import os +import pathlib +import sys +import logging + +from o3de import manifest, utils + +logger = logging.getLogger() +logging.basicConfig() + + +def update_values_in_key_list(existing_values: list, new_values: list or str, remove_values: list or str, + replace_values: list or str): + """ + Updates values within a list by first appending values in the new_values list, removing values in the remove_values + list and then replacing values in the replace_values list + :param existing_values list with existing values to modify + :param new_values list with values to add to the existing value list + :param remove_values list with values to remove from the existing value list + :param replace_values list with values to replace in the existing value list + + returns updated existing value list + """ + if new_values: + new_values = new_values.split() if isinstance(new_values, str) else new_values + existing_values.extend(new_values) + if remove_values: + remove_values = remove_values.split() if isinstance(remove_values, str) else remove_values + existing_values = list(filter(lambda value: value not in remove_values, existing_values)) + if replace_values: + replace_values = replace_values.split() if isinstance(replace_values, str) else replace_values + existing_values = replace_values + + return existing_values + + +def edit_gem_props(gem_path: pathlib.Path = None, + gem_name: str = None, + new_name: str = None, + new_display: str = None, + new_origin: str = None, + new_type: str = None, + new_summary: str = None, + new_icon: str = None, + new_requirements: str = None, + new_tags: list or str = None, + remove_tags: list or str = None, + replace_tags: list or str = None, + ) -> int: + + if not gem_path and not gem_name: + logger.error(f'Either a gem path or a gem name must be supplied to lookup gem.json') + return 1 + if not gem_path: + gem_path = manifest.get_registered(gem_name=gem_name) + + if not gem_path: + logger.error(f'Error unable locate gem path: No gem with name {gem_name} is registered in any manifest') + return 1 + + gem_json_data = manifest.get_gem_json_data(gem_path=gem_path) + if not gem_json_data: + return 1 + + update_key_dict = {} + if new_name: + if not utils.validate_identifier(new_name): + logger.error(f'Engine name must be fewer than 64 characters, contain only alphanumeric, "_" or "-"' + f' characters, and start with a letter. {new_name}') + return 1 + update_key_dict['gem_name'] = new_name + if new_display: + update_key_dict['display_name'] = new_display + if new_origin: + update_key_dict['origin'] = new_origin + if new_type: + update_key_dict['type'] = new_type + if new_summary: + update_key_dict['summary'] = new_summary + if new_icon: + update_key_dict['icon_path'] = new_icon + if new_requirements: + update_key_dict['icon_requirements'] = new_requirements + + update_key_dict['user_tags'] = update_values_in_key_list(gem_json_data.get('user_tags', []), new_tags, + remove_tags, replace_tags) + + gem_json_data.update(update_key_dict) + + return 0 if manifest.save_o3de_manifest(gem_json_data, pathlib.Path(gem_path) / 'gem.json') else 1 + + +def _edit_gem_props(args: argparse) -> int: + return edit_gem_props(args.gem_path, + args.gem_name, + args.gem_new_name, + args.gem_display, + args.gem_origin, + args.gem_type, + args.gem_summary, + args.gem_icon, + args.gem_requirements, + args.add_tags, + args.remove_tags, + args.replace_tags) + + +def add_parser_args(parser): + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument('-gp', '--gem-path', type=pathlib.Path, required=False, + help='The path to the gem.') + group.add_argument('-gn', '--gem-name', type=str, required=False, + help='The name of the gem.') + group = parser.add_argument_group('properties', 'arguments for modifying individual gem properties.') + group.add_argument('-gnn', '--gem-new-name', type=str, required=False, + help='Sets the name for the gem.') + group.add_argument('-gd', '--gem-display', type=str, required=False, + help='Sets the gem display name.') + group.add_argument('-go', '--gem-origin', type=str, required=False, + help='Sets description for gem origin.') + group.add_argument('-gt', '--gem-type', type=str, required=False, choices=['Code', 'Tool', 'Asset'], + help='Sets the gem type. Can only be one of the selected choices') + group.add_argument('-gs', '--gem-summary', type=str, required=False, + help='Sets the summary description of the gem.') + group.add_argument('-gi', '--gem-icon', type=str, required=False, + help='Sets the path to the projects icon resource.') + group.add_argument('-gr', '--gem-requirements', type=str, required=False, + help='Sets the description of the requirements needed to use the gem') + group = parser.add_mutually_exclusive_group(required=False) + group.add_argument('-at', '--add-tags', type=str, nargs='*', required=False, + help='Adds tag(s) to user_tags property. Can be specified multiple times') + group.add_argument('-dt', '--remove-tags', type=str, nargs='*', required=False, + help='Removes tag(s) from the user_tags property. Can be specified multiple times') + group.add_argument('-rt', '--replace-tags', type=str, nargs='*', required=False, + help='Replace tag(s) in user_tags property. Can be specified multiple times') + parser.set_defaults(func=_edit_gem_props) + + +def add_args(subparsers) -> None: + enable_gem_props_subparser = subparsers.add_parser('edit-gem-properties') + add_parser_args(enable_gem_props_subparser) + + +def main(): + the_parser = argparse.ArgumentParser() + add_parser_args(the_parser) + the_args = the_parser.parse_args() + ret = the_args.func(the_args) if hasattr(the_args, 'func') else 1 + sys.exit(ret) + + +if __name__ == "__main__": + main() diff --git a/scripts/o3de/o3de/project_properties.py b/scripts/o3de/o3de/project_properties.py index 977f9777b2..04731ad3de 100644 --- a/scripts/o3de/o3de/project_properties.py +++ b/scripts/o3de/o3de/project_properties.py @@ -26,7 +26,7 @@ def get_project_props(name: str = None, path: pathlib.Path = None) -> dict: return None return proj_json -def edit_project_props(proj_path: pathlib.Path, +def edit_project_props(proj_path: pathlib.Path = None, proj_name: str = None, new_name: str = None, new_origin: str = None, @@ -71,8 +71,8 @@ def edit_project_props(proj_path: pathlib.Path, tag_list = replace_tags.split() if isinstance(replace_tags, str) else replace_tags proj_json['user_tags'] = tag_list - manifest.save_o3de_manifest(proj_json, pathlib.Path(proj_path) / 'project.json') - return 0 + + return 0 if manifest.save_o3de_manifest(proj_json, pathlib.Path(proj_path) / 'project.json') else 1 def _edit_project_props(args: argparse) -> int: return edit_project_props(args.project_path, diff --git a/scripts/o3de/tests/CMakeLists.txt b/scripts/o3de/tests/CMakeLists.txt index 42ded05b29..00d0774c45 100644 --- a/scripts/o3de/tests/CMakeLists.txt +++ b/scripts/o3de/tests/CMakeLists.txt @@ -39,6 +39,13 @@ ly_add_pytest( EXCLUDE_TEST_RUN_TARGET_FROM_IDE ) +ly_add_pytest( + NAME o3de_engine_properties + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_engine_properties.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) + ly_add_pytest( NAME o3de_project_properties PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_project_properties.py @@ -46,6 +53,13 @@ ly_add_pytest( EXCLUDE_TEST_RUN_TARGET_FROM_IDE ) +ly_add_pytest( + NAME o3de_gem_properties + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_gem_properties.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) + ly_add_pytest( NAME o3de_template PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_engine_template.py diff --git a/scripts/o3de/tests/unit_test_engine_properties.py b/scripts/o3de/tests/unit_test_engine_properties.py new file mode 100644 index 0000000000..19cb7d4e62 --- /dev/null +++ b/scripts/o3de/tests/unit_test_engine_properties.py @@ -0,0 +1,72 @@ +# +# 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 +# +# + +import json +import pytest +import pathlib +from unittest.mock import patch + +from o3de import engine_properties + + +TEST_ENGINE_JSON_PAYLOAD = ''' +{ + "engine_name": "o3de", + "restricted_name": "o3de", + "FileVersion": 1, + "O3DEVersion": "0.0.0.0", + "O3DECopyrightYear": 2021, + "O3DEBuildNumber": 0, + "external_subdirectories": [ + "Gems/TestGem2" + ], + "projects": [ + ], + "templates": [ + "Templates/MinimalProject" + ] +} +''' + + +@pytest.fixture(scope='class') +def init_engine_json_data(request): + class EngineJsonData: + def __init__(self): + self.data = json.loads(TEST_ENGINE_JSON_PAYLOAD) + request.cls.engine_json = EngineJsonData() + +@pytest.mark.usefixtures('init_engine_json_data') +class TestEditEngineProperties: + @pytest.mark.parametrize("engine_path, engine_name, engine_new_name, engine_version, expected_result", [ + pytest.param(pathlib.PurePath('D:/o3de'), None, 'o3de-install', '1.0.0.0', 0), + pytest.param(None, 'o3de-install', 'o3de-sdk', '1.0.0.1', 0), + pytest.param(None, 'o3de-sdk', None, '2.0.0.0', 0), + ] + ) + def test_edit_engine_properties(self, engine_path, engine_name, engine_new_name, engine_version, expected_result): + + def get_engine_json_data(engine_path: pathlib.Path) -> dict: + return self.engine_json.data + + def get_engine_path(engine_name: str) -> pathlib.Path: + return pathlib.Path('D:/o3de') + + def save_o3de_manifest(new_engine_data: dict, engine_path: pathlib.Path) -> bool: + self.engine_json.data = new_engine_data + return True + + with patch('o3de.manifest.get_engine_json_data', side_effect=get_engine_json_data) as get_engine_json_data_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch, \ + patch('o3de.manifest.get_registered', side_effect=get_engine_path) as get_registered_patch: + result = engine_properties.edit_engine_props(engine_path, engine_name, engine_new_name, engine_version) + assert result == expected_result + if engine_new_name: + assert self.engine_json.data.get('engine_name', '') == engine_new_name + if engine_version: + assert self.engine_json.data.get('O3DEVersion', '') == engine_version diff --git a/scripts/o3de/tests/unit_test_gem_properties.py b/scripts/o3de/tests/unit_test_gem_properties.py new file mode 100644 index 0000000000..29d53fbee6 --- /dev/null +++ b/scripts/o3de/tests/unit_test_gem_properties.py @@ -0,0 +1,99 @@ +# +# 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 +# +# + +import json +import pytest +import pathlib +from unittest.mock import patch + +from o3de import gem_properties + + +TEST_GEM_JSON_PAYLOAD = ''' +{ + "gem_name": "TestGem", + "display_name": "TestGem", + "license": "What license TestGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "origin": "The primary repo for TestGem goes here: i.e. http://www.mydomain.com", + "type": "Code", + "summary": "A short description of TestGem.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "TestGem" + ], + "icon_path": "preview.png", + "requirements": "" +} +''' + + +@pytest.fixture(scope='class') +def init_gem_json_data(request): + class GemJsonData: + def __init__(self): + self.data = json.loads(TEST_GEM_JSON_PAYLOAD) + request.cls.gem_json = GemJsonData() + +@pytest.mark.usefixtures('init_gem_json_data') +class TestEditGemProperties: + @pytest.mark.parametrize("gem_path, gem_name, gem_new_name, gem_display, gem_origin,\ + gem_type, gem_summary, gem_icon, gem_requirements,\ + add_tags, remove_tags, replace_tags, expected_tags, expected_result", [ + pytest.param(pathlib.PurePath('D:/TestProject'), + None, 'TestGem2', 'New Gem Name', 'O3DE', 'Code', 'Gem that exercises Default Gem Template', + 'preview.png', '', + ['Physics', 'Rendering', 'Scripting'], None, None, ['TestGem', 'Physics', 'Rendering', 'Scripting'], + 0), + pytest.param(None, + 'TestGem2', None, 'New Gem Name', 'O3DE', 'Asset', 'Gem that exercises Default Gem Template', + 'preview.png', '', None, ['Physics'], None, ['TestGem', 'Rendering', 'Scripting'], 0), + pytest.param(None, + 'TestGem2', None, 'New Gem Name', 'O3DE', 'Tool', 'Gem that exercises Default Gem Template', + 'preview.png', '', None, None, ['Animation', 'TestGem'], ['Animation', 'TestGem'], 0) + ] + ) + def test_edit_gem_properties(self, gem_path, gem_name, gem_new_name, gem_display, gem_origin, + gem_type, gem_summary, gem_icon, gem_requirements, + add_tags, remove_tags, replace_tags, + expected_tags, expected_result): + + def get_gem_json_data(gem_path: pathlib.Path) -> dict: + return self.gem_json.data + + def get_gem_path(gem_name: str) -> pathlib.Path: + return pathlib.Path('D:/TestProject') + + def save_o3de_manifest(new_gem_data: dict, gem_path: pathlib.Path) -> bool: + self.gem_json.data = new_gem_data + return True + + with patch('o3de.manifest.get_gem_json_data', side_effect=get_gem_json_data) as get_gem_json_data_patch, \ + patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch, \ + patch('o3de.manifest.get_registered', side_effect=get_gem_path) as get_registered_patch: + result = gem_properties.edit_gem_props(gem_path, gem_name, gem_new_name, gem_display, gem_origin, + gem_type, gem_summary, gem_icon, gem_requirements, + add_tags, remove_tags, replace_tags) + assert result == expected_result + if gem_new_name: + assert self.gem_json.data.get('gem_name', '') == gem_new_name + if gem_display: + assert self.gem_json.data.get('display_name', '') == gem_display + if gem_origin: + assert self.gem_json.data.get('origin', '') == gem_origin + if gem_type: + assert self.gem_json.data.get('type', '') == gem_type + if gem_summary: + assert self.gem_json.data.get('summary', '') == gem_summary + if gem_icon: + assert self.gem_json.data.get('icon_path', '') == gem_icon + if gem_requirements: + assert self.gem_json.data.get('requirments', '') == gem_requirements + + assert set(self.gem_json.data.get('user_tags', [])) == set(expected_tags) diff --git a/scripts/o3de/tests/unit_test_project_properties.py b/scripts/o3de/tests/unit_test_project_properties.py index d85ed121c3..f72a4dfe4c 100644 --- a/scripts/o3de/tests/unit_test_project_properties.py +++ b/scripts/o3de/tests/unit_test_project_properties.py @@ -58,8 +58,9 @@ class TestEditProjectProperties: return None return self.project_json.data - def save_o3de_manifest(new_proj_data: dict, project_path) -> None: + def save_o3de_manifest(new_proj_data: dict, project_path) -> bool: self.project_json.data = new_proj_data + return True with patch('o3de.manifest.get_project_json_data', side_effect=get_project_json_data) as get_project_json_data_patch, \ patch('o3de.manifest.save_o3de_manifest', side_effect=save_o3de_manifest) as save_o3de_manifest_patch: From d38f17131e96c612cbd9dce29cda072af81ec4bc Mon Sep 17 00:00:00 2001 From: moraaar Date: Wed, 28 Jul 2021 13:14:56 +0100 Subject: [PATCH 43/58] Fixed cloth tangent generation (from 'stabilization/2106' @26c9853f) - The output vectors were not properly filled with zeros when they already had the expected size. - The tolerance was too large and was causing patches while computing tangents and bitangents. - The handedness was inverted to what is expected in the shader (which always inverts tangent's w). Signed-off-by: moraaar --- .../ClothComponentMesh/ClothComponentMesh.cpp | 2 +- .../Code/Source/System/TangentSpaceHelper.cpp | 20 ++++++++++++------- .../ClothConstraintsTest.cpp | 12 ++++++++--- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp index 9381d98620..bcce080752 100644 --- a/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp +++ b/Gems/NvCloth/Code/Source/Components/ClothComponentMesh/ClothComponentMesh.cpp @@ -578,7 +578,7 @@ namespace NvCloth const AZ::Vector3& renderTangent = renderTangents[renderVertexIndex]; destTangentsBuffer[index].Set( renderTangent, - 1.0f); + -1.0f); // Shader function ConstructTBN inverts w to change bitangent sign, but the bitangents passed are already corrected, so passing -1.0 to counteract. } if (destBitangentsBuffer) diff --git a/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp b/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp index d7ebc8b371..3c47ad46fd 100644 --- a/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp +++ b/Gems/NvCloth/Code/Source/System/TangentSpaceHelper.cpp @@ -12,7 +12,7 @@ namespace NvCloth { namespace { - const float Tolerance = 0.0001f; + const float Tolerance = 1e-7f; } bool TangentSpaceHelper::CalculateNormals( @@ -34,7 +34,8 @@ namespace NvCloth const size_t vertexCount = vertices.size(); // Reset results - outNormals.resize(vertexCount, AZ::Vector3::CreateZero()); + outNormals.resize(vertexCount); + AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero()); // calculate the normals per triangle for (size_t i = 0; i < triangleCount; ++i) @@ -115,8 +116,10 @@ namespace NvCloth const size_t vertexCount = vertices.size(); // Reset results - outTangents.resize(vertexCount, AZ::Vector3::CreateZero()); - outBitangents.resize(vertexCount, AZ::Vector3::CreateZero()); + outTangents.resize(vertexCount); + outBitangents.resize(vertexCount); + AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero()); + AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero()); // calculate the base vectors per triangle for (size_t i = 0; i < triangleCount; ++i) @@ -193,9 +196,12 @@ namespace NvCloth const size_t vertexCount = vertices.size(); // Reset results - outTangents.resize(vertexCount, AZ::Vector3::CreateZero()); - outBitangents.resize(vertexCount, AZ::Vector3::CreateZero()); - outNormals.resize(vertexCount, AZ::Vector3::CreateZero()); + outTangents.resize(vertexCount); + outBitangents.resize(vertexCount); + outNormals.resize(vertexCount); + AZStd::fill(outTangents.begin(), outTangents.end(), AZ::Vector3::CreateZero()); + AZStd::fill(outBitangents.begin(), outBitangents.end(), AZ::Vector3::CreateZero()); + AZStd::fill(outNormals.begin(), outNormals.end(), AZ::Vector3::CreateZero()); // calculate the base vectors per triangle for (size_t i = 0; i < triangleCount; ++i) diff --git a/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp b/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp index 4beb03502a..c44d200fe3 100644 --- a/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp +++ b/Gems/NvCloth/Code/Tests/Components/ClothComponentMesh/ClothConstraintsTest.cpp @@ -125,6 +125,9 @@ namespace UnitTest const AZStd::vector& motionConstraints = clothConstraints->GetMotionConstraints(); EXPECT_TRUE(motionConstraints.size() == SimulationParticles.size()); + EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(SimulationParticles[0].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(SimulationParticles[1].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(SimulationParticles[2].GetAsVector3(), Tolerance)); EXPECT_NEAR(motionConstraints[0].GetW(), 6.0f, Tolerance); EXPECT_NEAR(motionConstraints[1].GetW(), 0.0f, Tolerance); EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance); @@ -278,6 +281,9 @@ namespace UnitTest const AZStd::vector& separationConstraints = clothConstraints->GetSeparationConstraints(); EXPECT_TRUE(motionConstraints.size() == newParticles.size()); + EXPECT_THAT(motionConstraints[0].GetAsVector3(), IsCloseTolerance(newParticles[0].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[1].GetAsVector3(), IsCloseTolerance(newParticles[1].GetAsVector3(), Tolerance)); + EXPECT_THAT(motionConstraints[2].GetAsVector3(), IsCloseTolerance(newParticles[2].GetAsVector3(), Tolerance)); EXPECT_NEAR(motionConstraints[0].GetW(), 3.0f, Tolerance); EXPECT_NEAR(motionConstraints[1].GetW(), 1.5f, Tolerance); EXPECT_NEAR(motionConstraints[2].GetW(), 0.0f, Tolerance); @@ -286,8 +292,8 @@ namespace UnitTest EXPECT_NEAR(separationConstraints[0].GetW(), 3.0f, Tolerance); EXPECT_NEAR(separationConstraints[1].GetW(), 1.5f, Tolerance); EXPECT_NEAR(separationConstraints[2].GetW(), 0.3f, Tolerance); - EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-3.03902f, 2.80752f, 3.80752f), Tolerance)); - EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(-1.41659f, 0.651243f, -0.348757f), Tolerance)); - EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(6.15313f, -0.876132f, 0.123868f), Tolerance)); + EXPECT_THAT(separationConstraints[0].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 3.53553f, 4.53553f), Tolerance)); + EXPECT_THAT(separationConstraints[1].GetAsVector3(), IsCloseTolerance(AZ::Vector3(0.0f, 2.06066f, 1.06066f), Tolerance)); + EXPECT_THAT(separationConstraints[2].GetAsVector3(), IsCloseTolerance(AZ::Vector3(1.0f, -3.74767f, -2.74767f), Tolerance)); } } // namespace UnitTest From fd07f907bc8fabfc6ef7b2a9ffd562c474bd36e9 Mon Sep 17 00:00:00 2001 From: ibtehajn <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 13:22:24 +0100 Subject: [PATCH 44/58] Implement axis locking options for rigid bodies Linear and angular motion of rigid bodies can now be restricted along specific world-space axes. Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- .../Configuration/RigidBodyConfiguration.cpp | 6 +++ .../Configuration/RigidBodyConfiguration.h | 10 ++++ .../Code/Source/EditorRigidBodyComponent.cpp | 27 ++++++++++ Gems/PhysX/Code/Source/Utils.cpp | 8 +++ Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp | 54 +++++++++++++++++++ 5 files changed, 105 insertions(+) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp index a61f6a4845..cfea76f1d7 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.cpp @@ -123,6 +123,12 @@ namespace AzPhysics ->Field("Kinematic", &RigidBodyConfiguration::m_kinematic) ->Field("CCD Enabled", &RigidBodyConfiguration::m_ccdEnabled) ->Field("Compute Mass", &RigidBodyConfiguration::m_computeMass) + ->Field("Lock Linear X", &RigidBodyConfiguration::m_lockLinearX) + ->Field("Lock Linear Y", &RigidBodyConfiguration::m_lockLinearY) + ->Field("Lock Linear Z", &RigidBodyConfiguration::m_lockLinearZ) + ->Field("Lock Angular X", &RigidBodyConfiguration::m_lockAngularX) + ->Field("Lock Angular Y", &RigidBodyConfiguration::m_lockAngularY) + ->Field("Lock Angular Z", &RigidBodyConfiguration::m_lockAngularZ) ->Field("Mass", &RigidBodyConfiguration::m_mass) ->Field("Compute COM", &RigidBodyConfiguration::m_computeCenterOfMass) ->Field("Centre of mass offset", &RigidBodyConfiguration::m_centerOfMassOffset) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h index 59829e740c..46f2620938 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h @@ -62,6 +62,16 @@ namespace AzPhysics bool m_computeInertiaTensor = true; bool m_computeMass = true; + //! Flags to restrict motion along specific world-space axes. + bool m_lockLinearX = false; + bool m_lockLinearY = false; + bool m_lockLinearZ = false; + + //! Flags to restrict rotation around specific world-space axes. + bool m_lockAngularX = false; + bool m_lockAngularY = false; + bool m_lockAngularZ = false; + //! If set, non-simulated shapes will also be included in the mass properties calculation. bool m_includeAllShapesInMassCalculation = false; diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index d27874f030..c94cc46ba4 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -156,6 +156,33 @@ namespace PhysX ->DataElement(AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_kinematic, "Kinematic", "Rigid body is kinematic") ->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetKinematicVisibility) + + // Linear axis locking properties + ->ClassElement(AZ::Edit::ClassElements::Group, "Linear Axis Locking") + ->Attribute(AZ::Edit::Attributes::AutoExpand, false) + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearX, "Lock X", + "Lock linear momentum in X direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearY, "Lock Y", + "Lock linear momentum in Y direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearZ, "Lock Z", + "Lock linear momentum in Z direction") + + // Angular axis locking properties + ->ClassElement(AZ::Edit::ClassElements::Group, "Angular Axis Locking") + ->Attribute(AZ::Edit::Attributes::AutoExpand, false) + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularX, "Lock X", + "Lock angular momentum in X direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularY, "Lock Y", + "Lock angular momentum in Y direction") + ->DataElement( + AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularZ, "Lock Z", + "Lock angular momentum in Z direction") + ->ClassElement(AZ::Edit::ClassElements::Group, "Continuous Collision Detection") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) ->Attribute(AZ::Edit::Attributes::Visibility, &AzPhysics::RigidBodyConfiguration::GetCCDVisibility) diff --git a/Gems/PhysX/Code/Source/Utils.cpp b/Gems/PhysX/Code/Source/Utils.cpp index 4e5695e3c6..0b7ab9436b 100644 --- a/Gems/PhysX/Code/Source/Utils.cpp +++ b/Gems/PhysX/Code/Source/Utils.cpp @@ -1466,6 +1466,14 @@ namespace PhysX rigidDynamic->setRigidBodyFlag(physx::PxRigidBodyFlag::eKINEMATIC, configuration.m_kinematic); rigidDynamic->setMaxAngularVelocity(configuration.m_maxAngularVelocity); + // Set axis locks. + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X, configuration.m_lockLinearX); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y, configuration.m_lockLinearY); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Z, configuration.m_lockLinearZ); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_X, configuration.m_lockAngularX); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y, configuration.m_lockAngularY); + rigidDynamic->setRigidDynamicLockFlag(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z, configuration.m_lockAngularZ); + return rigidDynamic; } diff --git a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp index 770e47d477..76ee035b70 100644 --- a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp @@ -1102,6 +1102,60 @@ namespace PhysX SanityCheckValidFrustumParams(points.value(), validHeight, validBottomRadius, validTopRadius, validSubdivisions); } + TEST_F(PhysXSpecificTest, RigidBody_RigidBodyWithAxisLockFlagsCreated_InternalPhysXFlagsSetAccordingly) + { + // Helper function wrapping creation logic + auto CreateRigidBody = [this](bool linearX, bool linearY, bool linearZ, bool angularX, bool angularY, bool angularZ) -> AzPhysics::RigidBody* + { + AzPhysics::RigidBodyConfiguration rigidBodyConfig; + + rigidBodyConfig.m_lockLinearX = linearX; + rigidBodyConfig.m_lockLinearY = linearY; + rigidBodyConfig.m_lockLinearZ = linearZ; + + rigidBodyConfig.m_lockAngularX = angularX; + rigidBodyConfig.m_lockAngularY = angularY; + rigidBodyConfig.m_lockAngularZ = angularZ; + + if (auto* sceneInterface = AZ::Interface::Get()) + { + AzPhysics::SimulatedBodyHandle simBodyHandle = sceneInterface->AddSimulatedBody(m_testSceneHandle, &rigidBodyConfig); + return azdynamic_cast(sceneInterface->GetSimulatedBodyFromHandle(m_testSceneHandle, simBodyHandle)); + } + + return nullptr; + }; + + auto RemoveRigidBody = [this](AzPhysics::RigidBody*& rigidBody) + { + auto* sceneInterface = AZ::Interface::Get(); + if (rigidBody && sceneInterface) + { + sceneInterface->RemoveSimulatedBody(rigidBody->m_sceneOwner, rigidBody->m_bodyHandle); + } + rigidBody = nullptr; + }; + + auto TestLockFlags = [&CreateRigidBody, &RemoveRigidBody](bool linearX, bool linearY, bool linearZ, + bool angularX, bool angularY, bool angularZ, + physx::PxRigidDynamicLockFlags expectedFlags) + { + auto* rigidBody = CreateRigidBody(linearX, linearY, linearZ, angularX, angularY, angularZ); + ASSERT_TRUE(rigidBody != nullptr); + + physx::PxRigidDynamic* pxRigidBody = static_cast(rigidBody->GetNativePointer()); + EXPECT_EQ(pxRigidBody->getRigidDynamicLockFlags(), expectedFlags); + + RemoveRigidBody(rigidBody); + }; + + TestLockFlags(false, false, false, false, false, false, physx::PxRigidDynamicLockFlags(0)); + TestLockFlags(true, false, false, false, false, false, physx::PxRigidDynamicLockFlags(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_X)); + TestLockFlags(false, false, false, false, true, false, physx::PxRigidDynamicLockFlags(physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Y)); + TestLockFlags(false, true, false, false, false, true, + physx::PxRigidDynamicLockFlags(physx::PxRigidDynamicLockFlag::eLOCK_LINEAR_Y | physx::PxRigidDynamicLockFlag::eLOCK_ANGULAR_Z)); + } + TEST_F(PhysXSpecificTest, RigidBody_RigidBodyWithSimulatedFlagsHitsPlane_OnlySimulatedShapeCollidesWithPlane) { // Helper function wrapping creation logic From 16869d56f32316b8bdaa157e53de39fd68fcc6fa Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 14:09:26 +0100 Subject: [PATCH 45/58] Use regular comment The Doxygen comment would only apply to the first field in each group. Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- .../Physics/Configuration/RigidBodyConfiguration.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h index 46f2620938..51dcce842d 100644 --- a/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h +++ b/Code/Framework/AzFramework/AzFramework/Physics/Configuration/RigidBodyConfiguration.h @@ -62,12 +62,12 @@ namespace AzPhysics bool m_computeInertiaTensor = true; bool m_computeMass = true; - //! Flags to restrict motion along specific world-space axes. + // Flags to restrict motion along specific world-space axes. bool m_lockLinearX = false; bool m_lockLinearY = false; bool m_lockLinearZ = false; - //! Flags to restrict rotation around specific world-space axes. + // Flags to restrict rotation around specific world-space axes. bool m_lockAngularX = false; bool m_lockAngularY = false; bool m_lockAngularZ = false; From a7b613d388cfdc365fcd7112b4aeb70246d83560 Mon Sep 17 00:00:00 2001 From: Jakub Wlodek Date: Wed, 28 Jul 2021 11:56:46 -0400 Subject: [PATCH 46/58] Fixing typos in comments in AffineParts.h file (#2407) Signed-off-by: jwlodek --- Code/Editor/Util/AffineParts.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Code/Editor/Util/AffineParts.h b/Code/Editor/Util/AffineParts.h index cb2c609ecd..a2e3d2c79b 100644 --- a/Code/Editor/Util/AffineParts.h +++ b/Code/Editor/Util/AffineParts.h @@ -20,11 +20,11 @@ struct AffineParts Vec3 scale; //!< Stretch factors. float fDet; //!< Sign of determinant. - /** Decompose matrix to its affnie parts. + /** Decompose matrix to its affine parts. */ void Decompose(const Matrix34& mat); - /** Decompose matrix to its affnie parts. + /** Decompose matrix to its affine parts. Assume there`s no stretch rotation. */ void SpectralDecompose(const Matrix34& mat); From 433aec4f3407dffb9583b7c7bb8550d789252d96 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 28 Jul 2021 09:25:31 -0700 Subject: [PATCH 47/58] Disabling this since the fast checkup in VS doesnt solve what this was hoping to solve, we need to emit and add as dependencies all the includes involved in autogen (#2383) Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Framework/AzAutoGen/AzAutoGen.props | 7 ------- cmake/LyAutoGen.cmake | 1 - 2 files changed, 8 deletions(-) delete mode 100644 Code/Framework/AzAutoGen/AzAutoGen.props diff --git a/Code/Framework/AzAutoGen/AzAutoGen.props b/Code/Framework/AzAutoGen/AzAutoGen.props deleted file mode 100644 index 2f809d03a6..0000000000 --- a/Code/Framework/AzAutoGen/AzAutoGen.props +++ /dev/null @@ -1,7 +0,0 @@ - - - - - True - - diff --git a/cmake/LyAutoGen.cmake b/cmake/LyAutoGen.cmake index a1357e15b4..64cb73a453 100644 --- a/cmake/LyAutoGen.cmake +++ b/cmake/LyAutoGen.cmake @@ -40,7 +40,6 @@ function(ly_add_autogen) ) set_target_properties(${ly_add_autogen_NAME} PROPERTIES AUTOGEN_INPUT_FILES "${AZCG_INPUTFILES}") set_target_properties(${ly_add_autogen_NAME} PROPERTIES AUTOGEN_OUTPUT_FILES "${AUTOGEN_OUTPUTS}") - set_target_properties(${ly_add_autogen_NAME} PROPERTIES VS_USER_PROPS "${LY_ROOT_FOLDER}/Code/Framework/AzAutoGen/AzAutoGen.props") target_sources(${ly_add_autogen_NAME} PRIVATE ${AUTOGEN_OUTPUTS}) endif() From 0824bb462a44cf017827d0628a4f4694f1bf68a7 Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 16:33:02 +0100 Subject: [PATCH 48/58] Improve tooltip text Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp index c94cc46ba4..bd7c49a0a7 100644 --- a/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp +++ b/Gems/PhysX/Code/Source/EditorRigidBodyComponent.cpp @@ -162,26 +162,26 @@ namespace PhysX ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearX, "Lock X", - "Lock linear momentum in X direction") + "Lock motion along X direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearY, "Lock Y", - "Lock linear momentum in Y direction") + "Lock motion along Y direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockLinearZ, "Lock Z", - "Lock linear momentum in Z direction") + "Lock motion along Z direction") // Angular axis locking properties ->ClassElement(AZ::Edit::ClassElements::Group, "Angular Axis Locking") ->Attribute(AZ::Edit::Attributes::AutoExpand, false) ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularX, "Lock X", - "Lock angular momentum in X direction") + "Lock rotation around X direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularY, "Lock Y", - "Lock angular momentum in Y direction") + "Lock rotation around Y direction") ->DataElement( AZ::Edit::UIHandlers::Default, &AzPhysics::RigidBodyConfiguration::m_lockAngularZ, "Lock Z", - "Lock angular momentum in Z direction") + "Lock rotation around Z direction") ->ClassElement(AZ::Edit::ClassElements::Group, "Continuous Collision Detection") ->Attribute(AZ::Edit::Attributes::AutoExpand, true) From db8f78890f686c6549ad1771cd5863d4313158a0 Mon Sep 17 00:00:00 2001 From: Jacob Hilliard <64656371+jcbhl@users.noreply.github.com> Date: Wed, 28 Jul 2021 09:35:02 -0700 Subject: [PATCH 49/58] [ATOM-16017] Implement frame time histogram in visualizer (#2378) * Histogram: Basic working graph of frame times Signed-off-by: Jacob Hilliard * Histogram: Improve usability Implements horizontal frame limit lines, limit-based coloring, and a viewport indicator. Signed-off-by: Jacob Hilliard * Histogram: Implement interactions Signed-off-by: Jacob Hilliard --- .../Include/Atom/Utils/ImGuiCpuProfiler.h | 7 +- .../Include/Atom/Utils/ImGuiCpuProfiler.inl | 107 ++++++++++++++++-- 2 files changed, 104 insertions(+), 10 deletions(-) diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h index c0ee4f8e02..66be0b9137 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.h @@ -75,6 +75,8 @@ namespace AZ private: static constexpr float RowHeight = 50.0; static constexpr int DefaultFramesToCollect = 50; + static constexpr float MediumFrameTimeLimit = 16.6; // 60 fps + static constexpr float HighFrameTimeLimit = 33.3; // 30 fps // Draw the shared header between the two windows void DrawCommonHeader(); @@ -127,8 +129,11 @@ namespace AZ // Draw the ruler with frame time labels void DrawRuler(); + // Draw the frame time histogram + void DrawFrameTimeHistogram(); + // Converts raw ticks to a pixel value suitable to give to ImDrawList, handles window scrolling - float ConvertTickToPixelSpace(AZStd::sys_time_t tick) const; + float ConvertTickToPixelSpace(AZStd::sys_time_t tick, AZStd::sys_time_t leftBound, AZStd::sys_time_t rightBound) const; AZStd::sys_time_t GetViewportTickWidth() const; diff --git a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl index b59747421e..735dace1c7 100644 --- a/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl +++ b/Gems/Atom/Utils/Code/Include/Atom/Utils/ImGuiCpuProfiler.inl @@ -280,7 +280,7 @@ namespace AZ { ImGui::Columns(3, "Options", true); ImGui::Text("Frames To Collect:"); - ImGui::SliderInt("", &m_framesToCollect, 10, 100, "%d", ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic); + ImGui::SliderInt("", &m_framesToCollect, 10, 10000, "%d", ImGuiSliderFlags_AlwaysClamp | ImGuiSliderFlags_Logarithmic); ImGui::NextColumn(); @@ -295,6 +295,13 @@ namespace AZ "Hold the right mouse button to move around. Zoom by scrolling the mouse wheel while holding ."); } + ImGui::Columns(1, "FrameTimeColumn", true); + + if (ImGui::BeginChild("FrameTimeHistogram", { 0, 50 }, true, ImGuiWindowFlags_NoScrollbar)) + { + DrawFrameTimeHistogram(); + } + ImGui::EndChild(); ImGui::Columns(1, "RulerColumn", true); @@ -519,8 +526,8 @@ namespace AZ ImDrawList* drawList = ImGui::GetWindowDrawList(); - const float startPixel = ConvertTickToPixelSpace(block.m_startTick); - const float endPixel = ConvertTickToPixelSpace(block.m_endTick); + const float startPixel = ConvertTickToPixelSpace(block.m_startTick, m_viewportStartTick, m_viewportEndTick); + const float endPixel = ConvertTickToPixelSpace(block.m_endTick, m_viewportStartTick, m_viewportEndTick); const ImVec2 startPoint = { startPixel, wy + targetRow * RowHeight }; const ImVec2 endPoint = { endPixel, wy + targetRow * RowHeight + 40 }; @@ -656,7 +663,7 @@ namespace AZ while (endTickItr != m_frameEndTicks.end() && *endTickItr < m_viewportEndTick) { - const float horizontalPixel = ConvertTickToPixelSpace(*endTickItr); + const float horizontalPixel = ConvertTickToPixelSpace(*endTickItr, m_viewportStartTick, m_viewportEndTick); drawList->AddLine({ horizontalPixel, wy }, { horizontalPixel, wy + windowHeight }, red); ++endTickItr; } @@ -684,8 +691,8 @@ namespace AZ break; } - const float lastFrameBoundaryPixel = ConvertTickToPixelSpace(lastFrameBoundaryTick); - const float nextFrameBoundaryPixel = ConvertTickToPixelSpace(nextFrameBoundaryTick); + const float lastFrameBoundaryPixel = ConvertTickToPixelSpace(lastFrameBoundaryTick, m_viewportStartTick, m_viewportEndTick); + const float nextFrameBoundaryPixel = ConvertTickToPixelSpace(nextFrameBoundaryTick, m_viewportStartTick, m_viewportEndTick); const AZStd::string label = AZStd::string::format("%.2f ms", CpuProfilerImGuiHelper::TicksToMs(nextFrameBoundaryTick - lastFrameBoundaryTick)); @@ -738,16 +745,98 @@ namespace AZ } } + inline void ImGuiCpuProfiler::DrawFrameTimeHistogram() + { + ImDrawList* drawList = ImGui::GetWindowDrawList(); + const auto [wx, wy] = ImGui::GetWindowPos(); + const ImU32 orange = ImGui::GetColorU32({ 1, .7, 0, 1 }); + const ImU32 red = ImGui::GetColorU32({ 1, 0, 0, 1 }); + + const AZStd::sys_time_t ticksPerSecond = AZStd::GetTimeTicksPerSecond(); + const AZStd::sys_time_t viewportCenter = m_viewportEndTick - (m_viewportEndTick - m_viewportStartTick) / 2; + const AZStd::sys_time_t leftHistogramBound = viewportCenter - ticksPerSecond; + const AZStd::sys_time_t rightHistogramBound = viewportCenter + ticksPerSecond; + + // Draw frame limit lines + drawList->AddLine( + { wx, wy + ImGui::GetWindowHeight() - MediumFrameTimeLimit }, + { wx + ImGui::GetWindowWidth(), wy + ImGui::GetWindowHeight() - MediumFrameTimeLimit }, + orange); + + drawList->AddLine( + { wx, wy + ImGui::GetWindowHeight() - HighFrameTimeLimit }, + { wx + ImGui::GetWindowWidth(), wy + ImGui::GetWindowHeight() - HighFrameTimeLimit }, + red); + + + // Draw viewport bound rectangle + const float leftViewportPixel = ConvertTickToPixelSpace(m_viewportStartTick, leftHistogramBound, rightHistogramBound); + const float rightViewportPixel = ConvertTickToPixelSpace(m_viewportEndTick, leftHistogramBound, rightHistogramBound); + const ImVec2 topLeftPos = { leftViewportPixel, wy }; + const ImVec2 botRightPos = { rightViewportPixel, wy + ImGui::GetWindowHeight() }; + const ImU32 gray = ImGui::GetColorU32({ 1, 1, 1, .3 }); + drawList->AddRectFilled(topLeftPos, botRightPos, gray); + + // Find the first onscreen frame execution time + auto frameEndTickItr = AZStd::lower_bound(m_frameEndTicks.begin(), m_frameEndTicks.end(), leftHistogramBound); + if (frameEndTickItr != m_frameEndTicks.begin()) + { + --frameEndTickItr; + } + + // Since we only store the frame end ticks, we must calculate the execution times on the fly by comparing pairs of elements. + AZStd::sys_time_t lastFrameEndTick = *frameEndTickItr; + while (*frameEndTickItr < rightHistogramBound && ++frameEndTickItr != m_frameEndTicks.end()) + { + const AZStd::sys_time_t frameEndTick = *frameEndTickItr; + + const float framePixelPos = ConvertTickToPixelSpace(frameEndTick, leftHistogramBound, rightHistogramBound); + const float frameTimeMs = CpuProfilerImGuiHelper::TicksToMs(frameEndTick - lastFrameEndTick); + + const ImVec2 lineBottom = { framePixelPos, ImGui::GetWindowHeight() + wy }; + const ImVec2 lineTop = { framePixelPos, ImGui::GetWindowHeight() + wy - frameTimeMs }; + + ImU32 lineColor = ImGui::GetColorU32({ .3, .3, .3, 1 }); // Gray + if (frameTimeMs > HighFrameTimeLimit) + { + lineColor = ImGui::GetColorU32({1, 0, 0, 1}); // Red + } + else if (frameTimeMs > MediumFrameTimeLimit) + { + lineColor = ImGui::GetColorU32({1, .7, 0, 1}); // Orange + } + + drawList->AddLine(lineBottom, lineTop, lineColor, 3.0); + + lastFrameEndTick = frameEndTick; + } + + // Handle input + ImGui::InvisibleButton("HistogramInputCapture", { ImGui::GetWindowWidth(), ImGui::GetWindowHeight() }); + ImGuiIO& io = ImGui::GetIO(); + if (ImGui::IsItemClicked(ImGuiMouseButton_Left)) + { + const float mousePixelX = io.MousePos.x; + const float percentWindow = (mousePixelX - wx) / ImGui::GetWindowWidth(); + const AZStd::sys_time_t newViewportCenterTick = leftHistogramBound + + aznumeric_cast((rightHistogramBound - leftHistogramBound) * percentWindow); + + const AZStd::sys_time_t viewportWidth = GetViewportTickWidth(); + m_viewportEndTick = newViewportCenterTick + viewportWidth / 2; + m_viewportStartTick = newViewportCenterTick - viewportWidth / 2; + } + } + inline AZStd::sys_time_t ImGuiCpuProfiler::GetViewportTickWidth() const { return m_viewportEndTick - m_viewportStartTick; } - inline float ImGuiCpuProfiler::ConvertTickToPixelSpace(AZStd::sys_time_t tick) const + inline float ImGuiCpuProfiler::ConvertTickToPixelSpace(AZStd::sys_time_t tick, AZStd::sys_time_t leftBound, AZStd::sys_time_t rightBound) const { const float wx = ImGui::GetWindowPos().x; - const float tickSpaceShifted = aznumeric_cast(tick - m_viewportStartTick); // This will be close to zero, so FP inaccuracy should not be too bad - const float tickSpaceNormalized = tickSpaceShifted / GetViewportTickWidth(); + const float tickSpaceShifted = aznumeric_cast(tick - leftBound); // This will be close to zero, so FP inaccuracy should not be too bad + const float tickSpaceNormalized = tickSpaceShifted / (rightBound - leftBound); const float pixelSpace = tickSpaceNormalized * ImGui::GetWindowWidth() + wx; return pixelSpace; } From a7e414fafeb18834d5c930ae2eb225d8bd889d1c Mon Sep 17 00:00:00 2001 From: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> Date: Wed, 28 Jul 2021 17:58:31 +0100 Subject: [PATCH 50/58] Fix Linux compilation error in test code Signed-off-by: Ibtehaj Nadeem <81370835+ibtehajn@users.noreply.github.com> --- Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp index 76ee035b70..6e96db4db2 100644 --- a/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp +++ b/Gems/PhysX/Code/Tests/PhysXSpecificTest.cpp @@ -1144,7 +1144,9 @@ namespace PhysX ASSERT_TRUE(rigidBody != nullptr); physx::PxRigidDynamic* pxRigidBody = static_cast(rigidBody->GetNativePointer()); - EXPECT_EQ(pxRigidBody->getRigidDynamicLockFlags(), expectedFlags); + + // These values need to be cast to integral types to prevent a compilation error on somme platforms. + EXPECT_EQ(static_cast(pxRigidBody->getRigidDynamicLockFlags()), static_cast((expectedFlags))); RemoveRigidBody(rigidBody); }; From 567b4a7f282fb49d797f311fbaeee31ef3b24069 Mon Sep 17 00:00:00 2001 From: Cynthia Lin <15116870+synicalsyntax@users.noreply.github.com> Date: Wed, 28 Jul 2021 11:07:32 -0700 Subject: [PATCH 51/58] [ATOM-16016] Add initial level for AtomFeatureIntegrationBenchmark to AutomatedTesting. (#2405) * [ATOM-16016] Add initial level for AtomFeatureIntegrationBenchmark to AutomatedTesting. Signed-off-by: Cynthia Lin * [ATOM-16016] Add new AtomFeatureIntegrationBenchmark to AutomatedTesting. Signed-off-by: Cynthia Lin --- ...GPUTest_AtomFeatureIntegrationBenchmark.py | 102 ++++++++++++++++++ .../atom_utils/benchmark_utils.py | 84 +++++++++++++++ .../atom_renderer/test_Atom_GPUTests.py | 41 +++++++ .../AtomFeatureIntegrationBenchmark.ly | 3 + .../filelist.xml | 6 ++ .../AtomFeatureIntegrationBenchmark/level.pak | 3 + .../AtomFeatureIntegrationBenchmark/tags.txt | 12 +++ 7 files changed, 251 insertions(+) create mode 100644 AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py create mode 100644 AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py create mode 100644 AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly create mode 100644 AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml create mode 100644 AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak create mode 100644 AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py new file mode 100644 index 0000000000..b899d7dcde --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_hydra_scripts/hydra_GPUTest_AtomFeatureIntegrationBenchmark.py @@ -0,0 +1,102 @@ +""" +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 + +Hydra script that is used to create a new level with a default rendering setup. +After the level is setup, screenshots are diffed against golden images are used to verify pass/fail results of the test. + +See the run() function for more in-depth test info. +""" + +import os +import sys + +import azlmbr.legacy.general as general + +sys.path.append(os.path.join(azlmbr.paths.devroot, "AutomatedTesting", "Gem", "PythonTests")) + +import editor_python_test_tools.hydra_editor_utils as hydra +from editor_python_test_tools.editor_test_helper import EditorTestHelper +from atom_renderer.atom_utils.benchmark_utils import BenchmarkHelper + +SCREEN_WIDTH = 1280 +SCREEN_HEIGHT = 720 +DEGREE_RADIAN_FACTOR = 0.0174533 + +helper = EditorTestHelper(log_prefix="Test_Atom_BasicLevelSetup") + + +def run(): + """ + 1. View -> Layouts -> Restore Default Layout, sets the viewport to ratio 16:9 @ 1280 x 720 + 2. Runs console command r_DisplayInfo = 0 + 3. Opens AtomFeatureIntegrationBenchmark level + 4. Initializes benchmark helper with benchmark name to capture benchmark metadata. + 5. Idles for 100 frames, then collects pass timings for 100 frames. + :return: None + """ + def initial_viewport_setup(screen_width, screen_height): + general.set_viewport_size(screen_width, screen_height) + general.update_viewport() + helper.wait_for_condition( + function=lambda: helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) + and helper.isclose(a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1), + timeout_in_seconds=4.0 + ) + result = helper.isclose(a=general.get_viewport_size().x, b=SCREEN_WIDTH, rel_tol=0.1) and helper.isclose( + a=general.get_viewport_size().y, b=SCREEN_HEIGHT, rel_tol=0.1) + general.log(general.get_viewport_size().x) + general.log(general.get_viewport_size().y) + general.log(general.get_viewport_size().z) + general.log(f"Viewport is set to the expected size: {result}") + general.run_console("r_DisplayInfo = 0") + + def after_level_load(): + """Function to call after creating/opening a level to ensure it loads.""" + # Give everything a second to initialize. + general.idle_enable(True) + general.idle_wait(1.0) + general.update_viewport() + general.idle_wait(0.5) # half a second is more than enough for updating the viewport. + + # Close out problematic windows, FPS meters, and anti-aliasing. + if general.is_helpers_shown(): # Turn off the helper gizmos if visible + general.toggle_helpers() + general.idle_wait(1.0) + if general.is_pane_visible("Error Report"): # Close Error Report windows that block focus. + general.close_pane("Error Report") + if general.is_pane_visible("Error Log"): # Close Error Log windows that block focus. + general.close_pane("Error Log") + general.idle_wait(1.0) + general.run_console("r_displayInfo=0") + general.run_console("r_antialiasingmode=0") + general.idle_wait(1.0) + + return True + + # Wait for Editor idle loop before executing Python hydra scripts. + general.idle_enable(True) + + general.open_level_no_prompt("AtomFeatureIntegrationBenchmark") + + # Basic setup after opening level. + after_level_load() + initial_viewport_setup(SCREEN_WIDTH, SCREEN_HEIGHT) + + general.enter_game_mode() + general.idle_wait(1.0) + helper.wait_for_condition(function=lambda: general.is_in_game_mode(), timeout_in_seconds=2.0) + benchmarker = BenchmarkHelper("AtomFeatureIntegrationBenchmark") + benchmarker.capture_benchmark_metadata() + general.idle_wait_frames(100) + for i in range(1, 101): + benchmarker.capture_pass_timestamp(i) + general.exit_game_mode() + helper.wait_for_condition(function=lambda: not general.is_in_game_mode(), timeout_in_seconds=2.0) + general.log("Capturing complete.") + + +if __name__ == "__main__": + run() diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py new file mode 100644 index 0000000000..21c7489ed3 --- /dev/null +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/atom_utils/benchmark_utils.py @@ -0,0 +1,84 @@ +""" +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 +""" +import azlmbr.atom +import azlmbr.legacy.general as general + +FOLDER_PATH = '@user@/Scripts/PerformanceBenchmarks' +METADATA_FILE = 'benchmark_metadata.json' + +class BenchmarkHelper(object): + """ + A helper to capture benchmark data. + """ + def __init__(self, benchmark_name): + super().__init__() + self.benchmark_name = benchmark_name + self.output_path = f'{FOLDER_PATH}/{benchmark_name}' + self.done = False + self.capturedData = False + self.max_frames_to_wait = 200 + + def capture_benchmark_metadata(self): + """ + Capture benchmark metadata and block further execution until it has been written to the disk. + """ + self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler() + self.handler.connect() + self.handler.add_callback('OnCaptureBenchmarkMetadataFinished', self.on_data_captured) + + self.done = False + self.capturedData = False + success = azlmbr.atom.ProfilingCaptureRequestBus( + azlmbr.bus.Broadcast, "CaptureBenchmarkMetadata", self.benchmark_name, f'{self.output_path}/{METADATA_FILE}' + ) + if success: + self.wait_until_data() + general.log('Benchmark metadata captured.') + else: + general.log('Failed to capture benchmark metadata.') + return self.capturedData + + def capture_pass_timestamp(self, frame_number): + """ + Capture pass timestamps and block further execution until it has been written to the disk. + """ + self.handler = azlmbr.atom.ProfilingCaptureNotificationBusHandler() + self.handler.connect() + self.handler.add_callback('OnCaptureQueryTimestampFinished', self.on_data_captured) + + self.done = False + self.capturedData = False + success = azlmbr.atom.ProfilingCaptureRequestBus( + azlmbr.bus.Broadcast, "CapturePassTimestamp", f'{self.output_path}/frame{frame_number}_timestamps.json') + if success: + self.wait_until_data() + general.log('Pass timestamps captured.') + else: + general.log('Failed to capture pass timestamps.') + return self.capturedData + + def on_data_captured(self, parameters): + # the parameters come in as a tuple + if parameters[0]: + general.log('Captured data successfully.') + self.capturedData = True + else: + general.log('Failed to capture data.') + self.done = True + self.handler.disconnect() + + def wait_until_data(self): + frames_waited = 0 + while self.done == False: + general.idle_wait_frames(1) + if frames_waited > self.max_frames_to_wait: + general.log('Timed out while waiting for the data to be captured') + self.handler.disconnect() + break + else: + frames_waited = frames_waited + 1 + general.log(f'(waited {frames_waited} frames)') diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py index dad92d0932..ede140c075 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_GPUTests.py @@ -14,6 +14,7 @@ import pytest import ly_test_tools.environment.file_system as file_system from ly_test_tools.image.screenshot_compare_qssim import qssim as compare_screenshots +from ly_test_tools.benchmark.data_aggregator import BenchmarkDataAggregator import editor_python_test_tools.hydra_test_utils as hydra logger = logging.getLogger(__name__) @@ -83,3 +84,43 @@ class TestAllComponentsIndepthTests(object): for test_screenshot, golden_screenshot in zip(test_screenshots, golden_images): compare_screenshots(test_screenshot, golden_screenshot) + +@pytest.mark.parametrize('rhi', ['dx12', 'vulkan']) +@pytest.mark.parametrize("project", ["AutomatedTesting"]) +@pytest.mark.parametrize("launcher_platform", ["windows_editor"]) +@pytest.mark.parametrize("level", ["AtomFeatureIntegrationBenchmark"]) +class TestPerformanceBenchmarkSuite(object): + def test_AtomFeatureIntegrationBenchmark( + self, request, editor, workspace, rhi, project, launcher_platform, level): + """ + Please review the hydra script run by this test for more specific test info. + Tests the performance of the Simple level. + """ + expected_lines = [ + "Benchmark metadata captured.", + "Pass timestamps captured.", + "Capturing complete.", + "Captured data successfully." + ] + + unexpected_lines = [ + "Failed to capture data.", + "Failed to capture pass timestamps.", + "Failed to capture benchmark metadata." + ] + + hydra.launch_and_validate_results( + request, + TEST_DIRECTORY, + editor, + "hydra_GPUTest_AtomFeatureIntegrationBenchmark.py", + timeout=EDITOR_TIMEOUT, + expected_lines=expected_lines, + unexpected_lines=unexpected_lines, + halt_on_unexpected=True, + cfg_args=[level], + null_renderer=False, + ) + + aggregator = BenchmarkDataAggregator(workspace, logger, 'periodic') + aggregator.upload_metrics(rhi) diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly new file mode 100644 index 0000000000..4fc96f242b --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/AtomFeatureIntegrationBenchmark.ly @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5232563c3ff322669808ac4daeda3d822e4ef8c9c87db0fa245f0f9c9c34aada +size 23379 diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml new file mode 100644 index 0000000000..15b79f5e4f --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/filelist.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak new file mode 100644 index 0000000000..fecbc0b394 --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/level.pak @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e075be2cb7cf5aa98e3503c1119b94c3098b35500c98c4db32d025c9e1afa52d +size 5450 diff --git a/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt new file mode 100644 index 0000000000..a5e0705349 --- /dev/null +++ b/AutomatedTesting/Levels/AtomFeatureIntegrationBenchmark/tags.txt @@ -0,0 +1,12 @@ +495.045,510.96,35.8437,-0.166,0,-1.82124 +4.79827,4.71364,64.7838,-1.41886,0,2.48964 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 +0,0,0,0,0,0 From 15d6ca3252696903eb073870c65a66518104fb7f Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 28 Jul 2021 11:51:21 -0700 Subject: [PATCH 52/58] abandon attepts to enable script canvas tests on the farm Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Code/Framework/AzCore/CMakeLists.txt | 3 --- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Code/Framework/AzCore/CMakeLists.txt b/Code/Framework/AzCore/CMakeLists.txt index 785352cf05..ea7cc27af5 100644 --- a/Code/Framework/AzCore/CMakeLists.txt +++ b/Code/Framework/AzCore/CMakeLists.txt @@ -130,9 +130,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ly_add_googletest( NAME AZ::AzCore.Tests ) - if(PAL_TRAIT_TEST_GOOGLE_TEST_SUPPORTED) - set_tests_properties(AZ::AzCore.Tests.main::TEST_RUN PROPERTIES RUN_SERIAL true) - endif() ly_add_googlebenchmark( NAME AZ::AzCore.Benchmarks TARGET AZ::AzCore.Tests diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index 7291cd65eb..dada433772 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -113,8 +113,8 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests + TEST_SUITE smoke ) - set_tests_properties(Gem::ScriptCanvasTesting.Editor.Tests.main::TEST_RUN PROPERTIES RUN_SERIAL true) endif() From 6839497d99e0d9a3b762b42bf16d19d2e018ceb9 Mon Sep 17 00:00:00 2001 From: kberg-amzn Date: Wed, 28 Jul 2021 12:31:19 -0700 Subject: [PATCH 53/58] Corrects math computing blend factors to interpolate state between received network updates Signed-off-by: kberg-amzn --- .../Source/MultiplayerSystemComponent.cpp | 37 +++++++++++++------ .../Code/Source/MultiplayerSystemComponent.h | 2 +- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp index 9a46bb10de..21c7ce80d6 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.cpp @@ -69,19 +69,24 @@ namespace Multiplayer { using namespace AzNetworking; - AZ_CVAR(uint16_t, cl_clientport, 0, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port to bind to for game traffic when connecting to a remote host, a value of 0 will select any available port"); - AZ_CVAR(AZ::CVarFixedString, cl_serveraddr, AZ::CVarFixedString(LocalHost), nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The address of the remote server or host to connect to"); - AZ_CVAR(AZ::CVarFixedString, cl_serverpassword, "", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Optional server password"); + AZ_CVAR(uint16_t, cl_clientport, 0, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + "The port to bind to for game traffic when connecting to a remote host, a value of 0 will select any available port"); + AZ_CVAR(AZ::CVarFixedString, cl_serveraddr, AZ::CVarFixedString(LocalHost), nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + "The address of the remote server or host to connect to"); AZ_CVAR(uint16_t, cl_serverport, DefaultServerPort, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port of the remote host to connect to for game traffic"); AZ_CVAR(uint16_t, sv_port, DefaultServerPort, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The port that this multiplayer gem will bind to for game traffic"); AZ_CVAR(AZ::CVarFixedString, sv_map, "nolevel", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The map the server should load"); - AZ_CVAR(AZ::CVarFixedString, sv_gamerules, "norules", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "GameRules server works with"); AZ_CVAR(ProtocolType, sv_protocol, ProtocolType::Udp, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "This flag controls whether we use TCP or UDP for game networking"); AZ_CVAR(bool, sv_isDedicated, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Whether the host command creates an independent or client hosted server"); AZ_CVAR(bool, sv_isTransient, true, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Whether a dedicated server shuts down if all existing connections disconnect."); - AZ_CVAR(AZ::TimeMs, cl_defaultNetworkEntityActivationTimeSliceMs, AZ::TimeMs{ 0 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "Max Ms to use to activate entities coming from the network, 0 means instantiate everything"); + AZ_CVAR(AZ::TimeMs, cl_defaultNetworkEntityActivationTimeSliceMs, AZ::TimeMs{ 0 }, nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + "Max Ms to use to activate entities coming from the network, 0 means instantiate everything"); AZ_CVAR(AZ::TimeMs, sv_serverSendRateMs, AZ::TimeMs{ 50 }, nullptr, AZ::ConsoleFunctorFlags::Null, "Minimum number of milliseconds between each network update"); - AZ_CVAR(AZ::CVarFixedString, sv_defaultPlayerSpawnAsset, "prefabs/player.network.spawnable", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, "The default spawnable to use when a new player connects"); + AZ_CVAR(AZ::CVarFixedString, sv_defaultPlayerSpawnAsset, "prefabs/player.network.spawnable", nullptr, AZ::ConsoleFunctorFlags::DontReplicate, + "The default spawnable to use when a new player connects"); + AZ_CVAR(float, cl_renderTickBlendBase, 0.15f, nullptr, AZ::ConsoleFunctorFlags::Null, + "The base used for blending between network updates, 0.1 will be quite linear, 0.2 or 0.3 will " + "slow down quicker and may be better suited to connections with highly variable latency"); void MultiplayerSystemComponent::Reflect(AZ::ReflectContext* context) { @@ -546,7 +551,7 @@ namespace Multiplayer if ((GetAgentType() == MultiplayerAgentType::Client) && (packet.GetHostFrameId() > m_lastReplicatedHostFrameId)) { // Update client to latest server time - m_renderBlendFactor = 0.0f; + m_tickFactor = 0.0f; m_lastReplicatedHostTimeMs = packet.GetHostTimeMs(); m_lastReplicatedHostFrameId = packet.GetHostFrameId(); m_networkTime.AlterTime(m_lastReplicatedHostFrameId, m_lastReplicatedHostTimeMs, AzNetworking::InvalidConnectionId); @@ -849,10 +854,18 @@ namespace Multiplayer void MultiplayerSystemComponent::TickVisibleNetworkEntities(float deltaTime, float serverRateSeconds) { + m_tickFactor += deltaTime / serverRateSeconds; // Linear close to the origin, but asymptote at y = 1 - const float targetAdjustBlend = AZStd::clamp(deltaTime / serverRateSeconds, 0.0f, 1.0f); - m_renderBlendFactor = 1.0f - (std::pow(0.2f, m_renderBlendFactor + targetAdjustBlend)); - AZLOG(NET_Blending, "Computed blend factor of %0.2f using a frametime of %0.2f and a serverTickRate of %0.2f", m_renderBlendFactor, deltaTime, serverRateSeconds); + const float renderBlendFactor = AZStd::clamp(1.0f - (std::pow(cl_renderTickBlendBase, m_tickFactor)), 0.0f, 1.0f); + AZLOG + ( + NET_Blending, + "Computed blend factor of %0.3f using a tick factor of %0.3f, a frametime of %0.3f and a serverTickRate of %0.3f", + renderBlendFactor, + m_tickFactor, + deltaTime, + serverRateSeconds + ); if (Camera::ActiveCameraRequestBus::HasHandlers()) { @@ -895,7 +908,7 @@ namespace Multiplayer for (NetBindComponent* netBindComponent : gatheredEntities) { - netBindComponent->NotifyPreRender(deltaTime, m_renderBlendFactor); + netBindComponent->NotifyPreRender(deltaTime, renderBlendFactor); } } else @@ -907,7 +920,7 @@ namespace Multiplayer NetBindComponent* netBindComponent = entity->FindComponent(); if (netBindComponent != nullptr) { - netBindComponent->NotifyPreRender(deltaTime, m_renderBlendFactor); + netBindComponent->NotifyPreRender(deltaTime, renderBlendFactor); } } } diff --git a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h index 37e8138a71..ab37958962 100644 --- a/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h +++ b/Gems/Multiplayer/Code/Source/MultiplayerSystemComponent.h @@ -155,7 +155,7 @@ namespace Multiplayer HostFrameId m_lastReplicatedHostFrameId = HostFrameId(0); double m_serverSendAccumulator = 0.0; - float m_renderBlendFactor = 0.0f; + float m_tickFactor = 0.0f; #if !defined(AZ_RELEASE_BUILD) MultiplayerEditorConnection m_editorConnectionListener; From 055df374829d5b2b9c09424e5d098dc3c2a0302d Mon Sep 17 00:00:00 2001 From: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> Date: Wed, 28 Jul 2021 16:21:37 -0500 Subject: [PATCH 54/58] Register show command fix (#2408) * Updated print_registration functions to fix "register-show" command Added unit test to validate the argparse options to the register show command. Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the register.py script to once again register an engine list Previosly each engine were registered into a dictionary with multiple keys, but once the engine.json started to self describe the registered content that came with it, it was reduced to a single 'path' key. Therefore it has been changed to a list to be consistent with other o3de object paths Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated the SettingsRegistryMergeUtitls Code which parses the attempts to locate the engine path associated associated with the project.json engine key to check the 'engines_path' object within the o3de_manifest.json Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Updated print registration unit test to patch the get_project_path This is to make sure that the existence of the placeholder project path isn't validated when running the test Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Typo and formatting fixes for the print_registration script Also corrected indentation in unit_test_print_registration script Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> --- .../Settings/SettingsRegistryMergeUtils.cpp | 50 +-- scripts/o3de/o3de/manifest.py | 35 +- scripts/o3de/o3de/print_registration.py | 221 ++++++---- scripts/o3de/o3de/register.py | 79 ++-- scripts/o3de/tests/CMakeLists.txt | 9 +- .../tests/unit_test_print_registration.py | 383 ++++++++++++++++++ 6 files changed, 591 insertions(+), 186 deletions(-) create mode 100644 scripts/o3de/tests/unit_test_print_registration.py diff --git a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp index 74038c8aed..6b89b8c044 100644 --- a/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp +++ b/Code/Framework/AzCore/AzCore/Settings/SettingsRegistryMergeUtils.cpp @@ -57,6 +57,7 @@ namespace AZ::Internal // and avoid all this logic. using namespace AZ::SettingsRegistryMergeUtils; + using FixedValueString = AZ::SettingsRegistryInterface::FixedValueString; AZ::IO::FixedMaxPath engineRoot; if (auto engineManifestPath = AZ::Utils::GetEngineManifestPath(); !engineManifestPath.empty()) @@ -72,45 +73,16 @@ namespace AZ::Internal struct EngineInfo { AZ::IO::FixedMaxPath m_path; - AZ::SettingsRegistryInterface::FixedValueString m_moniker; + FixedValueString m_moniker; }; struct EnginePathsVisitor : public AZ::SettingsRegistryInterface::Visitor { void Visit( - [[maybe_unused]] AZStd::string_view path, [[maybe_unused]] AZStd::string_view valueName, + [[maybe_unused]] AZStd::string_view path, AZStd::string_view valueName, [[maybe_unused]] AZ::SettingsRegistryInterface::Type type, AZStd::string_view value) override { - m_enginePaths.emplace_back(EngineInfo{AZ::IO::FixedMaxPath{value}.LexicallyNormal(), {}}); - } - - AZ::SettingsRegistryInterface::VisitResponse Traverse( - [[maybe_unused]] AZStd::string_view path, AZStd::string_view valueName, - AZ::SettingsRegistryInterface::VisitAction action, AZ::SettingsRegistryInterface::Type type) override - { - auto response = AZ::SettingsRegistryInterface::VisitResponse::Continue; - if (action == AZ::SettingsRegistryInterface::VisitAction::Begin) - { - if (type == AZ::SettingsRegistryInterface::Type::Array) - { - if (valueName.compare("engines") != 0) - { - response = AZ::SettingsRegistryInterface::VisitResponse::Skip; - } - } - } - else if (action == AZ::SettingsRegistryInterface::VisitAction::Value) - { - if (type == AZ::SettingsRegistryInterface::Type::String) - { - if (valueName.compare("path") != 0) - { - response = AZ::SettingsRegistryInterface::VisitResponse::Skip; - } - } - } - - return response; + m_enginePaths.emplace_back(EngineInfo{ AZ::IO::FixedMaxPath{value}.LexicallyNormal(), FixedValueString{valueName} }); } AZStd::vector m_enginePaths{}; @@ -119,11 +91,11 @@ namespace AZ::Internal EnginePathsVisitor pathVisitor; if (manifestLoaded) { - auto enginePathsKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engines", EngineManifestRootKey); + auto enginePathsKey = FixedValueString::format("%s/engines_path", EngineManifestRootKey); settingsRegistry.Visit(pathVisitor, enginePathsKey); } - const auto engineMonikerKey = AZ::SettingsRegistryInterface::FixedValueString::format("%s/engine_name", EngineSettingsRootKey); + const auto engineMonikerKey = FixedValueString::format("%s/engine_name", EngineSettingsRootKey); AZStd::set projectPathsNotFound; @@ -135,7 +107,15 @@ namespace AZ::Internal if (settingsRegistry.MergeSettingsFile( engineSettingsPath.Native(), AZ::SettingsRegistryInterface::Format::JsonMergePatch, EngineSettingsRootKey)) { - settingsRegistry.Get(engineInfo.m_moniker, engineMonikerKey); + FixedValueString engineName; + settingsRegistry.Get(engineName, engineMonikerKey); + AZ_Warning("SettingsRegistryMergeUtils",engineInfo.m_moniker == engineName, + R"(The engine name key "%s" mapped to engine path "%s" within the global manifest of "%s")" + R"( does not match the "engine_name" field "%s" in the engine.json)" "\n" + "This engine should be re-registered.", + engineInfo.m_moniker.c_str(), engineInfo.m_path.c_str(), engineManifestPath.c_str(), + engineName.c_str()) + engineInfo.m_moniker = engineName; } } diff --git a/scripts/o3de/o3de/manifest.py b/scripts/o3de/o3de/manifest.py index 5bc6b95358..7e504d29cd 100644 --- a/scripts/o3de/o3de/manifest.py +++ b/scripts/o3de/o3de/manifest.py @@ -236,15 +236,13 @@ def get_gems_from_subdirectories(external_subdirs: list) -> list: # Data query methods -def get_this_engine() -> dict: - json_data = load_o3de_manifest() - engine_data = find_engine_data(json_data) - return engine_data - - def get_engines() -> list: json_data = load_o3de_manifest() - return json_data['engines'] if 'engines' in json_data else [] + engine_list = json_data['engines'] if 'engines' in json_data else [] + # Convert each engine dict entry into a string entry + return list(map( + lambda engine_object: engine_object.get('path', '') if isinstance(engine_object, dict) else engine_object, + engine_list)) def get_projects() -> list: @@ -424,20 +422,6 @@ def get_templates_for_generic_creation(): # temporary until we have a better wa return list(filter(filter_project_and_gem_templates_out, get_all_templates())) -def find_engine_data(json_data: dict, - engine_path: str or pathlib.Path = None) -> dict or None: - if not engine_path: - engine_path = get_this_engine_path() - engine_path = pathlib.Path(engine_path).resolve() - - for engine_object in json_data['engines']: - engine_object_path = pathlib.Path(engine_object['path']).resolve() - if engine_path == engine_object_path: - return engine_object - - return None - - def get_engine_json_data(engine_name: str = None, engine_path: str or pathlib.Path = None) -> dict or None: if not engine_name and not engine_path: @@ -639,8 +623,13 @@ def get_registered(engine_name: str = None, # check global first then this engine if isinstance(engine_name, str): - for engine in json_data['engines']: - engine_path = pathlib.Path(engine['path']).resolve() + engines = get_engines() + for engine in engines: + if isinstance(engine, dict): + engine_path = pathlib.Path(engine['path']).resolve() + else: + engine_path = pathlib.Path(engine_object).resolve() + engine_json = engine_path / 'engine.json' with engine_json.open('r') as f: try: diff --git a/scripts/o3de/o3de/print_registration.py b/scripts/o3de/o3de/print_registration.py index 10316cc4a8..b164243b7c 100644 --- a/scripts/o3de/o3de/print_registration.py +++ b/scripts/o3de/o3de/print_registration.py @@ -40,61 +40,67 @@ def get_project_path(project_path: pathlib.Path, project_name: str) -> pathlib.P def print_this_engine(verbose: int) -> int: - engine_data = manifest.get_this_engine() - print(json.dumps(engine_data, indent=4)) - result = True + this_engine_path = manifest.get_this_engine_path() + print(f'This Engine:\n{json.dumps(str(this_engine_path), indent=4)}') if verbose > 0: - result = print_manifest_json_data(engine_data, 'engine.json', 'This Engine', + return print_manifest_json_data([this_engine_path], 'This Engine', manifest.get_engine_json_data, 'engine_path') - return 0 if result else 1 + return 0 def print_engines(verbose: int) -> None: engines_data = manifest.get_engines() - print(json.dumps(engines_data, indent=4)) + print(f'Engine Paths:\n{json.dumps(engines_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(engines_data, 'engine.json', 'Engines', + return print_manifest_json_data(engines_data, 'Engine Jsons', manifest.get_engine_json_data, 'engine_path') return 0 def print_projects(verbose: int) -> int: projects_data = manifest.get_projects() - print(json.dumps(projects_data, indent=4)) + print(f'Project Paths:\n{json.dumps(projects_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(projects_data, 'project.json', 'Projects', + return print_manifest_json_data(projects_data, 'Project Jsons', manifest.get_project_json_data, 'project_path') return 0 def print_gems(verbose: int) -> int: gems_data = manifest.get_gems() - print(json.dumps(gems_data, indent=4)) + print(f'Gem Paths:\n{json.dumps(gems_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(gems_data, 'gem.json', 'Gems', + return print_manifest_json_data(gems_data, 'Gem Jsons', manifest.get_gem_json_data, 'gem_path') return 0 +def print_external_subdirectories(verbose: int) -> int: + external_subdirs_data = manifest.get_external_subdirectories() + print(f'External Subdirectories:\n{json.dumps(external_subdirs_data, indent=4)}') + return 0 + + + def print_templates(verbose: int) -> int: templates_data = manifest.get_templates() - print(json.dumps(templates_data, indent=4)) + print(f'Template Paths:\n{json.dumps(templates_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(templates_data, 'template.json', 'Templates', + return print_manifest_json_data(templates_data, 'Template Jsons', manifest.get_template_json_data, 'template_path') return 0 def print_restricted(verbose: int) -> int: restricted_data = manifest.get_restricted() - print(json.dumps(restricted_data, indent=4)) + print(f'Restricted Paths:\n{json.dumps(restricted_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(restricted_data, 'restricted.json', 'Restricted', + return print_manifest_json_data(restricted_data, 'Restricted Jsons', manifest.get_restricted_json_data, 'restricted_path') return 0 @@ -102,47 +108,47 @@ def print_restricted(verbose: int) -> int: # Engine output methods def print_engine_projects(verbose: int) -> int: engine_projects_data = manifest.get_engine_projects() - print(json.dumps(engine_projects_data, indent=4)) + print(f'Project Paths:\n{json.dumps(engine_projects_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(engine_projects_data, 'project.json', 'Projects', + return print_manifest_json_data(engine_projects_data, 'Project Jsons', manifest.get_project_json_data, 'project_path') return 0 def print_engine_gems(verbose: int) -> int: engine_gems_data = manifest.get_engine_gems() - print(json.dumps(engine_gems_data, indent=4)) + print(f'Gem Paths:\n{json.dumps(engine_gems_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(engine_gems_data, 'gem.json', 'Gems', + return print_manifest_json_data(engine_gems_data, 'Gem Jsons', manifest.get_gem_json_data, 'gem_path') return 0 def print_engine_templates(verbose: int) -> int: engine_templates_data = manifest.get_engine_templates() - print(json.dumps(engine_templates_data, indent=4)) + print(f'Template Paths:\n{json.dumps(engine_templates_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(engine_templates_data, 'template.json', 'Templates', + return print_manifest_json_data(engine_templates_data, 'Template Jsons', manifest.get_template_json_data, 'template_path') return 0 def print_engine_restricted(verbose: int) -> int: engine_restricted_data = manifest.get_engine_restricted() - print(json.dumps(engine_restricted_data, indent=4)) + print(f'Restricted Paths:\n{json.dumps(engine_restricted_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(engine_restricted_data, 'restricted.json', 'Restricted', + return print_manifest_json_data(engine_restricted_data, 'Restricted Jsons', manifest.get_restricted_json_data, 'restricted_path') return 0 -def print_engine_external_subdirectories() -> int: +def print_engine_external_subdirectories(verbose: int) -> int: external_subdirs_data = manifest.get_engine_external_subdirectories() - print(json.dumps(external_subdirs_data, indent=4)) + print(f'External Subdirectories:\n{json.dumps(external_subdirs_data, indent=4)}') return 0 @@ -153,21 +159,21 @@ def print_project_gems(verbose: int, project_path: pathlib.Path, project_name: s return 1 project_gems_data = manifest.get_project_gems(project_path) - print(json.dumps(project_gems_data, indent=4)) + print(f'Gem Paths:\n{json.dumps(project_gems_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(project_gems_data, 'gem.json', 'Gems', + return print_manifest_json_data(project_gems_data, 'Gems Jsons', manifest.get_gem_json_data, 'gem_path') return 0 -def print_project_external_subdirectories(project_path: pathlib.Path, project_name: str) -> int: +def print_project_external_subdirectories(verbose: int, project_path: pathlib.Path, project_name: str) -> int: project_path = get_project_path(project_path, project_name) if not project_path: return 1 external_subdirs_data = manifest.get_project_external_subdirectories(project_path) - print(json.dumps(external_subdirs_data, indent=4)) + print(f'External Subdirectories:\n{json.dumps(external_subdirs_data, indent=4)}') return 0 @@ -177,9 +183,9 @@ def print_project_templates(verbose: int, project_path: pathlib.Path, project_na return 1 project_templates_data = manifest.get_project_templates(project_path) - print(json.dumps(project_templates_data, indent=4)) + print(f'Template Paths:\n{json.dumps(project_templates_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(project_templates_data, 'template.json', 'Templates', + return print_manifest_json_data(project_templates_data, 'Template Jsons', manifest.get_template_json_data, 'template_path') return 0 @@ -190,73 +196,118 @@ def print_project_restricted(verbose: int, project_path: pathlib.Path, project_n return 1 project_restricted_data = manifest.get_project_restricted(project_path) - print(json.dumps(project_restricted_data, indent=4)) + print(f'Restricted Paths:\n{json.dumps(project_restricted_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(project_restricted_data, 'restricted.json', 'Restricted', + return print_manifest_json_data(project_restricted_data, 'Restricted Jsons', manifest.get_restricted_json_data, 'restricted_path') return 0 def print_all_projects(verbose: int) -> int: all_projects_data = manifest.get_all_projects() - print(json.dumps(all_projects_data, indent=4)) + print(f'Project Paths:\n{json.dumps(all_projects_data, indent=4)}') if verbose > 0: - return print_manifest_json_data(all_projects_data, 'project.json', 'Projects', + return print_manifest_json_data(all_projects_data, 'Project Jsons', manifest.get_project_json_data, 'project_path') return 0 -def print_all_gems(verbose: int) -> int: - all_gems_data = manifest.get_all_gems() - print(json.dumps(all_gems_data, indent=4)) +def print_all_gems(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: + all_gems = manifest.get_gems() + all_gems.extend(manifest.get_engine_gems()) + + # If a project path or project name is supplied query the gems from that project, otherwise query the gems from + # all projects + project_path = get_project_path(project_path, project_name) if project_path or project_name else None + projects = [project_path] if project_path else manifest.get_all_projects() + for project in projects: + all_gems.extend(manifest.get_project_gems(project)) + + # Filter out duplicates + all_gems = list(dict.fromkeys(all_gems)) + print(f'Gem Paths:\n{json.dumps(all_gems, indent=4)}') if verbose > 0: - return print_manifest_json_data(all_gems_data, 'gem.json', 'Gems', + return print_manifest_json_data(all_gems, 'Gem Jsons', manifest.get_gem_json_data, 'gem_path') return 0 -def print_all_external_subdirectories() -> int: - all_external_subdirectories_data = manifest.get_all_external_subdirectories() - print(json.dumps(all_external_subdirectories_data, indent=4)) +def print_all_external_subdirectories(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: + all_external_subdirectories = manifest.get_external_subdirectories() + all_external_subdirectories.extend(manifest.get_engine_external_subdirectories()) + + # If a project path or project name is supplied query the external subdirectories from that project, + # otherwise query the external subdirectories from all projects + project_path = get_project_path(project_path, project_name) if project_path or project_name else None + projects = [project_path] if project_path else manifest.get_all_projects() + for project in projects: + all_external_subdirectories.extend(manifest.get_project_external_subdirectories(project)) + + # Filter out duplicates + all_external_subdirectories = list(dict.fromkeys(all_external_subdirectories)) + print(f'External Subdirectories:\n{json.dumps(all_external_subdirectories, indent=4)}') return 0 -def print_all_templates(verbose: int) -> int: - all_templates_data = manifest.get_all_templates() - print(json.dumps(all_templates_data, indent=4)) + +def print_all_templates(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: + all_templates = manifest.get_templates() + all_templates.extend(manifest.get_engine_templates()) + + # If a project path or project name is supplied query the templates from that project, + # otherwise query the templates from all projects + project_path = get_project_path(project_path, project_name) if project_path or project_name else None + projects = [project_path] if project_path else manifest.get_all_projects() + for project in projects: + all_templates.extend(manifest.get_project_templates(project)) + + # Filter out duplicates + all_templates = list(dict.fromkeys(all_templates)) + print(f'Template Paths:\n{json.dumps(all_templates, indent=4)}') if verbose > 0: - return print_manifest_json_data(all_templates_data, 'template.json', 'Templates', + return print_manifest_json_data(all_templates, 'Template Jsons', manifest.get_template_json_data, 'template_path') return 0 -def print_all_restricted(verbose: int) -> int: - all_restricted_data = manifest.get_all_restricted() - print(json.dumps(all_restricted_data, indent=4)) +def print_all_restricted(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: + all_restricted = manifest.get_restricted() + all_restricted.extend(manifest.get_engine_restricted()) + + # If a project path or project name is supplied query the restricted from that project, + # otherwise query the restricted from all projects + project_path = get_project_path(project_path, project_name) if project_path or project_name else None + projects = [project_path] if project_path else manifest.get_all_projects() + for project in projects: + all_restricted.extend(manifest.get_project_restricted(project)) + + # Filter out duplicates + all_restricted = list(dict.fromkeys(all_restricted)) + print(f'Restricted Paths:\n{json.dumps(all_restricted, indent=4)}') if verbose > 0: - return print_manifest_json_data(all_restricted_data, 'restricted.json', 'Restricted', + return print_manifest_json_data(all_restricted, 'Restricted Jsons', manifest.get_restricted_json_data, 'restricted_path') return 0 -def print_manifest_json_data(uri_json_data: dict, json_filename: str, +def print_manifest_json_data(uri_json_data: list, print_prefix: str, get_json_func: callable, get_json_data_kw: str) -> int: print('\n') print(f"{print_prefix}================================================") for manifest_uri in uri_json_data: # if it's not local it should be in the cache - parsed_uri = urllib.parse.urlparse(manifest_uri) + parsed_uri = urllib.parse.urlparse(pathlib.Path(manifest_uri).as_posix()) if parsed_uri.scheme in ['http', 'https', 'ftp', 'ftps']: repo_sha256 = hashlib.sha256(manifest_uri.encode()) cache_folder = manifest.get_o3de_cache_folder() manifest_json_path = cache_folder / str(repo_sha256.hexdigest() + '.json') else: - manifest_json_path = pathlib.Path(manifest_uri).resolve() / json_filename + manifest_json_path = pathlib.Path(manifest_uri).resolve() - json_data = get_json_func(**{get_json_data_kwargs: manifest_json_path}) + json_data = get_json_func(**{get_json_data_kw: manifest_json_path}) if json_data: print(manifest_json_path) print(json.dumps(json_data, indent=4) + '\n') @@ -284,29 +335,30 @@ def print_repos_data(repos_data: dict) -> int: return 0 -def register_show_repos(verbose: int) -> None: +def print_repos(verbose: int) -> int: repos_data = manifest.get_repos() print(json.dumps(repos_data, indent=4)) if verbose > 0: - return print_repos_data(repos_data) == 0 + return print_repos_data(repos_data) return 0 -def register_show(verbose: int) -> None: +def register_show(verbose: int, project_path: pathlib.Path = None, project_name: str = None) -> int: json_data = manifest.load_o3de_manifest() print(f"{manifest.get_o3de_manifest()}:") print(json.dumps(json_data, indent=4)) - result = True + result = 0 if verbose > 0: - result = print_manifest_json_data(manifest.get_engines()) == 0 and result - result = print_manifest_json_data(manifest.get_all_projects()) == 0 and result - result = print_manifest_json_data(manifest.get_gems()) == 0 and result - result = print_manifest_json_data(manifest.get_all_templates()) == 0 and result - result = print_manifest_json_data(manifest.get_all_restricted()) == 0 and result - result = print_repos_data(manifest.get_repos()) == 0 and result - return 0 if result else 1 + result = print_engines(verbose) or result + result = print_all_projects(verbose) or result + result = print_all_gems(verbose, project_path, project_name) or result + result = print_all_templates(verbose, project_path, project_name) or result + result = print_all_restricted(verbose, project_path, project_name) or result + result = print_repos(verbose) or result + + return result def _run_register_show(args: argparse) -> int: @@ -321,6 +373,8 @@ def _run_register_show(args: argparse) -> int: return print_projects(args.verbose) elif args.gems: return print_gems(args.verbose) + elif args.external_subdirectories: + return print_external_subdirectories(args.verbose) elif args.templates: return print_templates(args.verbose) elif args.repos: @@ -333,7 +387,7 @@ def _run_register_show(args: argparse) -> int: elif args.engine_gems: return print_engine_gems(args.verbose) elif args.engine_external_subdirectories: - return print_engine_external_subdirectories() + return print_engine_external_subdirectories(args.verbose) elif args.engine_templates: return print_engine_templates(args.verbose) elif args.engine_restricted: @@ -342,7 +396,7 @@ def _run_register_show(args: argparse) -> int: elif args.project_gems: return print_project_gems(args.verbose, args.project_path, args.project_name) elif args.project_external_subdirectories: - return print_project_external_subdirectories(args.project_path, args.project_name) + return print_project_external_subdirectories(args.verbose, args.project_path, args.project_name) elif args.project_templates: return print_project_templates(args.verbose, args.project_path, args.project_name) elif args.project_restricted: @@ -351,16 +405,16 @@ def _run_register_show(args: argparse) -> int: elif args.all_projects: return print_all_projects(args.verbose) elif args.all_gems: - return print_all_gems(args.verbose) + return print_all_gems(args.verbose, args.project_path, args.project_name) elif args.all_external_subdirectories: - return print_all_external_subdirectories() + return print_all_external_subdirectories(args.verbose, args.project_path, args.project_name) elif args.all_templates: - return print_all_templates(args.verbose) + return print_all_templates(args.verbose, args.project_path, args.project_name) elif args.all_restricted: - return print_all_restricted(args.verbose) + return print_all_restricted(args.verbose, args.project_path, args.project_name) else: - return register_show(args.verbose) + return register_show(args.verbose, args.project_path, args.project_name) def add_parser_args(parser): @@ -393,6 +447,9 @@ def add_parser_args(parser): group.add_argument('-rs', '--restricted', action='store_true', required=False, default=False, help='Output the restricted directories registered in the global ~/.o3de/o3de_manifest.json.') + group.add_argument('-es', '--external-subdirectories', action='store_true', required=False, + default=False, + help='Output the external subdirectories registered in the global ~/.o3de/o3de_manifest.json.') group.add_argument('-ep', '--engine-projects', action='store_true', required=False, default=False, @@ -428,16 +485,28 @@ def add_parser_args(parser): help='Output all projects registered in the ~/.o3de/o3de_manifest.json and the current engine.json. Ignores repos.') group.add_argument('-ag', '--all-gems', action='store_true', required=False, default=False, - help='Output all gems registered in the ~/.o3de/o3de_manifest.json and the current engine.json. Ignores repos') + help='Output all gems registered in the ~/.o3de/o3de_manifest.json and the current engine.json.' + ' If --project-path or --project-name option is supplied, outputs gems registered in' + ' that project\'s project.json otherwise outputs registered gems from all registered projects.' + ' Ignores repos') group.add_argument('-at', '--all-templates', action='store_true', required=False, default=False, - help='Output all templates registered in the ~/.o3de/o3de_manifest.json and the current engine.json. Ignores repos.') + help='Output all templates registered in the ~/.o3de/o3de_manifest.json and the current engine.json.' + ' If --project-path or --project-name option is supplied, outputs templates registered in' + ' that project\'s project.json otherwise outputs registered templates from all registered' + ' projects. Ignores repos') group.add_argument('-ares', '--all-restricted', action='store_true', required=False, default=False, - help='Output all restricted directory registered in the ~/.o3de/o3de_manifest.json and the current engine.json.') + help='Output all restricted directory registered in the ~/.o3de/o3de_manifest.json and the current engine.json.' + ' If --project-path or --project-name option is supplied, outputs restricted' + ' directories registered in that project\'s project.json otherwise outputs restricted' + ' directories registered from all registered projects. Ignores repos') group.add_argument('-aes', '--all-external-subdirectories', action='store_true', default=False, - help='Output all external subdirectories registered in the ~/.o3de/o3de_manifest.json and the current engine.json.') + help='Output all external subdirectories registered in the ~/.o3de/o3de_manifest.json and the current engine.json.' + ' If --project-path or --project-name options is supplied, outputs external' + ' subdirectories registered in that project\'s project.json otherwise outputs external' + ' subdirectories registered from all registered projects. Ignores repos') parser.add_argument('-v', '--verbose', action='count', required=False, default=0, diff --git a/scripts/o3de/o3de/register.py b/scripts/o3de/o3de/register.py index fb91cb5bea..8481c5fae0 100644 --- a/scripts/o3de/o3de/register.py +++ b/scripts/o3de/o3de/register.py @@ -261,43 +261,6 @@ def add_engine_name_to_path(json_data: dict, engine_path: pathlib.Path, force: b return 0 -def register_engine_path(json_data: dict, - engine_path: pathlib.Path, - remove: bool = False, - force: bool = False) -> int: - if not engine_path: - logger.error(f'Engine path cannot be empty.') - return 1 - engine_path = pathlib.Path(engine_path).resolve() - - for engine_object in json_data.get('engines', []): - if isinstance(engine_object, dict): - engine_object_path = pathlib.Path(engine_object['path']).resolve() - else: - engine_object_path = pathlib.Path(engine_object).resolve() - if engine_object_path == engine_path: - json_data['engines'].remove(engine_object) - - if remove: - return remove_engine_name_to_path(json_data, engine_path) - - if not engine_path.is_dir(): - logger.error(f'Engine path {engine_path} does not exist.') - return 1 - - engine_json = engine_path / 'engine.json' - if not validation.valid_o3de_engine_json(engine_json): - logger.error(f'Engine json {engine_json} is not valid.') - return 1 - - engine_object = {} - engine_object.update({'path': engine_path.as_posix()}) - - json_data.setdefault('engines', []).insert(0, engine_object) - - return add_engine_name_to_path(json_data, engine_path, force) - - def register_o3de_object_path(json_data: dict, o3de_object_path: str or pathlib.Path, o3de_object_key: str, @@ -343,7 +306,7 @@ def register_o3de_object_path(json_data: dict, try: paths_to_remove.append(o3de_object_path.relative_to(save_path.parent)) except ValueError: - pass # It is OK relative path cannot be formed + pass # It is not an error if a relative path cannot be formed manifest_data[o3de_object_key] = list(filter(lambda p: pathlib.Path(p) not in paths_to_remove, manifest_data.setdefault(o3de_object_key, []))) @@ -358,7 +321,7 @@ def register_o3de_object_path(json_data: dict, manifest_json_path = o3de_object_path / o3de_json_filename if validation_func and not validation_func(manifest_json_path): - logger.error(f'o3de json {manifest_json_path} is not valid.') + logger.error(f'Manifest at path {manifest_json_path} is not valid.') return 1 # if there is a save path make it relative the directory containing o3de object json file @@ -374,6 +337,27 @@ def register_o3de_object_path(json_data: dict, return 0 +def register_engine_path(json_data: dict, + engine_path: pathlib.Path, + remove: bool = False, + force: bool = False) -> int: + # If the o3de_manifest.json 'engines' key is list containing dictionary entries, transform it to a list of strings + engine_list = json_data.get('engines', []) + + def transform_engine_dict_to_string(engine): return engine.get('path', '') if isinstance(engine, dict) else engine + json_data['engines'] = list(map(transform_engine_dict_to_string, engine_list)) + + result = register_o3de_object_path(json_data, engine_path, 'engines', 'engine.json', + validation.valid_o3de_engine_json, remove) + if result != 0: + return result + + if remove: + return remove_engine_name_to_path(json_data, engine_path) + + return add_engine_name_to_path(json_data, engine_path, force) + + def register_external_subdirectory(json_data: dict, external_subdir_path: pathlib.Path, remove: bool = False, @@ -677,37 +661,30 @@ def remove_invalid_o3de_projects(manifest_path: pathlib.Path = None) -> int: return result def remove_invalid_o3de_objects() -> None: - json_data = manifest.load_o3de_manifest() - - for engine_object in json_data.get('engines', []): - engine_path = engine_object.get('path', '') + for engine_path in manifest.get_engines(): if not validation.valid_o3de_engine_json(pathlib.Path(engine_path).resolve() / 'engine.json'): logger.warn(f"Engine path {engine_path} is invalid.") register(engine_path=engine_path, remove=True) remove_invalid_o3de_projects() - for gem in json_data.get('gems', []): - if not validation.valid_o3de_gem_json(pathlib.Path(gem).resolve() / 'gem.json'): - logger.warn(f"Gem path {gem} is invalid.") - register(gem_path=gem, remove=True) - - for external in json_data.get('external_subdirectories', []): + for external in manifest.get_external_subdirectories(): external = pathlib.Path(external).resolve() if not external.is_dir(): logger.warn(f"External subdirectory {external} is invalid.") register(engine_path=engine_path, external_subdir_path=external, remove=True) - for template in json_data.get('templates', []): + for template in manifest.get_templates(): if not validation.valid_o3de_template_json(pathlib.Path(template).resolve() / 'template.json'): logger.warn(f"Template path {template} is invalid.") register(template_path=template, remove=True) - for restricted in json_data.get('restricted', []): + for restricted in manifest.get_restricted(): if not validation.valid_o3de_restricted_json(pathlib.Path(restricted).resolve() / 'restricted.json'): logger.warn(f"Restricted path {restricted} is invalid.") register(restricted_path=restricted, remove=True) + json_data = manifest.load_o3de_manifest() default_engines_folder = pathlib.Path(json_data.get('default_engines_folder', manifest.get_o3de_engines_folder())).resolve() if not default_engines_folder.is_dir(): new_default_engines_folder = manifest.get_o3de_folder() / 'Engines' diff --git a/scripts/o3de/tests/CMakeLists.txt b/scripts/o3de/tests/CMakeLists.txt index 00d0774c45..1cd6eac7ee 100644 --- a/scripts/o3de/tests/CMakeLists.txt +++ b/scripts/o3de/tests/CMakeLists.txt @@ -65,4 +65,11 @@ ly_add_pytest( PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_engine_template.py TEST_SUITE smoke EXCLUDE_TEST_RUN_TARGET_FROM_IDE -) \ No newline at end of file +) + +ly_add_pytest( + NAME o3de_register_show + PATH ${CMAKE_CURRENT_LIST_DIR}/unit_test_print_registration.py + TEST_SUITE smoke + EXCLUDE_TEST_RUN_TARGET_FROM_IDE +) diff --git a/scripts/o3de/tests/unit_test_print_registration.py b/scripts/o3de/tests/unit_test_print_registration.py new file mode 100644 index 0000000000..7e3e75edcd --- /dev/null +++ b/scripts/o3de/tests/unit_test_print_registration.py @@ -0,0 +1,383 @@ +# +# 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 +# +# + +import argparse +import json +import logging +import pytest +import pathlib +from unittest.mock import patch + +from o3de import print_registration + + +TEST_PROJECT_JSON_PAYLOAD = ''' +{ + "project_name": "MinimalProject", + "origin": "The primary repo for MinimalProject goes here: i.e. http://www.mydomain.com", + "license": "What license MinimalProject uses goes here: i.e. https://opensource.org/licenses/MIT", + "display_name": "MinimalProject", + "summary": "A short description of MinimalProject.", + "canonical_tags": [ + "Project" + ], + "user_tags": [ + "MinimalProject" + ], + "icon_path": "preview.png", + "engine": "o3de-install", + "external_subdirectories": [ + "D:/TestGem" + ] +} +''' + +TEST_ENGINE_JSON_PAYLOAD = ''' +{ + "engine_name": "o3de", + "restricted_name": "o3de", + "FileVersion": 1, + "O3DEVersion": "0.0.0.0", + "O3DECopyrightYear": 2021, + "O3DEBuildNumber": 0, + "external_subdirectories": [ + "Gems/TestGem2" + ], + "projects": [ + ], + "templates": [ + "Templates/MinimalProject" + ] +} +''' + +TEST_GEM_JSON_PAYLOAD = ''' +{ + "gem_name": "TestGem", + "display_name": "TestGem", + "license": "What license TestGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "origin": "The primary repo for TestGem goes here: i.e. http://www.mydomain.com", + "type": "Code", + "summary": "A short description of TestGem.", + "canonical_tags": [ + "Gem" + ], + "user_tags": [ + "TestGem" + ], + "icon_path": "preview.png", + "requirements": "" +} +''' + +TEST_TEMPLATE_JSON_PAYLOAD = ''' +{ + "template_name": "AssetGem", + "origin": "The primary repo for AssetGem goes here: i.e. http://www.mydomain.com", + "license": "What license AssetGem uses goes here: i.e. https://opensource.org/licenses/MIT", + "display_name": "AssetGem", + "summary": "A short description of AssetGem template.", + "canonical_tags": [], + "user_tags": [ + "AssetGem" + ], + "icon_path": "preview.png", + "copyFiles": [ + { + "file": "CMakeLists.txt", + "origin": "CMakeLists.txt", + "isTemplated": true, + "isOptional": false + }, + { + "file": "gem.json", + "origin": "gem.json", + "isTemplated": true, + "isOptional": false + }, + { + "file": "preview.png", + "origin": "preview.png", + "isTemplated": false, + "isOptional": false + } + ], + "createDirectories": [ + { + "dir": "Assets", + "origin": "Assets" + } + ] +} +''' + +TEST_RESTRICTED_JSON_PAYLOAD = ''' +{ + "restricted_name": "o3de" +} +''' + +TEST_O3DE_MANIFEST_JSON_PAYLOAD = ''' +{ + "o3de_manifest_name": "testuser", + "origin": "C:/Users/testuser/.o3de", + "default_engines_folder": "C:/Users/testuser/.o3de/Engines", + "default_projects_folder": "C:/Users/testuser/.o3de/Projects", + "default_gems_folder": "C:/Users/testuser/.o3de/Gems", + "default_templates_folder": "C:/Users/testuser/.o3de/Templates", + "default_restricted_folder": "C:/Users/testuser/.o3de/Restricted", + "default_third_party_folder": "C:/Users/testuser/.o3de/3rdParty", + "projects": [ + "D:/MinimalProject" + ], + "external_subdirectories": [], + "templates": [], + "restricted": [], + "repos": [], + "engines": [ + "D:/o3de/o3de" + ], + "engines_path": { + "o3de": "D:/o3de/o3de" + } +} +''' + +class TestPrintRegistration: + @staticmethod + def load_manifest_json(): + return json.loads(TEST_O3DE_MANIFEST_JSON_PAYLOAD) + + @staticmethod + def get_engine_json_data(engine_path: pathlib.Path = None): + return json.loads(TEST_ENGINE_JSON_PAYLOAD) + + @staticmethod + def get_project_json_data(project_path: pathlib.Path = None): + return json.loads(TEST_PROJECT_JSON_PAYLOAD) + + @staticmethod + def get_gem_json_data(gem_path: pathlib.Path = None): + return json.loads(TEST_GEM_JSON_PAYLOAD) + + @staticmethod + def get_template_json_data(template_path: pathlib.Path = None): + return json.loads(TEST_TEMPLATE_JSON_PAYLOAD) + + @staticmethod + def get_restricted_json_data(restricted_path: pathlib.Path = None): + return json.loads(TEST_RESTRICTED_JSON_PAYLOAD) + + @pytest.mark.parametrize("project_path, verbose", [ + pytest.param(None, 0), + pytest.param(None, 1), + pytest.param(pathlib.Path("D:/MinimalProject"), 0), + pytest.param(pathlib.Path("D:/MinimalProject"), 1) + ]) + def test_print_registration_no_option(self, project_path, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [] + if project_path: + arg_list += ['--project-path', project_path.as_posix()] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_engine_json_data', + side_effect=self.get_engine_json_data) as get_engine_json_data_patch, \ + patch('o3de.manifest.get_project_json_data', + side_effect=self.get_project_json_data) as get_project_json_patch, \ + patch('o3de.manifest.get_gem_json_data', side_effect=self.get_gem_json_data) as get_gem_json_patch, \ + patch('o3de.manifest.get_template_json_data', side_effect=self.get_template_json_data) as get_template_json_patch, \ + patch('o3de.manifest.get_restricted_json_data', side_effect=self.get_restricted_json_data) as get_json_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 + + + @pytest.mark.parametrize("engine_arg_option, verbose", [ + pytest.param("--this-engine", 0), + pytest.param("--this-engine", 1), + pytest.param("--engines", 0), + pytest.param("--engines", 1) + ]) + def test_print_engine_registration(self, engine_arg_option, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [engine_arg_option] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_engine_json_data', side_effect=self.get_engine_json_data) as get_engine_json_data_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 + + + @pytest.mark.parametrize("arg_option, verbose", [ + pytest.param("--projects", 0), + pytest.param("--projects", 1), + pytest.param("--engine-projects", 0), + pytest.param("--engine-projects", 1), + pytest.param("--all-projects", 0), + pytest.param("--all-projects", 1) + ]) + def test_print_project_registration(self, arg_option, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [arg_option] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_project_json_data', side_effect=self.get_project_json_data) as get_json_data_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 + + + @pytest.mark.parametrize("arg_option, project_path, verbose", [ + pytest.param("--gems", None, 0), + pytest.param("--gems", None, 1), + pytest.param("--engine-gems", None, 0), + pytest.param("--engine-gems", None, 1), + pytest.param("--project-gems", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--project-gems", pathlib.Path("D:/MinimalProject"), 1), + pytest.param("--all-gems", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--all-gems", None, 0), + pytest.param("--all-gems", pathlib.Path("D:/MinimalProject"), 1), + pytest.param("--all-gems", None, 1) + ]) + def test_print_gem_registration(self, arg_option, project_path, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [arg_option] + if project_path: + arg_list += ['--project-path', project_path.as_posix()] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + # Patch the manifest.py function to locate gem.json files in external subdirectories + # to just return a fake path to a single test gem + def get_gems_from_subdirectories(external_subdirs: list) -> list: + return ["D:/TestGem"] + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_gem_json_data', side_effect=self.get_gem_json_data) as get_json_patch, \ + patch('o3de.manifest.get_project_json_data', side_effect=self.get_project_json_data) as get_project_json_patch, \ + patch('o3de.manifest.get_gems_from_subdirectories', side_effect=get_gems_from_subdirectories) as get_gems_from_subdirs_patch, \ + patch('o3de.print_registration.get_project_path', return_value=project_path) as get_project_path_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 + + + @pytest.mark.parametrize("arg_option, project_path, verbose", [ + pytest.param("--templates", None, 0), + pytest.param("--templates", None, 1), + pytest.param("--engine-templates", None, 0), + pytest.param("--engine-templates", None, 1), + pytest.param("--project-templates", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--project-templates", pathlib.Path("D:/MinimalProject"), 1), + pytest.param("--all-templates", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--all-templates", None, 0), + pytest.param("--all-templates", pathlib.Path("D:/MinimalProject"), 1), + pytest.param("--all-templates", None, 1) + ]) + def test_print_template_registration(self, arg_option, project_path, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [arg_option] + if project_path: + arg_list += ['--project-path', project_path.as_posix()] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_template_json_data', side_effect=self.get_template_json_data) as get_json_patch, \ + patch('o3de.manifest.get_project_json_data', side_effect=self.get_project_json_data) as get_project_json_patch, \ + patch('o3de.print_registration.get_project_path', return_value=project_path) as get_project_path_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 + + + @pytest.mark.parametrize("arg_option, project_path, verbose", [ + pytest.param("--restricted", None, 0), + pytest.param("--restricted", None, 1), + pytest.param("--engine-restricted", None, 0), + pytest.param("--engine-restricted", None, 1), + pytest.param("--project-restricted", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--project-restricted", pathlib.Path("D:/MinimalProject"), 1), + pytest.param("--all-restricted", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--all-restricted", None, 0), + pytest.param("--all-restricted", pathlib.Path("D:/MinimalProject"), 1), + pytest.param("--all-restricted", None, 1) + ]) + def test_print_restricted_registration(self, arg_option, project_path, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [arg_option] + if project_path: + arg_list += ['--project-path', project_path.as_posix()] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_restricted_json_data', side_effect=self.get_restricted_json_data) as get_json_patch, \ + patch('o3de.manifest.get_project_json_data', side_effect=self.get_project_json_data) as get_project_json_patch, \ + patch('o3de.print_registration.get_project_path', return_value=project_path) as get_project_path_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 + + + # Setting --verbose with the --*external-subdirectories option doesn't result in any additional output + # So it is only parameterized as 0 + @pytest.mark.parametrize("arg_option, project_path, verbose", [ + pytest.param("--external-subdirectories", None, 0), + pytest.param("--engine-external-subdirectories", None, 0), + pytest.param("--project-external-subdirectories", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--all-external-subdirectories", pathlib.Path("D:/MinimalProject"), 0), + pytest.param("--all-external-subdirectories", None, 0), + ]) + def test_print_external_subdirectories_registration(self, arg_option, project_path, verbose): + parser = argparse.ArgumentParser() + + # Register the registration script subparsers with the current argument parser + print_registration.add_parser_args(parser) + arg_list = [arg_option] + if project_path: + arg_list += ['--project-path', project_path.as_posix()] + if verbose: + arg_list += ['-' + 'v' * verbose] + test_args = parser.parse_args(arg_list) + + with patch('o3de.manifest.load_o3de_manifest', side_effect=self.load_manifest_json) as load_manifest_patch, \ + patch('o3de.manifest.get_project_json_data', + side_effect=self.get_project_json_data) as get_project_json_patch, \ + patch('o3de.print_registration.get_project_path', return_value=project_path) as get_project_path_patch: + result = print_registration._run_register_show(test_args) + assert result == 0 From 0040c7fd9b42b500be6783e198d3dc0eecd801f1 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 28 Jul 2021 14:48:06 -0700 Subject: [PATCH 55/58] Tweak test projects so the console window remains open (#2380) * tweak test projects so the console window remains open Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * doing it for all test projects Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * newline at the end of the file to make devs happy Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- cmake/LYTestWrappers.cmake | 9 +++++++++ cmake/Platform/Common/Directory.Build.props | 7 ++++++- cmake/Platform/Common/TestProject.props | 16 ++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 cmake/Platform/Common/TestProject.props diff --git a/cmake/LYTestWrappers.cmake b/cmake/LYTestWrappers.cmake index 535f00f58d..efb19a20dd 100644 --- a/cmake/LYTestWrappers.cmake +++ b/cmake/LYTestWrappers.cmake @@ -219,8 +219,17 @@ function(ly_add_test) VS_DEBUGGER_COMMAND_ARGUMENTS "${test_arguments_line}" ) + # In the case where we are creating a custom target, we need to add dependency to the target + if(ly_add_test_PARENT_NAME AND NOT ${ly_add_test_NAME} STREQUAL ${ly_add_test_PARENT_NAME}) + ly_add_dependencies(${unaliased_test_name} ${ly_add_test_PARENT_NAME}) + endif() + endif() + # For test projects that are custom targets, pass a props file that sets the project as "Console" so + # it leaves the console open when it finishes + set_target_properties(${unaliased_test_name} PROPERTIES VS_USER_PROPS "${LY_ROOT_FOLDER}/cmake/Platform/Common/TestProject.props") + # Include additional dependencies if (ly_add_test_RUNTIME_DEPENDENCIES) ly_add_dependencies(${unaliased_test_name} ${ly_add_test_RUNTIME_DEPENDENCIES}) diff --git a/cmake/Platform/Common/Directory.Build.props b/cmake/Platform/Common/Directory.Build.props index 73aa984073..76e4b28922 100644 --- a/cmake/Platform/Common/Directory.Build.props +++ b/cmake/Platform/Common/Directory.Build.props @@ -17,7 +17,12 @@ SPDX-License-Identifier: Apache-2.0 OR MIT - TurnOffAllWarnings + + TurnOffAllWarnings + + \ No newline at end of file diff --git a/cmake/Platform/Common/TestProject.props b/cmake/Platform/Common/TestProject.props new file mode 100644 index 0000000000..dff509b7ff --- /dev/null +++ b/cmake/Platform/Common/TestProject.props @@ -0,0 +1,16 @@ + + + + + + + + Console + + + From f0cafd0e9dc336e1f80a05dfacc8b7288b574b82 Mon Sep 17 00:00:00 2001 From: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> Date: Wed, 28 Jul 2021 15:53:14 -0700 Subject: [PATCH 56/58] Create RUN target as helpers for the project-centric workflow (#2520) * Create RUN target as helpers for the project-centric workflow Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * typo fix Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> * rename target as ".Imported" and create "" as the metatarget that is used for debugging and building in o3de Signed-off-by: Esteban Papp <81431996+amznestebanpapp@users.noreply.github.com> --- Code/Editor/CMakeLists.txt | 2 + cmake/Platform/Common/Install_common.cmake | 43 ++++++++++++++++++---- cmake/SettingsRegistry.cmake | 7 +--- cmake/install/InstalledTarget.in | 2 + 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/Code/Editor/CMakeLists.txt b/Code/Editor/CMakeLists.txt index fe694f165a..fca16a2093 100644 --- a/Code/Editor/CMakeLists.txt +++ b/Code/Editor/CMakeLists.txt @@ -163,6 +163,8 @@ ly_add_target( editor_files.cmake PLATFORM_INCLUDE_FILES Platform/${PAL_PLATFORM_NAME}/editor_${PAL_PLATFORM_NAME_LOWERCASE}.cmake + TARGET_PROPERTIES + LY_INSTALL_GENERATE_RUN_TARGET TRUE BUILD_DEPENDENCIES PRIVATE 3rdParty::Qt::Core diff --git a/cmake/Platform/Common/Install_common.cmake b/cmake/Platform/Common/Install_common.cmake index 2157a632c7..612358f938 100644 --- a/cmake/Platform/Common/Install_common.cmake +++ b/cmake/Platform/Common/Install_common.cmake @@ -10,6 +10,15 @@ include(cmake/FileUtil.cmake) set(CMAKE_INSTALL_MESSAGE NEVER) # Simplify messages to reduce output noise +define_property(TARGET PROPERTY LY_INSTALL_GENERATE_RUN_TARGET + BRIEF_DOCS "Defines if a \"RUN\" targets should be created when installing this target Gem" + FULL_DOCS [[ + Property which is set on targets that should generate a "RUN" + target when installed. This \"RUN\" target helps to run the + binary from the installed location directly from the IDE. + ]] +) + ly_set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Core) cmake_path(RELATIVE_PATH CMAKE_RUNTIME_OUTPUT_DIRECTORY BASE_DIRECTORY ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE runtime_output_directory) @@ -117,15 +126,19 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar set(NAMESPACE_PLACEHOLDER "") set(NAME_PLACEHOLDER ${TARGET_NAME}) endif() + get_target_property(should_create_helper ${TARGET_NAME} LY_INSTALL_GENERATE_RUN_TARGET) + if(should_create_helper) + set(NAME_PLACEHOLDER ${NAME_PLACEHOLDER}.Imported) + endif() set(TARGET_TYPE_PLACEHOLDER "") - get_target_property(target_type ${NAME_PLACEHOLDER} TYPE) + get_target_property(target_type ${TARGET_NAME} TYPE) # Remove the _LIBRARY since we dont need to pass that to ly_add_targets string(REPLACE "_LIBRARY" "" TARGET_TYPE_PLACEHOLDER ${target_type}) # For HEADER_ONLY libs we end up generating "INTERFACE" libraries, need to specify HEADERONLY instead string(REPLACE "INTERFACE" "HEADERONLY" TARGET_TYPE_PLACEHOLDER ${TARGET_TYPE_PLACEHOLDER}) if(TARGET_TYPE_PLACEHOLDER STREQUAL "MODULE") - get_target_property(gem_module ${NAME_PLACEHOLDER} GEM_MODULE) + get_target_property(gem_module ${TARGET_NAME} GEM_MODULE) if(gem_module) set(TARGET_TYPE_PLACEHOLDER "GEM_MODULE") endif() @@ -158,7 +171,6 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar unset(RUNTIME_DEPENDENCIES_PLACEHOLDER) endif() - get_target_property(inteface_build_dependencies_props ${TARGET_NAME} INTERFACE_LINK_LIBRARIES) unset(INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER) if(inteface_build_dependencies_props) @@ -182,6 +194,23 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar list(REMOVE_DUPLICATES INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER) string(REPLACE ";" "\n" INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER "${INTERFACE_BUILD_DEPENDENCIES_PLACEHOLDER}") + # If the target is an executable/application, add a custom target so we can debug the target in project-centric workflow + if(should_create_helper) + string(REPLACE ".Imported" "" RUN_TARGET_NAME ${NAME_PLACEHOLDER}) + set(target_types_with_debugging_helper EXECUTABLE APPLICATION) + if(NOT target_type IN_LIST target_types_with_debugging_helper) + message(FATAL_ERROR "Cannot generate a RUN target for ${TARGET_NAME}, type is ${target_type}") + endif() + set(TARGET_RUN_HELPER +"add_custom_target(${RUN_TARGET_NAME}) +set_target_properties(${RUN_TARGET_NAME} PROPERTIES + FOLDER \"CMakePredefinedTargets/SDK\" + VS_DEBUGGER_COMMAND \$> + VS_DEBUGGER_COMMAND_ARGUMENTS \"--project-path=\${LY_DEFAULT_PROJECT_PATH}\" +)" +) + endif() + # Config file set(target_file_contents "# Generated by O3DE install\n\n") if(NOT target_type STREQUAL INTERFACE_LIBRARY) @@ -194,13 +223,13 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar set(target_location "\${LY_ROOT_FOLDER}/${library_output_directory}/${PAL_PLATFORM_NAME}/$/${target_library_output_subdirectory}/$") elseif(target_type STREQUAL SHARED_LIBRARY) string(APPEND target_file_contents -"set_property(TARGET ${TARGET_NAME} +"set_property(TARGET ${NAME_PLACEHOLDER} APPEND_STRING PROPERTY IMPORTED_IMPLIB $<$$:\"\${LY_ROOT_FOLDER}/${archive_output_directory}/${PAL_PLATFORM_NAME}/$/$\"$ ) ") string(APPEND target_file_contents -"set_property(TARGET ${TARGET_NAME} +"set_property(TARGET ${NAME_PLACEHOLDER} PROPERTY IMPORTED_IMPLIB_$> \"\${LY_ROOT_FOLDER}/${archive_output_directory}/${PAL_PLATFORM_NAME}/$/$\" ) @@ -212,11 +241,11 @@ function(ly_setup_target OUTPUT_CONFIGURED_TARGET ALIAS_TARGET_NAME absolute_tar if(target_location) string(APPEND target_file_contents -"set_property(TARGET ${TARGET_NAME} +"set_property(TARGET ${NAME_PLACEHOLDER} APPEND_STRING PROPERTY IMPORTED_LOCATION $<$$:${target_location}$ ) -set_property(TARGET ${TARGET_NAME} +set_property(TARGET ${NAME_PLACEHOLDER} PROPERTY IMPORTED_LOCATION_$> ${target_location} ) diff --git a/cmake/SettingsRegistry.cmake b/cmake/SettingsRegistry.cmake index b740fefd25..ebf2254dc6 100644 --- a/cmake/SettingsRegistry.cmake +++ b/cmake/SettingsRegistry.cmake @@ -159,10 +159,6 @@ function(ly_delayed_generate_settings_registry) message(FATAL_ERROR "Dependency ${gem_target} from ${target} does not exist") endif() - get_property(has_manually_added_dependencies TARGET ${gem_target} PROPERTY MANUALLY_ADDED_DEPENDENCIES SET) - get_target_property(target_type ${gem_target} TYPE) - - ly_get_gem_module_root(gem_module_root ${gem_target}) file(RELATIVE_PATH gem_module_root_relative_to_engine_root ${LY_ROOT_FOLDER} ${gem_module_root}) @@ -180,7 +176,8 @@ function(ly_delayed_generate_settings_registry) list(JOIN target_gem_dependencies_names ",\n" target_gem_dependencies_names) string(CONFIGURE ${gems_json_template} gem_json @ONLY) get_target_property(is_imported ${target} IMPORTED) - if(is_imported) + get_target_property(target_type ${target} TYPE) + if(is_imported OR target_type STREQUAL UTILITY) unset(target_dir) foreach(conf IN LISTS CMAKE_CONFIGURATION_TYPES) string(TOUPPER ${conf} UCONF) diff --git a/cmake/install/InstalledTarget.in b/cmake/install/InstalledTarget.in index 0503fd5f2b..a4f4fa4763 100644 --- a/cmake/install/InstalledTarget.in +++ b/cmake/install/InstalledTarget.in @@ -17,6 +17,8 @@ ly_add_target( @RUNTIME_DEPENDENCIES_PLACEHOLDER@ ) +@TARGET_RUN_HELPER@ + set(configs @CMAKE_CONFIGURATION_TYPES@) foreach(config ${configs}) include("@NAME_PLACEHOLDER@_${config}.cmake" OPTIONAL) From d7a4b0d930f92335328a99b3d398a18497628817 Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 28 Jul 2021 16:51:25 -0700 Subject: [PATCH 57/58] fix for double asset registration and multiple outs from loop nodes Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- Gems/GraphCanvas/Code/Source/GraphCanvas.cpp | 29 - Gems/GraphCanvas/Code/Source/GraphCanvas.h | 2 - .../Grammar/AbstractCodeModel.cpp | 2 +- ...orEachMultipleOutSyntaxOnEach.scriptcanvas | 2215 +++++++++++++++++ .../Tests/ScriptCanvas_RuntimeInterpreted.cpp | 4 +- 5 files changed, 2218 insertions(+), 34 deletions(-) create mode 100644 Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ForEachMultipleOutSyntaxOnEach.scriptcanvas diff --git a/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp b/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp index 33cc99e2d5..c5333152a0 100644 --- a/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp +++ b/Gems/GraphCanvas/Code/Source/GraphCanvas.cpp @@ -191,7 +191,6 @@ namespace GraphCanvas void GraphCanvasSystemComponent::Activate() { - RegisterAssetHandler(); RegisterTranslationBuilder(); AzFramework::AssetCatalogEventBus::Handler::BusConnect(); @@ -386,34 +385,6 @@ namespace GraphCanvas AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequestBus::Events::EnumerateAssets, nullptr, collectAssetsCb, postEnumerateCb); } - void GraphCanvasSystemComponent::RegisterAssetHandler() - { - AZ::Data::AssetType assetType(azrtti_typeid()); - if (AZ::Data::AssetManager::Instance().GetHandler(assetType)) - { - return; // Asset Type already handled - } - - auto* catalogBus = AZ::Data::AssetCatalogRequestBus::FindFirstHandler(); - if (catalogBus) - { - // Register asset types the asset DB should query our catalog for. - catalogBus->AddAssetType(assetType); - - // Build the catalog (scan). - catalogBus->AddExtension(".names"); - } - - m_assetHandler = AZStd::make_unique(); - AZ::Data::AssetManager::Instance().RegisterHandler(m_assetHandler.get(), assetType); - - // Use AssetCatalog service to register ScriptEvent asset type and extension - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddAssetType, assetType); - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::EnableCatalogForAsset, assetType); - AZ::Data::AssetCatalogRequestBus::Broadcast(&AZ::Data::AssetCatalogRequests::AddExtension, TranslationAsset::GetFileFilter()); - - } - void GraphCanvasSystemComponent::UnregisterAssetHandler() { if (m_assetHandler) diff --git a/Gems/GraphCanvas/Code/Source/GraphCanvas.h b/Gems/GraphCanvas/Code/Source/GraphCanvas.h index a68052d5e1..7a4d9677ab 100644 --- a/Gems/GraphCanvas/Code/Source/GraphCanvas.h +++ b/Gems/GraphCanvas/Code/Source/GraphCanvas.h @@ -82,8 +82,6 @@ namespace GraphCanvas AZStd::unique_ptr m_assetHandler; void RegisterTranslationBuilder(); - - void RegisterAssetHandler(); void UnregisterAssetHandler(); TranslationAssetWorker m_translationAssetWorker; AZStd::vector m_translationAssets; diff --git a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp index 883e15cd29..3e4a425a6e 100644 --- a/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp +++ b/Gems/ScriptCanvas/Code/Include/ScriptCanvas/Grammar/AbstractCodeModel.cpp @@ -3230,7 +3230,7 @@ namespace ScriptCanvas auto valueSlot = forEachNodeSC->GetSlot(forEachNodeSC->GetValueSlotId()); AZ_Assert(valueSlot, "no value slot in for each node"); - lastExecution->AddChild({}); + lastExecution->AddChild({ &loopSlot, {}, nullptr }); auto outputValue = CreateOutputData(lastExecution, lastExecution->ModChild(0), *valueSlot); lastExecution->ModChild(0).m_output.push_back({ valueSlot, outputValue }); diff --git a/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ForEachMultipleOutSyntaxOnEach.scriptcanvas b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ForEachMultipleOutSyntaxOnEach.scriptcanvas new file mode 100644 index 0000000000..40e548eae0 --- /dev/null +++ b/Gems/ScriptCanvasTesting/Assets/ScriptCanvas/UnitTests/LY_SC_UnitTest_ForEachMultipleOutSyntaxOnEach.scriptcanvas @@ -0,0 +1,2215 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp index df29a56fd5..5999cf9250 100644 --- a/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp +++ b/Gems/ScriptCanvasTesting/Code/Tests/ScriptCanvas_RuntimeInterpreted.cpp @@ -84,9 +84,9 @@ public: } }; -TEST_F(ScriptCanvasTestFixture, ProveError) +TEST_F(ScriptCanvasTestFixture, ForEachMultipleOutSyntaxOnEach) { - EXPECT_TRUE(false); + RunUnitTestGraph("LY_SC_UnitTest_ForEachMultipleOutSyntaxOnEach"); } TEST_F(ScriptCanvasTestFixture, EntityIdInputForOnGraphStart) From eefc448dceb9aec1771e7112899e36ea97eb058e Mon Sep 17 00:00:00 2001 From: chcurran <82187351+carlitosan@users.noreply.github.com> Date: Wed, 28 Jul 2021 17:48:11 -0700 Subject: [PATCH 58/58] remove stack tracer change and attempt to restore SC tests Signed-off-by: chcurran <82187351+carlitosan@users.noreply.github.com> --- .../Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp | 2 +- Gems/ScriptCanvasTesting/Code/CMakeLists.txt | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp index a24d359bc9..d2cdac84c7 100644 --- a/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp +++ b/Code/Framework/AzCore/Platform/Windows/AzCore/Debug/StackTracer_Windows.cpp @@ -39,7 +39,7 @@ namespace AZ { struct SymbolStorageDynamicallyLoadedModules { size_t m_size; - DynamicallyLoadedModuleInfo m_modules[1024]; + DynamicallyLoadedModuleInfo m_modules[256]; SymbolStorageDynamicallyLoadedModules() : m_size(0) diff --git a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt index dada433772..23c9627e83 100644 --- a/Gems/ScriptCanvasTesting/Code/CMakeLists.txt +++ b/Gems/ScriptCanvasTesting/Code/CMakeLists.txt @@ -113,7 +113,6 @@ if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) ) ly_add_googletest( NAME Gem::ScriptCanvasTesting.Editor.Tests - TEST_SUITE smoke ) endif()