DecalComponentController.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  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 <Decals/DecalComponentController.h>
  9. #include <AzCore/Asset/AssetSerializer.h>
  10. #include <AzCore/RTTI/BehaviorContext.h>
  11. #include <AzCore/Serialization/EditContext.h>
  12. #include <AzCore/Serialization/SerializeContext.h>
  13. #include <Atom/RPI.Public/Scene.h>
  14. namespace AZ
  15. {
  16. namespace Render
  17. {
  18. void DecalComponentConfig::Reflect(ReflectContext* context)
  19. {
  20. if (auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  21. {
  22. serializeContext->Class<DecalComponentConfig, ComponentConfig>()
  23. ->Version(2)
  24. ->Field("Attenuation Angle", &DecalComponentConfig::m_attenuationAngle)
  25. ->Field("Opacity", &DecalComponentConfig::m_opacity)
  26. ->Field("Normal Map Opacity", &DecalComponentConfig::m_normalMapOpacity)
  27. ->Field("SortKey", &DecalComponentConfig::m_sortKey)
  28. ->Field("Decal Color", &DecalComponentConfig::m_decalColor)
  29. ->Field("Decal Color Factor", &DecalComponentConfig::m_decalColorFactor)
  30. ->Field("Material", &DecalComponentConfig::m_materialAsset)
  31. ;
  32. }
  33. }
  34. void DecalComponentController::Reflect(ReflectContext* context)
  35. {
  36. DecalComponentConfig::Reflect(context);
  37. if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
  38. {
  39. serializeContext->Class<DecalComponentController>()
  40. ->Version(0)
  41. ->Field("Configuration", &DecalComponentController::m_configuration);
  42. }
  43. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  44. {
  45. behaviorContext->EBus<DecalRequestBus>("DecalRequestBus")
  46. ->Event("GetAttenuationAngle", &DecalRequestBus::Events::GetAttenuationAngle)
  47. ->Event("SetAttenuationAngle", &DecalRequestBus::Events::SetAttenuationAngle)
  48. ->Event("GetOpacity", &DecalRequestBus::Events::GetOpacity)
  49. ->Event("SetOpacity", &DecalRequestBus::Events::SetOpacity)
  50. ->Event("GetNormalMapOpacity", &DecalRequestBus::Events::GetNormalMapOpacity)
  51. ->Event("SetNormalMapOpacity", &DecalRequestBus::Events::SetNormalMapOpacity)
  52. ->Event("SetSortKey", &DecalRequestBus::Events::SetSortKey)
  53. ->Event("GetSortKey", &DecalRequestBus::Events::GetSortKey)
  54. ->Event("GetDecalColor", &DecalRequestBus::Events::GetDecalColor)
  55. ->Event("SetDecalColor", &DecalRequestBus::Events::SetDecalColor)
  56. ->Event("GetDecalColorFactor", &DecalRequestBus::Events::GetDecalColorFactor)
  57. ->Event("SetDecalColorFactor", &DecalRequestBus::Events::SetDecalColorFactor)
  58. ->VirtualProperty("AttenuationAngle", "GetAttenuationAngle", "SetAttenuationAngle")
  59. ->VirtualProperty("Opacity", "GetOpacity", "SetOpacity")
  60. ->VirtualProperty("NormalMapOpacity", "GetNormalMapOpacity", "SetNormalMapOpacity")
  61. ->VirtualProperty("SortKey", "GetSortKey", "SetSortKey")
  62. ->VirtualProperty("DecalColor", "GetDecalColor", "SetDecalColor")
  63. ->VirtualProperty("DecalColorFactor", "GetDecalColorFactor", "SetDecalColorFactor")
  64. ->Event("SetMaterial", &DecalRequestBus::Events::SetMaterialAssetId)
  65. ->Event("GetMaterial", &DecalRequestBus::Events::GetMaterialAssetId)
  66. ->VirtualProperty("Material", "GetMaterial", "SetMaterial")
  67. ;
  68. }
  69. }
  70. void DecalComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  71. {
  72. provided.push_back(AZ_CRC_CE("DecalService"));
  73. }
  74. void DecalComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  75. {
  76. incompatible.push_back(AZ_CRC_CE("DecalService"));
  77. }
  78. void DecalComponentController::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent)
  79. {
  80. dependent.push_back(AZ_CRC_CE("TransformService"));
  81. dependent.push_back(AZ_CRC_CE("NonUniformScaleService"));
  82. }
  83. DecalComponentController::DecalComponentController(const DecalComponentConfig& config)
  84. : m_configuration(config)
  85. {
  86. }
  87. void DecalComponentController::Activate(EntityId entityId)
  88. {
  89. m_entityId = entityId;
  90. m_featureProcessor = RPI::Scene::GetFeatureProcessorForEntity<DecalFeatureProcessorInterface>(entityId);
  91. AZ_Assert(m_featureProcessor, "DecalRenderProxy was unable to find a decal FeatureProcessor on the entityId provided.");
  92. if (m_featureProcessor)
  93. {
  94. m_handle = m_featureProcessor->AcquireDecal();
  95. }
  96. m_cachedNonUniformScale = AZ::Vector3::CreateOne();
  97. AZ::NonUniformScaleRequestBus::EventResult(m_cachedNonUniformScale, m_entityId, &AZ::NonUniformScaleRequests::GetScale);
  98. AZ::NonUniformScaleRequestBus::Event(m_entityId, &AZ::NonUniformScaleRequests::RegisterScaleChangedEvent,
  99. m_nonUniformScaleChangedHandler);
  100. AZ::Transform local, world;
  101. AZ::TransformBus::Event(entityId, &AZ::TransformBus::Events::GetLocalAndWorld, local, world);
  102. OnTransformChanged(local, world);
  103. TransformNotificationBus::Handler::BusConnect(m_entityId);
  104. DecalRequestBus::Handler::BusConnect(m_entityId);
  105. ConfigurationChanged();
  106. }
  107. void DecalComponentController::Deactivate()
  108. {
  109. DecalRequestBus::Handler::BusDisconnect(m_entityId);
  110. TransformNotificationBus::Handler::BusDisconnect(m_entityId);
  111. m_nonUniformScaleChangedHandler.Disconnect();
  112. if (m_featureProcessor)
  113. {
  114. m_featureProcessor->ReleaseDecal(m_handle);
  115. m_handle.Reset();
  116. }
  117. }
  118. void DecalComponentController::SetConfiguration(const DecalComponentConfig& config)
  119. {
  120. m_configuration = config;
  121. ConfigurationChanged();
  122. }
  123. const DecalComponentConfig& DecalComponentController::GetConfiguration() const
  124. {
  125. return m_configuration;
  126. }
  127. void DecalComponentController::OnTransformChanged(const AZ::Transform& /*local*/, const AZ::Transform& world)
  128. {
  129. if (m_featureProcessor)
  130. {
  131. m_featureProcessor->SetDecalTransform(m_handle, world, m_cachedNonUniformScale);
  132. }
  133. }
  134. void DecalComponentController::HandleNonUniformScaleChange(const AZ::Vector3& nonUniformScale)
  135. {
  136. m_cachedNonUniformScale = nonUniformScale;
  137. if (m_featureProcessor)
  138. {
  139. AZ::Transform world = AZ::Transform::CreateIdentity();
  140. AZ::TransformBus::EventResult(world, m_entityId, &AZ::TransformBus::Events::GetWorldTM);
  141. m_featureProcessor->SetDecalTransform(m_handle, world, nonUniformScale);
  142. }
  143. }
  144. void DecalComponentController::ConfigurationChanged()
  145. {
  146. AttenuationAngleChanged();
  147. OpacityChanged();
  148. NormalMapOpacityChanged();
  149. SortKeyChanged();
  150. DecalColorChanged();
  151. DecalColorFactorChanged();
  152. MaterialChanged();
  153. }
  154. float DecalComponentController::GetAttenuationAngle() const
  155. {
  156. return m_configuration.m_attenuationAngle;
  157. }
  158. void DecalComponentController::SetAttenuationAngle(float attenuationAngle)
  159. {
  160. m_configuration.m_attenuationAngle = attenuationAngle;
  161. AttenuationAngleChanged();
  162. }
  163. const AZ::Vector3& DecalComponentController::GetDecalColor() const
  164. {
  165. return m_configuration.m_decalColor;
  166. }
  167. void DecalComponentController::SetDecalColor(const AZ::Vector3& color)
  168. {
  169. m_configuration.m_decalColor = color;
  170. DecalColorChanged();
  171. }
  172. float DecalComponentController::GetDecalColorFactor() const
  173. {
  174. return m_configuration.m_decalColorFactor;
  175. }
  176. void DecalComponentController::SetDecalColorFactor(float colorFactor)
  177. {
  178. m_configuration.m_decalColorFactor = colorFactor;
  179. DecalColorFactorChanged();
  180. }
  181. float DecalComponentController::GetOpacity() const
  182. {
  183. return m_configuration.m_opacity;
  184. }
  185. void DecalComponentController::SetOpacity(float opacity)
  186. {
  187. m_configuration.m_opacity = opacity;
  188. OpacityChanged();
  189. }
  190. float DecalComponentController::GetNormalMapOpacity() const
  191. {
  192. return m_configuration.m_normalMapOpacity;
  193. }
  194. void DecalComponentController::SetNormalMapOpacity(float opacity)
  195. {
  196. m_configuration.m_normalMapOpacity = opacity;
  197. NormalMapOpacityChanged();
  198. }
  199. uint8_t DecalComponentController::GetSortKey() const
  200. {
  201. return m_configuration.m_sortKey;
  202. }
  203. void DecalComponentController::SetSortKey(uint8_t sortKey)
  204. {
  205. m_configuration.m_sortKey = sortKey;
  206. SortKeyChanged();
  207. }
  208. void DecalComponentController::AttenuationAngleChanged()
  209. {
  210. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnAttenuationAngleChanged, m_configuration.m_attenuationAngle);
  211. if (m_featureProcessor)
  212. {
  213. m_featureProcessor->SetDecalAttenuationAngle(m_handle, m_configuration.m_attenuationAngle);
  214. }
  215. }
  216. void DecalComponentController::DecalColorChanged()
  217. {
  218. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnDecalColorChanged, m_configuration.m_decalColor);
  219. if (m_featureProcessor)
  220. {
  221. m_featureProcessor->SetDecalColor(m_handle, m_configuration.m_decalColor);
  222. }
  223. }
  224. void DecalComponentController::DecalColorFactorChanged()
  225. {
  226. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnDecalColorFactorChanged, m_configuration.m_decalColorFactor);
  227. if (m_featureProcessor)
  228. {
  229. m_featureProcessor->SetDecalColorFactor(m_handle, m_configuration.m_decalColorFactor);
  230. }
  231. }
  232. void DecalComponentController::OpacityChanged()
  233. {
  234. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnOpacityChanged, m_configuration.m_opacity);
  235. if (m_featureProcessor)
  236. {
  237. m_featureProcessor->SetDecalOpacity(m_handle, m_configuration.m_opacity);
  238. }
  239. }
  240. void DecalComponentController::NormalMapOpacityChanged()
  241. {
  242. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnNormalMapOpacityChanged, m_configuration.m_normalMapOpacity);
  243. if (m_featureProcessor)
  244. {
  245. m_featureProcessor->SetDecalNormalMapOpacity(m_handle, m_configuration.m_normalMapOpacity);
  246. }
  247. }
  248. void DecalComponentController::SortKeyChanged()
  249. {
  250. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnSortKeyChanged, m_configuration.m_sortKey);
  251. if (m_featureProcessor)
  252. {
  253. m_featureProcessor->SetDecalSortKey(m_handle, m_configuration.m_sortKey);
  254. }
  255. }
  256. void DecalComponentController::SetMaterialAssetId(Data::AssetId id)
  257. {
  258. Data::Asset<RPI::MaterialAsset> materialAsset;
  259. materialAsset.Create(id);
  260. m_configuration.m_materialAsset = materialAsset;
  261. MaterialChanged();
  262. }
  263. void DecalComponentController::MaterialChanged()
  264. {
  265. DecalNotificationBus::Event(m_entityId, &DecalNotifications::OnMaterialChanged, m_configuration.m_materialAsset);
  266. if (m_featureProcessor)
  267. {
  268. m_featureProcessor->SetDecalMaterial(m_handle, m_configuration.m_materialAsset.GetId());
  269. }
  270. }
  271. Data::AssetId DecalComponentController::GetMaterialAssetId() const
  272. {
  273. return m_configuration.m_materialAsset.GetId();
  274. }
  275. } // namespace Render
  276. } // namespace AZ