00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00037 #include "collision_checking/rss.h"
00038
00039 namespace collision_checking
00040 {
00041
00042 bool RSS::overlap(const RSS& other) const
00043 {
00044
00045
00046
00047 Vec3f t = other.Tr - Tr;
00048 Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2]));
00049 Vec3f R[3];
00050 R[0] = Vec3f(axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), axis[0].dot(other.axis[2]));
00051 R[1] = Vec3f(axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), axis[1].dot(other.axis[2]));
00052 R[2] = Vec3f(axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), axis[2].dot(other.axis[2]));
00053
00054 BVH_REAL dist = rectDistance(R, T, l, other.l);
00055 if(dist <= (r + other.r)) return true;
00056 return false;
00057 }
00058
00059 bool overlap(const Vec3f R0[3], const Vec3f& T0, const RSS& b1, const RSS& b2)
00060 {
00061
00062 Vec3f Rtemp_col[3];
00063 Rtemp_col[0] = Vec3f(R0[0].dot(b2.axis[0]), R0[1].dot(b2.axis[0]), R0[2].dot(b2.axis[0]));
00064 Rtemp_col[1] = Vec3f(R0[0].dot(b2.axis[1]), R0[1].dot(b2.axis[1]), R0[2].dot(b2.axis[1]));
00065 Rtemp_col[2] = Vec3f(R0[0].dot(b2.axis[2]), R0[1].dot(b2.axis[2]), R0[2].dot(b2.axis[2]));
00066
00067
00068 Vec3f R[3];
00069 R[0] = Vec3f(b1.axis[0].dot(Rtemp_col[0]), b1.axis[0].dot(Rtemp_col[1]), b1.axis[0].dot(Rtemp_col[2]));
00070 R[1] = Vec3f(b1.axis[1].dot(Rtemp_col[0]), b1.axis[1].dot(Rtemp_col[1]), b1.axis[1].dot(Rtemp_col[2]));
00071 R[2] = Vec3f(b1.axis[2].dot(Rtemp_col[0]), b1.axis[2].dot(Rtemp_col[1]), b1.axis[2].dot(Rtemp_col[2]));
00072
00073 Vec3f Ttemp = Vec3f(R0[0].dot(b2.Tr), R0[1].dot(b2.Tr), R0[2].dot(b2.Tr)) + T0 - b1.Tr;
00074
00075 Vec3f T = Vec3f(Ttemp.dot(b1.axis[0]), Ttemp.dot(b1.axis[1]), Ttemp.dot(b1.axis[2]));
00076
00077 BVH_REAL dist = RSS::rectDistance(R, T, b1.l, b2.l);
00078 if(dist <= (b1.r + b2.r)) return true;
00079 return false;
00080 }
00081
00082 bool RSS::contain(const Vec3f& p) const
00083 {
00084 Vec3f local_p = p - Tr;
00085 BVH_REAL proj0 = local_p.dot(axis[0]);
00086 BVH_REAL proj1 = local_p.dot(axis[1]);
00087 BVH_REAL proj2 = local_p.dot(axis[2]);
00088 BVH_REAL abs_proj2 = fabs(proj2);
00089 Vec3f proj(proj0, proj1, proj2);
00090
00091
00092 if((proj0 < l[0]) && (proj0 > 0) && (proj1 < l[1]) && (proj1 > 0))
00093 {
00094 if(abs_proj2 < r)
00095 return true;
00096 else
00097 return false;
00098 }
00099 else if((proj0 < l[0]) && (proj0 > 0) && ((proj1 < 0) || (proj1 > l[1])))
00100 {
00101 BVH_REAL y = (proj1 > 0) ? l[1] : 0;
00102 Vec3f v(proj0, y, 0);
00103 if((proj - v).sqrLength() < r * r)
00104 return true;
00105 else
00106 return false;
00107 }
00108 else if((proj1 < l[1]) && (proj1 > 0) && ((proj0 < 0) || (proj0 > l[0])))
00109 {
00110 BVH_REAL x = (proj0 > 0) ? l[0] : 0;
00111 Vec3f v(x, proj1, 0);
00112 if((proj - v).sqrLength() < r * r)
00113 return true;
00114 else
00115 return false;
00116 }
00117 else
00118 {
00119 BVH_REAL x = (proj0 > 0) ? l[0] : 0;
00120 BVH_REAL y = (proj1 > 0) ? l[1] : 0;
00121 Vec3f v(x, y, 0);
00122 if((proj - v).sqrLength() < r * r)
00123 return true;
00124 else
00125 return false;
00126 }
00127 }
00128
00129 RSS& RSS::operator += (const Vec3f& p)
00130 {
00131 Vec3f local_p = p - Tr;
00132 BVH_REAL proj0 = local_p.dot(axis[0]);
00133 BVH_REAL proj1 = local_p.dot(axis[1]);
00134 BVH_REAL proj2 = local_p.dot(axis[2]);
00135 BVH_REAL abs_proj2 = fabs(proj2);
00136 Vec3f proj(proj0, proj1, proj2);
00137
00138
00139 if((proj0 < l[0]) && (proj0 > 0) && (proj1 < l[1]) && (proj1 > 0))
00140 {
00141 if(abs_proj2 < r)
00142 ;
00143 else
00144 {
00145 r = 0.5 * (r + abs_proj2);
00146
00147 if(proj2 > 0)
00148 Tr[2] += 0.5 * (abs_proj2 - r);
00149 else
00150 Tr[2] -= 0.5 * (abs_proj2 - r);
00151 }
00152 }
00153 else if((proj0 < l[0]) && (proj0 > 0) && ((proj1 < 0) || (proj1 > l[1])))
00154 {
00155 BVH_REAL y = (proj1 > 0) ? l[1] : 0;
00156 Vec3f v(proj0, y, 0);
00157 BVH_REAL new_r_sqr = (proj - v).sqrLength();
00158 if(new_r_sqr < r * r)
00159 ;
00160 else
00161 {
00162 if(abs_proj2 < r)
00163 {
00164 BVH_REAL delta_y = - sqrt(r * r - proj2 * proj2) + fabs(proj1 - y);
00165 l[1] += delta_y;
00166 if(proj1 < 0)
00167 Tr[1] -= delta_y;
00168 }
00169 else
00170 {
00171 BVH_REAL delta_y = fabs(proj1 - y);
00172 l[1] += delta_y;
00173 if(proj1 < 0)
00174 Tr[1] -= delta_y;
00175
00176 if(proj2 > 0)
00177 Tr[2] += 0.5 * (abs_proj2 - r);
00178 else
00179 Tr[2] -= 0.5 * (abs_proj2 - r);
00180 }
00181 }
00182 }
00183 else if((proj1 < l[1]) && (proj1 > 0) && ((proj0 < 0) || (proj0 > l[0])))
00184 {
00185 BVH_REAL x = (proj0 > 0) ? l[0] : 0;
00186 Vec3f v(x, proj1, 0);
00187 BVH_REAL new_r_sqr = (proj - v).sqrLength();
00188 if(new_r_sqr < r * r)
00189 ;
00190 else
00191 {
00192 if(abs_proj2 < r)
00193 {
00194 BVH_REAL delta_x = - sqrt(r * r - proj2 * proj2) + fabs(proj0 - x);
00195 l[0] += delta_x;
00196 if(proj0 < 0)
00197 Tr[0] -= delta_x;
00198 }
00199 else
00200 {
00201 BVH_REAL delta_x = fabs(proj0 - x);
00202 l[0] += delta_x;
00203 if(proj0 < 0)
00204 Tr[0] -= delta_x;
00205
00206 if(proj2 > 0)
00207 Tr[2] += 0.5 * (abs_proj2 - r);
00208 else
00209 Tr[2] -= 0.5 * (abs_proj2 - r);
00210 }
00211 }
00212 }
00213 else
00214 {
00215 BVH_REAL x = (proj0 > 0) ? l[0] : 0;
00216 BVH_REAL y = (proj1 > 0) ? l[1] : 0;
00217 Vec3f v(x, y, 0);
00218 BVH_REAL new_r_sqr = (proj - v).sqrLength();
00219 if(new_r_sqr < r * r)
00220 ;
00221 else
00222 {
00223 if(abs_proj2 < r)
00224 {
00225 BVH_REAL diag = sqrt(new_r_sqr - proj2 * proj2);
00226 BVH_REAL delta_diag = - sqrt(r * r - proj2 * proj2) + diag;
00227
00228 BVH_REAL delta_x = delta_diag / diag * fabs(proj0 - x);
00229 BVH_REAL delta_y = delta_diag / diag * fabs(proj1 - y);
00230 l[0] += delta_x;
00231 l[1] += delta_y;
00232
00233 if(proj0 < 0 && proj1 < 0)
00234 {
00235 Tr[0] -= delta_x;
00236 Tr[1] -= delta_y;
00237 }
00238 }
00239 else
00240 {
00241 BVH_REAL delta_x = fabs(proj0 - x);
00242 BVH_REAL delta_y = fabs(proj1 - y);
00243
00244 l[0] += delta_x;
00245 l[1] += delta_y;
00246
00247 if(proj0 < 0 && proj1 < 0)
00248 {
00249 Tr[0] -= delta_x;
00250 Tr[1] -= delta_y;
00251 }
00252
00253 if(proj2 > 0)
00254 Tr[2] += 0.5 * (abs_proj2 - r);
00255 else
00256 Tr[2] -= 0.5 * (abs_proj2 - r);
00257 }
00258 }
00259 }
00260
00261 return *this;
00262 }
00263
00264 RSS RSS::operator + (const RSS& other) const
00265 {
00266 RSS res = *this;
00267
00268 Vec3f d0_pos = other.axis[0] * (other.l[0] + other.r);
00269 Vec3f d1_pos = other.axis[1] * (other.l[1] + other.r);
00270 Vec3f d0_neg = other.axis[0] * (-other.r);
00271 Vec3f d1_neg = other.axis[1] * (-other.r);
00272 Vec3f d2_pos = other.axis[2] * other.r;
00273 Vec3f d2_neg = other.axis[2] * (-other.r);
00274
00275 Vec3f v[8];
00276 v[0] = other.Tr + d0_pos + d1_pos + d2_pos;
00277 v[1] = other.Tr + d0_pos + d1_pos + d2_neg;
00278 v[2] = other.Tr + d0_pos + d1_neg + d2_pos;
00279 v[3] = other.Tr + d0_pos + d1_neg + d2_neg;
00280 v[4] = other.Tr + d0_neg + d1_pos + d2_pos;
00281 v[5] = other.Tr + d0_neg + d1_pos + d2_neg;
00282 v[6] = other.Tr + d0_neg + d1_neg + d2_pos;
00283 v[7] = other.Tr + d0_neg + d1_neg + d2_neg;
00284
00285 for(int i = 0; i < 8; ++i)
00286 {
00287 res += v[i];
00288 }
00289
00290 return res;
00291 }
00292
00293 BVH_REAL RSS::distance(const RSS& other) const
00294 {
00295
00296
00297
00298 Vec3f t = other.Tr - Tr;
00299 Vec3f T(t.dot(axis[0]), t.dot(axis[1]), t.dot(axis[2]));
00300 Vec3f R[3];
00301 R[0] = Vec3f(axis[0].dot(other.axis[0]), axis[0].dot(other.axis[1]), axis[0].dot(other.axis[2]));
00302 R[1] = Vec3f(axis[1].dot(other.axis[0]), axis[1].dot(other.axis[1]), axis[1].dot(other.axis[2]));
00303 R[2] = Vec3f(axis[2].dot(other.axis[0]), axis[2].dot(other.axis[1]), axis[2].dot(other.axis[2]));
00304
00305 BVH_REAL dist = rectDistance(R, T, l, other.l);
00306 dist -= (r + other.r);
00307 return (dist < (BVH_REAL)0.0) ? (BVH_REAL)0.0 : dist;
00308 }
00309
00310 BVH_REAL distance(const Vec3f R0[3], const Vec3f& T0, const RSS& b1, const RSS& b2, Vec3f* P, Vec3f* Q)
00311 {
00312
00313 Vec3f Rtemp_col[3];
00314 Rtemp_col[0] = Vec3f(R0[0].dot(b2.axis[0]), R0[1].dot(b2.axis[0]), R0[2].dot(b2.axis[0]));
00315 Rtemp_col[1] = Vec3f(R0[0].dot(b2.axis[1]), R0[1].dot(b2.axis[1]), R0[2].dot(b2.axis[1]));
00316 Rtemp_col[2] = Vec3f(R0[0].dot(b2.axis[2]), R0[1].dot(b2.axis[2]), R0[2].dot(b2.axis[2]));
00317
00318
00319 Vec3f R[3];
00320 R[0] = Vec3f(b1.axis[0].dot(Rtemp_col[0]), b1.axis[0].dot(Rtemp_col[1]), b1.axis[0].dot(Rtemp_col[2]));
00321 R[1] = Vec3f(b1.axis[1].dot(Rtemp_col[0]), b1.axis[1].dot(Rtemp_col[1]), b1.axis[1].dot(Rtemp_col[2]));
00322 R[2] = Vec3f(b1.axis[2].dot(Rtemp_col[0]), b1.axis[2].dot(Rtemp_col[1]), b1.axis[2].dot(Rtemp_col[2]));
00323
00324 Vec3f Ttemp = Vec3f(R0[0].dot(b2.Tr), R0[1].dot(b2.Tr), R0[2].dot(b2.Tr)) + T0 - b1.Tr;
00325
00326 Vec3f T = Vec3f(Ttemp.dot(b1.axis[0]), Ttemp.dot(b1.axis[1]), Ttemp.dot(b1.axis[2]));
00327
00328 BVH_REAL dist = RSS::rectDistance(R, T, b1.l, b2.l, P, Q);
00329 dist -= (b1.r + b2.r);
00330 return (dist < (BVH_REAL)0.0) ? (BVH_REAL)0.0 : dist;
00331 }
00332
00333
00334 BVH_REAL RSS::rectDistance(const Vec3f Rab[3], Vec3f const& Tab, const BVH_REAL a[2], const BVH_REAL b[2], Vec3f* P, Vec3f* Q)
00335 {
00336 BVH_REAL A0_dot_B0, A0_dot_B1, A1_dot_B0, A1_dot_B1;
00337
00338 A0_dot_B0 = Rab[0][0];
00339 A0_dot_B1 = Rab[0][1];
00340 A1_dot_B0 = Rab[1][0];
00341 A1_dot_B1 = Rab[1][1];
00342
00343 BVH_REAL aA0_dot_B0, aA0_dot_B1, aA1_dot_B0, aA1_dot_B1;
00344 BVH_REAL bA0_dot_B0, bA0_dot_B1, bA1_dot_B0, bA1_dot_B1;
00345
00346 aA0_dot_B0 = a[0] * A0_dot_B0;
00347 aA0_dot_B1 = a[0] * A0_dot_B1;
00348 aA1_dot_B0 = a[1] * A1_dot_B0;
00349 aA1_dot_B1 = a[1] * A1_dot_B1;
00350 bA0_dot_B0 = b[0] * A0_dot_B0;
00351 bA1_dot_B0 = b[0] * A1_dot_B0;
00352 bA0_dot_B1 = b[1] * A0_dot_B1;
00353 bA1_dot_B1 = b[1] * A1_dot_B1;
00354
00355 Vec3f Tba = MTxV(Rab, Tab);
00356
00357 Vec3f S;
00358 BVH_REAL t, u;
00359
00360
00361
00362 BVH_REAL ALL_x, ALU_x, AUL_x, AUU_x;
00363 BVH_REAL BLL_x, BLU_x, BUL_x, BUU_x;
00364 BVH_REAL LA1_lx, LA1_ux, UA1_lx, UA1_ux, LB1_lx, LB1_ux, UB1_lx, UB1_ux;
00365
00366 ALL_x = -Tba[0];
00367 ALU_x = ALL_x + aA1_dot_B0;
00368 AUL_x = ALL_x + aA0_dot_B0;
00369 AUU_x = ALU_x + aA0_dot_B0;
00370
00371 if(ALL_x < ALU_x)
00372 {
00373 LA1_lx = ALL_x;
00374 LA1_ux = ALU_x;
00375 UA1_lx = AUL_x;
00376 UA1_ux = AUU_x;
00377 }
00378 else
00379 {
00380 LA1_lx = ALU_x;
00381 LA1_ux = ALL_x;
00382 UA1_lx = AUU_x;
00383 UA1_ux = AUL_x;
00384 }
00385
00386 BLL_x = Tab[0];
00387 BLU_x = BLL_x + bA0_dot_B1;
00388 BUL_x = BLL_x + bA0_dot_B0;
00389 BUU_x = BLU_x + bA0_dot_B0;
00390
00391 if(BLL_x < BLU_x)
00392 {
00393 LB1_lx = BLL_x;
00394 LB1_ux = BLU_x;
00395 UB1_lx = BUL_x;
00396 UB1_ux = BUU_x;
00397 }
00398 else
00399 {
00400 LB1_lx = BLU_x;
00401 LB1_ux = BLL_x;
00402 UB1_lx = BUU_x;
00403 UB1_ux = BUL_x;
00404 }
00405
00406
00407
00408 if((UA1_ux > b[0]) && (UB1_ux > a[0]))
00409 {
00410 if(((UA1_lx > b[0]) ||
00411 inVoronoi(b[1], a[1], A1_dot_B0, aA0_dot_B0 - b[0] - Tba[0],
00412 A1_dot_B1, aA0_dot_B1 - Tba[1],
00413 -Tab[1] - bA1_dot_B0))
00414 &&
00415 ((UB1_lx > a[0]) ||
00416 inVoronoi(a[1], b[1], A0_dot_B1, Tab[0] + bA0_dot_B0 - a[0],
00417 A1_dot_B1, Tab[1] + bA1_dot_B0, Tba[1] - aA0_dot_B1)))
00418 {
00419 segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1] + bA1_dot_B0,
00420 Tba[1] - aA0_dot_B1);
00421
00422 S[0] = Tab[0] + Rab[0][0] * b[0] + Rab[0][1] * u - a[0] ;
00423 S[1] = Tab[1] + Rab[1][0] * b[0] + Rab[1][1] * u - t;
00424 S[2] = Tab[2] + Rab[2][0] * b[0] + Rab[2][1] * u;
00425
00426 if(P && Q)
00427 {
00428 *P = Vec3f(a[0], t, 0);
00429 *Q = S + (*P);
00430 }
00431
00432 return S.length();
00433 }
00434 }
00435
00436
00437
00438
00439 if((UA1_lx < 0) && (LB1_ux > a[0]))
00440 {
00441 if(((UA1_ux < 0) ||
00442 inVoronoi(b[1], a[1], -A1_dot_B0, Tba[0] - aA0_dot_B0,
00443 A1_dot_B1, aA0_dot_B1 - Tba[1], -Tab[1]))
00444 &&
00445 ((LB1_lx > a[0]) ||
00446 inVoronoi(a[1], b[1], A0_dot_B1, Tab[0] - a[0],
00447 A1_dot_B1, Tab[1], Tba[1] - aA0_dot_B1)))
00448 {
00449 segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1], Tba[1] - aA0_dot_B1);
00450
00451 S[0] = Tab[0] + Rab[0][1] * u - a[0];
00452 S[1] = Tab[1] + Rab[1][1] * u - t;
00453 S[2] = Tab[2] + Rab[2][1] * u;
00454
00455 if(P && Q)
00456 {
00457 *P = Vec3f(a[0], t, 0);
00458 *Q = S + (*P);
00459 }
00460
00461 return S.length();
00462 }
00463 }
00464
00465
00466
00467 if((LA1_ux > b[0]) && (UB1_lx < 0))
00468 {
00469 if(((LA1_lx > b[0]) ||
00470 inVoronoi(b[1], a[1], A1_dot_B0, -Tba[0] - b[0],
00471 A1_dot_B1, -Tba[1], -Tab[1] - bA1_dot_B0))
00472 &&
00473 ((UB1_ux < 0) ||
00474 inVoronoi(a[1], b[1], -A0_dot_B1, -Tab[0] - bA0_dot_B0,
00475 A1_dot_B1, Tab[1] + bA1_dot_B0, Tba[1])))
00476 {
00477 segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1] + bA1_dot_B0, Tba[1]);
00478
00479 S[0] = Tab[0] + Rab[0][0] * b[0] + Rab[0][1] * u;
00480 S[1] = Tab[1] + Rab[1][0] * b[0] + Rab[1][1] * u - t;
00481 S[2] = Tab[2] + Rab[2][0] * b[0] + Rab[2][1] * u;
00482
00483 if(P && Q)
00484 {
00485 *P = Vec3f(0, t, 0);
00486 *Q = S + (*P);
00487 }
00488
00489 return S.length();
00490 }
00491 }
00492
00493
00494
00495 if((LA1_lx < 0) && (LB1_lx < 0))
00496 {
00497 if (((LA1_ux < 0) ||
00498 inVoronoi(b[1], a[1], -A1_dot_B0, Tba[0], A1_dot_B1,
00499 -Tba[1], -Tab[1]))
00500 &&
00501 ((LB1_ux < 0) ||
00502 inVoronoi(a[1], b[1], -A0_dot_B1, -Tab[0], A1_dot_B1,
00503 Tab[1], Tba[1])))
00504 {
00505 segCoords(t, u, a[1], b[1], A1_dot_B1, Tab[1], Tba[1]);
00506
00507 S[0] = Tab[0] + Rab[0][1] * u;
00508 S[1] = Tab[1] + Rab[1][1] * u - t;
00509 S[2] = Tab[2] + Rab[2][1] * u;
00510
00511 if(P && Q)
00512 {
00513 *P = Vec3f(0, t, 0);
00514 *Q = S + (*P);
00515 }
00516
00517 return S.length();
00518 }
00519 }
00520
00521 BVH_REAL ALL_y, ALU_y, AUL_y, AUU_y;
00522
00523 ALL_y = -Tba[1];
00524 ALU_y = ALL_y + aA1_dot_B1;
00525 AUL_y = ALL_y + aA0_dot_B1;
00526 AUU_y = ALU_y + aA0_dot_B1;
00527
00528 BVH_REAL LA1_ly, LA1_uy, UA1_ly, UA1_uy, LB0_lx, LB0_ux, UB0_lx, UB0_ux;
00529
00530 if(ALL_y < ALU_y)
00531 {
00532 LA1_ly = ALL_y;
00533 LA1_uy = ALU_y;
00534 UA1_ly = AUL_y;
00535 UA1_uy = AUU_y;
00536 }
00537 else
00538 {
00539 LA1_ly = ALU_y;
00540 LA1_uy = ALL_y;
00541 UA1_ly = AUU_y;
00542 UA1_uy = AUL_y;
00543 }
00544
00545 if(BLL_x < BUL_x)
00546 {
00547 LB0_lx = BLL_x;
00548 LB0_ux = BUL_x;
00549 UB0_lx = BLU_x;
00550 UB0_ux = BUU_x;
00551 }
00552 else
00553 {
00554 LB0_lx = BUL_x;
00555 LB0_ux = BLL_x;
00556 UB0_lx = BUU_x;
00557 UB0_ux = BLU_x;
00558 }
00559
00560
00561
00562 if((UA1_uy > b[1]) && (UB0_ux > a[0]))
00563 {
00564 if(((UA1_ly > b[1]) ||
00565 inVoronoi(b[0], a[1], A1_dot_B1, aA0_dot_B1 - Tba[1] - b[1],
00566 A1_dot_B0, aA0_dot_B0 - Tba[0], -Tab[1] - bA1_dot_B1))
00567 &&
00568 ((UB0_lx > a[0]) ||
00569 inVoronoi(a[1], b[0], A0_dot_B0, Tab[0] - a[0] + bA0_dot_B1,
00570 A1_dot_B0, Tab[1] + bA1_dot_B1, Tba[0] - aA0_dot_B0)))
00571 {
00572 segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1] + bA1_dot_B1,
00573 Tba[0] - aA0_dot_B0);
00574
00575 S[0] = Tab[0] + Rab[0][1] * b[1] + Rab[0][0] * u - a[0] ;
00576 S[1] = Tab[1] + Rab[1][1] * b[1] + Rab[1][0] * u - t;
00577 S[2] = Tab[2] + Rab[2][1] * b[1] + Rab[2][0] * u;
00578
00579 if(P && Q)
00580 {
00581 *P = Vec3f(a[0], t, 0);
00582 *Q = S + (*P);
00583 }
00584
00585 return S.length();
00586 }
00587 }
00588
00589
00590
00591 if((UA1_ly < 0) && (LB0_ux > a[0]))
00592 {
00593 if(((UA1_uy < 0) ||
00594 inVoronoi(b[0], a[1], -A1_dot_B1, Tba[1] - aA0_dot_B1, A1_dot_B0,
00595 aA0_dot_B0 - Tba[0], -Tab[1]))
00596 &&
00597 ((LB0_lx > a[0]) ||
00598 inVoronoi(a[1], b[0], A0_dot_B0, Tab[0] - a[0],
00599 A1_dot_B0, Tab[1], Tba[0] - aA0_dot_B0)))
00600 {
00601 segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1], Tba[0] - aA0_dot_B0);
00602
00603 S[0] = Tab[0] + Rab[0][0] * u - a[0];
00604 S[1] = Tab[1] + Rab[1][0] * u - t;
00605 S[2] = Tab[2] + Rab[2][0] * u;
00606
00607 if(P && Q)
00608 {
00609 *P = Vec3f(a[0], t, 0);
00610 *Q = S + (*P);
00611 }
00612
00613 return S.length();
00614 }
00615 }
00616
00617
00618
00619 if((LA1_uy > b[1]) && (UB0_lx < 0))
00620 {
00621 if(((LA1_ly > b[1]) ||
00622 inVoronoi(b[0], a[1], A1_dot_B1, -Tba[1] - b[1],
00623 A1_dot_B0, -Tba[0], -Tab[1] - bA1_dot_B1))
00624 &&
00625
00626 ((UB0_ux < 0) ||
00627 inVoronoi(a[1], b[0], -A0_dot_B0, -Tab[0] - bA0_dot_B1, A1_dot_B0,
00628 Tab[1] + bA1_dot_B1, Tba[0])))
00629 {
00630 segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1] + bA1_dot_B1, Tba[0]);
00631
00632 S[0] = Tab[0] + Rab[0][1] * b[1] + Rab[0][0] * u;
00633 S[1] = Tab[1] + Rab[1][1] * b[1] + Rab[1][0] * u - t;
00634 S[2] = Tab[2] + Rab[2][1] * b[1] + Rab[2][0] * u;
00635
00636 if(P && Q)
00637 {
00638 *P = Vec3f(0, t, 0);
00639 *Q = S + (*P);
00640 }
00641
00642
00643 return S.length();
00644 }
00645 }
00646
00647
00648
00649 if((LA1_ly < 0) && (LB0_lx < 0))
00650 {
00651 if(((LA1_uy < 0) ||
00652 inVoronoi(b[0], a[1], -A1_dot_B1, Tba[1], A1_dot_B0,
00653 -Tba[0], -Tab[1]))
00654 &&
00655 ((LB0_ux < 0) ||
00656 inVoronoi(a[1], b[0], -A0_dot_B0, -Tab[0], A1_dot_B0,
00657 Tab[1], Tba[0])))
00658 {
00659 segCoords(t, u, a[1], b[0], A1_dot_B0, Tab[1], Tba[0]);
00660
00661 S[0] = Tab[0] + Rab[0][0] * u;
00662 S[1] = Tab[1] + Rab[1][0] * u - t;
00663 S[2] = Tab[2] + Rab[2][0] * u;
00664
00665 if(P&& Q)
00666 {
00667 *P = Vec3f(0, t, 0);
00668 *Q = S + (*P);
00669 }
00670
00671 return S.length();
00672 }
00673 }
00674
00675 BVH_REAL BLL_y, BLU_y, BUL_y, BUU_y;
00676
00677 BLL_y = Tab[1];
00678 BLU_y = BLL_y + bA1_dot_B1;
00679 BUL_y = BLL_y + bA1_dot_B0;
00680 BUU_y = BLU_y + bA1_dot_B0;
00681
00682 BVH_REAL LA0_lx, LA0_ux, UA0_lx, UA0_ux, LB1_ly, LB1_uy, UB1_ly, UB1_uy;
00683
00684 if(ALL_x < AUL_x)
00685 {
00686 LA0_lx = ALL_x;
00687 LA0_ux = AUL_x;
00688 UA0_lx = ALU_x;
00689 UA0_ux = AUU_x;
00690 }
00691 else
00692 {
00693 LA0_lx = AUL_x;
00694 LA0_ux = ALL_x;
00695 UA0_lx = AUU_x;
00696 UA0_ux = ALU_x;
00697 }
00698
00699 if(BLL_y < BLU_y)
00700 {
00701 LB1_ly = BLL_y;
00702 LB1_uy = BLU_y;
00703 UB1_ly = BUL_y;
00704 UB1_uy = BUU_y;
00705 }
00706 else
00707 {
00708 LB1_ly = BLU_y;
00709 LB1_uy = BLL_y;
00710 UB1_ly = BUU_y;
00711 UB1_uy = BUL_y;
00712 }
00713
00714
00715
00716 if((UA0_ux > b[0]) && (UB1_uy > a[1]))
00717 {
00718 if(((UA0_lx > b[0]) ||
00719 inVoronoi(b[1], a[0], A0_dot_B0, aA1_dot_B0 - Tba[0] - b[0],
00720 A0_dot_B1, aA1_dot_B1 - Tba[1], -Tab[0] - bA0_dot_B0))
00721 &&
00722 ((UB1_ly > a[1]) ||
00723 inVoronoi(a[0], b[1], A1_dot_B1, Tab[1] - a[1] + bA1_dot_B0,
00724 A0_dot_B1, Tab[0] + bA0_dot_B0, Tba[1] - aA1_dot_B1)))
00725 {
00726 segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0] + bA0_dot_B0,
00727 Tba[1] - aA1_dot_B1);
00728
00729 S[0] = Tab[0] + Rab[0][0] * b[0] + Rab[0][1] * u - t;
00730 S[1] = Tab[1] + Rab[1][0] * b[0] + Rab[1][1] * u - a[1];
00731 S[2] = Tab[2] + Rab[2][0] * b[0] + Rab[2][1] * u;
00732
00733 if(P && Q)
00734 {
00735 *P = Vec3f(t, a[1], 0);
00736 *Q = S + (*P);
00737 }
00738
00739 return S.length();
00740 }
00741 }
00742
00743
00744
00745 if((UA0_lx < 0) && (LB1_uy > a[1]))
00746 {
00747 if(((UA0_ux < 0) ||
00748 inVoronoi(b[1], a[0], -A0_dot_B0, Tba[0] - aA1_dot_B0, A0_dot_B1,
00749 aA1_dot_B1 - Tba[1], -Tab[0]))
00750 &&
00751 ((LB1_ly > a[1]) ||
00752 inVoronoi(a[0], b[1], A1_dot_B1, Tab[1] - a[1], A0_dot_B1, Tab[0],
00753 Tba[1] - aA1_dot_B1)))
00754 {
00755 segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0], Tba[1] - aA1_dot_B1);
00756
00757 S[0] = Tab[0] + Rab[0][1] * u - t;
00758 S[1] = Tab[1] + Rab[1][1] * u - a[1];
00759 S[2] = Tab[2] + Rab[2][1] * u;
00760
00761 if(P && Q)
00762 {
00763 *P = Vec3f(t, a[1], 0);
00764 *Q = S + (*P);
00765 }
00766
00767 return S.length();
00768 }
00769 }
00770
00771
00772
00773 if((LA0_ux > b[0]) && (UB1_ly < 0))
00774 {
00775 if(((LA0_lx > b[0]) ||
00776 inVoronoi(b[1], a[0], A0_dot_B0, -b[0] - Tba[0], A0_dot_B1, -Tba[1],
00777 -bA0_dot_B0 - Tab[0]))
00778 &&
00779 ((UB1_uy < 0) ||
00780 inVoronoi(a[0], b[1], -A1_dot_B1, -Tab[1] - bA1_dot_B0, A0_dot_B1,
00781 Tab[0] + bA0_dot_B0, Tba[1])))
00782 {
00783 segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0] + bA0_dot_B0, Tba[1]);
00784
00785 S[0] = Tab[0] + Rab[0][0] * b[0] + Rab[0][1] * u - t;
00786 S[1] = Tab[1] + Rab[1][0] * b[0] + Rab[1][1] * u;
00787 S[2] = Tab[2] + Rab[2][0] * b[0] + Rab[2][1] * u;
00788
00789 if(P && Q)
00790 {
00791 *P = Vec3f(t, 0, 0);
00792 *Q = S + (*P);
00793 }
00794
00795 return S.length();
00796 }
00797 }
00798
00799
00800
00801 if((LA0_lx < 0) && (LB1_ly < 0))
00802 {
00803 if(((LA0_ux < 0) ||
00804 inVoronoi(b[1], a[0], -A0_dot_B0, Tba[0], A0_dot_B1, -Tba[1],
00805 -Tab[0]))
00806 &&
00807 ((LB1_uy < 0) ||
00808 inVoronoi(a[0], b[1], -A1_dot_B1, -Tab[1], A0_dot_B1,
00809 Tab[0], Tba[1])))
00810 {
00811 segCoords(t, u, a[0], b[1], A0_dot_B1, Tab[0], Tba[1]);
00812
00813 S[0] = Tab[0] + Rab[0][1] * u - t;
00814 S[1] = Tab[1] + Rab[1][1] * u;
00815 S[2] = Tab[2] + Rab[2][1] * u;
00816
00817 if(P && Q)
00818 {
00819 *P = Vec3f(t, 0, 0);
00820 *Q = S + (*P);
00821 }
00822
00823 return S.length();
00824 }
00825 }
00826
00827 BVH_REAL LA0_ly, LA0_uy, UA0_ly, UA0_uy, LB0_ly, LB0_uy, UB0_ly, UB0_uy;
00828
00829 if(ALL_y < AUL_y)
00830 {
00831 LA0_ly = ALL_y;
00832 LA0_uy = AUL_y;
00833 UA0_ly = ALU_y;
00834 UA0_uy = AUU_y;
00835 }
00836 else
00837 {
00838 LA0_ly = AUL_y;
00839 LA0_uy = ALL_y;
00840 UA0_ly = AUU_y;
00841 UA0_uy = ALU_y;
00842 }
00843
00844 if(BLL_y < BUL_y)
00845 {
00846 LB0_ly = BLL_y;
00847 LB0_uy = BUL_y;
00848 UB0_ly = BLU_y;
00849 UB0_uy = BUU_y;
00850 }
00851 else
00852 {
00853 LB0_ly = BUL_y;
00854 LB0_uy = BLL_y;
00855 UB0_ly = BUU_y;
00856 UB0_uy = BLU_y;
00857 }
00858
00859
00860
00861 if((UA0_uy > b[1]) && (UB0_uy > a[1]))
00862 {
00863 if(((UA0_ly > b[1]) ||
00864 inVoronoi(b[0], a[0], A0_dot_B1, aA1_dot_B1 - Tba[1] - b[1],
00865 A0_dot_B0, aA1_dot_B0 - Tba[0], -Tab[0] - bA0_dot_B1))
00866 &&
00867 ((UB0_ly > a[1]) ||
00868 inVoronoi(a[0], b[0], A1_dot_B0, Tab[1] - a[1] + bA1_dot_B1, A0_dot_B0,
00869 Tab[0] + bA0_dot_B1, Tba[0] - aA1_dot_B0)))
00870 {
00871 segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0] + bA0_dot_B1,
00872 Tba[0] - aA1_dot_B0);
00873
00874 S[0] = Tab[0] + Rab[0][1] * b[1] + Rab[0][0] * u - t;
00875 S[1] = Tab[1] + Rab[1][1] * b[1] + Rab[1][0] * u - a[1];
00876 S[2] = Tab[2] + Rab[2][1] * b[1] + Rab[2][0] * u;
00877
00878 if(P && Q)
00879 {
00880 *P = Vec3f(t, a[1], 0);
00881 *Q = S + (*P);
00882 }
00883
00884 return S.length();
00885 }
00886 }
00887
00888
00889
00890 if((UA0_ly < 0) && (LB0_uy > a[1]))
00891 {
00892 if(((UA0_uy < 0) ||
00893 inVoronoi(b[0], a[0], -A0_dot_B1, Tba[1] - aA1_dot_B1, A0_dot_B0,
00894 aA1_dot_B0 - Tba[0], -Tab[0]))
00895 &&
00896 ((LB0_ly > a[1]) ||
00897 inVoronoi(a[0], b[0], A1_dot_B0, Tab[1] - a[1],
00898 A0_dot_B0, Tab[0], Tba[0] - aA1_dot_B0)))
00899 {
00900 segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0], Tba[0] - aA1_dot_B0);
00901
00902 S[0] = Tab[0] + Rab[0][0] * u - t;
00903 S[1] = Tab[1] + Rab[1][0] * u - a[1];
00904 S[2] = Tab[2] + Rab[2][0] * u;
00905
00906 if(P && Q)
00907 {
00908 *P = Vec3f(t, a[1], 0);
00909 *Q = S + (*P);
00910 }
00911
00912 return S.length();
00913 }
00914 }
00915
00916
00917
00918 if((LA0_uy > b[1]) && (UB0_ly < 0))
00919 {
00920 if(((LA0_ly > b[1]) ||
00921 inVoronoi(b[0], a[0], A0_dot_B1, -Tba[1] - b[1], A0_dot_B0, -Tba[0],
00922 -Tab[0] - bA0_dot_B1))
00923 &&
00924
00925 ((UB0_uy < 0) ||
00926 inVoronoi(a[0], b[0], -A1_dot_B0, -Tab[1] - bA1_dot_B1, A0_dot_B0,
00927 Tab[0] + bA0_dot_B1, Tba[0])))
00928 {
00929 segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0] + bA0_dot_B1, Tba[0]);
00930
00931 S[0] = Tab[0] + Rab[0][1] * b[1] + Rab[0][0] * u - t;
00932 S[1] = Tab[1] + Rab[1][1] * b[1] + Rab[1][0] * u;
00933 S[2] = Tab[2] + Rab[2][1] * b[1] + Rab[2][0] * u;
00934
00935 if(P && Q)
00936 {
00937 *P = Vec3f(t, 0, 0);
00938 *Q = S + (*P);
00939 }
00940
00941 return S.length();
00942 }
00943 }
00944
00945
00946
00947 if((LA0_ly < 0) && (LB0_ly < 0))
00948 {
00949 if(((LA0_uy < 0) ||
00950 inVoronoi(b[0], a[0], -A0_dot_B1, Tba[1], A0_dot_B0,
00951 -Tba[0], -Tab[0]))
00952 &&
00953 ((LB0_uy < 0) ||
00954 inVoronoi(a[0], b[0], -A1_dot_B0, -Tab[1], A0_dot_B0,
00955 Tab[0], Tba[0])))
00956 {
00957 segCoords(t, u, a[0], b[0], A0_dot_B0, Tab[0], Tba[0]);
00958
00959 S[0] = Tab[0] + Rab[0][0] * u - t;
00960 S[1] = Tab[1] + Rab[1][0] * u;
00961 S[2] = Tab[2] + Rab[2][0] * u;
00962
00963 if(P && Q)
00964 {
00965 *P = Vec3f(t, 0, 0);
00966 *Q = S + (*P);
00967 }
00968
00969 return S.length();
00970 }
00971 }
00972
00973
00974
00975 BVH_REAL sep1, sep2;
00976
00977 if(Tab[2] > 0.0)
00978 {
00979 sep1 = Tab[2];
00980 if (Rab[2][0] < 0.0) sep1 += b[0] * Rab[2][0];
00981 if (Rab[2][1] < 0.0) sep1 += b[1] * Rab[2][1];
00982 }
00983 else
00984 {
00985 sep1 = -Tab[2];
00986 if (Rab[2][0] > 0.0) sep1 -= b[0] * Rab[2][0];
00987 if (Rab[2][1] > 0.0) sep1 -= b[1] * Rab[2][1];
00988 }
00989
00990 if(Tba[2] < 0)
00991 {
00992 sep2 = -Tba[2];
00993 if (Rab[0][2] < 0.0) sep2 += a[0] * Rab[0][2];
00994 if (Rab[1][2] < 0.0) sep2 += a[1] * Rab[1][2];
00995 }
00996 else
00997 {
00998 sep2 = Tba[2];
00999 if (Rab[0][2] > 0.0) sep2 -= a[0] * Rab[0][2];
01000 if (Rab[1][2] > 0.0) sep2 -= a[1] * Rab[1][2];
01001 }
01002
01003 if(sep1 >= sep2 && sep1 >= 0)
01004 {
01005 if(Tab[2] > 0)
01006 S = Vec3f(0, 0, sep1);
01007 else
01008 S = Vec3f(0, 0, -sep1);
01009
01010 if(P && Q)
01011 {
01012 *Q = S;
01013 *P = Vec3f(0, 0, 0);
01014 }
01015 }
01016
01017 if(sep2 >= sep1 && sep2 >= 0)
01018 {
01019 Vec3f Q_(Tab[0], Tab[1], Tab[2]);
01020 Vec3f P_;
01021 if(Tba[2] < 0)
01022 {
01023 P_[0] = Rab[0][2] * sep2 + Tab[0];
01024 P_[1] = Rab[1][2] * sep2 + Tab[1];
01025 P_[2] = Rab[2][2] * sep2 + Tab[2];
01026 }
01027 else
01028 {
01029 P_[0] = -Rab[0][2] * sep2 + Tab[0];
01030 P_[1] = -Rab[1][2] * sep2 + Tab[1];
01031 P_[2] = -Rab[2][2] * sep2 + Tab[2];
01032 }
01033
01034 S = Q_ - P_;
01035
01036 if(P && Q)
01037 {
01038 *P = P_;
01039 *Q = Q_;
01040 }
01041 }
01042
01043 BVH_REAL sep = (sep1 > sep2 ? sep1 : sep2);
01044 return (sep > 0 ? sep : 0);
01045 }
01046
01047
01048 void RSS::clipToRange(BVH_REAL& val, BVH_REAL a, BVH_REAL b)
01049 {
01050 if(val < a) val = a;
01051 else if(val > b) val = b;
01052 }
01053
01054
01055 void RSS::segCoords(BVH_REAL& t, BVH_REAL& u, BVH_REAL a, BVH_REAL b, BVH_REAL A_dot_B, BVH_REAL A_dot_T, BVH_REAL B_dot_T)
01056 {
01057 BVH_REAL denom = 1 - A_dot_B * A_dot_B;
01058
01059 if(denom == 0) t = 0;
01060 else
01061 {
01062 t = (A_dot_T - B_dot_T * A_dot_B) / denom;
01063 clipToRange(t, 0, a);
01064 }
01065
01066 u = t * A_dot_B - B_dot_T;
01067 if(u < 0)
01068 {
01069 u = 0;
01070 t = A_dot_T;
01071 clipToRange(t, 0, a);
01072 }
01073 else if(u > b)
01074 {
01075 u = b;
01076 t = u * A_dot_B + A_dot_T;
01077 clipToRange(t, 0, a);
01078 }
01079 }
01080
01081 bool RSS::inVoronoi(BVH_REAL a, BVH_REAL b, BVH_REAL Anorm_dot_B, BVH_REAL Anorm_dot_T, BVH_REAL A_dot_B, BVH_REAL A_dot_T, BVH_REAL B_dot_T)
01082 {
01083 if(fabs(Anorm_dot_B) < 1e-7) return false;
01084
01085 BVH_REAL t, u, v;
01086
01087 u = -Anorm_dot_T / Anorm_dot_B;
01088 clipToRange(u, 0, b);
01089
01090 t = u * A_dot_B + A_dot_T;
01091 clipToRange(t, 0, a);
01092
01093 v = t * A_dot_B - B_dot_T;
01094
01095 if(Anorm_dot_B > 0)
01096 {
01097 if(v > (u + 1e-7)) return true;
01098 }
01099 else
01100 {
01101 if(v < (u - 1e-7)) return true;
01102 }
01103 return false;
01104 }
01105
01106
01107
01108
01109
01110 }