43 int axis = -1, prevAxis, rightOrig;
44 float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
45 float split = G3D::fnan(), prevSplit;
52 G3D::Vector3 d(gridBox.
hi - gridBox.
lo);
53 if (d.x < 0 || d.y < 0 || d.z < 0)
54 throw std::logic_error(
"negative node extents");
55 for (
int i = 0; i < 3; i++)
57 if (nodeBox.
hi[i] < gridBox.
lo[i] || nodeBox.
lo[i] > gridBox.
hi[i])
60 throw std::logic_error(
"invalid node overlap");
64 axis = d.primaryAxis();
65 split = 0.5f * (gridBox.
lo[axis] + gridBox.
hi[axis]);
70 float nodeL = G3D::finf();
71 float nodeR = -G3D::finf();
72 for (
int i = left; i <= right;)
75 float minb = dat.
primBound[obj].low()[axis];
76 float maxb = dat.
primBound[obj].high()[axis];
77 float center = (minb + maxb) * 0.5f;
95 nodeL = std::min(nodeL, minb);
96 nodeR = std::max(nodeR, maxb);
99 if (nodeL > nodeBox.
lo[axis] && nodeR < nodeBox.
hi[axis])
101 float nodeBoxW = nodeBox.
hi[axis] - nodeBox.
lo[axis];
102 float nodeNewW = nodeR - nodeL;
104 if (1.3f * nodeNewW < nodeBoxW)
107 int nextIndex = tempTree.size();
109 tempTree.push_back(0);
110 tempTree.push_back(0);
111 tempTree.push_back(0);
114 tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
115 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(nodeL);
116 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(nodeR);
118 nodeBox.
lo[axis] = nodeL;
119 nodeBox.
hi[axis] = nodeR;
120 subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
125 if (right == rightOrig)
128 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
138 gridBox.
hi[axis] = split;
143 gridBox.
hi[axis] = split;
144 prevClip = G3D::fnan();
146 else if (left > right)
150 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
160 gridBox.
lo[axis] = split;
165 gridBox.
lo[axis] = split;
166 prevClip = G3D::fnan();
171 if (prevAxis != -1 && !std::isnan(prevClip))
175 int nextIndex = tempTree.size();
177 tempTree.push_back(0);
178 tempTree.push_back(0);
179 tempTree.push_back(0);
185 tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
186 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(prevClip);
187 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(G3D::finf());
194 tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
195 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(-G3D::finf());
196 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(prevClip);
202 nodeIndex = nextIndex;
208 int nextIndex = tempTree.size();
210 int nl = right - left + 1;
211 int nr = rightOrig - (right + 1) + 1;
214 tempTree.push_back(0);
215 tempTree.push_back(0);
216 tempTree.push_back(0);
223 tempTree.push_back(0);
224 tempTree.push_back(0);
225 tempTree.push_back(0);
229 tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
230 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(clipL);
231 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(clipR);
233 AABound gridBoxL(gridBox), gridBoxR(gridBox);
234 AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
235 gridBoxL.hi[axis] = gridBoxR.
lo[axis] = split;
236 nodeBoxL.hi[axis] = clipL;
237 nodeBoxR.
lo[axis] = clipR;
240 subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
244 subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
295 printf(
"Tree stats:\n");
296 printf(
" * Nodes: %d\n", numNodes);
297 printf(
" * Leaves: %d\n", numLeaves);
298 printf(
" * Objects: min %d\n", minObjects);
299 printf(
" avg %.2f\n", (
float)sumObjects / numLeaves);
300 printf(
" avg(n>0) %.2f\n", (
float)sumObjects / (numLeaves - numLeavesN[0]));
301 printf(
" max %d\n", maxObjects);
302 printf(
" * Depth: min %d\n", minDepth);
303 printf(
" avg %.2f\n", (
float)sumDepth / numLeaves);
304 printf(
" max %d\n", maxDepth);
305 printf(
" * Leaves w/: N=0 %3d%%\n", 100 * numLeavesN[0] / numLeaves);
306 printf(
" N=1 %3d%%\n", 100 * numLeavesN[1] / numLeaves);
307 printf(
" N=2 %3d%%\n", 100 * numLeavesN[2] / numLeaves);
308 printf(
" N=3 %3d%%\n", 100 * numLeavesN[3] / numLeaves);
309 printf(
" N=4 %3d%%\n", 100 * numLeavesN[4] / numLeaves);
310 printf(
" N>4 %3d%%\n", 100 * numLeavesN[5] / numLeaves);
311 printf(
" * BVH2 nodes: %d (%3d%%)\n", numBVH2, 100 * numBVH2 / (numNodes + numLeaves - 2 * numBVH2));