108 void intersectRay(
const G3D::Ray &r, RayCallback& intersectCallback,
float &maxDist,
bool stopAtFirst=
false)
const
110 float intervalMin = -1.f;
111 float intervalMax = -1.f;
112 G3D::Vector3 org = r.origin();
113 G3D::Vector3 dir = r.direction();
115 for (
int i=0; i<3; ++i)
117 invDir[i] = 1.f / dir[i];
118 if (G3D::fuzzyNe(dir[i], 0.0f))
120 float t1 = (
bounds.low()[i] - org[i]) * invDir[i];
121 float t2 = (
bounds.high()[i] - org[i]) * invDir[i];
124 if (t1 > intervalMin)
126 if (t2 < intervalMax || intervalMax < 0.f)
130 if (intervalMax <= 0 || intervalMin >= maxDist)
135 if (intervalMin > intervalMax)
137 intervalMin = std::max(intervalMin, 0.f);
138 intervalMax = std::min(intervalMax, maxDist);
146 for (
int i=0; i<3; ++i)
149 offsetBack[i] = offsetFront[i] ^ 1;
150 offsetFront3[i] = offsetFront[i] * 3;
151 offsetBack3[i] = offsetBack[i] * 3;
166 uint32 axis = (tn & (3 << 30)) >> 30;
167 bool BVH2 = tn & (1 << 29);
168 int offset = tn & ~(7 << 29);
174 float tf = (
intBitsToFloat(
tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
175 float tb = (
intBitsToFloat(
tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
177 if (tf < intervalMin && tb > intervalMax)
179 int back = offset + offsetBack3[axis];
182 if (tf < intervalMin) {
183 intervalMin = (tb >= intervalMin) ? tb : intervalMin;
186 node = offset + offsetFront3[axis];
188 if (tb > intervalMax) {
189 intervalMax = (tf <= intervalMax) ? tf : intervalMax;
194 stack[stackPos].
node = back;
195 stack[stackPos].
tnear = (tb >= intervalMin) ? tb : intervalMin;
196 stack[stackPos].
tfar = intervalMax;
199 intervalMax = (tf <= intervalMax) ? tf : intervalMax;
205 int n =
tree[node + 1];
207 bool hit = intersectCallback(r,
objects[offset], maxDist, stopAtFirst);
208 if (stopAtFirst && hit)
return;
219 float tf = (
intBitsToFloat(
tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
220 float tb = (
intBitsToFloat(
tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
222 intervalMin = (tf >= intervalMin) ? tf : intervalMin;
223 intervalMax = (tb <= intervalMax) ? tb : intervalMax;
224 if (intervalMin > intervalMax)
236 intervalMin = stack[stackPos].
tnear;
237 if (maxDist < intervalMin)
239 node = stack[stackPos].
node;
240 intervalMax = stack[stackPos].
tfar;
247 void intersectPoint(
const G3D::Vector3 &p, IsectCallback& intersectCallback)
const
260 uint32 axis = (tn & (3 << 30)) >> 30;
261 bool BVH2 = tn & (1 << 29);
262 int offset = tn & ~(7 << 29);
271 if (tl < p[axis] && tr > p[axis])
273 int right = offset + 3;
286 stack[stackPos].
node = right;
293 int n =
tree[node + 1];
295 intersectCallback(p,
objects[offset]);
309 if (tl > p[axis] || tr < p[axis])
320 node = stack[stackPos].
node;
384 void subdivide(
int left,
int right, std::vector<uint32> &tempTree, buildData &dat,
AABound &gridBox,
AABound &nodeBox,
int nodeIndex,
int depth, BuildStats &stats);