Browse Source

{lyn15166} Adding context during update manifest event handling (#12016)

* {lyn15166} Adding context during update manifest event handling


Signed-off-by: Allen Jackson <[email protected]>

* renaming DebugScope to DebugOutputScope


Signed-off-by: Allen Jackson <[email protected]>

* updated based on feedback

Signed-off-by: Allen Jackson <[email protected]>

* added unit tests for the new registery settings debug flag


Signed-off-by: Allen Jackson <[email protected]>

* Some interface fix ups

Signed-off-by: Allen Jackson <[email protected]>

Signed-off-by: Allen Jackson <[email protected]>
Allen Jackson 2 years ago
parent
commit
d1ce13dbc5
29 changed files with 454 additions and 15 deletions
  1. 4 0
      Code/Tools/SceneAPI/SceneBuilder/SceneImportRequestHandler.h
  2. 5 2
      Code/Tools/SceneAPI/SceneCore/Containers/SceneManifest.h
  3. 107 0
      Code/Tools/SceneAPI/SceneCore/Events/AssetImportRequest.cpp
  4. 53 3
      Code/Tools/SceneAPI/SceneCore/Events/AssetImportRequest.h
  5. 4 0
      Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.h
  6. 2 0
      Code/Tools/SceneAPI/SceneCore/Mocks/Events/MockAssetImportRequest.h
  7. 162 1
      Code/Tools/SceneAPI/SceneCore/Tests/Events/AssetImporterRequestTests.cpp
  8. 2 1
      Code/Tools/SceneAPI/SceneCore/Utilities/Reporting.h
  9. 4 1
      Code/Tools/SceneAPI/SceneData/Behaviors/AnimationGroup.h
  10. 4 1
      Code/Tools/SceneAPI/SceneData/Behaviors/BlendShapeRuleBehavior.h
  11. 4 0
      Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h
  12. 4 0
      Code/Tools/SceneAPI/SceneData/Behaviors/MeshAdvancedRule.h
  13. 4 0
      Code/Tools/SceneAPI/SceneData/Behaviors/MeshGroup.h
  14. 5 0
      Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h
  15. 4 0
      Code/Tools/SceneAPI/SceneData/Behaviors/SkeletonGroup.h
  16. 5 0
      Code/Tools/SceneAPI/SceneData/Behaviors/SkinGroup.h
  17. 5 1
      Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/ActorGroupBehavior.h
  18. 4 0
      Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/LodRuleBehavior.h
  19. 4 1
      Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MorphTargetRuleBehavior.h
  20. 6 1
      Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionGroupBehavior.h
  21. 5 0
      Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionRangeRuleBehavior.h
  22. 4 0
      Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/SkeletonOptimizationRuleBehavior.h
  23. 4 0
      Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h
  24. 4 0
      Gems/PhysX/Code/Source/Pipeline/MeshBehavior.h
  25. 4 0
      Gems/Prefab/PrefabBuilder/PrefabGroup/PrefabGroupBehavior.cpp
  26. 4 0
      Gems/SceneLoggingExample/Code/Behaviors/LoggingGroupBehavior.h
  27. 4 0
      Gems/SceneLoggingExample/Code/Processors/LoadingTrackingProcessor.h
  28. 4 0
      Gems/SceneProcessing/Code/Source/Config/Components/SceneProcessingConfigSystemComponent.h
  29. 29 3
      Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderWorker.cpp

+ 4 - 0
Code/Tools/SceneAPI/SceneBuilder/SceneImportRequestHandler.h

@@ -40,6 +40,10 @@ namespace AZ
             void GetSupportedFileExtensions(AZStd::unordered_set<AZStd::string>& extensions) override;
             Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid,
                 RequestingApplication requester) override;
+            void GetPolicyName(AZStd::string& result) const override
+            {
+                result = "SceneImportRequestHandler";
+            }
 
             static void GetProvidedServices(ComponentDescriptor::DependencyArrayType& provided);
 

+ 5 - 2
Code/Tools/SceneAPI/SceneCore/Containers/SceneManifest.h

@@ -87,7 +87,7 @@ namespace AZ
                  * Save manifest to file. Overwrites the file in case it already exists and creates a new file if not.
                  * @param absoluteFilePath the absolute path of the file you want to save to.
                  * @param context If no serialize context was specified, it will get the serialize context from the application component bus.
-                 * @result True in case saving went all fine, false if an error occured.
+                 * @result True in case saving went all fine, false if an error occurred.
                  */
                 bool SaveToFile(const AZStd::string& absoluteFilePath, SerializeContext* context = nullptr);
 
@@ -98,7 +98,10 @@ namespace AZ
                 static void Reflect(ReflectContext* context);
                 static bool VersionConverter(SerializeContext& context, SerializeContext::DataElementNode& node);
 
