FogDensityComponent.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <AnKi/Scene/Components/SceneComponent.h>
  7. #include <AnKi/Renderer/RenderQueue.h>
  8. #include <AnKi/Collision/Aabb.h>
  9. #include <AnKi/Collision/Sphere.h>
  10. namespace anki
  11. {
  12. /// @addtogroup scene
  13. /// @{
  14. /// Fog density component. Controls the fog density.
  15. class FogDensityComponent : public SceneComponent
  16. {
  17. ANKI_SCENE_COMPONENT(FogDensityComponent)
  18. public:
  19. static constexpr F32 MIN_SHAPE_SIZE = 1.0_cm;
  20. FogDensityComponent(SceneNode* node)
  21. : SceneComponent(node, getStaticClassId())
  22. , m_isBox(true)
  23. , m_markedForUpdate(true)
  24. {
  25. }
  26. void setBoxVolumeSize(Vec3 sizeXYZ)
  27. {
  28. sizeXYZ = sizeXYZ.max(Vec3(MIN_SHAPE_SIZE));
  29. m_aabbMin = -sizeXYZ / 2.0f;
  30. m_aabbMax = sizeXYZ / 2.0f;
  31. m_isBox = true;
  32. m_markedForUpdate = true;
  33. }
  34. Vec3 getBoxVolumeSize() const
  35. {
  36. ANKI_ASSERT(isAabb());
  37. return m_aabbMax.xyz() - m_aabbMin.xyz();
  38. }
  39. Aabb getAabbWorldSpace() const
  40. {
  41. ANKI_ASSERT(isAabb());
  42. return Aabb(m_aabbMin + m_worldPos, m_aabbMax + m_worldPos);
  43. }
  44. void setSphereVolumeRadius(F32 radius)
  45. {
  46. m_sphereRadius = max(MIN_SHAPE_SIZE, radius);
  47. m_isBox = false;
  48. m_markedForUpdate = true;
  49. }
  50. F32 getSphereVolumeRadius() const
  51. {
  52. ANKI_ASSERT(isSphere());
  53. return m_sphereRadius;
  54. }
  55. Sphere getSphereWorldSpace() const
  56. {
  57. ANKI_ASSERT(isSphere());
  58. return Sphere(m_worldPos, m_sphereRadius);
  59. }
  60. Bool isAabb() const
  61. {
  62. return m_isBox == true;
  63. }
  64. Bool isSphere() const
  65. {
  66. return !m_isBox;
  67. }
  68. void setDensity(F32 d)
  69. {
  70. ANKI_ASSERT(d >= 0.0f);
  71. m_density = d;
  72. }
  73. F32 getDensity() const
  74. {
  75. return m_density;
  76. }
  77. void setWorldPosition(const Vec3& pos)
  78. {
  79. m_worldPos = pos;
  80. m_markedForUpdate = true;
  81. }
  82. void setupFogDensityQueueElement(FogDensityQueueElement& el) const
  83. {
  84. el.m_density = m_density;
  85. el.m_isBox = m_isBox;
  86. if(m_isBox)
  87. {
  88. el.m_aabbMin = (m_aabbMin + m_worldPos).xyz();
  89. el.m_aabbMax = (m_aabbMax + m_worldPos).xyz();
  90. }
  91. else
  92. {
  93. el.m_sphereCenter = m_worldPos.xyz();
  94. el.m_sphereRadius = m_sphereRadius;
  95. }
  96. }
  97. Error update(SceneNode& node, Second prevTime, Second crntTime, Bool& updated) override
  98. {
  99. updated = m_markedForUpdate;
  100. m_markedForUpdate = false;
  101. return Error::NONE;
  102. }
  103. private:
  104. Vec3 m_aabbMin = Vec3(0.0f);
  105. union
  106. {
  107. Vec3 m_aabbMax = Vec3(1.0f);
  108. F32 m_sphereRadius;
  109. };
  110. Vec3 m_worldPos = Vec3(0.0f);
  111. F32 m_density = 1.0f;
  112. Bool m_isBox : 1;
  113. Bool m_markedForUpdate : 1;
  114. };
  115. } // end namespace anki