SharedThumbnailRenderer.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  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 <Atom/Feature/Utils/LightingPreset.h>
  9. #include <Atom/Feature/Utils/ModelPreset.h>
  10. #include <Atom/RPI.Edit/Common/AssetUtils.h>
  11. #include <Atom/RPI.Edit/Material/MaterialSourceData.h>
  12. #include <Atom/RPI.Reflect/System/AnyAsset.h>
  13. #include <AtomToolsFramework/PreviewRenderer/PreviewRendererCaptureRequest.h>
  14. #include <AtomToolsFramework/PreviewRenderer/PreviewRendererInterface.h>
  15. #include <AtomToolsFramework/Util/Util.h>
  16. #include <AzFramework/Asset/AssetSystemBus.h>
  17. #include <AzToolsFramework/AssetBrowser/AssetBrowserBus.h>
  18. #include <AzToolsFramework/Thumbnails/ThumbnailerBus.h>
  19. #include <SharedPreview/SharedPreviewContent.h>
  20. #include <SharedPreview/SharedPreviewUtils.h>
  21. #include <SharedPreview/SharedThumbnailRenderer.h>
  22. namespace AZ
  23. {
  24. namespace LyIntegration
  25. {
  26. template<typename T>
  27. void LoadPreviewAsset(AZ::Data::Asset<T>& asset, const AZ::Data::AssetId& assetId)
  28. {
  29. if (!asset.IsReady() && !asset.IsLoading() && assetId.IsValid())
  30. {
  31. AZ::Data::AssetInfo assetInfo;
  32. AZ::Data::AssetCatalogRequestBus::BroadcastResult(
  33. assetInfo, &AZ::Data::AssetCatalogRequestBus::Events::GetAssetInfoById, assetId);
  34. if (assetInfo.m_assetId.IsValid())
  35. {
  36. asset.Create(assetId, true);
  37. }
  38. }
  39. }
  40. template<typename T>
  41. void LoadPreviewAsset(AZ::Data::Asset<T>& asset, const AZ::Data::AssetId& assetId, const AZStd::string& assetIdOverrideSettingKey)
  42. {
  43. LoadPreviewAsset(asset, AtomToolsFramework::GetSettingsObject<AZ::Data::AssetId>(assetIdOverrideSettingKey, assetId));
  44. }
  45. SharedThumbnailRenderer::SharedThumbnailRenderer()
  46. {
  47. for (const AZ::Uuid& typeId : SharedPreviewUtils::GetSupportedAssetTypes())
  48. {
  49. AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusConnect(typeId);
  50. }
  51. SystemTickBus::Handler::BusConnect();
  52. }
  53. SharedThumbnailRenderer::~SharedThumbnailRenderer()
  54. {
  55. AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::MultiHandler::BusDisconnect();
  56. SystemTickBus::Handler::BusDisconnect();
  57. }
  58. bool SharedThumbnailRenderer::ThumbnailConfig::IsValid() const
  59. {
  60. return m_modelAsset.GetId().IsValid() || m_materialAsset.GetId().IsValid() || m_lightingAsset.GetId().IsValid();
  61. }
  62. SharedThumbnailRenderer::ThumbnailConfig SharedThumbnailRenderer::GetThumbnailConfig(
  63. AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey)
  64. {
  65. const auto assetInfo = SharedPreviewUtils::GetSupportedAssetInfo(thumbnailKey);
  66. if (assetInfo.m_assetType == RPI::ModelAsset::RTTI_Type())
  67. {
  68. ThumbnailConfig thumbnailConfig;
  69. LoadPreviewAsset(thumbnailConfig.m_modelAsset, assetInfo.m_assetId);
  70. LoadPreviewAsset(
  71. thumbnailConfig.m_materialAsset,
  72. m_defaultMaterialAsset.GetId(),
  73. "/O3DE/Atom/CommonFeature/SharedPreview/ModelAssetType/MaterialAssetId");
  74. LoadPreviewAsset(
  75. thumbnailConfig.m_lightingAsset,
  76. m_defaultLightingPresetAsset.GetId(),
  77. "/O3DE/Atom/CommonFeature/SharedPreview/ModelAssetType/LightingAssetId");
  78. return thumbnailConfig;
  79. }
  80. if (assetInfo.m_assetType == RPI::MaterialAsset::RTTI_Type())
  81. {
  82. ThumbnailConfig thumbnailConfig;
  83. LoadPreviewAsset(thumbnailConfig.m_materialAsset, assetInfo.m_assetId);
  84. LoadPreviewAsset(
  85. thumbnailConfig.m_modelAsset,
  86. m_defaultModelAsset.GetId(),
  87. "/O3DE/Atom/CommonFeature/SharedPreview/MaterialAssetType/ModelAssetId");
  88. LoadPreviewAsset(
  89. thumbnailConfig.m_lightingAsset,
  90. m_defaultLightingPresetAsset.GetId(),
  91. "/O3DE/Atom/CommonFeature/SharedPreview/MaterialAssetType/LightingAssetId");
  92. return thumbnailConfig;
  93. }
  94. if (assetInfo.m_assetType == RPI::MaterialTypeAsset::RTTI_Type())
  95. {
  96. // Material type assets are not renderable so we generate a material asset from the material type.
  97. ThumbnailConfig thumbnailConfig;
  98. AZ::RPI::MaterialSourceData materialSourceData;
  99. materialSourceData.m_materialType = AZ::RPI::AssetUtils::GetSourcePathByAssetId(assetInfo.m_assetId);
  100. auto outcome = materialSourceData.CreateMaterialAsset(AZ::Uuid::CreateRandom(), "", false);
  101. if (outcome)
  102. {
  103. thumbnailConfig.m_materialAsset = outcome.TakeValue();
  104. LoadPreviewAsset(
  105. thumbnailConfig.m_modelAsset,
  106. m_defaultModelAsset.GetId(),
  107. "/O3DE/Atom/CommonFeature/SharedPreview/MaterialTypeAssetType/ModelAssetId");
  108. LoadPreviewAsset(
  109. thumbnailConfig.m_lightingAsset,
  110. m_defaultLightingPresetAsset.GetId(),
  111. "/O3DE/Atom/CommonFeature/SharedPreview/MaterialTypeAssetType/LightingAssetId");
  112. }
  113. return thumbnailConfig;
  114. }
  115. const auto& path = AZ::RPI::AssetUtils::GetSourcePathByAssetId(assetInfo.m_assetId);
  116. if (assetInfo.m_assetType == RPI::AnyAsset::RTTI_Type() && path.ends_with(AZ::Render::LightingPreset::Extension))
  117. {
  118. ThumbnailConfig thumbnailConfig;
  119. LoadPreviewAsset(thumbnailConfig.m_lightingAsset, assetInfo.m_assetId);
  120. LoadPreviewAsset(
  121. thumbnailConfig.m_modelAsset,
  122. m_defaultModelAsset.GetId(),
  123. "/O3DE/Atom/CommonFeature/SharedPreview/LightingPresetAssetType/ModelAssetId");
  124. LoadPreviewAsset(
  125. thumbnailConfig.m_materialAsset,
  126. m_reflectionMaterialAsset.GetId(),
  127. "/O3DE/Atom/CommonFeature/SharedPreview/LightingPresetAssetType/MaterialAssetId");
  128. return thumbnailConfig;
  129. }
  130. if (assetInfo.m_assetType == RPI::AnyAsset::RTTI_Type() && path.ends_with(AZ::Render::ModelPreset::Extension))
  131. {
  132. // Model preset assets are relatively small JSON files containing a reference to a model asset and possibly other
  133. // parameters. The preset must be loaded to get the model asset ID. Then the preview will be rendered like any other model.
  134. AZ::Data::Asset<AZ::RPI::AnyAsset> asset = AZ::RPI::AssetUtils::LoadAssetById<AZ::RPI::AnyAsset>(assetInfo.m_assetId);
  135. const AZ::Render::ModelPreset& preset = *AZ::RPI::GetDataFromAnyAsset<AZ::Render::ModelPreset>(asset);
  136. ThumbnailConfig thumbnailConfig;
  137. thumbnailConfig.m_modelAsset = preset.m_modelAsset;
  138. LoadPreviewAsset(
  139. thumbnailConfig.m_materialAsset,
  140. m_defaultMaterialAsset.GetId(),
  141. "/O3DE/Atom/CommonFeature/SharedPreview/ModelPresetAssetType/MaterialAssetId");
  142. LoadPreviewAsset(
  143. thumbnailConfig.m_lightingAsset,
  144. m_defaultLightingPresetAsset.GetId(),
  145. "/O3DE/Atom/CommonFeature/SharedPreview/ModelPresetAssetType/LightingAssetId");
  146. return thumbnailConfig;
  147. }
  148. return ThumbnailConfig();
  149. }
  150. void SharedThumbnailRenderer::RenderThumbnail(AzToolsFramework::Thumbnailer::SharedThumbnailKey thumbnailKey, int thumbnailSize)
  151. {
  152. auto previewRenderer = AZ::Interface<AtomToolsFramework::PreviewRendererInterface>::Get();
  153. if (!previewRenderer)
  154. {
  155. AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
  156. thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
  157. return;
  158. }
  159. if (!m_defaultModelAsset.IsReady() || !m_defaultLightingPresetAsset.IsReady() || !m_reflectionMaterialAsset.IsReady())
  160. {
  161. AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
  162. thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
  163. return;
  164. }
  165. const auto& thumbnailConfig = GetThumbnailConfig(thumbnailKey);
  166. if (!thumbnailConfig.IsValid())
  167. {
  168. AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
  169. thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
  170. return;
  171. }
  172. previewRenderer->AddCaptureRequest(
  173. { thumbnailSize,
  174. AZStd::make_shared<SharedPreviewContent>(
  175. previewRenderer->GetScene(), previewRenderer->GetView(), previewRenderer->GetEntityContextId(),
  176. thumbnailConfig.m_modelAsset, thumbnailConfig.m_materialAsset, thumbnailConfig.m_lightingAsset,
  177. Render::MaterialPropertyOverrideMap()),
  178. [thumbnailKey]()
  179. {
  180. AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
  181. thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailFailedToRender);
  182. },
  183. [thumbnailKey](const QPixmap& pixmap)
  184. {
  185. AzToolsFramework::Thumbnailer::ThumbnailerRendererNotificationBus::Event(
  186. thumbnailKey, &AzToolsFramework::Thumbnailer::ThumbnailerRendererNotifications::ThumbnailRendered, pixmap);
  187. } });
  188. }
  189. bool SharedThumbnailRenderer::Installed() const
  190. {
  191. return true;
  192. }
  193. void SharedThumbnailRenderer::OnSystemTick()
  194. {
  195. // models/sphere.azmodel
  196. LoadPreviewAsset(m_defaultModelAsset, AZ::Data::AssetId("{6DE0E9A8-A1C7-5D0F-9407-4E627C1F223C}", 284780167));
  197. // lightingpresets/thumbnail.lightingpreset.azasset
  198. LoadPreviewAsset(m_defaultLightingPresetAsset, AZ::Data::AssetId("{4F3761EF-E279-5FDD-98C3-EF90F924FBAC}", 0));
  199. // materials/reflectionprobe/reflectionprobevisualization.azmaterial
  200. LoadPreviewAsset(m_reflectionMaterialAsset, AZ::Data::AssetId("{4322FBCB-8916-5572-9CDA-18582E22D238}", 0));
  201. AzToolsFramework::Thumbnailer::ThumbnailerRendererRequestBus::ExecuteQueuedEvents();
  202. }
  203. } // namespace LyIntegration
  204. } // namespace AZ