Octree.h 3.7 KB

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