38 int axis = -1, prevAxis, rightOrig;
39 float clipL = G3D::fnan(), clipR = G3D::fnan(), prevClip = G3D::fnan();
40 float split = G3D::fnan(), prevSplit;
47 G3D::Vector3 d( gridBox.
hi - gridBox.
lo );
48 if (d.x < 0 || d.y < 0 || d.z < 0)
49 throw std::logic_error(
"negative node extents");
50 for (
int i = 0; i < 3; i++)
52 if (nodeBox.
hi[i] < gridBox.
lo[i] || nodeBox.
lo[i] > gridBox.
hi[i])
55 throw std::logic_error(
"invalid node overlap");
59 axis = d.primaryAxis();
60 split = 0.5f * (gridBox.
lo[axis] + gridBox.
hi[axis]);
65 float nodeL = G3D::inf();
66 float nodeR = -G3D::inf();
67 for (
int i = left; i <= right;)
70 float minb = dat.
primBound[obj].low()[axis];
71 float maxb = dat.
primBound[obj].high()[axis];
72 float center = (minb + maxb) * 0.5f;
90 nodeL = std::min(nodeL, minb);
91 nodeR = std::max(nodeR, maxb);
94 if (nodeL > nodeBox.
lo[axis] && nodeR < nodeBox.
hi[axis])
96 float nodeBoxW = nodeBox.
hi[axis] - nodeBox.
lo[axis];
97 float nodeNewW = nodeR - nodeL;
99 if (1.3f * nodeNewW < nodeBoxW)
102 int nextIndex = tempTree.size();
104 tempTree.push_back(0);
105 tempTree.push_back(0);
106 tempTree.push_back(0);
109 tempTree[nodeIndex + 0] = (axis << 30) | (1 << 29) | nextIndex;
113 nodeBox.
lo[axis] = nodeL;
114 nodeBox.
hi[axis] = nodeR;
115 subdivide(left, rightOrig, tempTree, dat, gridBox, nodeBox, nextIndex, depth + 1, stats);
120 if (right == rightOrig)
123 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
129 if (clipL <= split) {
131 gridBox.
hi[axis] = split;
136 gridBox.
hi[axis] = split;
137 prevClip = G3D::fnan();
139 else if (left > right)
142 if (prevAxis == axis && G3D::fuzzyEq(prevSplit, split)) {
149 if (clipR >= split) {
151 gridBox.
lo[axis] = split;
156 gridBox.
lo[axis] = split;
157 prevClip = G3D::fnan();
162 if (prevAxis != -1 && !
isnan(prevClip))
166 int nextIndex = tempTree.size();
168 tempTree.push_back(0);
169 tempTree.push_back(0);
170 tempTree.push_back(0);
175 tempTree[nodeIndex + 0] = (prevAxis << 30) | nextIndex;
182 tempTree[nodeIndex + 0] = (prevAxis << 30) | (nextIndex - 3);
190 nodeIndex = nextIndex;
196 int nextIndex = tempTree.size();
198 int nl = right - left + 1;
199 int nr = rightOrig - (right + 1) + 1;
201 tempTree.push_back(0);
202 tempTree.push_back(0);
203 tempTree.push_back(0);
208 tempTree.push_back(0);
209 tempTree.push_back(0);
210 tempTree.push_back(0);
214 tempTree[nodeIndex + 0] = (axis << 30) | nextIndex;
218 AABound gridBoxL(gridBox), gridBoxR(gridBox);
219 AABound nodeBoxL(nodeBox), nodeBoxR(nodeBox);
220 gridBoxL.hi[axis] = gridBoxR.
lo[axis] = split;
221 nodeBoxL.hi[axis] = clipL;
222 nodeBoxR.
lo[axis] = clipR;
225 subdivide(left, right, tempTree, dat, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
229 subdivide(right + 1, rightOrig, tempTree, dat, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);