-            protected:
+                //! Save manifest to string buffer.
+                //! @param context If no serialize context was specified, it will get the context from the application component bus.
+                //! @param registrationContext If no Json registration context was specified, it will get the context from the application component bus.
+                //! @result True in case saving went all fine, false if an error occurred.
                 AZ::Outcome<rapidjson::Document, AZStd::string> SaveToJsonDocument(SerializeContext* context = nullptr, JsonRegistrationContext* registrationContext = nullptr);
 
             private:

+ 107 - 0
Code/Tools/SceneAPI/SceneCore/Events/AssetImportRequest.cpp

@@ -17,6 +17,11 @@
 #include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
 #include <SceneAPI/SceneCore/Events/SceneSerializationBus.h>
 #include <SceneAPI/SceneCore/Utilities/Reporting.h>
+#include <AzCore/Serialization/Json/JsonUtils.h>
+#include <AzCore/Settings/SettingsRegistryMergeUtils.h>
+#include <AzToolsFramework/Debug/TraceContext.h>
+#include <AzCore/JSON/writer.h>
+#include <AzCore/IO/TextStreamWriters.h>
 
 namespace AZ
 {
@@ -24,6 +29,102 @@ namespace AZ
     {
         namespace Events
         {
+            struct UpdateManifestScope final
+                : public AssetImportRequestReporter
+            {
+                AZ_RTTI(UpdateManifestScope, "{C9DD605E-2A9D-4C0D-A22E-A71B44528420}", AssetImportRequestReporter);
+
+                UpdateManifestScope(AZStd::shared_ptr<Containers::Scene> scene)
+                    : m_scene(scene)
+                {
+                    m_registered = false;
+                    if (AZ::SettingsRegistry::Get())
+                    {
+                        AZ::SettingsRegistry::Get()->Get(m_registered, AZ::SceneAPI::Utilities::Key_AssetProcessorInDebugOutput);
+                    }
+                    if (m_registered)
+                    {
+                        AZ::Interface<AssetImportRequestReporter>::Register(this);
+                    }
+                }
+
+                ~UpdateManifestScope()
+                {
+                    if (m_registered)
+                    {
+                        AZ::Interface<AssetImportRequestReporter>::Unregister(this);
+                        m_registered = false;
+                    }
+                    m_previous = {};
+                    m_previousSet = false;
+                }
+
+                void ReportStart([[maybe_unused]] const AssetImportRequest* instance) override
+                {
+                    ++m_reportNumber;
+
+                    if (!m_previousSet && m_scene->GetManifest().GetEntryCount() > 0)
+                    {
+                        auto saveToJsonOutcome = m_scene->GetManifest().SaveToJsonDocument();
+                        if (!saveToJsonOutcome.IsSuccess())
+                        {
+                            AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false,
+                                "UpdateManifest(%d) error: %.*s",
+                                m_reportNumber,
+                                AZ_STRING_ARG(saveToJsonOutcome.GetError()));
+                            return;
+                        }
+                        m_previous.CopyFrom(saveToJsonOutcome.GetValue(), m_previous.GetAllocator(), true);
+                        m_previousSet = true;
+                    }
+                }
+
+                void ReportFinish([[maybe_unused]] const AssetImportRequest* instance) override
+                {
+                    AZStd::string policy;
+                    instance->GetPolicyName(policy);
+                    AZ_TraceContext("PolicyName", policy.c_str());
+
+                    if (!m_previousSet && m_scene->GetManifest().GetEntryCount() > 0)
+                    {
+                        return;
+                    }
+
+                    auto saveToJsonOutcome = m_scene->GetManifest().SaveToJsonDocument();
+                    if (!saveToJsonOutcome.IsSuccess())
+                    {
+                        AZ_Error(AZ::SceneAPI::Utilities::ErrorWindow, false,
+                            "UpdateManifest(%d) error: %.*s",
+                            m_reportNumber,
+                            AZ_STRING_ARG(saveToJsonOutcome.GetError()));
+                        return;
+                    }
+
+                    if (m_previous == saveToJsonOutcome.GetValue())
+                    {
+                        AZ_TraceContext("UpdateManifest", "No Changes");
+                        AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "UpdateManifest(%d): No Changes \n", m_reportNumber);
+                        return;
+                    }
+                    m_previous = {};
+                    m_previousSet = false;
+
+                    rapidjson::StringBuffer buffer;
+                    rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
+                    if (saveToJsonOutcome.GetValue().Accept(writer))
+                    {
+                        AZ_TraceContext("Update Manifest", buffer.GetString());
+                        AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "UpdateManifest(%d): Updated \n", m_reportNumber);
+                    }
+                }
+
+                AZStd::shared_ptr<Containers::Scene> m_scene;
+                AZ::s32 m_reportNumber = 0;
+                bool m_registered = false;
+                rapidjson::Document m_previous;
+                bool m_previousSet = false;
+            };
+
             // an internal scope object that is active during a scene import
             struct ImportScope final
                 : public AZ::SceneAPI::Events::AssetPostImportRequestBus::Handler
