88
99JPH_NAMESPACE_BEGIN
1010
11- AABBTreeBuilder::Node::Node ()
12- {
13- mChild [0 ] = nullptr ;
14- mChild [1 ] = nullptr ;
15- }
16-
17- AABBTreeBuilder::Node::~Node ()
18- {
19- delete mChild [0 ];
20- delete mChild [1 ];
21- }
22-
23- uint AABBTreeBuilder::Node::GetMinDepth () const
11+ uint AABBTreeBuilder::Node::GetMinDepth (const Array<Node> &inNodes) const
2412{
2513 if (HasChildren ())
2614 {
27- uint left = mChild [0 ]-> GetMinDepth ();
28- uint right = mChild [1 ]-> GetMinDepth ();
15+ uint left = inNodes[ mChild [0 ]]. GetMinDepth (inNodes );
16+ uint right = inNodes[ mChild [1 ]]. GetMinDepth (inNodes );
2917 return min (left, right) + 1 ;
3018 }
3119 else
3220 return 1 ;
3321}
3422
35- uint AABBTreeBuilder::Node::GetMaxDepth () const
23+ uint AABBTreeBuilder::Node::GetMaxDepth (const Array<Node> &inNodes ) const
3624{
3725 if (HasChildren ())
3826 {
39- uint left = mChild [0 ]-> GetMaxDepth ();
40- uint right = mChild [1 ]-> GetMaxDepth ();
27+ uint left = inNodes[ mChild [0 ]]. GetMaxDepth (inNodes );
28+ uint right = inNodes[ mChild [1 ]]. GetMaxDepth (inNodes );
4129 return max (left, right) + 1 ;
4230 }
4331 else
4432 return 1 ;
4533}
4634
47- uint AABBTreeBuilder::Node::GetNodeCount () const
35+ uint AABBTreeBuilder::Node::GetNodeCount (const Array<Node> &inNodes ) const
4836{
4937 if (HasChildren ())
50- return mChild [0 ]-> GetNodeCount () + mChild [1 ]-> GetNodeCount () + 1 ;
38+ return inNodes[ mChild [0 ]]. GetNodeCount (inNodes ) + inNodes[ mChild [1 ]]. GetNodeCount (inNodes ) + 1 ;
5139 else
5240 return 1 ;
5341}
5442
55- uint AABBTreeBuilder::Node::GetLeafNodeCount () const
43+ uint AABBTreeBuilder::Node::GetLeafNodeCount (const Array<Node> &inNodes ) const
5644{
5745 if (HasChildren ())
58- return mChild [0 ]-> GetLeafNodeCount () + mChild [1 ]-> GetLeafNodeCount ();
46+ return inNodes[ mChild [0 ]]. GetLeafNodeCount (inNodes ) + inNodes[ mChild [1 ]]. GetLeafNodeCount (inNodes );
5947 else
6048 return 1 ;
6149}
6250
63- uint AABBTreeBuilder::Node::GetTriangleCountInTree () const
51+ uint AABBTreeBuilder::Node::GetTriangleCountInTree (const Array<Node> &inNodes ) const
6452{
6553 if (HasChildren ())
66- return mChild [0 ]-> GetTriangleCountInTree () + mChild [1 ]-> GetTriangleCountInTree ();
54+ return inNodes[ mChild [0 ]]. GetTriangleCountInTree (inNodes ) + inNodes[ mChild [1 ]]. GetTriangleCountInTree (inNodes );
6755 else
6856 return GetTriangleCount ();
6957}
7058
71- void AABBTreeBuilder::Node::GetTriangleCountPerNode (float &outAverage, uint &outMin, uint &outMax) const
59+ void AABBTreeBuilder::Node::GetTriangleCountPerNode (const Array<Node> &inNodes, float &outAverage, uint &outMin, uint &outMax) const
7260{
7361 outMin = INT_MAX;
7462 outMax = 0 ;
7563 outAverage = 0 ;
7664 uint avg_divisor = 0 ;
77- GetTriangleCountPerNodeInternal (outAverage, avg_divisor, outMin, outMax);
65+ GetTriangleCountPerNodeInternal (inNodes, outAverage, avg_divisor, outMin, outMax);
7866 if (avg_divisor > 0 )
7967 outAverage /= avg_divisor;
8068}
8169
82- float AABBTreeBuilder::Node::CalculateSAHCost (float inCostTraversal, float inCostLeaf) const
70+ float AABBTreeBuilder::Node::CalculateSAHCost (const Array<Node> &inNodes, float inCostTraversal, float inCostLeaf) const
8371{
8472 float surface_area = mBounds .GetSurfaceArea ();
85- return surface_area > 0 .0f ? CalculateSAHCostInternal (inCostTraversal / surface_area, inCostLeaf / surface_area) : 0 .0f ;
73+ return surface_area > 0 .0f ? CalculateSAHCostInternal (inNodes, inCostTraversal / surface_area, inCostLeaf / surface_area) : 0 .0f ;
8674}
8775
88- void AABBTreeBuilder::Node::GetNChildren (uint inN, Array<const Node *> &outChildren) const
76+ void AABBTreeBuilder::Node::GetNChildren (const Array<Node> &inNodes, uint inN, Array<const Node*> &outChildren) const
8977{
9078 JPH_ASSERT (outChildren.empty ());
9179
@@ -94,8 +82,8 @@ void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChild
9482 return ;
9583
9684 // Start with the children of this node
97- outChildren.push_back (mChild [0 ]);
98- outChildren.push_back (mChild [1 ]);
85+ outChildren.push_back (&inNodes[ mChild [0 ] ]);
86+ outChildren.push_back (&inNodes[ mChild [1 ] ]);
9987
10088 size_t next = 0 ;
10189 bool all_triangles = true ;
@@ -116,8 +104,8 @@ void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChild
116104 if (to_expand->HasChildren ())
117105 {
118106 outChildren.erase (outChildren.begin () + next);
119- outChildren.push_back (to_expand->mChild [0 ]);
120- outChildren.push_back (to_expand->mChild [1 ]);
107+ outChildren.push_back (&inNodes[ to_expand->mChild [0 ] ]);
108+ outChildren.push_back (&inNodes[ to_expand->mChild [1 ] ]);
121109 all_triangles = false ;
122110 }
123111 else
@@ -127,22 +115,22 @@ void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChild
127115 }
128116}
129117
130- float AABBTreeBuilder::Node::CalculateSAHCostInternal (float inCostTraversalDivSurfaceArea, float inCostLeafDivSurfaceArea) const
118+ float AABBTreeBuilder::Node::CalculateSAHCostInternal (const Array<Node> &inNodes, float inCostTraversalDivSurfaceArea, float inCostLeafDivSurfaceArea) const
131119{
132120 if (HasChildren ())
133121 return inCostTraversalDivSurfaceArea * mBounds .GetSurfaceArea ()
134- + mChild [0 ]-> CalculateSAHCostInternal (inCostTraversalDivSurfaceArea, inCostLeafDivSurfaceArea)
135- + mChild [1 ]-> CalculateSAHCostInternal (inCostTraversalDivSurfaceArea, inCostLeafDivSurfaceArea);
122+ + inNodes[ mChild [0 ]]. CalculateSAHCostInternal (inNodes, inCostTraversalDivSurfaceArea, inCostLeafDivSurfaceArea)
123+ + inNodes[ mChild [1 ]]. CalculateSAHCostInternal (inNodes, inCostTraversalDivSurfaceArea, inCostLeafDivSurfaceArea);
136124 else
137125 return inCostLeafDivSurfaceArea * mBounds .GetSurfaceArea () * GetTriangleCount ();
138126}
139127
140- void AABBTreeBuilder::Node::GetTriangleCountPerNodeInternal (float &outAverage, uint &outAverageDivisor, uint &outMin, uint &outMax) const
128+ void AABBTreeBuilder::Node::GetTriangleCountPerNodeInternal (const Array<Node> &inNodes, float &outAverage, uint &outAverageDivisor, uint &outMin, uint &outMax) const
141129{
142130 if (HasChildren ())
143131 {
144- mChild [0 ]-> GetTriangleCountPerNodeInternal (outAverage, outAverageDivisor, outMin, outMax);
145- mChild [1 ]-> GetTriangleCountPerNodeInternal (outAverage, outAverageDivisor, outMin, outMax);
132+ inNodes[ mChild [0 ]]. GetTriangleCountPerNodeInternal (inNodes, outAverage, outAverageDivisor, outMin, outMax);
133+ inNodes[ mChild [1 ]]. GetTriangleCountPerNodeInternal (inNodes, outAverage, outAverageDivisor, outMin, outMax);
146134 }
147135 else
148136 {
@@ -162,28 +150,36 @@ AABBTreeBuilder::AABBTreeBuilder(TriangleSplitter &inSplitter, uint inMaxTriangl
162150AABBTreeBuilder::Node *AABBTreeBuilder::Build (AABBTreeBuilderStats &outStats)
163151{
164152 TriangleSplitter::Range initial = mTriangleSplitter .GetInitialRange ();
165- Node *root = BuildInternal (initial);
166153
154+ // Worst case for number of nodes: 1 leaf node per triangle. At each level above, the number of nodes is half that of the level below.
155+ // This means that at most we'll be allocating 2x the number of triangles in nodes.
156+ mNodes .reserve (2 * initial.Count ());
157+ mTriangles .reserve (initial.Count ());
158+
159+ // Build the tree
160+ Node &root = mNodes [BuildInternal (initial)];
161+
162+ // Collect stats
167163 float avg_triangles_per_leaf;
168164 uint min_triangles_per_leaf, max_triangles_per_leaf;
169- root-> GetTriangleCountPerNode (avg_triangles_per_leaf, min_triangles_per_leaf, max_triangles_per_leaf);
165+ root. GetTriangleCountPerNode (mNodes , avg_triangles_per_leaf, min_triangles_per_leaf, max_triangles_per_leaf);
170166
171167 mTriangleSplitter .GetStats (outStats.mSplitterStats );
172168
173- outStats.mSAHCost = root-> CalculateSAHCost (1 .0f , 1 .0f );
174- outStats.mMinDepth = root-> GetMinDepth ();
175- outStats.mMaxDepth = root-> GetMaxDepth ();
176- outStats.mNodeCount = root-> GetNodeCount ();
177- outStats.mLeafNodeCount = root-> GetLeafNodeCount ();
169+ outStats.mSAHCost = root. CalculateSAHCost (mNodes , 1 .0f , 1 .0f );
170+ outStats.mMinDepth = root. GetMinDepth (mNodes );
171+ outStats.mMaxDepth = root. GetMaxDepth (mNodes );
172+ outStats.mNodeCount = root. GetNodeCount (mNodes );
173+ outStats.mLeafNodeCount = root. GetLeafNodeCount (mNodes );
178174 outStats.mMaxTrianglesPerLeaf = mMaxTrianglesPerLeaf ;
179175 outStats.mTreeMinTrianglesPerLeaf = min_triangles_per_leaf;
180176 outStats.mTreeMaxTrianglesPerLeaf = max_triangles_per_leaf;
181177 outStats.mTreeAvgTrianglesPerLeaf = avg_triangles_per_leaf;
182178
183- return root;
179+ return & root;
184180}
185181
186- AABBTreeBuilder::Node * AABBTreeBuilder::BuildInternal (const TriangleSplitter::Range &inTriangles)
182+ uint AABBTreeBuilder::BuildInternal (const TriangleSplitter::Range &inTriangles)
187183{
188184 // Check if there are too many triangles left
189185 if (inTriangles.Count () > mMaxTrianglesPerLeaf )
@@ -214,26 +210,33 @@ AABBTreeBuilder::Node *AABBTreeBuilder::BuildInternal(const TriangleSplitter::Ra
214210 }
215211
216212 // Recursively build
217- Node *node = new Node ();
218- node->mChild [0 ] = BuildInternal (left);
219- node->mChild [1 ] = BuildInternal (right);
220- node->mBounds = node->mChild [0 ]->mBounds ;
221- node->mBounds .Encapsulate (node->mChild [1 ]->mBounds );
222- return node;
213+ const uint node_index = (uint)mNodes .size ();
214+ mNodes .push_back (Node ());
215+ uint left_index = BuildInternal (left);
216+ uint right_index = BuildInternal (right);
217+ Node &node = mNodes [node_index];
218+ node.mChild [0 ] = left_index;
219+ node.mChild [1 ] = right_index;
220+ node.mBounds = mNodes [node.mChild [0 ]].mBounds ;
221+ node.mBounds .Encapsulate (mNodes [node.mChild [1 ]].mBounds );
222+ return node_index;
223223 }
224224
225225 // Create leaf node
226- Node *node = new Node ();
227- node->mTriangles .reserve (inTriangles.Count ());
226+ const uint node_index = (uint)mNodes .size ();
227+ mNodes .push_back (Node ());
228+ Node &node = mNodes .back ();
229+ node.mTrianglesBegin = (uint)mTriangles .size ();
230+ node.mNumTriangles = inTriangles.mEnd - inTriangles.mBegin ;
231+ const VertexList &v = mTriangleSplitter .GetVertices ();
228232 for (uint i = inTriangles.mBegin ; i < inTriangles.mEnd ; ++i)
229233 {
230234 const IndexedTriangle &t = mTriangleSplitter .GetTriangle (i);
231- const VertexList &v = mTriangleSplitter .GetVertices ();
232- node->mTriangles .push_back (t);
233- node->mBounds .Encapsulate (v, t);
235+ mTriangles .push_back (t);
236+ node.mBounds .Encapsulate (v, t);
234237 }
235238
236- return node ;
239+ return node_index ;
237240}
238241
239242JPH_NAMESPACE_END
0 commit comments