Clusterer.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. // Copyright (C) 2009-2015, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/renderer/Common.h>
  7. #include <anki/Math.h>
  8. #include <anki/collision/Aabb.h>
  9. #include <anki/core/Timestamp.h>
  10. namespace anki {
  11. class FrustumComponent;
  12. class SceneNode;
  13. /// @addtogroup renderer
  14. /// @{
  15. /// The result of the cluster tests.
  16. class ClustererTestResult
  17. {
  18. friend class Clusterer;
  19. public:
  20. ClustererTestResult()
  21. {}
  22. ~ClustererTestResult()
  23. {
  24. m_clusterIds.destroy(m_alloc);
  25. }
  26. DArray<Array<U8, 3>>::ConstIterator getClustersBegin() const
  27. {
  28. return m_clusterIds.getBegin();
  29. }
  30. DArray<Array<U8, 3>>::ConstIterator getClustersEnd() const
  31. {
  32. return m_clusterIds.getBegin() + m_count;
  33. }
  34. U getClusterCount() const
  35. {
  36. return m_count;
  37. }
  38. private:
  39. DArray<Array<U8, 3>> m_clusterIds;
  40. U32 m_count = 0;
  41. GenericMemoryPoolAllocator<U8> m_alloc;
  42. void pushBack(U x, U y, U z)
  43. {
  44. ANKI_ASSERT(x <= 0xFF && y <= 0xFF && z <= 0xFF);
  45. m_clusterIds[m_count++] = Array<U8, 3>{U8(x), U8(y), U8(z)};
  46. }
  47. };
  48. /// Collection of clusters for visibility tests.
  49. class Clusterer
  50. {
  51. friend class UpdatePlanesPerspectiveCameraTask;
  52. public:
  53. Clusterer()
  54. {}
  55. ~Clusterer();
  56. void init(const GenericMemoryPoolAllocator<U8>& alloc, U clusterCountX,
  57. U clusterCountY, U clusterCountZ);
  58. /// Prepare for visibility tests.
  59. void prepare(ThreadPool& threadpool, const FrustumComponent& frc);
  60. void initTestResults(const GenericMemoryPoolAllocator<U8>& alloc,
  61. ClustererTestResult& rez) const;
  62. /// Bin collision shape.
  63. void bin(const CollisionShape& cs, const Aabb& csBox,
  64. ClustererTestResult& rez) const;
  65. F32 getDivisor() const
  66. {
  67. return m_calcNearOpt;
  68. }
  69. U getClusterCountX() const
  70. {
  71. return m_counts[0];
  72. }
  73. U getClusterCountY() const
  74. {
  75. return m_counts[1];
  76. }
  77. U getClusterCountZ() const
  78. {
  79. return m_counts[2];
  80. }
  81. U getClusterCount() const
  82. {
  83. return m_counts[0] * m_counts[1] * m_counts[2];
  84. }
  85. public:
  86. GenericMemoryPoolAllocator<U8> m_alloc;
  87. Array<U8, 3> m_counts;
  88. /// Tile planes.
  89. DArray<Plane> m_allPlanes; ///< Do one allocation.
  90. SArray<Plane> m_planesY; ///< Local space.
  91. SArray<Plane> m_planesX; ///< Local space.
  92. SArray<Plane> m_planesYW;
  93. SArray<Plane> m_planesXW;
  94. Plane* m_nearPlane; ///< In world space
  95. Plane* m_farPlane; ///< In world space
  96. /// Used to check if the frustum is changed and we need to update the
  97. /// planes.
  98. const SceneNode* m_node = nullptr;
  99. const FrustumComponent* m_frc = nullptr; ///< Cache it.
  100. /// Timestamp for the same reason as m_frc.
  101. Timestamp m_planesLSpaceTimestamp = 0;
  102. F32 m_near = 0.0;
  103. F32 m_far = 0.0;
  104. F32 m_calcNearOpt = 0.0;
  105. F32 calcNear(U k) const;
  106. U calcZ(F32 zVspace) const;
  107. void binGeneric(const CollisionShape& cs, U xBegin, U xEnd, U yBegin,
  108. U yEnd, U zBegin, U zEnd, ClustererTestResult& rez) const;
  109. /// Special fast path for binning spheres.
  110. void binSphere(const Sphere& s, const Aabb& aabb,
  111. ClustererTestResult& rez) const;
  112. void computeSplitRange(const CollisionShape& cs, U& zBegin, U& zEnd) const;
  113. void update(U32 threadId, PtrSize threadsCount, Bool frustumChanged);
  114. /// Calculate and set a top looking plane.
  115. void calcPlaneY(U i, const Vec4& projParams);
  116. /// Calculate and set a right looking plane.
  117. void calcPlaneX(U j, const Vec4& projParams);
  118. /// Call this when a shape is visible by all tiles.
  119. void totallyInsideAllTiles(U zBegin, U zEnd, ClustererTestResult& rez) const;
  120. };
  121. /// @}
  122. } // end namespace anki