Octree.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. #ifndef ANKI_SCENE_OCTREE_H
  2. #define ANKI_SCENE_OCTREE_H
  3. #include "anki/collision/Aabb.h"
  4. #include "anki/util/Array.h"
  5. #include "anki/scene/Common.h"
  6. #include "anki/scene/Visibility.h"
  7. #include <memory>
  8. #if ANKI_CFG_OCTREE_THREAD_SAFE
  9. # include <mutex>
  10. #endif
  11. namespace anki {
  12. // Forward
  13. class Frustumable;
  14. class SceneNode;
  15. class Octree;
  16. class Sector;
  17. /// Octree node
  18. class OctreeNode
  19. {
  20. friend class Octree;
  21. public:
  22. typedef Array<OctreeNode*, 8> ChildrenContainer;
  23. OctreeNode(const Aabb& aabb, OctreeNode* parent,
  24. const SceneAllocator<U8>& alloc);
  25. ~OctreeNode();
  26. /// @name Accessors
  27. /// @{
  28. const OctreeNode* getChild(U id) const
  29. {
  30. return children[id];
  31. }
  32. const OctreeNode* getParent() const
  33. {
  34. return parent;
  35. }
  36. const Aabb& getAabb() const
  37. {
  38. return aabb;
  39. }
  40. SceneVector<SceneNode*>::iterator getSceneNodesBegin()
  41. {
  42. return sceneNodes.begin();
  43. }
  44. SceneVector<SceneNode*>::const_iterator getSceneNodesBegin() const
  45. {
  46. return sceneNodes.begin();
  47. }
  48. SceneVector<SceneNode*>::iterator getSceneNodesEnd()
  49. {
  50. return sceneNodes.end();
  51. }
  52. SceneVector<SceneNode*>::const_iterator getSceneNodesEnd() const
  53. {
  54. return sceneNodes.end();
  55. }
  56. /// @}
  57. Bool isRoot() const
  58. {
  59. return parent == nullptr;
  60. }
  61. void removeSceneNode(SceneNode* sn);
  62. /// @{
  63. /// Will traverse to find the octree
  64. const Octree& getOctree() const;
  65. Octree& getOctree();
  66. /// @}
  67. private:
  68. ChildrenContainer children;
  69. OctreeNode* parent;
  70. Aabb aabb; ///< Including AABB
  71. SceneVector<SceneNode*> sceneNodes;
  72. #if ANKI_CFG_OCTREE_THREAD_SAFE
  73. std::mutex mtx;
  74. #endif
  75. void addSceneNode(SceneNode* sn);
  76. void addChild(U pos, OctreeNode* child);
  77. };
  78. /// Root octree node. Its seperate because it holds pointer to the octree
  79. class RootOctreeNode: public OctreeNode
  80. {
  81. friend class OctreeNode;
  82. friend class Octree;
  83. public:
  84. RootOctreeNode(const Aabb& aabb, const SceneAllocator<U8>& alloc,
  85. Octree* octree_)
  86. : OctreeNode(aabb, nullptr, alloc), octree(octree_)
  87. {
  88. ANKI_ASSERT(octree != nullptr);
  89. }
  90. private:
  91. Octree* octree;
  92. };
  93. /// Octree
  94. class Octree
  95. {
  96. public:
  97. Octree(Sector* sector, const Aabb& aabb, U8 maxDepth, F32 looseness = 1.5);
  98. ~Octree();
  99. /// @name Accessors
  100. /// @{
  101. const OctreeNode& getRoot() const
  102. {
  103. return root;
  104. }
  105. OctreeNode& getRoot()
  106. {
  107. return root;
  108. }
  109. U getMaxDepth() const
  110. {
  111. return maxDepth;
  112. }
  113. Sector& getSector()
  114. {
  115. return *sector;
  116. }
  117. const Sector& getSector() const
  118. {
  119. return *sector;
  120. }
  121. /// @}
  122. /// Place a spatial in the tree
  123. void placeSceneNode(SceneNode* sn);
  124. /// Do the visibility tests
  125. void doVisibilityTests(SceneNode& frustumableSceneNode,
  126. VisibilityTest test, VisibilityTestResults& visibles);
  127. private:
  128. Sector* sector;
  129. U maxDepth;
  130. F32 looseness;
  131. RootOctreeNode root;
  132. OctreeNode* placeInternal(const Aabb& aabb, U depth, OctreeNode& node);
  133. /// Place an AABB inside the tree. The algorithm is pretty simple, find the
  134. /// node that completely includes the aabb. If found then go deeper into
  135. /// the node's children. The aabb will not be in more than one nodes. Also,
  136. /// if it is ourside the tree then return nullptr
  137. OctreeNode* place(const Aabb& aabb);
  138. /// Recursive method
  139. void doVisibilityTestsInternal(
  140. SceneNode& frustumableSceneNode,
  141. VisibilityTest test,
  142. VisibilityTestResults& visibles,
  143. OctreeNode& node);
  144. void createChildren(OctreeNode& parent);
  145. /// Calculate the AABB of a child given the parent's AABB and its
  146. /// position
  147. /// @param[in] i 0: left, 1: right
  148. /// @param[in] j 0: down, 1: up
  149. /// @param[in] k 0: back, 1: front
  150. /// @param[in] parentAabb The parent's AABB
  151. /// @param[out] out The out AABB
  152. void calcAabb(U i, U j, U k, const Aabb& parentAabb, Aabb& out) const;
  153. };
  154. } // end namespace anki
  155. #endif