@@ -98,6 +199,11 @@ namespace AZ
             {
             }
 
+            void AssetImportRequest::GetPolicyName(AZStd::string& result) const
+            {
+                result = "AssetImportRequest Base";
+            }
+
             void AssetImportRequest::GetSupportedFileExtensions(AZStd::unordered_set<AZStd::string>& /*extensions*/)
             {
             }
@@ -188,6 +294,7 @@ namespace AZ
                     scene->GetManifest().Clear();
                     action = ManifestAction::ConstructDefault;
                 }
+                UpdateManifestScope updateManifestScope(scene);
                 ProcessingResultCombiner manifestUpdate;
                 AssetImportRequestBus::BroadcastResult(manifestUpdate, &AssetImportRequestBus::Events::UpdateManifest, *scene, action, requester);
                 if (manifestUpdate.GetResult() == ProcessingResult::Failure)

+ 53 - 3
Code/Tools/SceneAPI/SceneCore/Events/AssetImportRequest.h

@@ -15,6 +15,7 @@
 #include <AzCore/std/containers/unordered_set.h>
 #include <SceneAPI/SceneCore/SceneCoreConfiguration.h>
 #include <SceneAPI/SceneCore/Events/ProcessingResult.h>
+#include <AzCore/Interface/Interface.h>
 
 namespace AZ
 {
@@ -35,6 +36,53 @@ namespace AZ
                 ManifestFailure
             };
 
+            class AssetImportRequest;
+
+            struct AssetImportRequestReporter
+            {
+                AZ_RTTI(AssetImportRequestReporter, "{3BCEDF5C-9FE6-4A16-A521-D2362E51522F}");
+
+                virtual void ReportStart(const AssetImportRequest* instance) = 0;
+                virtual void ReportFinish(const AssetImportRequest* instance) = 0;
+            };
+
+            struct AssetImportRequestEventProcessingPolicy
+            {
+                template<class Interface>
+                static void ReportStart(Interface&& iface)
+                {
+                    if (auto* reporter = AZ::Interface<AssetImportRequestReporter>::Get(); reporter)
+                    {
+                        reporter->ReportStart(static_cast<const AssetImportRequest*>(iface));
+                    }
+                }
+
+                template<class Interface>
+                static void ReportFinish(Interface&& iface)
+                {
+                    if (auto* reporter = AZ::Interface<AssetImportRequestReporter>::Get(); reporter)
+                    {
+                        reporter->ReportFinish(static_cast<const AssetImportRequest*>(iface));
+                    }
+                }
+
+                template<class Results, class Function, class Interface, class... InputArgs>
+                static void CallResult(Results& results, Function&& func, Interface&& iface, InputArgs&&... args)
+                {
+                    ReportStart(iface);
+                    results = AZStd::invoke(AZStd::forward<Function>(func), AZStd::forward<Interface>(iface), AZStd::forward<InputArgs>(args)...);
+                    ReportFinish(iface);
+                }
+
+                template<class Function, class Interface, class... InputArgs>
+                static void Call(Function&& func, Interface&& iface, InputArgs&&... args)
+                {
+                    ReportStart(iface);
+                    AZStd::invoke(AZStd::forward<Function>(func), AZStd::forward<Interface>(iface), AZStd::forward<InputArgs>(args)...);
+                    ReportFinish(iface);
+                }
+            };
+
             class SCENE_CORE_API LoadingResultCombiner
             {
             public:
@@ -66,6 +114,7 @@ namespace AZ
 
                 static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple;
                 using MutexType = AZStd::recursive_mutex;
+                using EventProcessingPolicy = AssetImportRequestEventProcessingPolicy;
 
                 static AZ::Crc32 GetAssetImportRequestComponentTag()
                 {
@@ -80,6 +129,8 @@ namespace AZ
                 virtual void GetManifestExtension(AZStd::string& result);
                 //! Gets the file extension for the generated manifest.
                 virtual void GetGeneratedManifestExtension(AZStd::string& result);
+                //! Gets the label for a scene builder using this HandlerPolicy
+                virtual void GetPolicyName(AZStd::string& result) const;
 
                 //! Before asset loading starts this is called to allow for any required initialization.
                 virtual ProcessingResult PrepareForAssetLoading(Containers::Scene& scene, RequestingApplication requester);
@@ -87,14 +138,13 @@ namespace AZ
                 //! the calling application.
                 virtual LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid, RequestingApplication requester);
                 //! FinalizeAssetLoading can be used to do any work to complete loading, such as complete asynchronous loading
-                //! or adjust the loaded content in the the SceneGraph. While manifest changes can be done here as well, it's
+                //! or adjust the loaded content in the SceneGraph. While manifest changes can be done here as well, it's
                 //! recommended to wait for the UpdateManifest call.
                 virtual void FinalizeAssetLoading(Containers::Scene& scene, RequestingApplication requester);
                 //! After all loading has completed, this call can be used to make adjustments to the manifest. Based on the given
                 //! action this can mean constructing a new manifest or updating an existing manifest. This call is intended
                 //! to deal with any default behavior of the manifest.
-                virtual ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
-                    RequestingApplication requester);
+                virtual ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action, RequestingApplication requester);
 
                 // Get scene processing project setting: UseCustomNormal 
                 virtual void AreCustomNormalsUsed(bool & value);

