81 void build(PrimArray
const& primitives, BoundsFunc& getBounds,
uint32 leafSize = 3,
bool printStats =
false)
83 if (primitives.size() == 0)
94 getBounds(primitives[0], bounds);
98 getBounds(primitives[i], dat.
primBound[i]);
101 std::vector<uint32> tempTree;
103 buildHierarchy(tempTree, dat, stats);
119 void intersectRay(
const G3D::Ray &r, RayCallback& intersectCallback,
float &maxDist,
bool stopAtFirst =
false)
const
121 float intervalMin = -1.f;
122 float intervalMax = -1.f;
123 G3D::Vector3 org = r.origin();
124 G3D::Vector3 dir = r.direction();
126 for (
int i=0; i<3; ++i)
128 invDir[i] = 1.f / dir[i];
129 if (G3D::fuzzyNe(dir[i], 0.0f))
131 float t1 = (bounds.low()[i] - org[i]) * invDir[i];
132 float t2 = (bounds.high()[i] - org[i]) * invDir[i];
135 if (t1 > intervalMin)
137 if (t2 < intervalMax || intervalMax < 0.f)
141 if (intervalMax <= 0 || intervalMin >= maxDist)
146 if (intervalMin > intervalMax)
148 intervalMin = std::max(intervalMin, 0.f);
149 intervalMax = std::min(intervalMax, maxDist);
157 for (
int i=0; i<3; ++i)
160 offsetBack[i] = offsetFront[i] ^ 1;
161 offsetFront3[i] = offsetFront[i] * 3;
162 offsetBack3[i] = offsetBack[i] * 3;
177 uint32 axis = (tn & (3 << 30)) >> 30;
178 bool BVH2 = (tn & (1 << 29)) != 0;
179 int offset = tn & ~(7 << 29);
185 float tf = (
intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
186 float tb = (
intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
188 if (tf < intervalMin && tb > intervalMax)
190 int back = offset + offsetBack3[axis];
193 if (tf < intervalMin) {
194 intervalMin = (tb >= intervalMin) ? tb : intervalMin;
197 node = offset + offsetFront3[axis];
199 if (tb > intervalMax) {
200 intervalMax = (tf <= intervalMax) ? tf : intervalMax;
205 stack[stackPos].
node = back;
206 stack[stackPos].
tnear = (tb >= intervalMin) ? tb : intervalMin;
207 stack[stackPos].
tfar = intervalMax;
210 intervalMax = (tf <= intervalMax) ? tf : intervalMax;
216 int n = tree[node + 1];
218 bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirst);
219 if (stopAtFirst && hit)
return;
230 float tf = (
intBitsToFloat(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
231 float tb = (
intBitsToFloat(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
233 intervalMin = (tf >= intervalMin) ? tf : intervalMin;
234 intervalMax = (tb <= intervalMax) ? tb : intervalMax;
235 if (intervalMin > intervalMax)
247 intervalMin = stack[stackPos].
tnear;
248 if (maxDist < intervalMin)
250 node = stack[stackPos].
node;
251 intervalMax = stack[stackPos].
tfar;
258 void intersectPoint(
const G3D::Vector3 &p, IsectCallback& intersectCallback)
const
260 if (!bounds.contains(p))
271 uint32 axis = (tn & (3 << 30)) >> 30;
272 bool BVH2 = (tn & (1 << 29)) != 0;
273 int offset = tn & ~(7 << 29);
282 if (tl < p[axis] && tr > p[axis])
284 int right = offset + 3;
297 stack[stackPos].
node = right;
304 int n = tree[node + 1];
306 intersectCallback(p, objects[offset]);
320 if (tl > p[axis] || tr < p[axis])
331 node = stack[stackPos].
node;
395 void subdivide(
int left,
int right, std::vector<uint32> &tempTree, buildData &dat,
AABound &gridBox,
AABound &nodeBox,
int nodeIndex,
int depth, BuildStats &stats);