FogDensityComponent.h 2.5 KB

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