SceneSerializationHandler.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzCore/Debug/Profiler.h>
  9. #include <AzCore/IO/Path/Path.h>
  10. #include <AzCore/IO/SystemFile.h>
  11. #include <AzCore/std/algorithm.h>
  12. #include <AzCore/std/string/conversions.h>
  13. #include <AzCore/Settings/SettingsRegistryMergeUtils.h>
  14. #include <AzFramework/StringFunc/StringFunc.h>
  15. #include <AzToolsFramework/API/EditorAssetSystemAPI.h>
  16. #include <AzToolsFramework/Debug/TraceContext.h>
  17. #include <SceneAPI/SceneCore/Events/AssetImportRequest.h>
  18. #include <SceneAPI/SceneCore/Components/LoadingComponent.h>
  19. #include <SceneAPI/SceneCore/Utilities/Reporting.h>
  20. #include <SceneSerializationHandler.h>
  21. namespace AZ
  22. {
  23. SceneSerializationHandler::~SceneSerializationHandler()
  24. {
  25. Deactivate();
  26. }
  27. void SceneSerializationHandler::Activate()
  28. {
  29. BusConnect();
  30. }
  31. void SceneSerializationHandler::Deactivate()
  32. {
  33. BusDisconnect();
  34. }
  35. AZStd::shared_ptr<SceneAPI::Containers::Scene> SceneSerializationHandler::LoadScene(
  36. const AZStd::string& filePath, Uuid sceneSourceGuid)
  37. {
  38. AZ_PROFILE_FUNCTION(Editor);
  39. namespace Utilities = AZ::SceneAPI::Utilities;
  40. using AZ::SceneAPI::Events::AssetImportRequest;
  41. CleanSceneMap();
  42. AZ_TraceContext("File", filePath);
  43. if (!IsValidExtension(filePath))
  44. {
  45. return nullptr;
  46. }
  47. AZ::IO::Path enginePath;
  48. if (auto settingsRegistry = AZ::SettingsRegistry::Get(); settingsRegistry != nullptr)
  49. {
  50. settingsRegistry->Get(enginePath.Native(), AZ::SettingsRegistryMergeUtils::FilePathKey_EngineRootFolder);
  51. }
  52. AZ::IO::Path cleanPath = (enginePath / filePath).LexicallyNormal();
  53. auto sceneIt = m_scenes.find(cleanPath.Native());
  54. if (sceneIt != m_scenes.end())
  55. {
  56. AZStd::shared_ptr<SceneAPI::Containers::Scene> scene = sceneIt->second.lock();
  57. if (scene)
  58. {
  59. return scene;
  60. }
  61. // There's a small window in between which the scene was closed after searching for
  62. // it in the scene map. In this case continue and simply reload the scene.
  63. }
  64. if (!AZ::IO::SystemFile::Exists(cleanPath.c_str()))
  65. {
  66. AZ_TracePrintf(Utilities::ErrorWindow, "No file exists at given source path.");
  67. return nullptr;
  68. }
  69. if (sceneSourceGuid.IsNull())
  70. {
  71. bool result = false;
  72. AZ::Data::AssetInfo info;
  73. AZStd::string watchFolder;
  74. AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, cleanPath.c_str(), info, watchFolder);
  75. if (!result)
  76. {
  77. AZ_TracePrintf(Utilities::ErrorWindow, "Failed to retrieve file info needed to determine the uuid of the source file.");
  78. return nullptr;
  79. }
  80. sceneSourceGuid = info.m_assetId.m_guid;
  81. }
  82. AZStd::shared_ptr<SceneAPI::Containers::Scene> scene =
  83. AssetImportRequest::LoadSceneFromVerifiedPath(cleanPath.Native(), sceneSourceGuid, AssetImportRequest::RequestingApplication::Editor, SceneAPI::SceneCore::LoadingComponent::TYPEINFO_Uuid());
  84. if (!scene)
  85. {
  86. AZ_TracePrintf(Utilities::ErrorWindow, "Failed to load the requested scene.");
  87. return nullptr;
  88. }
  89. m_scenes.emplace(AZStd::move(cleanPath.Native()), scene);
  90. return scene;
  91. }
  92. bool SceneSerializationHandler::IsValidExtension(const AZStd::string& filePath) const
  93. {
  94. namespace Utilities = AZ::SceneAPI::Utilities;
  95. if (AZ::SceneAPI::Events::AssetImportRequest::IsManifestExtension(filePath.c_str()))
  96. {
  97. AZ_TracePrintf(Utilities::ErrorWindow, "Provided path contains the manifest path, not the path to the source file.");
  98. return false;
  99. }
  100. if (!AZ::SceneAPI::Events::AssetImportRequest::IsSceneFileExtension(filePath.c_str()))
  101. {
  102. AZ_TracePrintf(Utilities::ErrorWindow, "Provided path doesn't contain an extension supported by the SceneAPI.");
  103. return false;
  104. }
  105. return true;
  106. }
  107. void SceneSerializationHandler::CleanSceneMap()
  108. {
  109. for (auto it = m_scenes.begin(); it != m_scenes.end(); )
  110. {
  111. if (it->second.expired())
  112. {
  113. it = m_scenes.erase(it);
  114. }
  115. else
  116. {
  117. ++it;
  118. }
  119. }
  120. }
  121. } // namespace AZ