3
0

SharedPreviewContent.cpp 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  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/ImageBasedLights/ImageBasedLightFeatureProcessorInterface.h>
  9. #include <Atom/Feature/PostProcess/PostProcessFeatureProcessorInterface.h>
  10. #include <Atom/Feature/SkyBox/SkyBoxFeatureProcessorInterface.h>
  11. #include <Atom/Feature/Utils/LightingPreset.h>
  12. #include <Atom/RPI.Public/Scene.h>
  13. #include <Atom/RPI.Reflect/Asset/AssetUtils.h>
  14. #include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentBus.h>
  15. #include <AtomLyIntegration/CommonFeatures/Material/MaterialComponentConstants.h>
  16. #include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentBus.h>
  17. #include <AtomLyIntegration/CommonFeatures/Mesh/MeshComponentConstants.h>
  18. #include <AzCore/Asset/AssetCommon.h>
  19. #include <AzCore/Component/Entity.h>
  20. #include <AzCore/Component/TransformBus.h>
  21. #include <AzCore/Math/MatrixUtils.h>
  22. #include <AzCore/Math/Transform.h>
  23. #include <AzFramework/Components/TransformComponent.h>
  24. #include <AzFramework/Entity/EntityContextBus.h>
  25. #include <SharedPreview/SharedPreviewContent.h>
  26. namespace AZ
  27. {
  28. namespace LyIntegration
  29. {
  30. SharedPreviewContent::SharedPreviewContent(
  31. RPI::ScenePtr scene,
  32. RPI::ViewPtr view,
  33. AZ::Uuid entityContextId,
  34. const Data::Asset<RPI::ModelAsset>& modelAsset,
  35. const Data::Asset<RPI::MaterialAsset>& materialAsset,
  36. const Data::Asset<RPI::AnyAsset>& lightingPresetAsset,
  37. const Render::MaterialPropertyOverrideMap& materialPropertyOverrides)
  38. : m_scene(scene)
  39. , m_view(view)
  40. , m_entityContextId(entityContextId)
  41. , m_modelAsset(modelAsset)
  42. , m_materialAsset(materialAsset)
  43. , m_lightingPresetAsset(lightingPresetAsset)
  44. , m_materialPropertyOverrides(materialPropertyOverrides)
  45. {
  46. // Create preview model
  47. AzFramework::EntityContextRequestBus::EventResult(
  48. m_modelEntity, m_entityContextId, &AzFramework::EntityContextRequestBus::Events::CreateEntity, "SharedPreviewContentModel");
  49. m_modelEntity->CreateComponent(Render::MeshComponentTypeId);
  50. m_modelEntity->CreateComponent(Render::MaterialComponentTypeId);
  51. m_modelEntity->CreateComponent(azrtti_typeid<AzFramework::TransformComponent>());
  52. m_modelEntity->Init();
  53. m_modelEntity->Activate();
  54. }
  55. SharedPreviewContent::~SharedPreviewContent()
  56. {
  57. if (m_modelEntity)
  58. {
  59. m_modelEntity->Deactivate();
  60. AzFramework::EntityContextRequestBus::Event(
  61. m_entityContextId, &AzFramework::EntityContextRequestBus::Events::DestroyEntity, m_modelEntity);
  62. m_modelEntity = nullptr;
  63. }
  64. }
  65. void SharedPreviewContent::Load()
  66. {
  67. m_modelAsset.QueueLoad();
  68. m_materialAsset.QueueLoad();
  69. m_lightingPresetAsset.QueueLoad();
  70. }
  71. bool SharedPreviewContent::IsReady() const
  72. {
  73. return (!m_modelAsset.GetId().IsValid() || m_modelAsset.IsReady()) &&
  74. (!m_materialAsset.GetId().IsValid() || m_materialAsset.IsReady()) &&
  75. (!m_lightingPresetAsset.GetId().IsValid() || m_lightingPresetAsset.IsReady());
  76. }
  77. bool SharedPreviewContent::IsError() const
  78. {
  79. return m_modelAsset.IsError() || m_materialAsset.IsError() || m_lightingPresetAsset.IsError();
  80. }
  81. void SharedPreviewContent::ReportErrors()
  82. {
  83. AZ_Warning(
  84. "SharedPreviewContent", !m_modelAsset.GetId().IsValid() || m_modelAsset.IsReady(), "Asset failed to load in time: %s",
  85. m_modelAsset.ToString<AZStd::string>().c_str());
  86. AZ_Warning(
  87. "SharedPreviewContent", !m_materialAsset.GetId().IsValid() || m_materialAsset.IsReady(), "Asset failed to load in time: %s",
  88. m_materialAsset.ToString<AZStd::string>().c_str());
  89. AZ_Warning(
  90. "SharedPreviewContent", !m_lightingPresetAsset.GetId().IsValid() || m_lightingPresetAsset.IsReady(),
  91. "Asset failed to load in time: %s", m_lightingPresetAsset.ToString<AZStd::string>().c_str());
  92. }
  93. void SharedPreviewContent::Update()
  94. {
  95. UpdateModel();
  96. UpdateLighting();
  97. UpdateCamera();
  98. }
  99. void SharedPreviewContent::UpdateModel()
  100. {
  101. Render::MeshComponentRequestBus::Event(
  102. m_modelEntity->GetId(), &Render::MeshComponentRequestBus::Events::SetModelAsset, m_modelAsset);
  103. Render::MaterialComponentRequestBus::Event(
  104. m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetMaterialAssetId,
  105. Render::DefaultMaterialAssignmentId, m_materialAsset.GetId());
  106. Render::MaterialComponentRequestBus::Event(
  107. m_modelEntity->GetId(), &Render::MaterialComponentRequestBus::Events::SetPropertyValues,
  108. Render::DefaultMaterialAssignmentId, m_materialPropertyOverrides);
  109. }
  110. void SharedPreviewContent::UpdateLighting()
  111. {
  112. if (m_lightingPresetAsset.IsReady())
  113. {
  114. auto preset = m_lightingPresetAsset->GetDataAs<Render::LightingPreset>();
  115. if (preset)
  116. {
  117. auto iblFeatureProcessor = m_scene->GetFeatureProcessor<Render::ImageBasedLightFeatureProcessorInterface>();
  118. auto postProcessFeatureProcessor = m_scene->GetFeatureProcessor<Render::PostProcessFeatureProcessorInterface>();
  119. auto postProcessSettingInterface = postProcessFeatureProcessor->GetOrCreateSettingsInterface(EntityId());
  120. auto exposureControlSettingInterface = postProcessSettingInterface->GetOrCreateExposureControlSettingsInterface();
  121. auto directionalLightFeatureProcessor =
  122. m_scene->GetFeatureProcessor<Render::DirectionalLightFeatureProcessorInterface>();
  123. auto skyboxFeatureProcessor = m_scene->GetFeatureProcessor<Render::SkyBoxFeatureProcessorInterface>();
  124. skyboxFeatureProcessor->Enable(true);
  125. skyboxFeatureProcessor->SetSkyboxMode(Render::SkyBoxMode::Cubemap);
  126. Camera::Configuration cameraConfig;
  127. cameraConfig.m_fovRadians = FieldOfView;
  128. cameraConfig.m_nearClipDistance = NearDist;
  129. cameraConfig.m_farClipDistance = FarDist;
  130. cameraConfig.m_frustumWidth = 100.0f;
  131. cameraConfig.m_frustumHeight = 100.0f;
  132. AZStd::vector<Render::DirectionalLightFeatureProcessorInterface::LightHandle> lightHandles;
  133. preset->ApplyLightingPreset(
  134. iblFeatureProcessor, skyboxFeatureProcessor, exposureControlSettingInterface, directionalLightFeatureProcessor,
  135. cameraConfig, lightHandles, false);
  136. }
  137. }
  138. }
  139. void SharedPreviewContent::UpdateCamera()
  140. {
  141. // Get bounding sphere of the model asset and estimate how far the camera needs to be see all of it
  142. Vector3 center = {};
  143. float radius = {};
  144. if (m_modelAsset.IsReady())
  145. {
  146. m_modelAsset->GetAabb().GetAsSphere(center, radius);
  147. }
  148. const auto distance = fabsf(radius / sinf(FieldOfView)) + NearDist;
  149. const auto cameraRotation = Quaternion::CreateFromAxisAngle(Vector3::CreateAxisX(), -CameraRotationAngle);
  150. const auto cameraPosition = center + cameraRotation.TransformVector(-Vector3::CreateAxisY() * distance);
  151. const auto cameraTransform = Transform::CreateLookAt(cameraPosition, center);
  152. m_view->SetCameraTransform(Matrix3x4::CreateFromTransform(cameraTransform));
  153. }
  154. } // namespace LyIntegration
  155. } // namespace AZ