PostFxLayerComponentController.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  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 <PostProcess/PostFxLayerComponentController.h>
  9. #include <AtomLyIntegration/CommonFeatures/PostProcess/PostFxWeightRequestBus.h>
  10. #include <LmbrCentral/Scripting/TagComponentBus.h>
  11. #include <LmbrCentral/Scripting/EditorTagComponentBus.h>
  12. #include <AzCore/Component/TransformBus.h>
  13. #include <AzCore/RTTI/BehaviorContext.h>
  14. #include <Atom/RPI.Public/Scene.h>
  15. #include <Atom/RPI.Public/ViewProviderBus.h>
  16. #include <Atom/RPI.Public/ViewportContextBus.h>
  17. namespace AZ
  18. {
  19. namespace Render
  20. {
  21. void PostFxLayerComponentController::Reflect(ReflectContext* context)
  22. {
  23. PostFxLayerComponentConfig::Reflect(context);
  24. if (auto* serializeContext = azrtti_cast<SerializeContext*>(context))
  25. {
  26. serializeContext->Class<PostFxLayerComponentController>()
  27. ->Version(0)
  28. ->Field("Configuration", &PostFxLayerComponentController::m_configuration);
  29. }
  30. if (AZ::BehaviorContext* behaviorContext = azrtti_cast<AZ::BehaviorContext*>(context))
  31. {
  32. behaviorContext->EBus<PostFxLayerRequestBus>("PostFxLayerRequestBus")
  33. // Auto-gen behavior context...
  34. #define PARAM_EVENT_BUS PostFxLayerRequestBus::Events
  35. #include <Atom/Feature/ParamMacros/StartParamBehaviorContext.inl>
  36. #include <Atom/Feature/PostProcess/PostProcessParams.inl>
  37. #include <Atom/Feature/ParamMacros/EndParams.inl>
  38. #undef PARAM_EVENT_BUS
  39. ;
  40. }
  41. }
  42. void PostFxLayerComponentController::OnTick(float deltaTime, ScriptTimePoint time)
  43. {
  44. AZ_UNUSED(deltaTime);
  45. AZ_UNUSED(time);
  46. // get all camera entities if no tags were set in the PostFx layer
  47. const AZStd::unordered_set<AZ::EntityId>& cameraEntityList = GetCameraEntityList();
  48. // Get views of each camera
  49. AZStd::unordered_set<AZ::RPI::View*> allSceneViews;
  50. for (const AZ::EntityId& cameraEntityId : cameraEntityList)
  51. {
  52. for (uint32_t i = 0; i < AZ::RPI::MaxViewTypes; i++)
  53. {
  54. if (i == AZ::RPI::DefaultViewType)
  55. {
  56. // Get the view pointer associated to each camera entity
  57. AZ::RPI::ViewPtr view = nullptr;
  58. AZ::RPI::ViewProviderBus::EventResult(view, cameraEntityId, &AZ::RPI::ViewProvider::GetView);
  59. if (view != nullptr)
  60. {
  61. allSceneViews.insert(view.get());
  62. }
  63. }
  64. else
  65. {
  66. AZ::RPI::ViewPtr stereoscopicView = nullptr;
  67. AZ::RPI::ViewProviderBus::EventResult(
  68. stereoscopicView, cameraEntityId, &AZ::RPI::ViewProvider::GetStereoscopicView, static_cast<AZ::RPI::ViewType>(i));
  69. if (stereoscopicView != nullptr)
  70. {
  71. allSceneViews.insert(stereoscopicView.get());
  72. }
  73. }
  74. }
  75. }
  76. // Add the current view which can potentially be the editor view
  77. auto atomViewportRequests = AZ::Interface<AZ::RPI::ViewportContextRequestsInterface>::Get();
  78. const AZ::Name contextName = atomViewportRequests->GetDefaultViewportContextName();
  79. auto currentView = atomViewportRequests->GetCurrentViewGroup(contextName)->GetView();
  80. if (IsEditorView(currentView))
  81. {
  82. allSceneViews.insert(currentView.get());
  83. }
  84. // calculate blend weights for all cameras
  85. PostProcessSettingsInterface::ViewBlendWeightMap perViewBlendWeights;
  86. for (auto view : allSceneViews)
  87. {
  88. if (view)
  89. {
  90. // get the view position
  91. AZ::Vector3 viewPosition = view->GetViewToWorldMatrix().GetTranslation();
  92. // calculate blend weight based on proximity to weight modifier
  93. float blendWeightResult = 1.0f;
  94. AZ::Render::PostFxWeightRequestBus::EventResult(
  95. blendWeightResult,
  96. m_entityId,
  97. &AZ::Render::PostFxWeightRequests::GetWeightAtPosition,
  98. viewPosition
  99. );
  100. // store result
  101. perViewBlendWeights[view] = blendWeightResult;
  102. }
  103. }
  104. // copy cameraToBlendWeight data to settings
  105. m_postProcessInterface = m_featureProcessorInterface->GetOrCreateSettingsInterface(m_entityId);
  106. m_postProcessInterface->CopyViewToBlendWeightSettings(perViewBlendWeights);
  107. m_postProcessInterface->OnConfigChanged();
  108. }
  109. void PostFxLayerComponentController::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided)
  110. {
  111. provided.push_back(AZ_CRC_CE("PostFXLayerService"));
  112. }
  113. void PostFxLayerComponentController::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible)
  114. {
  115. incompatible.push_back(AZ_CRC_CE("PostFXLayerService"));
  116. }
  117. PostFxLayerComponentController::PostFxLayerComponentController(const PostFxLayerComponentConfig& config)
  118. : m_configuration(config)
  119. {
  120. }
  121. void PostFxLayerComponentController::OnEntityTagAdded(const AZ::EntityId& entityId)
  122. {
  123. // If the entity contains an exclusion tag, do not add it to the tagged camera entities
  124. if (!HasTags(entityId, m_configuration.m_exclusionTags))
  125. {
  126. m_taggedCameraEntities.insert(entityId);
  127. }
  128. }
  129. void PostFxLayerComponentController::OnEntityTagRemoved(const AZ::EntityId& entityId)
  130. {
  131. m_taggedCameraEntities.erase(entityId);
  132. }
  133. void PostFxLayerComponentController::OnCameraAdded(const AZ::EntityId& cameraId)
  134. {
  135. // If the entity contains an exclusion tag, do not add it to the camera entities
  136. if (!HasTags(cameraId, m_configuration.m_exclusionTags))
  137. {
  138. m_cameraEntities.insert(cameraId);
  139. }
  140. AZ::RPI::ViewPtr view = nullptr;
  141. AZ::RPI::ViewProviderBus::EventResult(view, cameraId, &AZ::RPI::ViewProvider::GetView);
  142. if (view != nullptr)
  143. {
  144. m_allCameraViews.insert(view.get());
  145. }
  146. }
  147. void PostFxLayerComponentController::OnCameraRemoved(const AZ::EntityId& cameraId)
  148. {
  149. m_cameraEntities.erase(cameraId);
  150. }
  151. void PostFxLayerComponentController::RebuildCameraEntitiesList()
  152. {
  153. // Reconnect buses to regenerate the entities list
  154. m_taggedCameraEntities.clear();
  155. BusConnectToTags();
  156. m_cameraEntities.clear();
  157. Camera::CameraNotificationBus::Handler::BusDisconnect();
  158. Camera::CameraNotificationBus::Handler::BusConnect();
  159. }
  160. const AZStd::unordered_set<AZ::EntityId>& PostFxLayerComponentController::GetCameraEntityList() const
  161. {
  162. if (m_configuration.m_cameraTags.empty())
  163. {
  164. return m_cameraEntities;
  165. }
  166. else
  167. {
  168. return m_taggedCameraEntities;
  169. }
  170. }
  171. bool PostFxLayerComponentController::IsEditorView(const AZ::RPI::ViewPtr view)
  172. {
  173. return m_allCameraViews.find(view.get()) == m_allCameraViews.end() ? true : false;
  174. }
  175. bool PostFxLayerComponentController::HasTags(const AZ::EntityId& entityId, const AZStd::vector<AZStd::string>& tags) const
  176. {
  177. bool hasTag = false;
  178. for (auto tag : tags)
  179. {
  180. LmbrCentral::TagComponentRequestBus::EventResult(
  181. hasTag,
  182. entityId,
  183. &LmbrCentral::TagComponentRequests::HasTag,
  184. LmbrCentral::Tag(tag)
  185. );
  186. LmbrCentral::EditorTagComponentRequestBus::EventResult(
  187. hasTag,
  188. entityId,
  189. &LmbrCentral::EditorTagComponentRequests::HasTag,
  190. tag.c_str()
  191. );
  192. if (hasTag)
  193. {
  194. return true;
  195. }
  196. }
  197. return false;
  198. }
  199. void PostFxLayerComponentController::BusConnectToTags()
  200. {
  201. LmbrCentral::TagGlobalNotificationBus::MultiHandler::BusDisconnect();
  202. for (auto tag : m_configuration.m_cameraTags)
  203. {
  204. LmbrCentral::TagGlobalNotificationBus::MultiHandler::BusConnect(LmbrCentral::Tag(tag));
  205. }
  206. }
  207. void PostFxLayerComponentController::Activate(EntityId entityId)
  208. {
  209. m_entityId = entityId;
  210. m_featureProcessorInterface = RPI::Scene::GetFeatureProcessorForEntity<PostProcessFeatureProcessorInterface>(m_entityId);
  211. if (m_featureProcessorInterface)
  212. {
  213. m_postProcessInterface = m_featureProcessorInterface->GetOrCreateSettingsInterface(m_entityId);
  214. m_configuration.CopySettingsTo(m_postProcessInterface);
  215. }
  216. BusConnectToTags();
  217. Camera::CameraNotificationBus::Handler::BusConnect();
  218. PostFxLayerRequestBus::Handler::BusConnect(m_entityId);
  219. AZ::TickBus::Handler::BusConnect();
  220. }
  221. void PostFxLayerComponentController::Deactivate()
  222. {
  223. AZ::TickBus::Handler::BusDisconnect();
  224. PostFxLayerRequestBus::Handler::BusDisconnect(m_entityId);
  225. Camera::CameraNotificationBus::Handler::BusDisconnect();
  226. LmbrCentral::TagGlobalNotificationBus::MultiHandler::BusDisconnect();
  227. if (m_featureProcessorInterface)
  228. {
  229. m_featureProcessorInterface->RemoveSettingsInterface(m_entityId);
  230. }
  231. m_postProcessInterface = nullptr;
  232. m_featureProcessorInterface = nullptr;
  233. m_entityId.SetInvalid();
  234. }
  235. void PostFxLayerComponentController::SetConfiguration(const PostFxLayerComponentConfig& config)
  236. {
  237. m_configuration = config;
  238. }
  239. const PostFxLayerComponentConfig& PostFxLayerComponentController::GetConfiguration() const
  240. {
  241. return m_configuration;
  242. }
  243. void PostFxLayerComponentController::OnConfigChanged()
  244. {
  245. if (m_postProcessInterface)
  246. {
  247. m_configuration.CopySettingsTo(m_postProcessInterface);
  248. m_postProcessInterface->OnConfigChanged();
  249. }
  250. }
  251. // Auto-gen getter/setter function definitions...
  252. // The setter functions will set the values on the Atom settings class, then get the value back
  253. // from the settings class to set the local configuration. This is in case the settings class
  254. // applies some custom logic that results in the set value being different from the input
  255. #define AZ_GFX_COMMON_PARAM(ValueType, Name, MemberName, DefaultValue) \
  256. \
  257. ValueType PostFxLayerComponentController::Get##Name() const \
  258. { \
  259. return m_configuration.MemberName; \
  260. } \
  261. void PostFxLayerComponentController::Set##Name(ValueType val) \
  262. { \
  263. if(m_postProcessInterface) \
  264. { \
  265. m_postProcessInterface->Set##Name(val); \
  266. m_postProcessInterface->OnConfigChanged(); \
  267. m_configuration.MemberName = m_postProcessInterface->Get##Name(); \
  268. } \
  269. else \
  270. { \
  271. m_configuration.MemberName = val; \
  272. } \
  273. } \
  274. #define AZ_GFX_COMMON_OVERRIDE(ValueType, Name, MemberName, OverrideValueType) \
  275. \
  276. OverrideValueType PostFxLayerComponentController::Get##Name##Override() const \
  277. { \
  278. return m_configuration.MemberName##Override; \
  279. } \
  280. void PostFxLayerComponentController::Set##Name##Override(OverrideValueType val) \
  281. { \
  282. m_configuration.MemberName = val; \
  283. if(m_postProcessInterface) \
  284. { \
  285. m_postProcessInterface->Set##Name##Override(val); \
  286. m_postProcessInterface->OnConfigChanged(); \
  287. } \
  288. } \
  289. #include <Atom/Feature/ParamMacros/MapAllCommon.inl>
  290. #include <Atom/Feature/PostProcess/PostProcessParams.inl>
  291. #include <Atom/Feature/ParamMacros/EndParams.inl>
  292. } // namespace Render
  293. } // namespace AZ