90 void intersectRay(G3D::Ray
const& r, RayCallback& intersectCallback,
float& maxDist,
bool stopAtFirst =
false)
const
92 float intervalMin = -1.f;
93 float intervalMax = -1.f;
94 G3D::Vector3
const& org = r.origin();
95 G3D::Vector3
const& dir = r.direction();
96 G3D::Vector3
const& invDir = r.invDirection();
97 for (
int i = 0; i < 3; ++i)
99 if (G3D::fuzzyNe(dir[i], 0.0f))
101 float t1 = (bounds.low()[i] - org[i]) * invDir[i];
102 float t2 = (bounds.high()[i] - org[i]) * invDir[i];
105 if (t1 > intervalMin)
107 if (t2 < intervalMax || intervalMax < 0.f)
111 if (intervalMax <= 0 || intervalMin >= maxDist)
116 if (intervalMin > intervalMax)
118 intervalMin = std::max(intervalMin, 0.f);
119 intervalMax = std::min(intervalMax, maxDist);
127 for (
int i = 0; i < 3; ++i)
129 offsetFront[i] = advstd::bit_cast<uint32>(dir[i]) >> 31;
130 offsetBack[i] = offsetFront[i] ^ 1;
131 offsetFront3[i] = offsetFront[i] * 3;
132 offsetBack3[i] = offsetBack[i] * 3;
148 uint32 axis = (tn & (3 << 30)) >> 30;
149 bool BVH2 = (tn & (1 << 29)) != 0;
150 int offset = tn & ~(7 << 29);
156 float tf = (advstd::bit_cast<float>(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
157 float tb = (advstd::bit_cast<float>(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
159 if (tf < intervalMin && tb > intervalMax)
161 int back = offset + offsetBack3[axis];
164 if (tf < intervalMin)
166 intervalMin = (tb >= intervalMin) ? tb : intervalMin;
169 node = offset + offsetFront3[axis];
171 if (tb > intervalMax)
173 intervalMax = (tf <= intervalMax) ? tf : intervalMax;
178 stack[stackPos].
node = back;
179 stack[stackPos].
tnear = (tb >= intervalMin) ? tb : intervalMin;
180 stack[stackPos].
tfar = intervalMax;
183 intervalMax = (tf <= intervalMax) ? tf : intervalMax;
189 int n = tree[node + 1];
192 bool hit = intersectCallback(r, objects[offset], maxDist, stopAtFirst);
193 if (stopAtFirst && hit)
return;
204 float tf = (advstd::bit_cast<float>(tree[node + offsetFront[axis]]) - org[axis]) * invDir[axis];
205 float tb = (advstd::bit_cast<float>(tree[node + offsetBack[axis]]) - org[axis]) * invDir[axis];
207 intervalMin = (tf >= intervalMin) ? tf : intervalMin;
208 intervalMax = (tb <= intervalMax) ? tb : intervalMax;
209 if (intervalMin > intervalMax)
221 intervalMin = stack[stackPos].
tnear;
222 if (maxDist < intervalMin)
224 node = stack[stackPos].
node;
225 intervalMax = stack[stackPos].
tfar;
232 void intersectPoint(G3D::Vector3
const& p, IsectCallback& intersectCallback)
const
234 if (!bounds.contains(p))
246 uint32 axis = (tn & (3 << 30)) >> 30;
247 bool BVH2 = (tn & (1 << 29)) != 0;
248 int offset = tn & ~(7 << 29);
254 float tl = advstd::bit_cast<float>(tree[node + 1]);
255 float tr = advstd::bit_cast<float>(tree[node + 2]);
257 if (tl < p[axis] && tr > p[axis])
259 int right = offset + 3;
274 stack[stackPos].
node = right;
281 int n = tree[node + 1];
284 intersectCallback(p, objects[offset]);
295 float tl = advstd::bit_cast<float>(tree[node + 1]);
296 float tr = advstd::bit_cast<float>(tree[node + 2]);
298 if (tl > p[axis] || tr < p[axis])
309 node = stack[stackPos].
node;
373 static void subdivide(
int left,
int right, std::vector<uint32>& tempTree, buildData& dat,
AABound& gridBox,
AABound& nodeBox,
int nodeIndex,
int depth, BuildStats& stats);