23 #define isnan std::isnan
29 tempTree.push_back(
uint32(3 << 30));
30 tempTree.insert(tempTree.end(), 2, 0);
50 int axis = -1, prevAxis, rightOrig;
51 float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
52 float split = G3D::fnan(), prevSplit;
59 G3D::Vector3 d( gridBox.
hi - gridBox.
lo );
60 if (d.x < 0 || d.y < 0 || d.z < 0)
61 throw std::logic_error(
"negative node extents");
62 for (
int i = 0; i < 3; i++)
64 if (nodeBox.
hi[i] < gridBox.
lo[i] || nodeBox.
lo[i] > gridBox.
hi[i])
67 throw std::logic_error(
"invalid node overlap");
71 axis = d.primaryAxis();
72 split = 0.5f * (gridBox.
lo[axis] + gridBox.
hi[axis]);
77 float nodeL = G3D::finf();
78 float nodeR = -G3D::finf();
79 for (
int i = left; i <= right;)
82 float minb = dat.
primBound[obj].low()[axis];
83 float maxb = dat.
primBound[obj].high()[axis];
84 float center = (minb + maxb) * 0.5f;
102 nodeL = std::min(nodeL, minb);
103 nodeR = std::max(nodeR, maxb);
106 if (nodeL > nodeBox.
lo[axis] && nodeR < nodeBox.
hi[axis])
108 float nodeBoxW = nodeBox.
hi[axis] - nodeBox.
lo[axis];
109 float nodeNewW = nodeR - nodeL;
111 if (1.3f * nodeNewW < nodeBoxW)
114 int nextIndex = tempTree.size();
116 tempTree.push_back(0);
117 tempTree.push_back(0);
118 tempTree.push_back(0);
121 tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
125 nodeBox.
lo[axis] = nodeL;
126 nodeBox.
hi[axis] = nodeR;
127 subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
132 if (right == rightOrig)
135 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
141 if (clipL <= split) {
143 gridBox.
hi[axis] = split;
148 gridBox.
hi[axis] = split;
149 prevClip = G3D::fnan();
151 else if (left > right)
155 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
161 if (clipR >= split) {
163 gridBox.
lo[axis] = split;
168 gridBox.
lo[axis] = split;
169 prevClip = G3D::fnan();
174 if (prevAxis != -1 && !
isnan(prevClip))
178 int nextIndex = tempTree.size();
180 tempTree.push_back(0);
181 tempTree.push_back(0);
182 tempTree.push_back(0);
187 tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
194 tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
202 nodeIndex = nextIndex;
208 int nextIndex = tempTree.size();
210 int nl = right - left + 1;
211 int nr = rightOrig - (right + 1) + 1;
213 tempTree.push_back(0);
214 tempTree.push_back(0);
215 tempTree.push_back(0);
220 tempTree.push_back(0);
221 tempTree.push_back(0);
222 tempTree.push_back(0);
226 tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
230 AABound gridBoxL(gridBox), gridBoxR(gridBox);
231 AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
232 gridBoxL.hi[axis] = gridBoxR.
lo[axis] = split;
233 nodeBoxL.hi[axis] = clipL;
234 nodeBoxR.
lo[axis] = clipR;
237 subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
241 subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
250 check += fwrite(&
bounds.low(),
sizeof(
float), 3, wf);
251 check += fwrite(&
bounds.high(),
sizeof(
float), 3, wf);
252 check += fwrite(&treeSize,
sizeof(
uint32), 1, wf);
253 check += fwrite(&
tree[0],
sizeof(
uint32), treeSize, wf);
255 check += fwrite(&count,
sizeof(
uint32), 1, wf);
257 return check == (3 + 3 + 2 + treeSize + count);
265 check += fread(&lo,
sizeof(
float), 3, rf);
266 check += fread(&hi,
sizeof(
float), 3, rf);
267 bounds = G3D::AABox(lo, hi);
268 check += fread(&treeSize,
sizeof(
uint32), 1, rf);
269 tree.resize(treeSize);
270 check += fread(&
tree[0],
sizeof(
uint32), treeSize, rf);
271 check += fread(&count,
sizeof(
uint32), 1, rf);
286 int nl = std::min(n, 5);
292 printf(
"Tree stats:\n");
293 printf(
" * Nodes: %d\n", numNodes);
294 printf(
" * Leaves: %d\n", numLeaves);
295 printf(
" * Objects: min %d\n", minObjects);
296 printf(
" avg %.2f\n", (
float) sumObjects / numLeaves);
297 printf(
" avg(n>0) %.2f\n", (
float) sumObjects / (numLeaves - numLeavesN[0]));
298 printf(
" max %d\n", maxObjects);
299 printf(
" * Depth: min %d\n", minDepth);
300 printf(
" avg %.2f\n", (
float) sumDepth / numLeaves);
301 printf(
" max %d\n", maxDepth);
302 printf(
" * Leaves w/: N=0 %3d%%\n", 100 * numLeavesN[0] / numLeaves);
303 printf(
" N=1 %3d%%\n", 100 * numLeavesN[1] / numLeaves);
304 printf(
" N=2 %3d%%\n", 100 * numLeavesN[2] / numLeaves);
305 printf(
" N=3 %3d%%\n", 100 * numLeavesN[3] / numLeaves);
306 printf(
" N=4 %3d%%\n", 100 * numLeavesN[4] / numLeaves);
307 printf(
" N>4 %3d%%\n", 100 * numLeavesN[5] / numLeaves);
308 printf(
" * BVH2 nodes: %d (%3d%%)\n", numBVH2, 100 * numBVH2 / (numNodes + numLeaves - 2 * numBVH2));
static uint32 floatToRawIntBits(float f)
void updateLeaf(int depth, int n)
bool writeToFile(FILE *wf) const
void createNode(std::vector< uint32 > &tempTree, int nodeIndex, uint32 left, uint32 right) const
std::vector< uint32 > objects
void buildHierarchy(std::vector< uint32 > &tempTree, buildData &dat, BuildStats &stats)
std::vector< uint32 > tree
bool readFromFile(FILE *rf)
void subdivide(int left, int right, std::vector< uint32 > &tempTree, buildData &dat, AABound &gridBox, AABound &nodeBox, int nodeIndex, int depth, BuildStats &stats)