AABBTreeBuilder.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. // Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
  2. // SPDX-FileCopyrightText: 2021 Jorrit Rouwe
  3. // SPDX-License-Identifier: MIT
  4. #pragma once
  5. #include <Jolt/TriangleSplitter/TriangleSplitter.h>
  6. #include <Jolt/Geometry/AABox.h>
  7. #include <Jolt/Core/NonCopyable.h>
  8. JPH_NAMESPACE_BEGIN
  9. struct AABBTreeBuilderStats
  10. {
  11. ///@name Splitter stats
  12. TriangleSplitter::Stats mSplitterStats; ///< Stats returned by the triangle splitter algorithm
  13. ///@name Tree structure
  14. float mSAHCost = 0.0f; ///< Surface Area Heuristic cost of this tree
  15. int mMinDepth = 0; ///< Minimal depth of tree (number of nodes)
  16. int mMaxDepth = 0; ///< Maximum depth of tree (number of nodes)
  17. int mNodeCount = 0; ///< Number of nodes in the tree
  18. int mLeafNodeCount = 0; ///< Number of leaf nodes (that contain triangles)
  19. ///@name Configured stats
  20. int mMaxTrianglesPerLeaf = 0; ///< Configured max triangles per leaf
  21. ///@name Actual stats
  22. int mTreeMinTrianglesPerLeaf = 0; ///< Minimal amount of triangles in a leaf
  23. int mTreeMaxTrianglesPerLeaf = 0; ///< Maximal amount of triangles in a leaf
  24. float mTreeAvgTrianglesPerLeaf = 0.0f; ///< Average amount of triangles in leaf nodes
  25. };
  26. /// Helper class to build an AABB tree
  27. class JPH_EXPORT AABBTreeBuilder
  28. {
  29. public:
  30. /// A node in the tree, contains the AABox for the tree and any child nodes or triangles
  31. class Node
  32. {
  33. public:
  34. JPH_OVERRIDE_NEW_DELETE
  35. /// Indicates that there is no child
  36. static constexpr uint cInvalidNodeIndex = ~uint(0);
  37. /// Get number of triangles in this node
  38. inline uint GetTriangleCount() const { return mNumTriangles; }
  39. /// Check if this node has any children
  40. inline bool HasChildren() const { return mChild[0] != cInvalidNodeIndex || mChild[1] != cInvalidNodeIndex; }
  41. /// Get child node
  42. inline const Node * GetChild(uint inIdx, const Array<Node> &inNodes) const { return mChild[inIdx] != cInvalidNodeIndex? &inNodes[mChild[inIdx]] : nullptr; }
  43. /// Min depth of tree
  44. uint GetMinDepth(const Array<Node> &inNodes) const;
  45. /// Max depth of tree
  46. uint GetMaxDepth(const Array<Node> &inNodes) const;
  47. /// Number of nodes in tree
  48. uint GetNodeCount(const Array<Node> &inNodes) const;
  49. /// Number of leaf nodes in tree
  50. uint GetLeafNodeCount(const Array<Node> &inNodes) const;
  51. /// Get triangle count in tree
  52. uint GetTriangleCountInTree(const Array<Node> &inNodes) const;
  53. /// Calculate min and max triangles per node
  54. void GetTriangleCountPerNode(const Array<Node> &inNodes, float &outAverage, uint &outMin, uint &outMax) const;
  55. /// Calculate the total cost of the tree using the surface area heuristic
  56. float CalculateSAHCost(const Array<Node> &inNodes, float inCostTraversal, float inCostLeaf) const;
  57. /// Recursively get children (breadth first) to get in total inN children (or less if there are no more)
  58. void GetNChildren(const Array<Node> &inNodes, uint inN, Array<const Node *> &outChildren) const;
  59. /// Bounding box
  60. AABox mBounds;
  61. /// Triangles (if no child nodes)
  62. uint mTrianglesBegin; // Index into mTriangles
  63. uint mNumTriangles = 0;
  64. /// Child node indices (if no triangles)
  65. uint mChild[2] = { cInvalidNodeIndex, cInvalidNodeIndex };
  66. private:
  67. friend class AABBTreeBuilder;
  68. /// Recursive helper function to calculate cost of the tree
  69. float CalculateSAHCostInternal(const Array<Node> &inNodes, float inCostTraversalDivSurfaceArea, float inCostLeafDivSurfaceArea) const;
  70. /// Recursive helper function to calculate min and max triangles per node
  71. void GetTriangleCountPerNodeInternal(const Array<Node> &inNodes, float &outAverage, uint &outAverageDivisor, uint &outMin, uint &outMax) const;
  72. };
  73. /// Constructor
  74. explicit AABBTreeBuilder(TriangleSplitter &inSplitter, uint inMaxTrianglesPerLeaf = 16);
  75. /// Recursively build tree, returns the root node of the tree
  76. Node * Build(AABBTreeBuilderStats &outStats);
  77. /// Get all nodes
  78. const Array<Node> & GetNodes() const { return mNodes; }
  79. /// Get all triangles
  80. const Array<IndexedTriangle> &GetTriangles() const { return mTriangles; }
  81. private:
  82. uint BuildInternal(const TriangleSplitter::Range &inTriangles);
  83. TriangleSplitter & mTriangleSplitter;
  84. const uint mMaxTrianglesPerLeaf;
  85. Array<Node> mNodes;
  86. Array<IndexedTriangle> mTriangles;
  87. };
  88. JPH_NAMESPACE_END