+ 4 - 0
Code/Tools/SceneAPI/SceneCore/Import/ManifestImportRequestHandler.h

@@ -34,6 +34,10 @@ namespace AZ
                 void GetGeneratedManifestExtension(AZStd::string& result) override;
                 Events::LoadingResult LoadAsset(Containers::Scene& scene, const AZStd::string& path, const Uuid& guid,
                     RequestingApplication requester) override;
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "ManifestImportRequestHandler";
+                }
                 
             private:
                 static const char* s_extension;

+ 2 - 0
Code/Tools/SceneAPI/SceneCore/Mocks/Events/MockAssetImportRequest.h

@@ -50,6 +50,8 @@ namespace AZ
                 MOCK_METHOD3(UpdateManifest,
                     ProcessingResult(Containers::Scene& scene, ManifestAction action, RequestingApplication requester));
 
+                MOCK_CONST_METHOD1(GetPolicyName, void(AZStd::string& result));
+
                 void DefaultGetSupportedFileExtensions(AZStd::unordered_set<AZStd::string>& extensions)
                 {
                     extensions.insert(".asset");

+ 162 - 1
Code/Tools/SceneAPI/SceneCore/Tests/Events/AssetImporterRequestTests.cpp

@@ -9,10 +9,15 @@
 #include <AzTest/AzTest.h>
 #include <AzCore/Debug/TraceMessageBus.h>
 #include <AzCore/Math/Guid.h>
+#include <AzCore/std/smart_ptr/make_shared.h>
+#include <AzCore/UnitTest/Mocks/MockSettingsRegistry.h>
+#include <AzCore/UnitTest/TestTypes.h>
 #include <SceneAPI/SceneCore/Containers/Scene.h>
 #include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
 #include <SceneAPI/SceneCore/Components/LoadingComponent.h>
 #include <SceneAPI/SceneCore/Mocks/Events/MockAssetImportRequest.h>
+#include <SceneAPI/SceneCore/Mocks/DataTypes/Groups/MockIGroup.h>
+#include <SceneAPI/SceneCore/Utilities/Reporting.h>
 
 namespace AZ
 {
@@ -360,7 +365,163 @@ namespace AZ
                     AssetImportRequest::LoadSceneFromVerifiedPath("test.asset", m_testId, Events::AssetImportRequest::RequestingApplication::Generic, SceneCore::LoadingComponent::TYPEINFO_Uuid());
                 EXPECT_NE(nullptr, result);
             }
-            
+
+            /*
+            * AssetImporterRequestToolTests
+            */
+            class AssetImporterRequestToolTests
+                : public ::UnitTest::ScopedAllocatorSetupFixture
+            {
+            public:
+                void SetUp() override
+                {
+                    UnitTest::ScopedAllocatorSetupFixture::SetUp();
+
+                    m_settings.reset(new AZ::NiceSettingsRegistrySimpleMock);
+                    ON_CALL(*m_settings.get(), Get(::testing::Matcher<bool&>(::testing::_), ::testing::_))
+                        .WillByDefault([this](bool& value, AZStd::string_view key) -> bool
+                            {
+                                if (key == AZ::SceneAPI::Utilities::Key_AssetProcessorInDebugOutput)
+                                {
+                                    value = this->m_inDebugOutputMode;
+                                }
+                                else
+                                {
+                                    value = false;
+                                }
+                                return true;
+                            });
+                    AZ::SettingsRegistry::Register(m_settings.get());
+                }
+
+                void TearDown() override
+                {
+                    AZ::SettingsRegistry::Unregister(m_settings.get());
+                    m_settings.reset();
+
+                    UnitTest::ScopedAllocatorSetupFixture::TearDown();
+                }
+
+                void SetDefaultResults(StrictMock<MockAssetImportRequestHandler>& handler)
+                {
+                    using namespace AZ::SceneAPI;
+
+                    ON_CALL(handler, PrepareForAssetLoading(Matcher<Containers::Scene&>(_), Matcher<AssetImportRequest::RequestingApplication>(_)))
+                        .WillByDefault(Return(ProcessingResult::Ignored));
+
+                    ON_CALL(handler, LoadAsset)
+                        .WillByDefault([](Containers::Scene&, const AZStd::string&, const Uuid&, AssetImportRequest::RequestingApplication) -> Events::LoadingResult
+                            {
+                                return LoadingResult::AssetLoaded;
+                            }
+                    );
+
+                    ON_CALL(handler, UpdateManifest)
+                        .WillByDefault([](Containers::Scene& scene, AssetImportRequest::ManifestAction, AssetImportRequest::RequestingApplication) -> Events::ProcessingResult
+                            {
+                                scene.GetManifest().AddEntry(AZStd::make_shared<AZ::SceneAPI::DataTypes::MockIGroup>());
+                                return ProcessingResult::Success;
+                            });
+                }
+
+                AZStd::unique_ptr<AZ::NiceSettingsRegistrySimpleMock> m_settings;
+                bool m_inDebugOutputMode = false;
+            };
+
+            TEST_F(AssetImporterRequestToolTests, AssetImportRequestBus_UpdateSceneManifest_DoesNotLogHandlers)
+            {
+                using namespace AZ::SceneAPI::Events;
+                using namespace AZ::SceneAPI::SceneCore;
+
+                StrictMock<MockAssetImportRequestHandler> assetHandler;
+                assetHandler.SetDefaultExtensions();
+                assetHandler.SetDefaultProcessingResults(false);
+                ON_CALL(assetHandler, GetPolicyName).WillByDefault([](AZStd::string& result)
+                {
+                    result = "assetHandler";
+                });
+
+                StrictMock<MockAssetImportRequestHandler> manifestHandler;
+                manifestHandler.SetDefaultExtensions();
+                manifestHandler.SetDefaultProcessingResults(true);
+                ON_CALL(manifestHandler, GetPolicyName).WillByDefault([](AZStd::string& result)
+                {
+                    result = "manifestHandler";
+                });
+
+                EXPECT_CALL(assetHandler, GetManifestExtension(_)).Times(0);
+                EXPECT_CALL(assetHandler, GetSupportedFileExtensions(_)).Times(0);
+                EXPECT_CALL(assetHandler, PrepareForAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(assetHandler, LoadAsset(_, _, _, _)).Times(1);
+                EXPECT_CALL(assetHandler, FinalizeAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(assetHandler, UpdateManifest(_, _, _)).Times(1);
+                EXPECT_CALL(assetHandler, GetPolicyName(_)).Times(0);
+
+                EXPECT_CALL(manifestHandler, GetManifestExtension(_)).Times(0);
+                EXPECT_CALL(manifestHandler, GetSupportedFileExtensions(_)).Times(0);
+                EXPECT_CALL(manifestHandler, PrepareForAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(manifestHandler, LoadAsset(_, _, _, _)).Times(1);
+                EXPECT_CALL(manifestHandler, FinalizeAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(manifestHandler, UpdateManifest(_, _, _)).Times(1);
+                EXPECT_CALL(manifestHandler, GetPolicyName(_)).Times(0);
+
+                auto result = AssetImportRequest::LoadSceneFromVerifiedPath(
+                    "test.asset",
+                    AZ::Uuid("{B28DA8AF-B5F5-48E2-8E1A-3FE2CEFC2817}"),
+                    AssetImportRequest::RequestingApplication::Generic,
+                    LoadingComponent::TYPEINFO_Uuid());
+
+                EXPECT_NE(nullptr, result);
+            }
+
+            TEST_F(AssetImporterRequestToolTests, AssetImportRequestBus_UpdateSceneManifest_DoesLogHandlers)
+            {
+                using namespace AZ::SceneAPI::Events;
+                using namespace AZ::SceneAPI::SceneCore;
+
+                m_inDebugOutputMode = true;
+
+                StrictMock<MockAssetImportRequestHandler> assetHandler;
+                assetHandler.SetDefaultExtensions();
+                ON_CALL(assetHandler, GetPolicyName)
+                    .WillByDefault([](AZStd::string& result)
+                    {
+                        result = "assetHandler";
+                    });
+                SetDefaultResults(assetHandler);
+
+                StrictMock<MockAssetImportRequestHandler> manifestHandler;
+                manifestHandler.SetDefaultExtensions();
+                ON_CALL(manifestHandler, GetPolicyName)
+                    .WillByDefault([](AZStd::string& result)
+                    {
+                        result = "manifestHandler";
+                    });
+                SetDefaultResults(manifestHandler);
+
+                EXPECT_CALL(assetHandler, GetManifestExtension(_)).Times(0);
+                EXPECT_CALL(assetHandler, GetSupportedFileExtensions(_)).Times(0);
+                EXPECT_CALL(assetHandler, PrepareForAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(assetHandler, LoadAsset(_, _, _, _)).Times(1);
+                EXPECT_CALL(assetHandler, FinalizeAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(assetHandler, UpdateManifest(_, _, _)).Times(1);
+                EXPECT_CALL(assetHandler, GetPolicyName(_)).Times(1);
+
+                EXPECT_CALL(manifestHandler, GetManifestExtension(_)).Times(0);
+                EXPECT_CALL(manifestHandler, GetSupportedFileExtensions(_)).Times(0);
+                EXPECT_CALL(manifestHandler, PrepareForAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(manifestHandler, LoadAsset(_, _, _, _)).Times(1);
+                EXPECT_CALL(manifestHandler, FinalizeAssetLoading(_, _)).Times(1);
+                EXPECT_CALL(manifestHandler, UpdateManifest(_, _, _)).Times(1);
+                EXPECT_CALL(manifestHandler, GetPolicyName(_)).Times(1);
+
+                AssetImportRequest::LoadSceneFromVerifiedPath(
+                    "test.asset",
+                    AZ::Uuid("{B28DA8AF-B5F5-48E2-8E1A-3FE2CEFC2817}"),
+                    AssetImportRequest::RequestingApplication::Generic,
+                    LoadingComponent::TYPEINFO_Uuid());                
+            }
+
         } // Events
     } // SceneAPI
 } // AZ

+ 2 - 1
Code/Tools/SceneAPI/SceneCore/Utilities/Reporting.h

@@ -22,7 +22,8 @@ namespace AZ
             const char* const SuccessWindow = "Success";
             // Window name used for logging through AZ_TracePrintf.
             const char* const LogWindow = "SceneAPI";
-
+            // A key to indicate if the scene builder is in debug mode
+            inline constexpr const char* Key_AssetProcessorInDebugOutput = "/O3DE/AssetProcessor/InDebug";
         } // Utilities
     } // SceneAPI
 } // AZ

+ 4 - 1
Code/Tools/SceneAPI/SceneData/Behaviors/AnimationGroup.h

@@ -39,7 +39,10 @@ namespace AZ
                 // AssetImportRequest
                 Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
-                
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "AnimationGroup";
+                }
             private:
                 Events::ProcessingResult BuildDefault(Containers::Scene& scene) const;
                 Events::ProcessingResult UpdateAnimationGroups(Containers::Scene& scene) const;

+ 4 - 1
Code/Tools/SceneAPI/SceneData/Behaviors/BlendShapeRuleBehavior.h

@@ -41,7 +41,10 @@ namespace AZ
                 void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override;
                 Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
-
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "BlendShapeRuleBehavior";
+                }
             private:
                 size_t SelectBlendShapes(const Containers::Scene& scene, DataTypes::ISceneNodeSelectionList& selection) const;
                 void UpdateBlendShapeRules(Containers::Scene& scene) const;

