17 template <
typename Real>
60 template <
typename Real>
67 box.GetCenteredForm(boxCenter, boxExtent);
72 DoQuery(point, direction, boxExtent, result);
75 result.closestPoint[0] =
76 line.origin + result.lineParameter*line.direction;
79 result.closestPoint[1] = boxCenter + point;
83 template <
typename Real>
88 result.sqrDistance = (Real)0;
89 result.lineParameter = (Real)0;
93 for (
int i = 0; i < 3; ++i)
95 if (direction[i] < (Real)0)
98 direction[i] = -direction[i];
107 if (direction[0] > (Real)0)
109 if (direction[1] > (Real)0)
111 if (direction[2] > (Real)0)
113 CaseNoZeros(point, direction, boxExtent, result);
117 Case0(0, 1, 2, point, direction, boxExtent, result);
122 if (direction[2] > (Real)0)
124 Case0(0, 2, 1, point, direction, boxExtent, result);
128 Case00(0, 1, 2, point, direction, boxExtent, result);
134 if (direction[1] > (Real)0)
136 if (direction[2] > (Real)0)
138 Case0(1, 2, 0, point, direction, boxExtent, result);
142 Case00(1, 0, 2, point, direction, boxExtent, result);
147 if (direction[2] > (Real)0)
149 Case00(2, 0, 1, point, direction, boxExtent, result);
153 Case000(point, boxExtent, result);
159 for (
int i = 0; i < 3; ++i)
163 point[i] = -point[i];
167 result.distance = sqrt(result.sqrDistance);
170 template <
typename Real>
176 Real lenSqr, inv, tmp,
param,
t, delta;
178 PpE[i1] = pnt[i1] + boxExtent[i1];
179 PpE[i2] = pnt[i2] + boxExtent[i2];
180 if (dir[i0] * PpE[i1] >= dir[i1] * PmE[i0])
182 if (dir[i0] * PpE[i2] >= dir[i2] * PmE[i0])
185 pnt[i0] = boxExtent[i0];
186 inv = ((Real)1) / dir[i0];
187 pnt[i1] -= dir[i1] * PmE[i0] * inv;
188 pnt[i2] -= dir[i2] * PmE[i0] * inv;
189 result.lineParameter = -PmE[i0] * inv;
194 lenSqr = dir[i0] * dir[i0] + dir[i2] * dir[i2];
195 tmp = lenSqr*PpE[i1] - dir[i1] * (dir[i0] * PmE[i0] +
197 if (tmp <= ((Real)2)*lenSqr*boxExtent[i1])
200 lenSqr += dir[i1] * dir[i1];
202 delta = dir[i0] * PmE[i0] + dir[i1] * tmp + dir[i2] * PpE[i2];
203 param = -delta / lenSqr;
204 result.sqrDistance += PmE[i0] * PmE[i0] + tmp*tmp +
205 PpE[i2] * PpE[i2] + delta*
param;
207 result.lineParameter =
param;
208 pnt[i0] = boxExtent[i0];
209 pnt[i1] = t - boxExtent[i1];
210 pnt[i2] = -boxExtent[i2];
214 lenSqr += dir[i1] * dir[i1];
215 delta = dir[i0] * PmE[i0] + dir[i1] * PmE[i1] + dir[i2] * PpE[i2];
216 param = -delta / lenSqr;
217 result.sqrDistance += PmE[i0] * PmE[i0] + PmE[i1] * PmE[i1]
218 + PpE[i2] * PpE[i2] + delta*
param;
220 result.lineParameter =
param;
221 pnt[i0] = boxExtent[i0];
222 pnt[i1] = boxExtent[i1];
223 pnt[i2] = -boxExtent[i2];
229 if (dir[i0] * PpE[i2] >= dir[i2] * PmE[i0])
232 lenSqr = dir[i0] * dir[i0] + dir[i1] * dir[i1];
233 tmp = lenSqr*PpE[i2] - dir[i2] * (dir[i0] * PmE[i0] +
235 if (tmp <= ((Real)2)*lenSqr*boxExtent[i2])
238 lenSqr += dir[i2] * dir[i2];
240 delta = dir[i0] * PmE[i0] + dir[i1] * PpE[i1] + dir[i2] * tmp;
241 param = -delta / lenSqr;
242 result.sqrDistance += PmE[i0] * PmE[i0] + PpE[i1] * PpE[i1] +
243 tmp*tmp + delta*
param;
245 result.lineParameter =
param;
246 pnt[i0] = boxExtent[i0];
247 pnt[i1] = -boxExtent[i1];
248 pnt[i2] = t - boxExtent[i2];
252 lenSqr += dir[i2] * dir[i2];
253 delta = dir[i0] * PmE[i0] + dir[i1] * PpE[i1] + dir[i2] * PmE[i2];
254 param = -delta / lenSqr;
255 result.sqrDistance += PmE[i0] * PmE[i0] + PpE[i1] * PpE[i1] +
256 PmE[i2] * PmE[i2] + delta*
param;
258 result.lineParameter =
param;
259 pnt[i0] = boxExtent[i0];
260 pnt[i1] = -boxExtent[i1];
261 pnt[i2] = boxExtent[i2];
267 lenSqr = dir[i0] * dir[i0] + dir[i2] * dir[i2];
268 tmp = lenSqr*PpE[i1] - dir[i1] * (dir[i0] * PmE[i0] +
273 if (tmp <= ((Real)2)*lenSqr*boxExtent[i1])
276 lenSqr += dir[i1] * dir[i1];
278 delta = dir[i0] * PmE[i0] + dir[i1] * tmp + dir[i2] * PpE[i2];
279 param = -delta / lenSqr;
280 result.sqrDistance += PmE[i0] * PmE[i0] + tmp*tmp +
281 PpE[i2] * PpE[i2] + delta*
param;
283 result.lineParameter =
param;
284 pnt[i0] = boxExtent[i0];
285 pnt[i1] = t - boxExtent[i1];
286 pnt[i2] = -boxExtent[i2];
290 lenSqr += dir[i1] * dir[i1];
291 delta = dir[i0] * PmE[i0] + dir[i1] * PmE[i1]
293 param = -delta / lenSqr;
294 result.sqrDistance += PmE[i0] * PmE[i0] + PmE[i1] * PmE[i1]
295 + PpE[i2] * PpE[i2] + delta*
param;
297 result.lineParameter =
param;
298 pnt[i0] = boxExtent[i0];
299 pnt[i1] = boxExtent[i1];
300 pnt[i2] = -boxExtent[i2];
305 lenSqr = dir[i0] * dir[i0] + dir[i1] * dir[i1];
306 tmp = lenSqr*PpE[i2] - dir[i2] * (dir[i0] * PmE[i0] +
311 if (tmp <= ((Real)2)*lenSqr*boxExtent[i2])
314 lenSqr += dir[i2] * dir[i2];
316 delta = dir[i0] * PmE[i0] + dir[i1] * PpE[i1] + dir[i2] * tmp;
317 param = -delta / lenSqr;
318 result.sqrDistance += PmE[i0] * PmE[i0] + PpE[i1] * PpE[i1] +
319 tmp*tmp + delta*
param;
321 result.lineParameter =
param;
322 pnt[i0] = boxExtent[i0];
323 pnt[i1] = -boxExtent[i1];
324 pnt[i2] = t - boxExtent[i2];
328 lenSqr += dir[i2] * dir[i2];
329 delta = dir[i0] * PmE[i0] + dir[i1] * PpE[i1]
331 param = -delta / lenSqr;
332 result.sqrDistance += PmE[i0] * PmE[i0] + PpE[i1] * PpE[i1]
333 + PmE[i2] * PmE[i2] + delta*
param;
335 result.lineParameter =
param;
336 pnt[i0] = boxExtent[i0];
337 pnt[i1] = -boxExtent[i1];
338 pnt[i2] = boxExtent[i2];
344 lenSqr += dir[i2] * dir[i2];
345 delta = dir[i0] * PmE[i0] + dir[i1] * PpE[i1] + dir[i2] * PpE[i2];
346 param = -delta / lenSqr;
347 result.sqrDistance += PmE[i0] * PmE[i0] + PpE[i1] * PpE[i1]
348 + PpE[i2] * PpE[i2] + delta*
param;
350 result.lineParameter =
param;
351 pnt[i0] = boxExtent[i0];
352 pnt[i1] = -boxExtent[i1];
353 pnt[i2] = -boxExtent[i2];
358 template <
typename Real>
364 Real prodDxPy = dir[0] * PmE[1];
365 Real prodDyPx = dir[1] * PmE[0];
366 Real prodDzPx, prodDxPz, prodDzPy, prodDyPz;
368 if (prodDyPx >= prodDxPy)
370 prodDzPx = dir[2] * PmE[0];
371 prodDxPz = dir[0] * PmE[2];
372 if (prodDzPx >= prodDxPz)
375 Face(0, 1, 2, pnt, dir, PmE, boxExtent, result);
380 Face(2, 0, 1, pnt, dir, PmE, boxExtent, result);
385 prodDzPy = dir[2] * PmE[1];
386 prodDyPz = dir[1] * PmE[2];
387 if (prodDzPy >= prodDyPz)
390 Face(1, 2, 0, pnt, dir, PmE, boxExtent, result);
395 Face(2, 0, 1, pnt, dir, PmE, boxExtent, result);
400 template <
typename Real>
405 Real PmE0 = pnt[i0] - boxExtent[i0];
406 Real PmE1 = pnt[i1] - boxExtent[i1];
407 Real prod0 = dir[i1] * PmE0;
408 Real prod1 = dir[i0] * PmE1;
409 Real delta, invLSqr, inv;
414 pnt[i0] = boxExtent[i0];
416 Real PpE1 = pnt[i1] + boxExtent[i1];
417 delta = prod0 - dir[i0] * PpE1;
418 if (delta >= (Real)0)
420 invLSqr = ((Real)1) / (dir[i0] * dir[i0] + dir[i1] * dir[i1]);
421 result.sqrDistance += delta*delta*invLSqr;
422 pnt[i1] = -boxExtent[i1];
423 result.lineParameter = -(dir[i0] * PmE0 + dir[i1] * PpE1)*invLSqr;
427 inv = ((Real)1) / dir[i0];
428 pnt[i1] -= prod0*inv;
429 result.lineParameter = -PmE0*inv;
435 pnt[i1] = boxExtent[i1];
437 Real PpE0 = pnt[i0] + boxExtent[i0];
438 delta = prod1 - dir[i1] * PpE0;
439 if (delta >= (Real)0)
441 invLSqr = ((Real)1) / (dir[i0] * dir[i0] + dir[i1] * dir[i1]);
442 result.sqrDistance += delta*delta*invLSqr;
443 pnt[i0] = -boxExtent[i0];
444 result.lineParameter = -(dir[i0] * PpE0 + dir[i1] * PmE1)*invLSqr;
448 inv = ((Real)1) / dir[i1];
449 pnt[i0] -= prod1*inv;
450 result.lineParameter = -PmE1*inv;
454 if (pnt[i2] < -boxExtent[i2])
456 delta = pnt[i2] + boxExtent[i2];
457 result.sqrDistance += delta*delta;
458 pnt[i2] = -boxExtent[i2];
460 else if (pnt[i2] > boxExtent[i2])
462 delta = pnt[i2] - boxExtent[i2];
463 result.sqrDistance += delta*delta;
464 pnt[i2] = boxExtent[i2];
468 template <
typename Real>
475 result.lineParameter = (boxExtent[i0] - pnt[i0]) / dir[i0];
477 pnt[i0] = boxExtent[i0];
479 if (pnt[i1] < -boxExtent[i1])
481 delta = pnt[i1] + boxExtent[i1];
482 result.sqrDistance += delta*delta;
483 pnt[i1] = -boxExtent[i1];
485 else if (pnt[i1] > boxExtent[i1])
487 delta = pnt[i1] - boxExtent[i1];
488 result.sqrDistance += delta*delta;
489 pnt[i1] = boxExtent[i1];
492 if (pnt[i2] < -boxExtent[i2])
494 delta = pnt[i2] + boxExtent[i2];
495 result.sqrDistance += delta*delta;
496 pnt[i2] = -boxExtent[i2];
498 else if (pnt[i2] > boxExtent[i2])
500 delta = pnt[i2] - boxExtent[i2];
501 result.sqrDistance += delta*delta;
502 pnt[i2] = boxExtent[i2];
506 template <
typename Real>
512 if (pnt[0] < -boxExtent[0])
514 delta = pnt[0] + boxExtent[0];
515 result.sqrDistance += delta*delta;
516 pnt[0] = -boxExtent[0];
518 else if (pnt[0] > boxExtent[0])
520 delta = pnt[0] - boxExtent[0];
521 result.sqrDistance += delta*delta;
522 pnt[0] = boxExtent[0];
525 if (pnt[1] < -boxExtent[1])
527 delta = pnt[1] + boxExtent[1];
528 result.sqrDistance += delta*delta;
529 pnt[1] = -boxExtent[1];
531 else if (pnt[1] > boxExtent[1])
533 delta = pnt[1] - boxExtent[1];
534 result.sqrDistance += delta*delta;
535 pnt[1] = boxExtent[1];
538 if (pnt[2] < -boxExtent[2])
540 delta = pnt[2] + boxExtent[2];
541 result.sqrDistance += delta*delta;
542 pnt[2] = -boxExtent[2];
544 else if (pnt[2] > boxExtent[2])
546 delta = pnt[2] - boxExtent[2];
547 result.sqrDistance += delta*delta;
548 pnt[2] = boxExtent[2];
GLsizei GLsizei GLfloat distance
Result operator()(Type0 const &primitive0, Type1 const &primitive1)