LightDelegateBase.inl 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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/RPI.Public/Scene.h>
  9. namespace AZ
  10. {
  11. namespace Render
  12. {
  13. template <typename FeatureProcessorType>
  14. LightDelegateBase<FeatureProcessorType>::LightDelegateBase(EntityId entityId, bool isVisible)
  15. {
  16. m_featureProcessor = RPI::Scene::GetFeatureProcessorForEntity<FeatureProcessorType>(entityId);
  17. AZ_Error("LightDelegateBase", m_featureProcessor, "Unable to find a %s on the scene.", FeatureProcessorType::RTTI_TypeName());
  18. if (m_featureProcessor && isVisible)
  19. {
  20. m_lightHandle = m_featureProcessor->AcquireLight();
  21. }
  22. }
  23. template <typename FeatureProcessorType>
  24. LightDelegateBase<FeatureProcessorType>::~LightDelegateBase()
  25. {
  26. TransformNotificationBus::Handler::BusDisconnect();
  27. LmbrCentral::ShapeComponentNotificationsBus::Handler::BusDisconnect();
  28. if (m_lightHandle.IsValid())
  29. {
  30. m_featureProcessor->ReleaseLight(m_lightHandle);
  31. }
  32. }
  33. template <typename FeatureProcessorType>
  34. void LightDelegateBase<FeatureProcessorType>::InitBase(EntityId entityId)
  35. {
  36. m_photometricValue.SetEffectiveSolidAngle(GetEffectiveSolidAngle());
  37. m_shapeBus = LmbrCentral::ShapeComponentRequestsBus::FindFirstHandler(entityId);
  38. AZ::Transform entityTransform = AZ::Transform::CreateIdentity();
  39. TransformBus::EventResult(entityTransform, entityId, &TransformBus::Events::GetWorldTM);
  40. m_transform = ComputeOverallTransform(entityTransform);
  41. if (m_shapeBus != nullptr)
  42. {
  43. LmbrCentral::ShapeComponentNotificationsBus::Handler::BusConnect(entityId);
  44. OnShapeChanged(ShapeChangeReasons::TransformChanged);
  45. }
  46. else if (m_lightHandle.IsValid())
  47. {
  48. // Only connect to the transform bus if there's no shape bus, otherwise the shape bus handles transforms.
  49. TransformNotificationBus::Handler::BusConnect(entityId);
  50. HandleShapeChanged();
  51. m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
  52. }
  53. }
  54. template <typename FeatureProcessorType>
  55. void LightDelegateBase<FeatureProcessorType>::SetConfig(const AreaLightComponentConfig* config)
  56. {
  57. m_componentConfig = config;
  58. }
  59. template <typename FeatureProcessorType>
  60. void LightDelegateBase<FeatureProcessorType>::SetChroma(const Color& color)
  61. {
  62. m_photometricValue.SetChroma(color);
  63. if (m_lightHandle.IsValid())
  64. {
  65. m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
  66. }
  67. }
  68. template <typename FeatureProcessorType>
  69. void LightDelegateBase<FeatureProcessorType>::SetIntensity(float intensity)
  70. {
  71. m_photometricValue.SetIntensity(intensity);
  72. if (m_lightHandle.IsValid())
  73. {
  74. m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
  75. }
  76. }
  77. template <typename FeatureProcessorType>
  78. float LightDelegateBase<FeatureProcessorType>::SetPhotometricUnit(PhotometricUnit unit)
  79. {
  80. m_photometricValue.SetArea(GetSurfaceArea());
  81. m_photometricValue.ConvertToPhotometricUnit(unit);
  82. if (m_lightHandle.IsValid())
  83. {
  84. m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
  85. }
  86. return m_photometricValue.GetIntensity();
  87. }
  88. template <typename FeatureProcessorType>
  89. void LightDelegateBase<FeatureProcessorType>::OnShapeChanged([[maybe_unused]] ShapeChangeReasons changeReason)
  90. {
  91. AZ_Assert(m_shapeBus, "OnShapeChanged called without a shape bus present.");
  92. // need to update the overall transform whether the change reason is TransformChanged or ShapeChanged, because changes to the
  93. // translation offset trigger the event with ShapeChanged
  94. Aabb aabb; // unused, but required for GetTransformAndLocalBounds()
  95. AZ::Transform entityTransform = AZ::Transform::CreateIdentity();
  96. m_shapeBus->GetTransformAndLocalBounds(entityTransform, aabb);
  97. m_transform = ComputeOverallTransform(entityTransform);
  98. m_photometricValue.SetArea(GetSurfaceArea());
  99. if (m_lightHandle.IsValid())
  100. {
  101. m_featureProcessor->SetRgbIntensity(m_lightHandle, m_photometricValue.GetCombinedRgb<FeatureProcessorType::PhotometricUnitType>());
  102. }
  103. HandleShapeChanged();
  104. }
  105. template <typename FeatureProcessorType>
  106. void LightDelegateBase<FeatureProcessorType>::OnTransformChanged(const Transform& /*local*/, const Transform& world)
  107. {
  108. m_transform = ComputeOverallTransform(world);
  109. HandleShapeChanged();
  110. }
  111. template <typename FeatureProcessorType>
  112. AZ::Transform LightDelegateBase<FeatureProcessorType>::ComputeOverallTransform(const Transform& world)
  113. {
  114. const AZ::Vector3 translationOffset = m_shapeBus ? m_shapeBus->GetTranslationOffset() : AZ::Vector3::CreateZero();
  115. return world * AZ::Transform::CreateTranslation(translationOffset);
  116. }
  117. template <typename FeatureProcessorType>
  118. void LightDelegateBase<FeatureProcessorType>::SetVisibility(bool isVisible)
  119. {
  120. if (m_lightHandle.IsValid() && !isVisible)
  121. {
  122. // no longer visible, release light handle
  123. m_featureProcessor->ReleaseLight(m_lightHandle);
  124. }
  125. else if (!m_lightHandle.IsValid() && isVisible && m_featureProcessor)
  126. {
  127. // now visible, acquire light handle and update values.
  128. m_lightHandle = m_featureProcessor->AcquireLight();
  129. if (m_shapeBus)
  130. {
  131. // For lights that get their transform from the shape bus, force an OnShapeChanged to update the transform.
  132. OnShapeChanged(ShapeChangeReasons::TransformChanged);
  133. }
  134. else
  135. {
  136. // OnShapeChanged() already calls this for delegates with a shape bus
  137. HandleShapeChanged();
  138. }
  139. }
  140. }
  141. template <typename FeatureProcessorType>
  142. void LightDelegateBase<FeatureProcessorType>::SetAttenuationRadius(float radius)
  143. {
  144. if (m_lightHandle.IsValid())
  145. {
  146. m_featureProcessor->SetAttenuationRadius(m_lightHandle, radius);
  147. }
  148. }
  149. template<typename FeatureProcessorType>
  150. void LightDelegateBase<FeatureProcessorType>::SetLightingChannelMask(uint32_t lightingChannelMask)
  151. {
  152. if (m_lightHandle.IsValid())
  153. {
  154. m_featureProcessor->SetLightingChannelMask(m_lightHandle, lightingChannelMask);
  155. }
  156. }
  157. }
  158. }