3
0

PolygonLightDelegate.cpp 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  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. #include <AtomLyIntegration/CommonFeatures/CoreLights/AreaLightComponentConfig.h>
  10. #include <CoreLights/PolygonLightDelegate.h>
  11. namespace AZ::Render
  12. {
  13. PolygonLightDelegate::PolygonLightDelegate(LmbrCentral::PolygonPrismShapeComponentRequests* shapeBus, EntityId entityId, bool isVisible)
  14. : LightDelegateBase<PolygonLightFeatureProcessorInterface>(entityId, isVisible)
  15. , m_shapeBus(shapeBus)
  16. {
  17. InitBase(entityId);
  18. shapeBus->SetHeight(0.0f);
  19. }
  20. void PolygonLightDelegate::SetLightEmitsBothDirections(bool lightEmitsBothDirections)
  21. {
  22. if (GetLightHandle().IsValid())
  23. {
  24. GetFeatureProcessor()->SetLightEmitsBothDirections(GetLightHandle(), lightEmitsBothDirections);
  25. }
  26. }
  27. float PolygonLightDelegate::CalculateAttenuationRadius(float lightThreshold) const
  28. {
  29. // Calculate the radius at which the irradiance will be equal to cutoffIntensity.
  30. const float intensity = GetPhotometricValue().GetCombinedIntensity(PhotometricUnit::Lumen);
  31. return Sqrt(intensity / lightThreshold);
  32. }
  33. void PolygonLightDelegate::HandleShapeChanged()
  34. {
  35. if (GetLightHandle().IsValid())
  36. {
  37. GetFeatureProcessor()->SetPosition(GetLightHandle(), GetTransform().GetTranslation());
  38. AZStd::vector<Vector2> vertices = m_shapeBus->GetPolygonPrism()->m_vertexContainer.GetVertices();
  39. Transform transform = GetTransform();
  40. transform.SetUniformScale(transform.GetUniformScale()); // Polygon Prism only supports uniform scale.
  41. AZStd::vector<Vector3> transformedVertices;
  42. transformedVertices.reserve(vertices.size());
  43. for (const Vector2& vertex : vertices)
  44. {
  45. transformedVertices.push_back(transform.TransformPoint(Vector3(vertex, 0.0f)));
  46. }
  47. GetFeatureProcessor()->SetPolygonPoints(
  48. GetLightHandle(),
  49. transformedVertices.data(),
  50. static_cast<uint32_t>(transformedVertices.size()),
  51. GetTransform().GetBasisZ());
  52. }
  53. }
  54. float PolygonLightDelegate::GetSurfaceArea() const
  55. {
  56. // Surprisingly simple to calculate area of arbitrary polygon assuming no self-intersection. See
  57. // https://en.wikipedia.org/wiki/Shoelace_formula
  58. float twiceArea = 0.0f;
  59. AZStd::vector<Vector2> vertices = m_shapeBus->GetPolygonPrism()->m_vertexContainer.GetVertices();
  60. for (size_t i = 0; i < vertices.size(); ++i)
  61. {
  62. size_t j = (i + 1) % vertices.size();
  63. twiceArea += vertices.at(i).GetX() * vertices.at(j).GetY();
  64. twiceArea -= vertices.at(i).GetY() * vertices.at(j).GetX();
  65. }
  66. float scale = GetTransform().GetUniformScale();
  67. return GetAbs(twiceArea * 0.5f * scale * scale);
  68. }
  69. void PolygonLightDelegate::DrawDebugDisplay(
  70. const Transform& transform, const Color& color, AzFramework::DebugDisplayRequests& debugDisplay, bool isSelected) const
  71. {
  72. if (isSelected)
  73. {
  74. debugDisplay.SetColor(color);
  75. // Draw a Polygon for the attenuation radius
  76. debugDisplay.DrawWireSphere(transform.GetTranslation(), GetConfig()->m_attenuationRadius);
  77. debugDisplay.DrawArrow(transform.GetTranslation(), transform.GetTranslation() + transform.GetBasisZ());
  78. }
  79. }
  80. Aabb PolygonLightDelegate::GetLocalVisualizationBounds() const
  81. {
  82. return Aabb::CreateCenterRadius(Vector3::CreateZero(), GetConfig()->m_attenuationRadius);
  83. }
  84. } // namespace AZ::Render