8
8
9
9
JPH_NAMESPACE_BEGIN
10
10
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
24
12
{
25
13
if (HasChildren ())
26
14
{
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 );
29
17
return min (left, right) + 1 ;
30
18
}
31
19
else
32
20
return 1 ;
33
21
}
34
22
35
- uint AABBTreeBuilder::Node::GetMaxDepth () const
23
+ uint AABBTreeBuilder::Node::GetMaxDepth (const Array<Node> &inNodes ) const
36
24
{
37
25
if (HasChildren ())
38
26
{
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 );
41
29
return max (left, right) + 1 ;
42
30
}
43
31
else
44
32
return 1 ;
45
33
}
46
34
47
- uint AABBTreeBuilder::Node::GetNodeCount () const
35
+ uint AABBTreeBuilder::Node::GetNodeCount (const Array<Node> &inNodes ) const
48
36
{
49
37
if (HasChildren ())
50
- return mChild [0 ]-> GetNodeCount () + mChild [1 ]-> GetNodeCount () + 1 ;
38
+ return inNodes[ mChild [0 ]]. GetNodeCount (inNodes ) + inNodes[ mChild [1 ]]. GetNodeCount (inNodes ) + 1 ;
51
39
else
52
40
return 1 ;
53
41
}
54
42
55
- uint AABBTreeBuilder::Node::GetLeafNodeCount () const
43
+ uint AABBTreeBuilder::Node::GetLeafNodeCount (const Array<Node> &inNodes ) const
56
44
{
57
45
if (HasChildren ())
58
- return mChild [0 ]-> GetLeafNodeCount () + mChild [1 ]-> GetLeafNodeCount ();
46
+ return inNodes[ mChild [0 ]]. GetLeafNodeCount (inNodes ) + inNodes[ mChild [1 ]]. GetLeafNodeCount (inNodes );
59
47
else
60
48
return 1 ;
61
49
}
62
50
63
- uint AABBTreeBuilder::Node::GetTriangleCountInTree () const
51
+ uint AABBTreeBuilder::Node::GetTriangleCountInTree (const Array<Node> &inNodes ) const
64
52
{
65
53
if (HasChildren ())
66
- return mChild [0 ]-> GetTriangleCountInTree () + mChild [1 ]-> GetTriangleCountInTree ();
54
+ return inNodes[ mChild [0 ]]. GetTriangleCountInTree (inNodes ) + inNodes[ mChild [1 ]]. GetTriangleCountInTree (inNodes );
67
55
else
68
56
return GetTriangleCount ();
69
57
}
70
58
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
72
60
{
73
61
outMin = INT_MAX;
74
62
outMax = 0 ;
75
63
outAverage = 0 ;
76
64
uint avg_divisor = 0 ;
77
- GetTriangleCountPerNodeInternal (outAverage, avg_divisor, outMin, outMax);
65
+ GetTriangleCountPerNodeInternal (inNodes, outAverage, avg_divisor, outMin, outMax);
78
66
if (avg_divisor > 0 )
79
67
outAverage /= avg_divisor;
80
68
}
81
69
82
- float AABBTreeBuilder::Node::CalculateSAHCost (float inCostTraversal, float inCostLeaf) const
70
+ float AABBTreeBuilder::Node::CalculateSAHCost (const Array<Node> &inNodes, float inCostTraversal, float inCostLeaf) const
83
71
{
84
72
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 ;
86
74
}
87
75
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
89
77
{
90
78
JPH_ASSERT (outChildren.empty ());
91
79
@@ -94,8 +82,8 @@ void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChild
94
82
return ;
95
83
96
84
// 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 ] ]);
99
87
100
88
size_t next = 0 ;
101
89
bool all_triangles = true ;
@@ -116,8 +104,8 @@ void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChild
116
104
if (to_expand->HasChildren ())
117
105
{
118
106
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 ] ]);
121
109
all_triangles = false ;
122
110
}
123
111
else
@@ -127,22 +115,22 @@ void AABBTreeBuilder::Node::GetNChildren(uint inN, Array<const Node *> &outChild
127
115
}
128
116
}
129
117
130
- float AABBTreeBuilder::Node::CalculateSAHCostInternal (float inCostTraversalDivSurfaceArea, float inCostLeafDivSurfaceArea) const
118
+ float AABBTreeBuilder::Node::CalculateSAHCostInternal (const Array<Node> &inNodes, float inCostTraversalDivSurfaceArea, float inCostLeafDivSurfaceArea) const
131
119
{
132
120
if (HasChildren ())
133
121
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);
136
124
else
137
125
return inCostLeafDivSurfaceArea * mBounds .GetSurfaceArea () * GetTriangleCount ();
138
126
}
139
127
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
141
129
{
142
130
if (HasChildren ())
143
131
{
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);
146
134
}
147
135
else
148
136
{
@@ -162,28 +150,36 @@ AABBTreeBuilder::AABBTreeBuilder(TriangleSplitter &inSplitter, uint inMaxTriangl
162
150
AABBTreeBuilder::Node *AABBTreeBuilder::Build (AABBTreeBuilderStats &outStats)
163
151
{
164
152
TriangleSplitter::Range initial = mTriangleSplitter .GetInitialRange ();
165
- Node *root = BuildInternal (initial);
166
153
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
167
163
float avg_triangles_per_leaf;
168
164
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);
170
166
171
167
mTriangleSplitter .GetStats (outStats.mSplitterStats );
172
168
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 );
178
174
outStats.mMaxTrianglesPerLeaf = mMaxTrianglesPerLeaf ;
179
175
outStats.mTreeMinTrianglesPerLeaf = min_triangles_per_leaf;
180
176
outStats.mTreeMaxTrianglesPerLeaf = max_triangles_per_leaf;
181
177
outStats.mTreeAvgTrianglesPerLeaf = avg_triangles_per_leaf;
182
178
183
- return root;
179
+ return & root;
184
180
}
185
181
186
- AABBTreeBuilder::Node * AABBTreeBuilder::BuildInternal (const TriangleSplitter::Range &inTriangles)
182
+ uint AABBTreeBuilder::BuildInternal (const TriangleSplitter::Range &inTriangles)
187
183
{
188
184
// Check if there are too many triangles left
189
185
if (inTriangles.Count () > mMaxTrianglesPerLeaf )
@@ -214,26 +210,33 @@ AABBTreeBuilder::Node *AABBTreeBuilder::BuildInternal(const TriangleSplitter::Ra
214
210
}
215
211
216
212
// 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;
223
223
}
224
224
225
225
// 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 ();
228
232
for (uint i = inTriangles.mBegin ; i < inTriangles.mEnd ; ++i)
229
233
{
230
234
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);
234
237
}
235
238
236
- return node ;
239
+ return node_index ;
237
240
}
238
241
239
242
JPH_NAMESPACE_END
0 commit comments