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
00032 double
00033 pointBoxDistanceSq(const BoundingBox &box, const position &p)
00034 {
00035 vec3 v = (p - position::ORIGIN) - box.getTran().translation();
00036 mat3 RMat;
00037 box.getTran().rotation().ToRotationMatrix(RMat);
00038
00039 double sqDist = 0.0;
00040 for (int i=0; i<3; i++) {
00041 double d = v % RMat.row(i);
00042 double excess = 0.0;
00043
00044
00045 if (d < -box.halfSize[i])
00046 excess = d + box.halfSize[i];
00047 else if (d > box.halfSize[i])
00048 excess = d - box.halfSize[i];
00049 sqDist += excess * excess;
00050 }
00051 return sqDist;
00052 }
00053
00057 position
00058 closestPtBbox(const BoundingBox &bbox, const position &p)
00059 {
00060 vec3 d = (p - position::ORIGIN) - bbox.getTran().translation();
00061 mat3 RMat;
00062 bbox.getTran().rotation().ToRotationMatrix(RMat);
00063
00064 vec3 q = bbox.getTran().translation();
00065
00066 for (int i=0; i<3; i++) {
00067
00068
00069 double dist = d % RMat.row(i);
00070
00071 if (dist > bbox.halfSize[i]) dist = bbox.halfSize[i];
00072 if (dist < -bbox.halfSize[i]) dist = -bbox.halfSize[i];
00073
00074 q += dist * RMat.row(i);
00075 }
00076 return position( q.x(), q.y(), q.z() );
00077 }
00078
00079 void
00080 BoundingBox::applyTransform(const transf &t)
00081 {
00082 mTran = mTran * t;
00083 mTranInv = mTran.inverse();
00084 }
00085
00086 bool
00087 bboxOverlap(const BoundingBox &bb1, const BoundingBox &bb2, const transf &tran2To1)
00088 {
00089 int i, k;
00090
00091 transf BtoA = bb2.getTran() * tran2To1 * bb1.getTranInv();
00092 mat3 RMat;
00093 BtoA.rotation().ToRotationMatrix(RMat);
00094
00095 double B[3][3];
00096 for( i=0; i<3 ; i++ ) {
00097 for( k=0; k<3 ; k++ ) {
00098 B[i][k] = RMat.element(k,i);
00099 }
00100 }
00101
00102
00103 vec3 T = BtoA.translation();
00104
00105 vec3 a = bb1.halfSize;
00106 vec3 b = bb2.halfSize;
00107
00108 double t, s;
00109 register int r;
00110 double Bf[3][3];
00111 const double reps = 1e-6;
00112
00113
00114 Bf[0][0] = fabs(B[0][0]); Bf[0][0] += reps;
00115 Bf[0][1] = fabs(B[0][1]); Bf[0][1] += reps;
00116 Bf[0][2] = fabs(B[0][2]); Bf[0][2] += reps;
00117 Bf[1][0] = fabs(B[1][0]); Bf[1][0] += reps;
00118 Bf[1][1] = fabs(B[1][1]); Bf[1][1] += reps;
00119 Bf[1][2] = fabs(B[1][2]); Bf[1][2] += reps;
00120 Bf[2][0] = fabs(B[2][0]); Bf[2][0] += reps;
00121 Bf[2][1] = fabs(B[2][1]); Bf[2][1] += reps;
00122 Bf[2][2] = fabs(B[2][2]); Bf[2][2] += reps;
00123
00124
00125 r = 1;
00126
00127
00128 t = fabs(T[0]);
00129
00130 r &= (t <=
00131 (a[0] + b[0] * Bf[0][0] + b[1] * Bf[0][1] + b[2] * Bf[0][2]));
00132 if (!r) return false;
00133
00134
00135 s = T[0]*B[0][0] + T[1]*B[1][0] + T[2]*B[2][0];
00136 t = fabs(s);
00137
00138 r &= ( t <=
00139 (b[0] + a[0] * Bf[0][0] + a[1] * Bf[1][0] + a[2] * Bf[2][0]));
00140 if (!r) return false;
00141
00142
00143 t = fabs(T[1]);
00144
00145 r &= ( t <=
00146 (a[1] + b[0] * Bf[1][0] + b[1] * Bf[1][1] + b[2] * Bf[1][2]));
00147 if (!r) return false;
00148
00149
00150 t = fabs(T[2]);
00151
00152 r &= ( t <=
00153 (a[2] + b[0] * Bf[2][0] + b[1] * Bf[2][1] + b[2] * Bf[2][2]));
00154 if (!r) return false;
00155
00156
00157 s = T[0]*B[0][1] + T[1]*B[1][1] + T[2]*B[2][1];
00158 t = fabs(s);
00159
00160 r &= ( t <=
00161 (b[1] + a[0] * Bf[0][1] + a[1] * Bf[1][1] + a[2] * Bf[2][1]));
00162 if (!r) return false;
00163
00164
00165 s = T[0]*B[0][2] + T[1]*B[1][2] + T[2]*B[2][2];
00166 t = fabs(s);
00167
00168 r &= ( t <=
00169 (b[2] + a[0] * Bf[0][2] + a[1] * Bf[1][2] + a[2] * Bf[2][2]));
00170 if (!r) return false;
00171
00172
00173 s = T[2] * B[1][0] - T[1] * B[2][0];
00174 t = fabs(s);
00175
00176 r &= ( t <=
00177 (a[1] * Bf[2][0] + a[2] * Bf[1][0] +
00178 b[1] * Bf[0][2] + b[2] * Bf[0][1]));
00179 if (!r) return false;
00180
00181
00182 s = T[2] * B[1][1] - T[1] * B[2][1];
00183 t = fabs(s);
00184
00185 r &= ( t <=
00186 (a[1] * Bf[2][1] + a[2] * Bf[1][1] +
00187 b[0] * Bf[0][2] + b[2] * Bf[0][0]));
00188 if (!r) return false;
00189
00190
00191 s = T[2] * B[1][2] - T[1] * B[2][2];
00192 t = fabs(s);
00193
00194 r &= ( t <=
00195 (a[1] * Bf[2][2] + a[2] * Bf[1][2] +
00196 b[0] * Bf[0][1] + b[1] * Bf[0][0]));
00197 if (!r) return false;
00198
00199
00200 s = T[0] * B[2][0] - T[2] * B[0][0];
00201 t = fabs(s);
00202
00203 r &= ( t <=
00204 (a[0] * Bf[2][0] + a[2] * Bf[0][0] +
00205 b[1] * Bf[1][2] + b[2] * Bf[1][1]));
00206 if (!r) return false;
00207
00208
00209 s = T[0] * B[2][1] - T[2] * B[0][1];
00210 t = fabs(s);
00211
00212 r &= ( t <=
00213 (a[0] * Bf[2][1] + a[2] * Bf[0][1] +
00214 b[0] * Bf[1][2] + b[2] * Bf[1][0]));
00215 if (!r) return false;
00216
00217
00218 s = T[0] * B[2][2] - T[2] * B[0][2];
00219 t = fabs(s);
00220
00221 r &= (t <=
00222 (a[0] * Bf[2][2] + a[2] * Bf[0][2] +
00223 b[0] * Bf[1][1] + b[1] * Bf[1][0]));
00224 if (!r) return false;
00225
00226
00227 s = T[1] * B[0][0] - T[0] * B[1][0];
00228 t = fabs(s);
00229
00230 r &= (t <=
00231 (a[0] * Bf[1][0] + a[1] * Bf[0][0] +
00232 b[1] * Bf[2][2] + b[2] * Bf[2][1]));
00233 if (!r) return false;
00234
00235
00236 s = T[1] * B[0][1] - T[0] * B[1][1];
00237 t = fabs(s);
00238
00239 r &= ( t <=
00240 (a[0] * Bf[1][1] + a[1] * Bf[0][1] +
00241 b[0] * Bf[2][2] + b[2] * Bf[2][0]));
00242 if (!r) return false;
00243
00244
00245 s = T[1] * B[0][2] - T[0] * B[1][2];
00246 t = fabs(s);
00247
00248 r &= ( t <=
00249 (a[0] * Bf[1][2] + a[1] * Bf[0][2] +
00250 b[0] * Bf[2][1] + b[1] * Bf[2][0]));
00251 if (!r) return false;
00252
00253 return true;
00254 }
00255
00256 double bboxDistanceApp(const BoundingBox &bb1, const BoundingBox &bb2)
00257 {
00258
00259
00260
00261 vec3 t = bb1.getTran().translation() - bb2.getTran().translation();
00262 double dist = t.len();
00263 dist -= bb1.halfSize.len();
00264 dist -= bb2.halfSize.len();
00265 return dist;
00266 }
00267
00268 double bboxDistanceSq(const BoundingBox &bb1, const BoundingBox &bb2, const transf &tran2To1)
00269 {
00270
00271 int i, k;
00272
00273 transf BtoA = bb2.getTran() * tran2To1 * bb1.getTranInv();
00274 mat3 RMat;
00275 BtoA.rotation().ToRotationMatrix(RMat);
00276
00277 double B[3][3];
00278 for( i=0; i<3 ; i++ ) {
00279 for( k=0; k<3 ; k++ ) {
00280 B[i][k] = RMat.element(k,i);
00281 }
00282 }
00283
00284
00285 vec3 T = BtoA.translation();
00286
00287 vec3 a = bb1.halfSize;
00288 vec3 b = bb2.halfSize;
00289
00290 double Bf[3][3];
00291 const double reps = 1e-6;
00292
00293
00294 Bf[0][0] = fabs(B[0][0]); Bf[0][0] += reps;
00295 Bf[0][1] = fabs(B[0][1]); Bf[0][1] += reps;
00296 Bf[0][2] = fabs(B[0][2]); Bf[0][2] += reps;
00297 Bf[1][0] = fabs(B[1][0]); Bf[1][0] += reps;
00298 Bf[1][1] = fabs(B[1][1]); Bf[1][1] += reps;
00299 Bf[1][2] = fabs(B[1][2]); Bf[1][2] += reps;
00300 Bf[2][0] = fabs(B[2][0]); Bf[2][0] += reps;
00301 Bf[2][1] = fabs(B[2][1]); Bf[2][1] += reps;
00302 Bf[2][2] = fabs(B[2][2]); Bf[2][2] += reps;
00303
00304 double d, maxD = -1.0e10;
00305 double t, s;
00306 double a0,a1,a2,b0,b1,b2;
00307
00308
00309
00310 t = fabs(T[0]);
00311 d = t - (a[0] + b[0] * Bf[0][0] + b[1] * Bf[0][1] + b[2] * Bf[0][2]);
00312 a0 = std::max(0.0, d); a0*=a0;
00313
00314
00315 t = fabs(T[1]);
00316 d = t - (a[1] + b[0] * Bf[1][0] + b[1] * Bf[1][1] + b[2] * Bf[1][2]);
00317 a1 = std::max(0.0, d); a1*=a1;
00318
00319
00320 t = fabs(T[2]);
00321 d = t - (a[2] + b[0] * Bf[2][0] + b[1] * Bf[2][1] + b[2] * Bf[2][2]);
00322 a2 = std::max(0.0, d); a2*=a2;
00323
00324
00325 s = T[0]*B[0][0] + T[1]*B[1][0] + T[2]*B[2][0];
00326 t = fabs(s);
00327 d = t - (b[0] + a[0] * Bf[0][0] + a[1] * Bf[1][0] + a[2] * Bf[2][0]);
00328 b0 = std::max(0.0, d); b0*=b0;
00329
00330
00331 s = T[0]*B[0][1] + T[1]*B[1][1] + T[2]*B[2][1];
00332 t = fabs(s);
00333 d = t - (b[1] + a[0] * Bf[0][1] + a[1] * Bf[1][1] + a[2] * Bf[2][1]);
00334 b1 = std::max(0.0, d); b1*=b1;
00335
00336
00337 s = T[0]*B[0][2] + T[1]*B[1][2] + T[2]*B[2][2];
00338 t = fabs(s);
00339 d = t - (b[2] + a[0] * Bf[0][2] + a[1] * Bf[1][2] + a[2] * Bf[2][2]);
00340 b2 = std::max(0.0, d); b2*=b2;
00341
00342 maxD = std::max(a0+a1+a2, b0+b1+b2);
00343
00344
00345
00346
00347
00348
00349 s = T[2] * B[1][0] - T[1] * B[2][0];
00350 t = fabs(s);
00351 d = t - (a[1] * Bf[2][0] + a[2] * Bf[1][0] + b[1] * Bf[0][2] + b[2] * Bf[0][1]);
00352 d = std::max(0.0, d); d*=d;
00353 maxD = std::max(maxD, std::max(a0+d, b0+d));
00354
00355
00356 s = T[2] * B[1][1] - T[1] * B[2][1];
00357 t = fabs(s);
00358 d = t - (a[1] * Bf[2][1] + a[2] * Bf[1][1] + b[0] * Bf[0][2] + b[2] * Bf[0][0]);
00359 d = std::max(0.0, d); d*=d;
00360 maxD = std::max(maxD, std::max(a0+d, b1+d));
00361
00362
00363 s = T[2] * B[1][2] - T[1] * B[2][2];
00364 t = fabs(s);
00365 d = t - (a[1] * Bf[2][2] + a[2] * Bf[1][2] + b[0] * Bf[0][1] + b[1] * Bf[0][0]);
00366 d = std::max(0.0, d); d*=d;
00367 maxD = std::max(maxD, std::max(a0+d, b2+d));
00368
00369
00370 s = T[0] * B[2][0] - T[2] * B[0][0];
00371 t = fabs(s);
00372 d = t - (a[0] * Bf[2][0] + a[2] * Bf[0][0] + b[1] * Bf[1][2] + b[2] * Bf[1][1]);
00373 d = std::max(0.0, d); d*=d;
00374 maxD = std::max(maxD, std::max(a1+d, b0+d));
00375
00376
00377 s = T[0] * B[2][1] - T[2] * B[0][1];
00378 t = fabs(s);
00379 d = t - (a[0] * Bf[2][1] + a[2] * Bf[0][1] + b[0] * Bf[1][2] + b[2] * Bf[1][0]);
00380 d = std::max(0.0, d); d*=d;
00381 maxD = std::max(maxD, std::max(a1+d, b1+d));
00382
00383
00384 s = T[0] * B[2][2] - T[2] * B[0][2];
00385 t = fabs(s);
00386 d = t - (a[0] * Bf[2][2] + a[2] * Bf[0][2] + b[0] * Bf[1][1] + b[1] * Bf[1][0]);
00387 d = std::max(0.0, d); d*=d;
00388 maxD = std::max(maxD, std::max(a1+d, b2+d));
00389
00390
00391 s = T[1] * B[0][0] - T[0] * B[1][0];
00392 t = fabs(s);
00393 d = t - (a[0] * Bf[1][0] + a[1] * Bf[0][0] + b[1] * Bf[2][2] + b[2] * Bf[2][1]);
00394 d = std::max(0.0, d); d*=d;
00395 maxD = std::max(maxD, std::max(a2+d, b0+d));
00396
00397
00398 s = T[1] * B[0][1] - T[0] * B[1][1];
00399 t = fabs(s);
00400 d = t - (a[0] * Bf[1][1] + a[1] * Bf[0][1] + b[0] * Bf[2][2] + b[2] * Bf[2][0]);
00401 d = std::max(0.0, d); d*=d;
00402 maxD = std::max(maxD, std::max(a2+d, b1+d));
00403
00404
00405 s = T[1] * B[0][2] - T[0] * B[1][2];
00406 t = fabs(s);
00407 d = t - (a[0] * Bf[1][2] + a[1] * Bf[0][2] + b[0] * Bf[2][1] + b[1] * Bf[2][0]);
00408 d = std::max(0.0, d); d*=d;
00409 maxD = std::max(maxD, std::max(a2+d, b2+d));
00410
00411 if (maxD == 0.0) return -1;
00412 return maxD;
00413 }