+ 4 - 0
Code/Tools/SceneAPI/SceneData/Behaviors/LodRuleBehavior.h

@@ -50,6 +50,10 @@ namespace AZ
 
                 SCENE_DATA_API void GetVirtualTypeName(AZStd::string& name, Crc32 type) override;
                 SCENE_DATA_API void GetAllVirtualTypes(AZStd::set<Crc32>& types) override;
+                SCENE_DATA_API void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "LodRuleBehavior";
+                }
 
             private:
                 size_t SelectLodMeshes(const Containers::Scene& scene, DataTypes::ISceneNodeSelectionList& selection, size_t lodLevel) const;

+ 4 - 0
Code/Tools/SceneAPI/SceneData/Behaviors/MeshAdvancedRule.h

@@ -42,6 +42,10 @@ namespace AZ
                 void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override;
                 Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "MeshAdvancedRule";
+                }
 
             private:
                 void UpdateMeshAdvancedRules(Containers::Scene& scene) const;

+ 4 - 0
Code/Tools/SceneAPI/SceneData/Behaviors/MeshGroup.h

@@ -36,6 +36,10 @@ namespace AZ
                 void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override;
                 Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "SceneAPI::MeshGroup";
+                }
 
             private:
                 Events::ProcessingResult BuildDefault(Containers::Scene& scene) const;

