23 tempTree = { 3u << 30u, 0u, 0u };
42 int axis = -1, prevAxis, rightOrig;
43 float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
44 float split = G3D::fnan(), prevSplit;
51 G3D::Vector3 d(gridBox.
hi - gridBox.
lo);
52 if (d.x < 0 || d.y < 0 || d.z < 0)
53 throw std::logic_error(
"negative node extents");
54 for (
int i = 0; i < 3; i++)
56 if (nodeBox.
hi[i] < gridBox.
lo[i] || nodeBox.
lo[i] > gridBox.
hi[i])
59 throw std::logic_error(
"invalid node overlap");
63 axis = d.primaryAxis();
64 split = 0.5f * (gridBox.
lo[axis] + gridBox.
hi[axis]);
69 float nodeL = G3D::finf();
70 float nodeR = -G3D::finf();
71 for (
int i = left; i <= right;)
74 float minb = dat.
primBound[obj].low()[axis];
75 float maxb = dat.
primBound[obj].high()[axis];
76 float center = (minb + maxb) * 0.5f;
94 nodeL = std::min(nodeL, minb);
95 nodeR = std::max(nodeR, maxb);
98 if (nodeL > nodeBox.
lo[axis] && nodeR < nodeBox.
hi[axis])
100 float nodeBoxW = nodeBox.
hi[axis] - nodeBox.
lo[axis];
101 float nodeNewW = nodeR - nodeL;
103 if (1.3f * nodeNewW < nodeBoxW)
106 int nextIndex = tempTree.size();
108 tempTree.push_back(0);
109 tempTree.push_back(0);
110 tempTree.push_back(0);
113 tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
114 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(nodeL);
115 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(nodeR);
117 nodeBox.
lo[axis] = nodeL;
118 nodeBox.
hi[axis] = nodeR;
119 subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
124 if (right == rightOrig)
127 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
137 gridBox.
hi[axis] = split;
142 gridBox.
hi[axis] = split;
143 prevClip = G3D::fnan();
145 else if (left > right)
149 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split))
159 gridBox.
lo[axis] = split;
164 gridBox.
lo[axis] = split;
165 prevClip = G3D::fnan();
170 if (prevAxis != -1 && !std::isnan(prevClip))
174 int nextIndex = tempTree.size();
176 tempTree.push_back(0);
177 tempTree.push_back(0);
178 tempTree.push_back(0);
184 tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
185 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(prevClip);
186 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(G3D::finf());
193 tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
194 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(-G3D::finf());
195 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(prevClip);
201 nodeIndex = nextIndex;
207 int nextIndex = tempTree.size();
209 int nl = right - left + 1;
210 int nr = rightOrig - (right + 1) + 1;
213 tempTree.push_back(0);
214 tempTree.push_back(0);
215 tempTree.push_back(0);
222 tempTree.push_back(0);
223 tempTree.push_back(0);
224 tempTree.push_back(0);
228 tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
229 tempTree[nodeIndex + 1] = advstd::bit_cast<uint32>(clipL);
230 tempTree[nodeIndex + 2] = advstd::bit_cast<uint32>(clipR);
232 AABound gridBoxL(gridBox), gridBoxR(gridBox);
233 AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
234 gridBoxL.hi[axis] = gridBoxR.
lo[axis] = split;
235 nodeBoxL.hi[axis] = clipL;
236 nodeBoxR.
lo[axis] = clipR;
239 subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
243 subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
252 check += fwrite(&
bounds.low(),
sizeof(
float), 3, wf);
253 check += fwrite(&
bounds.high(),
sizeof(
float), 3, wf);
254 check += fwrite(&treeSize,
sizeof(
uint32), 1, wf);
255 check += fwrite(
tree.data(),
sizeof(
uint32), treeSize, wf);
257 check += fwrite(&count,
sizeof(
uint32), 1, wf);
259 return check == (3 + 3 + 2 + treeSize + count);
266 uint32 check = 0, count = 0;
267 check += fread(&lo,
sizeof(
float), 3, rf);
268 check += fread(&hi,
sizeof(
float), 3, rf);
269 bounds = G3D::AABox(lo, hi);
270 check += fread(&treeSize,
sizeof(
uint32), 1, rf);
271 tree.resize(treeSize);
272 check += fread(
tree.data(),
sizeof(
uint32), treeSize, rf);
273 check += fread(&count,
sizeof(
uint32), 1, rf);
288 int nl = std::min(n, 5);
294 printf(
"Tree stats:\n");
295 printf(
" * Nodes: %d\n", numNodes);
296 printf(
" * Leaves: %d\n", numLeaves);
297 printf(
" * Objects: min %d\n", minObjects);
298 printf(
" avg %.2f\n", (
float)sumObjects / numLeaves);
299 printf(
" avg(n>0) %.2f\n", (
float)sumObjects / (numLeaves - numLeavesN[0]));
300 printf(
" max %d\n", maxObjects);
301 printf(
" * Depth: min %d\n", minDepth);
302 printf(
" avg %.2f\n", (
float)sumDepth / numLeaves);
303 printf(
" max %d\n", maxDepth);
304 printf(
" * Leaves w/: N=0 %3d%%\n", 100 * numLeavesN[0] / numLeaves);
305 printf(
" N=1 %3d%%\n", 100 * numLeavesN[1] / numLeaves);
306 printf(
" N=2 %3d%%\n", 100 * numLeavesN[2] / numLeaves);
307 printf(
" N=3 %3d%%\n", 100 * numLeavesN[3] / numLeaves);
308 printf(
" N=4 %3d%%\n", 100 * numLeavesN[4] / numLeaves);
309 printf(
" N>4 %3d%%\n", 100 * numLeavesN[5] / numLeaves);
310 printf(
" * BVH2 nodes: %d (%3d%%)\n", numBVH2, 100 * numBVH2 / (numNodes + numLeaves - 2 * numBVH2));
void updateLeaf(int depth, int n)
bool writeToFile(FILE *wf) const
void buildHierarchy(std::vector< uint32 > &tempTree, buildData &dat, BuildStats &stats) const
static void createNode(std::vector< uint32 > &tempTree, int nodeIndex, uint32 left, uint32 right)
std::vector< uint32 > objects
std::vector< uint32 > tree
bool readFromFile(FILE *rf)
static void subdivide(int left, int right, std::vector< uint32 > &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)