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
00038 #include "fcl/traversal/traversal_recurse.h"
00039
00040 namespace fcl
00041 {
00042 void collisionRecurse(CollisionTraversalNodeBase* node, int b1, int b2, BVHFrontList* front_list)
00043 {
00044 bool l1 = node->isFirstNodeLeaf(b1);
00045 bool l2 = node->isSecondNodeLeaf(b2);
00046
00047 if(l1 && l2)
00048 {
00049 updateFrontList(front_list, b1, b2);
00050
00051 if(node->BVTesting(b1, b2)) return;
00052
00053 node->leafTesting(b1, b2);
00054 return;
00055 }
00056
00057 if(node->BVTesting(b1, b2))
00058 {
00059 updateFrontList(front_list, b1, b2);
00060 return;
00061 }
00062
00063 if(node->firstOverSecond(b1, b2))
00064 {
00065 int c1 = node->getFirstLeftChild(b1);
00066 int c2 = node->getFirstRightChild(b1);
00067
00068 collisionRecurse(node, c1, b2, front_list);
00069
00070
00071 if(node->canStop() && !front_list) return;
00072
00073 collisionRecurse(node, c2, b2, front_list);
00074 }
00075 else
00076 {
00077 int c1 = node->getSecondLeftChild(b2);
00078 int c2 = node->getSecondRightChild(b2);
00079
00080 collisionRecurse(node, b1, c1, front_list);
00081
00082
00083 if(node->canStop() && !front_list) return;
00084
00085 collisionRecurse(node, b1, c2, front_list);
00086 }
00087 }
00088
00089 void collisionRecurse(MeshCollisionTraversalNodeOBB* node, int b1, int b2, const Matrix3f& R, const Vec3f& T, BVHFrontList* front_list)
00090 {
00091 bool l1 = node->isFirstNodeLeaf(b1);
00092 bool l2 = node->isSecondNodeLeaf(b2);
00093
00094 if(l1 && l2)
00095 {
00096 updateFrontList(front_list, b1, b2);
00097
00098 if(node->BVTesting(b1, b2, R, T)) return;
00099
00100 node->leafTesting(b1, b2, R, T);
00101 return;
00102 }
00103
00104 if(node->BVTesting(b1, b2, R, T))
00105 {
00106 updateFrontList(front_list, b1, b2);
00107 return;
00108 }
00109
00110 Vec3f temp;
00111
00112 if(node->firstOverSecond(b1, b2))
00113 {
00114 int c1 = node->getFirstLeftChild(b1);
00115 int c2 = node->getFirstRightChild(b1);
00116
00117 const OBB& bv1 = node->model1->getBV(c1).bv;
00118
00119 Matrix3f Rc(R.transposeTimes(bv1.axis[0]), R.transposeTimes(bv1.axis[1]), R.transposeTimes(bv1.axis[2]));
00120 temp = T - bv1.To;
00121 Vec3f Tc(temp.dot(bv1.axis[0]), temp.dot(bv1.axis[1]), temp.dot(bv1.axis[2]));
00122
00123 collisionRecurse(node, c1, b2, Rc, Tc, front_list);
00124
00125
00126 if(node->canStop() && !front_list) return;
00127
00128 const OBB& bv2 = node->model1->getBV(c2).bv;
00129
00130 Rc = Matrix3f(R.transposeTimes(bv2.axis[0]), R.transposeTimes(bv2.axis[1]), R.transposeTimes(bv2.axis[2]));
00131 temp = T - bv2.To;
00132 Tc.setValue(temp.dot(bv2.axis[0]), temp.dot(bv2.axis[1]), temp.dot(bv2.axis[2]));
00133
00134 collisionRecurse(node, c2, b2, Rc, Tc, front_list);
00135 }
00136 else
00137 {
00138 int c1 = node->getSecondLeftChild(b2);
00139 int c2 = node->getSecondRightChild(b2);
00140
00141 const OBB& bv1 = node->model2->getBV(c1).bv;
00142 Matrix3f Rc;
00143 temp = R * bv1.axis[0];
00144 Rc(0, 0) = temp[0]; Rc(1, 0) = temp[1]; Rc(2, 0) = temp[2];
00145 temp = R * bv1.axis[1];
00146 Rc(0, 1) = temp[0]; Rc(1, 1) = temp[1]; Rc(2, 1) = temp[2];
00147 temp = R * bv1.axis[2];
00148 Rc(0, 2) = temp[0]; Rc(1, 2) = temp[1]; Rc(2, 2) = temp[2];
00149 Vec3f Tc = R * bv1.To + T;
00150
00151 collisionRecurse(node, b1, c1, Rc, Tc, front_list);
00152
00153
00154 if(node->canStop() && !front_list) return;
00155
00156 const OBB& bv2 = node->model2->getBV(c2).bv;
00157 temp = R * bv2.axis[0];
00158 Rc(0, 0) = temp[0]; Rc(1, 0) = temp[1]; Rc(2, 0) = temp[2];
00159 temp = R * bv2.axis[1];
00160 Rc(0, 1) = temp[0]; Rc(1, 1) = temp[1]; Rc(2, 1) = temp[2];
00161 temp = R * bv2.axis[2];
00162 Rc(0, 2) = temp[0]; Rc(1, 2) = temp[1]; Rc(2, 2) = temp[2];
00163 Tc = R * bv2.To + T;
00164
00165 collisionRecurse(node, b1, c2, Rc, Tc, front_list);
00166 }
00167 }
00168
00169 void collisionRecurse(MeshCollisionTraversalNodeRSS* node, int b1, int b2, const Matrix3f& R, const Vec3f& T, BVHFrontList* front_list)
00170 {
00171
00172 }
00173
00177 void selfCollisionRecurse(CollisionTraversalNodeBase* node, int b, BVHFrontList* front_list)
00178 {
00179 bool l = node->isFirstNodeLeaf(b);
00180
00181 if(l) return;
00182
00183 int c1 = node->getFirstLeftChild(b);
00184 int c2 = node->getFirstRightChild(b);
00185
00186 selfCollisionRecurse(node, c1, front_list);
00187 if(node->canStop() && !front_list) return;
00188
00189 selfCollisionRecurse(node, c2, front_list);
00190 if(node->canStop() && !front_list) return;
00191
00192 collisionRecurse(node, c1, c2, front_list);
00193 }
00194
00195 void distanceRecurse(DistanceTraversalNodeBase* node, int b1, int b2, BVHFrontList* front_list)
00196 {
00197 bool l1 = node->isFirstNodeLeaf(b1);
00198 bool l2 = node->isSecondNodeLeaf(b2);
00199
00200 if(l1 && l2)
00201 {
00202 updateFrontList(front_list, b1, b2);
00203
00204 node->leafTesting(b1, b2);
00205 return;
00206 }
00207
00208 int a1, a2, c1, c2;
00209
00210 if(node->firstOverSecond(b1, b2))
00211 {
00212 a1 = node->getFirstLeftChild(b1);
00213 a2 = b2;
00214 c1 = node->getFirstRightChild(b1);
00215 c2 = b2;
00216 }
00217 else
00218 {
00219 a1 = b1;
00220 a2 = node->getSecondLeftChild(b2);
00221 c1 = b1;
00222 c2 = node->getSecondRightChild(b2);
00223 }
00224
00225 FCL_REAL d1 = node->BVTesting(a1, a2);
00226 FCL_REAL d2 = node->BVTesting(c1, c2);
00227
00228 if(d2 < d1)
00229 {
00230 if(!node->canStop(d2))
00231 distanceRecurse(node, c1, c2, front_list);
00232 else
00233 updateFrontList(front_list, c1, c2);
00234
00235 if(!node->canStop(d1))
00236 distanceRecurse(node, a1, a2, front_list);
00237 else
00238 updateFrontList(front_list, a1, a2);
00239 }
00240 else
00241 {
00242 if(!node->canStop(d1))
00243 distanceRecurse(node, a1, a2, front_list);
00244 else
00245 updateFrontList(front_list, a1, a2);
00246
00247 if(!node->canStop(d2))
00248 distanceRecurse(node, c1, c2, front_list);
00249 else
00250 updateFrontList(front_list, c1, c2);
00251 }
00252 }
00253
00254
00256 struct BVT
00257 {
00259 FCL_REAL d;
00260
00262 int b1, b2;
00263 };
00264
00266 struct BVT_Comparer
00267 {
00268 bool operator() (const BVT& lhs, const BVT& rhs) const
00269 {
00270 return lhs.d > rhs.d;
00271 }
00272 };
00273
00274 struct BVTQ
00275 {
00276 BVTQ() : qsize(2) {}
00277
00278 bool empty() const
00279 {
00280 return pq.empty();
00281 }
00282
00283 size_t size() const
00284 {
00285 return pq.size();
00286 }
00287
00288 const BVT& top() const
00289 {
00290 return pq.top();
00291 }
00292
00293 void push(const BVT& x)
00294 {
00295 pq.push(x);
00296 }
00297
00298 void pop()
00299 {
00300 pq.pop();
00301 }
00302
00303 bool full() const
00304 {
00305 return (pq.size() + 1 >= qsize);
00306 }
00307
00308 std::priority_queue<BVT, std::vector<BVT>, BVT_Comparer> pq;
00309
00311 int qsize;
00312 };
00313
00314
00315 void distanceQueueRecurse(DistanceTraversalNodeBase* node, int b1, int b2, BVHFrontList* front_list, int qsize)
00316 {
00317 BVTQ bvtq;
00318 bvtq.qsize = qsize;
00319
00320 BVT min_test;
00321 min_test.b1 = b1;
00322 min_test.b2 = b2;
00323
00324 while(1)
00325 {
00326 bool l1 = node->isFirstNodeLeaf(min_test.b1);
00327 bool l2 = node->isSecondNodeLeaf(min_test.b2);
00328
00329 if(l1 && l2)
00330 {
00331 updateFrontList(front_list, min_test.b1, min_test.b2);
00332
00333 node->leafTesting(min_test.b1, min_test.b2);
00334 }
00335 else if(bvtq.full())
00336 {
00337
00338
00339 distanceQueueRecurse(node, min_test.b1, min_test.b2, front_list, qsize);
00340 }
00341 else
00342 {
00343
00344 BVT bvt1, bvt2;
00345
00346 if(node->firstOverSecond(min_test.b1, min_test.b2))
00347 {
00348 int c1 = node->getFirstLeftChild(min_test.b1);
00349 int c2 = node->getFirstRightChild(min_test.b1);
00350 bvt1.b1 = c1;
00351 bvt1.b2 = min_test.b2;
00352 bvt1.d = node->BVTesting(bvt1.b1, bvt1.b2);
00353
00354 bvt2.b1 = c2;
00355 bvt2.b2 = min_test.b2;
00356 bvt2.d = node->BVTesting(bvt2.b1, bvt2.b2);
00357 }
00358 else
00359 {
00360 int c1 = node->getSecondLeftChild(min_test.b2);
00361 int c2 = node->getSecondRightChild(min_test.b2);
00362 bvt1.b1 = min_test.b1;
00363 bvt1.b2 = c1;
00364 bvt1.d = node->BVTesting(bvt1.b1, bvt1.b2);
00365
00366 bvt2.b1 = min_test.b1;
00367 bvt2.b2 = c2;
00368 bvt2.d = node->BVTesting(bvt2.b1, bvt2.b2);
00369 }
00370
00371 bvtq.push(bvt1);
00372 bvtq.push(bvt2);
00373 }
00374
00375 if(bvtq.empty())
00376 break;
00377 else
00378 {
00379 min_test = bvtq.top();
00380 bvtq.pop();
00381
00382 if(node->canStop(min_test.d))
00383 {
00384 updateFrontList(front_list, min_test.b1, min_test.b2);
00385 break;
00386 }
00387 }
00388 }
00389 }
00390
00391 void propagateBVHFrontListCollisionRecurse(CollisionTraversalNodeBase* node, BVHFrontList* front_list)
00392 {
00393 BVHFrontList::iterator front_iter;
00394 BVHFrontList append;
00395 for(front_iter = front_list->begin(); front_iter != front_list->end(); ++front_iter)
00396 {
00397 int b1 = front_iter->left;
00398 int b2 = front_iter->right;
00399 bool l1 = node->isFirstNodeLeaf(b1);
00400 bool l2 = node->isSecondNodeLeaf(b2);
00401
00402 if(l1 & l2)
00403 {
00404 front_iter->valid = false;
00405 collisionRecurse(node, b1, b2, &append);
00406 }
00407 else
00408 {
00409 if(!node->BVTesting(b1, b2))
00410 {
00411 front_iter->valid = false;
00412
00413 if(node->firstOverSecond(b1, b2))
00414 {
00415 int c1 = node->getFirstLeftChild(b1);
00416 int c2 = node->getFirstRightChild(b2);
00417
00418 collisionRecurse(node, c1, b2, front_list);
00419 collisionRecurse(node, c2, b2, front_list);
00420 }
00421 else
00422 {
00423 int c1 = node->getSecondLeftChild(b2);
00424 int c2 = node->getSecondRightChild(b2);
00425
00426 collisionRecurse(node, b1, c1, front_list);
00427 collisionRecurse(node, b1, c2, front_list);
00428 }
00429 }
00430 }
00431 }
00432
00433
00434
00435 for(front_iter = front_list->begin(); front_iter != front_list->end();)
00436 {
00437 if(!front_iter->valid)
00438 front_iter = front_list->erase(front_iter);
00439 else
00440 ++front_iter;
00441 }
00442
00443 for(front_iter = append.begin(); front_iter != append.end(); ++front_iter)
00444 {
00445 front_list->push_back(*front_iter);
00446 }
00447 }
00448
00449
00450 }