+ 5 - 0
Code/Tools/SceneAPI/SceneData/Behaviors/ScriptProcessorRuleBehavior.h

@@ -53,6 +53,11 @@ namespace AZ::SceneAPI::Behaviors
             RequestingApplication requester) override;
 
         SCENE_DATA_API void GetManifestDependencyPaths(AZStd::vector<AZStd::string>& paths) override;
+
+        SCENE_DATA_API void GetPolicyName(AZStd::string& result) const override
+        {
+            result = "ScriptProcessorRuleBehavior";
+        }
     protected:
         bool LoadPython(const AZ::SceneAPI::Containers::Scene& scene, AZStd::string& scriptPath, Events::ProcessingResult& fallbackResult);
         void UnloadPython();

+ 4 - 0
Code/Tools/SceneAPI/SceneData/Behaviors/SkeletonGroup.h

@@ -36,6 +36,10 @@ namespace AZ
                 void InitializeObject(const Containers::Scene& scene, DataTypes::IManifestObject& target) override;
                 Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "SkeletonGroup";
+                }
 
             private:
                 Events::ProcessingResult BuildDefault(Containers::Scene& scene);

+ 5 - 0
Code/Tools/SceneAPI/SceneData/Behaviors/SkinGroup.h

@@ -46,6 +46,11 @@ namespace AZ
                     Containers::SceneGraph::NodeIndex node) override;
                 void GetAllVirtualTypes(AZStd::set<Crc32>& types) override;
                 void GetVirtualTypeName(AZStd::string& name, Crc32 type) override;
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "SkinGroup";
+                }
+
 
             private:
                 Events::ProcessingResult BuildDefault(Containers::Scene& scene) const;

+ 5 - 1
Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/ActorGroupBehavior.h

@@ -42,7 +42,11 @@ namespace EMotionFX
                     RequestingApplication requester) override;
 
                 void GetAvailableModifiers(ModifiersList& modifiers, const AZ::SceneAPI::Containers::Scene& scene, const AZ::SceneAPI::DataTypes::IManifestObject& target) override;
-                
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "ActorGroupBehavior";
+                }
+
             private:
                 AZ::SceneAPI::Events::ProcessingResult BuildDefault(AZ::SceneAPI::Containers::Scene& scene) const;
                 AZ::SceneAPI::Events::ProcessingResult UpdateActorGroups(AZ::SceneAPI::Containers::Scene& scene) const;

+ 4 - 0
Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/LodRuleBehavior.h

@@ -51,6 +51,10 @@ namespace EMotionFX
                     RequestingApplication requester) override;
 
                 void GetVirtualTypeName(AZStd::string& name, AZ::Crc32 type) override;
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "LodRuleBehavior";
+                }
 
             private:
                 void UpdateLodRules(SceneContainers::Scene& scene) const;

+ 4 - 1
Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MorphTargetRuleBehavior.h

@@ -45,7 +45,10 @@ namespace EMotionFX
                 void InitializeObject(const AZ::SceneAPI::Containers::Scene& scene, AZ::SceneAPI::DataTypes::IManifestObject& target) override;
                 AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
-
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "MorphTargetRuleBehavior";
+                }
             private:
                 void UpdateMorphTargetRules(const AZ::SceneAPI::Containers::Scene& scene) const;
             };

+ 6 - 1
Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionGroupBehavior.h

@@ -41,7 +41,12 @@ namespace EMotionFX
                 // AssetImportRequest
                 AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
-                
+
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "MotionGroupBehavior";
+                }
+
             private:
                 AZ::SceneAPI::Events::ProcessingResult BuildDefault(AZ::SceneAPI::Containers::Scene& scene) const;
                 AZ::SceneAPI::Events::ProcessingResult UpdateMotionGroupBehaviors(AZ::SceneAPI::Containers::Scene& scene) const;

+ 5 - 0
Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/MotionRangeRuleBehavior.h

@@ -40,6 +40,11 @@ namespace EMotionFX
                 // AssetImportRequest
                 AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
+
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "MotionRangeRuleBehavior";
+                }
             };
         } // Behavior
     } // Pipeline

+ 4 - 0
Gems/EMotionFX/Code/EMotionFX/Pipeline/SceneAPIExt/Behaviors/SkeletonOptimizationRuleBehavior.h

@@ -37,6 +37,10 @@ namespace EMotionFX
                 SceneEvents::ProcessingResult UpdateManifest(SceneContainers::Scene& scene, ManifestAction action,
                     RequestingApplication requester) override;
 
+                void GetPolicyName(AZStd::string& result) const override
+                {
+                    result = "SkeletonOptimizationRuleBehavior";
+                }
             private:
                 AZ::SceneAPI::Events::ProcessingResult UpdateSelection(AZ::SceneAPI::Containers::Scene& scene) const;
             };

+ 4 - 0
Gems/NvCloth/Code/Source/Pipeline/SceneAPIExt/ClothRuleBehavior.h

@@ -61,6 +61,10 @@ namespace NvCloth
                 const AZ::SceneAPI::Containers::Scene& scene,
                 const AZ::SceneAPI::DataTypes::IManifestObject& target) override;
             void InitializeObject(const AZ::SceneAPI::Containers::Scene& scene, AZ::SceneAPI::DataTypes::IManifestObject& target) override;
+            void GetPolicyName(AZStd::string& result) const override
+            {
+                result = "ClothRuleBehavior";
+            }
 
             // AssetImportRequestBus::Handler overrides ....
             AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action, RequestingApplication requester) override;

+ 4 - 0
Gems/PhysX/Code/Source/Pipeline/MeshBehavior.h

@@ -34,6 +34,10 @@ namespace PhysX
             void InitializeObject(const AZ::SceneAPI::Containers::Scene& scene, AZ::SceneAPI::DataTypes::IManifestObject& target) override;
             AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action,
                 RequestingApplication requester) override;
+            void GetPolicyName(AZStd::string& result) const override
+            {
+                result = "PhysX::Pipeline::MeshBehavior";
+            }
 
         private:
             AZ::SceneAPI::Events::ProcessingResult BuildDefault(AZ::SceneAPI::Containers::Scene& scene) const;

+ 4 - 0
Gems/Prefab/PrefabBuilder/PrefabGroup/PrefabGroupBehavior.cpp

@@ -91,6 +91,10 @@ namespace AZ::SceneAPI::Behaviors
         // AssetImportRequest
         Events::ProcessingResult UpdateManifest(Containers::Scene& scene, ManifestAction action, RequestingApplication requester) override;
         Events::ProcessingResult PrepareForAssetLoading(Containers::Scene& scene, RequestingApplication requester) override;
+        void GetPolicyName(AZStd::string& result) const override
+        {
+            result = "PrefabGroupBehavior::ExportEventHandler";
+        }
     };
 
     Events::ProcessingResult PrefabGroupBehavior::ExportEventHandler::PrepareForAssetLoading(

+ 4 - 0
Gems/SceneLoggingExample/Code/Behaviors/LoggingGroupBehavior.h

@@ -36,5 +36,9 @@ namespace SceneLoggingExample
         AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, 
             ManifestAction action, RequestingApplication requester) override;
         void InitializeObject(const AZ::SceneAPI::Containers::Scene& scene, AZ::SceneAPI::DataTypes::IManifestObject& target) override;
+        void GetPolicyName(AZStd::string& result) const override
+        {
+            result = "LoggingGroupBehavior";
+        }
     };
 } // namespace SceneLoggingExample

+ 4 - 0
Gems/SceneLoggingExample/Code/Processors/LoadingTrackingProcessor.h

@@ -37,6 +37,10 @@ namespace SceneLoggingExample
         void FinalizeAssetLoading(AZ::SceneAPI::Containers::Scene& scene, RequestingApplication requester) override;
         AZ::SceneAPI::Events::ProcessingResult UpdateManifest(AZ::SceneAPI::Containers::Scene& scene, ManifestAction action,
             RequestingApplication requester) override;
+        void GetPolicyName(AZStd::string& result) const override
+        {
+            result = "LoadingTrackingProcessor";
+        }
 
         uint8_t GetPriority() const override;
 

+ 4 - 0
Gems/SceneProcessing/Code/Source/Config/Components/SceneProcessingConfigSystemComponent.h

@@ -57,6 +57,10 @@ namespace AZ
             // SceneProcessingConfigRequestBus END
 
             void AreCustomNormalsUsed(bool &value) override;
+            void GetPolicyName(AZStd::string& result) const override
+            {
+                result = "SceneProcessingConfigSystemComponent";
+            }
 
             static void Reflect(AZ::ReflectContext* context);
 

+ 29 - 3
Gems/SceneProcessing/Code/Source/SceneBuilder/SceneBuilderWorker.cpp

@@ -43,6 +43,29 @@
 
 namespace SceneBuilder
 {
+    struct DebugOutputScope final
+    {
+        DebugOutputScope() = delete;
+        DebugOutputScope(bool isDebug)
+            : m_inDebug(isDebug)
+        {
+            if (AZ::SettingsRegistry::Get())
+            {
+                AZ::SettingsRegistry::Get()->Set(AZ::SceneAPI::Utilities::Key_AssetProcessorInDebugOutput, m_inDebug);
+            }
+        }
+
+        ~DebugOutputScope()
+        {
+            if (AZ::SettingsRegistry::Get())
+            {
+                AZ::SettingsRegistry::Get()->Set(AZ::SceneAPI::Utilities::Key_AssetProcessorInDebugOutput, false);
+            }
+        }
+
+        bool m_inDebug;
+    };
+
     void SceneBuilderWorker::ShutDown()
     {
         m_isShuttingDown = true;
@@ -232,11 +255,14 @@ namespace SceneBuilder
         // Load Scene graph and manifest from the provided path and then initialize them.
         if (m_isShuttingDown)
         {
-            AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Loading scene was cancelled.\n");
+            AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Loading scene was canceled.\n");
             response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled;
             return;
         }
 
+        auto debugFlagItr = request.m_jobDescription.m_jobParameters.find(AZ_CRC_CE("DebugFlag"));
+        DebugOutputScope theDebugOutputScope(debugFlagItr != request.m_jobDescription.m_jobParameters.end() && debugFlagItr->second == "true");
+
         AZStd::shared_ptr<Scene> scene;
         if (!LoadScene(scene, request, response))
         {
@@ -246,7 +272,7 @@ namespace SceneBuilder
         // Run scene generation step to allow for runtime generation of SceneGraph objects
         if (m_isShuttingDown)
         {
-            AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Generation of dynamic scene objects was cancelled.\n");
+            AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Generation of dynamic scene objects was canceled.\n");
             response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled;
             return;
         }
@@ -258,7 +284,7 @@ namespace SceneBuilder
         // Process the scene.
         if (m_isShuttingDown)
         {
-            AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Processing scene was cancelled.\n");
+            AZ_TracePrintf(AZ::SceneAPI::Utilities::LogWindow, "Processing scene was canceled.\n");
             response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled;
             return;
         }