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 "fcl/broadphase/broadphase_dynamic_AABB_tree_array.h"
00038
00039 #if FCL_HAVE_OCTOMAP
00040 #include "fcl/octree.h"
00041 #endif
00042
00043 namespace fcl
00044 {
00045
00046 namespace details
00047 {
00048
00049 namespace dynamic_AABB_tree_array
00050 {
00051
00052 #if FCL_HAVE_OCTOMAP
00053 bool collisionRecurse_(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id, const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& root2_bv, const Transform3f& tf2, void* cdata, CollisionCallBack callback)
00054 {
00055 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root1 = nodes1 + root1_id;
00056 if(!root2)
00057 {
00058 if(root1->isLeaf())
00059 {
00060 CollisionObject* obj1 = static_cast<CollisionObject*>(root1->data);
00061
00062 if(!obj1->isFree())
00063 {
00064 OBB obb1, obb2;
00065 convertBV(root1->bv, Transform3f(), obb1);
00066 convertBV(root2_bv, tf2, obb2);
00067
00068 if(obb1.overlap(obb2))
00069 {
00070 Box* box = new Box();
00071 Transform3f box_tf;
00072 constructBox(root2_bv, tf2, *box, box_tf);
00073
00074 box->cost_density = tree2->getDefaultOccupancy();
00075
00076 CollisionObject obj2(boost::shared_ptr<CollisionGeometry>(box), box_tf);
00077 return callback(obj1, &obj2, cdata);
00078 }
00079 }
00080 }
00081 else
00082 {
00083 if(collisionRecurse_(nodes1, root1->children[0], tree2, NULL, root2_bv, tf2, cdata, callback))
00084 return true;
00085 if(collisionRecurse_(nodes1, root1->children[1], tree2, NULL, root2_bv, tf2, cdata, callback))
00086 return true;
00087 }
00088
00089 return false;
00090 }
00091 else if(root1->isLeaf() && !root2->hasChildren())
00092 {
00093 CollisionObject* obj1 = static_cast<CollisionObject*>(root1->data);
00094 if(!tree2->isNodeFree(root2) && !obj1->isFree())
00095 {
00096 OBB obb1, obb2;
00097 convertBV(root1->bv, Transform3f(), obb1);
00098 convertBV(root2_bv, tf2, obb2);
00099
00100 if(obb1.overlap(obb2))
00101 {
00102 Box* box = new Box();
00103 Transform3f box_tf;
00104 constructBox(root2_bv, tf2, *box, box_tf);
00105
00106 box->cost_density = root2->getOccupancy();
00107 box->threshold_occupied = tree2->getOccupancyThres();
00108
00109 CollisionObject obj2(boost::shared_ptr<CollisionGeometry>(box), box_tf);
00110 return callback(obj1, &obj2, cdata);
00111 }
00112 else return false;
00113 }
00114 else return false;
00115 }
00116
00117 OBB obb1, obb2;
00118 convertBV(root1->bv, Transform3f(), obb1);
00119 convertBV(root2_bv, tf2, obb2);
00120
00121 if(tree2->isNodeFree(root2) || !obb1.overlap(obb2)) return false;
00122
00123 if(!root2->hasChildren() || (!root1->isLeaf() && (root1->bv.size() > root2_bv.size())))
00124 {
00125 if(collisionRecurse_(nodes1, root1->children[0], tree2, root2, root2_bv, tf2, cdata, callback))
00126 return true;
00127 if(collisionRecurse_(nodes1, root1->children[1], tree2, root2, root2_bv, tf2, cdata, callback))
00128 return true;
00129 }
00130 else
00131 {
00132 for(unsigned int i = 0; i < 8; ++i)
00133 {
00134 if(root2->childExists(i))
00135 {
00136 const OcTree::OcTreeNode* child = root2->getChild(i);
00137 AABB child_bv;
00138 computeChildBV(root2_bv, i, child_bv);
00139
00140 if(collisionRecurse_(nodes1, root1_id, tree2, child, child_bv, tf2, cdata, callback))
00141 return true;
00142 }
00143 else
00144 {
00145 AABB child_bv;
00146 computeChildBV(root2_bv, i, child_bv);
00147 if(collisionRecurse_(nodes1, root1_id, tree2, NULL, child_bv, tf2, cdata, callback))
00148 return true;
00149 }
00150 }
00151 }
00152
00153 return false;
00154 }
00155
00156
00157 bool collisionRecurse_(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id, const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& root2_bv, const Vec3f& tf2, void* cdata, CollisionCallBack callback)
00158 {
00159 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root1 = nodes1 + root1_id;
00160 if(!root2)
00161 {
00162 if(root1->isLeaf())
00163 {
00164 CollisionObject* obj1 = static_cast<CollisionObject*>(root1->data);
00165
00166 if(!obj1->isFree())
00167 {
00168 const AABB& root_bv_t = translate(root2_bv, tf2);
00169 if(root1->bv.overlap(root_bv_t))
00170 {
00171 Box* box = new Box();
00172 Transform3f box_tf;
00173 constructBox(root2_bv, tf2, *box, box_tf);
00174
00175 box->cost_density = tree2->getDefaultOccupancy();
00176
00177 CollisionObject obj2(boost::shared_ptr<CollisionGeometry>(box), box_tf);
00178 return callback(obj1, &obj2, cdata);
00179 }
00180 }
00181 }
00182 else
00183 {
00184 if(collisionRecurse_(nodes1, root1->children[0], tree2, NULL, root2_bv, tf2, cdata, callback))
00185 return true;
00186 if(collisionRecurse_(nodes1, root1->children[1], tree2, NULL, root2_bv, tf2, cdata, callback))
00187 return true;
00188 }
00189
00190 return false;
00191 }
00192 else if(root1->isLeaf() && !root2->hasChildren())
00193 {
00194 CollisionObject* obj1 = static_cast<CollisionObject*>(root1->data);
00195 if(!tree2->isNodeFree(root2) && !obj1->isFree())
00196 {
00197 const AABB& root_bv_t = translate(root2_bv, tf2);
00198 if(root1->bv.overlap(root_bv_t))
00199 {
00200 Box* box = new Box();
00201 Transform3f box_tf;
00202 constructBox(root2_bv, tf2, *box, box_tf);
00203
00204 box->cost_density = root2->getOccupancy();
00205 box->threshold_occupied = tree2->getOccupancyThres();
00206
00207 CollisionObject obj2(boost::shared_ptr<CollisionGeometry>(box), box_tf);
00208 return callback(obj1, &obj2, cdata);
00209 }
00210 else return false;
00211 }
00212 else return false;
00213 }
00214
00215 const AABB& root_bv_t = translate(root2_bv, tf2);
00216 if(tree2->isNodeFree(root2) || !root1->bv.overlap(root_bv_t)) return false;
00217
00218 if(!root2->hasChildren() || (!root1->isLeaf() && (root1->bv.size() > root2_bv.size())))
00219 {
00220 if(collisionRecurse_(nodes1, root1->children[0], tree2, root2, root2_bv, tf2, cdata, callback))
00221 return true;
00222 if(collisionRecurse_(nodes1, root1->children[1], tree2, root2, root2_bv, tf2, cdata, callback))
00223 return true;
00224 }
00225 else
00226 {
00227 for(unsigned int i = 0; i < 8; ++i)
00228 {
00229 if(root2->childExists(i))
00230 {
00231 const OcTree::OcTreeNode* child = root2->getChild(i);
00232 AABB child_bv;
00233 computeChildBV(root2_bv, i, child_bv);
00234
00235 if(collisionRecurse_(nodes1, root1_id, tree2, child, child_bv, tf2, cdata, callback))
00236 return true;
00237 }
00238 else
00239 {
00240 AABB child_bv;
00241 computeChildBV(root2_bv, i, child_bv);
00242 if(collisionRecurse_(nodes1, root1_id, tree2, NULL, child_bv, tf2, cdata, callback))
00243 return true;
00244 }
00245 }
00246 }
00247
00248 return false;
00249 }
00250
00251
00252 bool distanceRecurse_(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id, const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& root2_bv, const Transform3f& tf2, void* cdata, DistanceCallBack callback, FCL_REAL& min_dist)
00253 {
00254 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root1 = nodes1 + root1_id;
00255 if(root1->isLeaf() && !root2->hasChildren())
00256 {
00257 if(tree2->isNodeOccupied(root2))
00258 {
00259 Box* box = new Box();
00260 Transform3f box_tf;
00261 constructBox(root2_bv, tf2, *box, box_tf);
00262 CollisionObject obj(boost::shared_ptr<CollisionGeometry>(box), box_tf);
00263 return callback(static_cast<CollisionObject*>(root1->data), &obj, cdata, min_dist);
00264 }
00265 else return false;
00266 }
00267
00268 if(!tree2->isNodeOccupied(root2)) return false;
00269
00270 if(!root2->hasChildren() || (!root1->isLeaf() && (root1->bv.size() > root2_bv.size())))
00271 {
00272 AABB aabb2;
00273 convertBV(root2_bv, tf2, aabb2);
00274
00275 FCL_REAL d1 = aabb2.distance((nodes1 + root1->children[0])->bv);
00276 FCL_REAL d2 = aabb2.distance((nodes1 + root1->children[1])->bv);
00277
00278 if(d2 < d1)
00279 {
00280 if(d2 < min_dist)
00281 {
00282 if(distanceRecurse_(nodes1, root1->children[1], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00283 return true;
00284 }
00285
00286 if(d1 < min_dist)
00287 {
00288 if(distanceRecurse_(nodes1, root1->children[0], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00289 return true;
00290 }
00291 }
00292 else
00293 {
00294 if(d1 < min_dist)
00295 {
00296 if(distanceRecurse_(nodes1, root1->children[0], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00297 return true;
00298 }
00299
00300 if(d2 < min_dist)
00301 {
00302 if(distanceRecurse_(nodes1, root1->children[1], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00303 return true;
00304 }
00305 }
00306 }
00307 else
00308 {
00309 for(unsigned int i = 0; i < 8; ++i)
00310 {
00311 if(root2->childExists(i))
00312 {
00313 const OcTree::OcTreeNode* child = root2->getChild(i);
00314 AABB child_bv;
00315 computeChildBV(root2_bv, i, child_bv);
00316
00317 AABB aabb2;
00318 convertBV(child_bv, tf2, aabb2);
00319 FCL_REAL d = root1->bv.distance(aabb2);
00320
00321 if(d < min_dist)
00322 {
00323 if(distanceRecurse_(nodes1, root1_id, tree2, child, child_bv, tf2, cdata, callback, min_dist))
00324 return true;
00325 }
00326 }
00327 }
00328 }
00329
00330 return false;
00331 }
00332
00333
00334 bool distanceRecurse_(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id, const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& root2_bv, const Vec3f& tf2, void* cdata, DistanceCallBack callback, FCL_REAL& min_dist)
00335 {
00336 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root1 = nodes1 + root1_id;
00337 if(root1->isLeaf() && !root2->hasChildren())
00338 {
00339 if(tree2->isNodeOccupied(root2))
00340 {
00341 Box* box = new Box();
00342 Transform3f box_tf;
00343 constructBox(root2_bv, tf2, *box, box_tf);
00344 CollisionObject obj(boost::shared_ptr<CollisionGeometry>(box), box_tf);
00345 return callback(static_cast<CollisionObject*>(root1->data), &obj, cdata, min_dist);
00346 }
00347 else return false;
00348 }
00349
00350 if(!tree2->isNodeOccupied(root2)) return false;
00351
00352 if(!root2->hasChildren() || (!root1->isLeaf() && (root1->bv.size() > root2_bv.size())))
00353 {
00354 const AABB& aabb2 = translate(root2_bv, tf2);
00355
00356 FCL_REAL d1 = aabb2.distance((nodes1 + root1->children[0])->bv);
00357 FCL_REAL d2 = aabb2.distance((nodes1 + root1->children[1])->bv);
00358
00359 if(d2 < d1)
00360 {
00361 if(d2 < min_dist)
00362 {
00363 if(distanceRecurse_(nodes1, root1->children[1], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00364 return true;
00365 }
00366
00367 if(d1 < min_dist)
00368 {
00369 if(distanceRecurse_(nodes1, root1->children[0], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00370 return true;
00371 }
00372 }
00373 else
00374 {
00375 if(d1 < min_dist)
00376 {
00377 if(distanceRecurse_(nodes1, root1->children[0], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00378 return true;
00379 }
00380
00381 if(d2 < min_dist)
00382 {
00383 if(distanceRecurse_(nodes1, root1->children[1], tree2, root2, root2_bv, tf2, cdata, callback, min_dist))
00384 return true;
00385 }
00386 }
00387 }
00388 else
00389 {
00390 for(unsigned int i = 0; i < 8; ++i)
00391 {
00392 if(root2->childExists(i))
00393 {
00394 const OcTree::OcTreeNode* child = root2->getChild(i);
00395 AABB child_bv;
00396 computeChildBV(root2_bv, i, child_bv);
00397
00398 const AABB& aabb2 = translate(child_bv, tf2);
00399 FCL_REAL d = root1->bv.distance(aabb2);
00400
00401 if(d < min_dist)
00402 {
00403 if(distanceRecurse_(nodes1, root1_id, tree2, child, child_bv, tf2, cdata, callback, min_dist))
00404 return true;
00405 }
00406 }
00407 }
00408 }
00409
00410 return false;
00411 }
00412
00413
00414 #endif
00415
00416 bool collisionRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id,
00417 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes2, size_t root2_id,
00418 void* cdata, CollisionCallBack callback)
00419 {
00420 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root1 = nodes1 + root1_id;
00421 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root2 = nodes2 + root2_id;
00422 if(root1->isLeaf() && root2->isLeaf())
00423 {
00424 if(!root1->bv.overlap(root2->bv)) return false;
00425 return callback(static_cast<CollisionObject*>(root1->data), static_cast<CollisionObject*>(root2->data), cdata);
00426 }
00427
00428 if(!root1->bv.overlap(root2->bv)) return false;
00429
00430 if(root2->isLeaf() || (!root1->isLeaf() && (root1->bv.size() > root2->bv.size())))
00431 {
00432 if(collisionRecurse(nodes1, root1->children[0], nodes2, root2_id, cdata, callback))
00433 return true;
00434 if(collisionRecurse(nodes1, root1->children[1], nodes2, root2_id, cdata, callback))
00435 return true;
00436 }
00437 else
00438 {
00439 if(collisionRecurse(nodes1, root1_id, nodes2, root2->children[0], cdata, callback))
00440 return true;
00441 if(collisionRecurse(nodes1, root1_id, nodes2, root2->children[1], cdata, callback))
00442 return true;
00443 }
00444 return false;
00445 }
00446
00447 bool collisionRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes, size_t root_id, CollisionObject* query, void* cdata, CollisionCallBack callback)
00448 {
00449 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root = nodes + root_id;
00450 if(root->isLeaf())
00451 {
00452 if(!root->bv.overlap(query->getAABB())) return false;
00453 return callback(static_cast<CollisionObject*>(root->data), query, cdata);
00454 }
00455
00456 if(!root->bv.overlap(query->getAABB())) return false;
00457
00458 int select_res = implementation_array::select(query->getAABB(), root->children[0], root->children[1], nodes);
00459
00460 if(collisionRecurse(nodes, root->children[select_res], query, cdata, callback))
00461 return true;
00462
00463 if(collisionRecurse(nodes, root->children[1-select_res], query, cdata, callback))
00464 return true;
00465
00466 return false;
00467 }
00468
00469 bool selfCollisionRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes, size_t root_id, void* cdata, CollisionCallBack callback)
00470 {
00471 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root = nodes + root_id;
00472 if(root->isLeaf()) return false;
00473
00474 if(selfCollisionRecurse(nodes, root->children[0], cdata, callback))
00475 return true;
00476
00477 if(selfCollisionRecurse(nodes, root->children[1], cdata, callback))
00478 return true;
00479
00480 if(collisionRecurse(nodes, root->children[0], nodes, root->children[1], cdata, callback))
00481 return true;
00482
00483 return false;
00484 }
00485
00486 bool distanceRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id,
00487 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes2, size_t root2_id,
00488 void* cdata, DistanceCallBack callback, FCL_REAL& min_dist)
00489 {
00490 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root1 = nodes1 + root1_id;
00491 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root2 = nodes2 + root2_id;
00492 if(root1->isLeaf() && root2->isLeaf())
00493 {
00494 CollisionObject* root1_obj = static_cast<CollisionObject*>(root1->data);
00495 CollisionObject* root2_obj = static_cast<CollisionObject*>(root2->data);
00496 return callback(root1_obj, root2_obj, cdata, min_dist);
00497 }
00498
00499 if(root2->isLeaf() || (!root1->isLeaf() && (root1->bv.size() > root2->bv.size())))
00500 {
00501 FCL_REAL d1 = root2->bv.distance((nodes1 + root1->children[0])->bv);
00502 FCL_REAL d2 = root2->bv.distance((nodes1 + root1->children[1])->bv);
00503
00504 if(d2 < d1)
00505 {
00506 if(d2 < min_dist)
00507 {
00508 if(distanceRecurse(nodes1, root1->children[1], nodes2, root2_id, cdata, callback, min_dist))
00509 return true;
00510 }
00511
00512 if(d1 < min_dist)
00513 {
00514 if(distanceRecurse(nodes1, root1->children[0], nodes2, root2_id, cdata, callback, min_dist))
00515 return true;
00516 }
00517 }
00518 else
00519 {
00520 if(d1 < min_dist)
00521 {
00522 if(distanceRecurse(nodes1, root1->children[0], nodes2, root2_id, cdata, callback, min_dist))
00523 return true;
00524 }
00525
00526 if(d2 < min_dist)
00527 {
00528 if(distanceRecurse(nodes1, root1->children[1], nodes2, root2_id, cdata, callback, min_dist))
00529 return true;
00530 }
00531 }
00532 }
00533 else
00534 {
00535 FCL_REAL d1 = root1->bv.distance((nodes2 + root2->children[0])->bv);
00536 FCL_REAL d2 = root1->bv.distance((nodes2 + root2->children[1])->bv);
00537
00538 if(d2 < d1)
00539 {
00540 if(d2 < min_dist)
00541 {
00542 if(distanceRecurse(nodes1, root1_id, nodes2, root2->children[1], cdata, callback, min_dist))
00543 return true;
00544 }
00545
00546 if(d1 < min_dist)
00547 {
00548 if(distanceRecurse(nodes1, root1_id, nodes2, root2->children[0], cdata, callback, min_dist))
00549 return true;
00550 }
00551 }
00552 else
00553 {
00554 if(d1 < min_dist)
00555 {
00556 if(distanceRecurse(nodes1, root1_id, nodes2, root2->children[0], cdata, callback, min_dist))
00557 return true;
00558 }
00559
00560 if(d2 < min_dist)
00561 {
00562 if(distanceRecurse(nodes1, root1_id, nodes2, root2->children[1], cdata, callback, min_dist))
00563 return true;
00564 }
00565 }
00566 }
00567
00568 return false;
00569 }
00570
00571 bool distanceRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes, size_t root_id, CollisionObject* query, void* cdata, DistanceCallBack callback, FCL_REAL& min_dist)
00572 {
00573 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root = nodes + root_id;
00574 if(root->isLeaf())
00575 {
00576 CollisionObject* root_obj = static_cast<CollisionObject*>(root->data);
00577 return callback(root_obj, query, cdata, min_dist);
00578 }
00579
00580 FCL_REAL d1 = query->getAABB().distance((nodes + root->children[0])->bv);
00581 FCL_REAL d2 = query->getAABB().distance((nodes + root->children[1])->bv);
00582
00583 if(d2 < d1)
00584 {
00585 if(d2 < min_dist)
00586 {
00587 if(distanceRecurse(nodes, root->children[1], query, cdata, callback, min_dist))
00588 return true;
00589 }
00590
00591 if(d1 < min_dist)
00592 {
00593 if(distanceRecurse(nodes, root->children[0], query, cdata, callback, min_dist))
00594 return true;
00595 }
00596 }
00597 else
00598 {
00599 if(d1 < min_dist)
00600 {
00601 if(distanceRecurse(nodes, root->children[0], query, cdata, callback, min_dist))
00602 return true;
00603 }
00604
00605 if(d2 < min_dist)
00606 {
00607 if(distanceRecurse(nodes, root->children[1], query, cdata, callback, min_dist))
00608 return true;
00609 }
00610 }
00611
00612 return false;
00613 }
00614
00615 bool selfDistanceRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes, size_t root_id, void* cdata, DistanceCallBack callback, FCL_REAL& min_dist)
00616 {
00617 DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* root = nodes + root_id;
00618 if(root->isLeaf()) return false;
00619
00620 if(selfDistanceRecurse(nodes, root->children[0], cdata, callback, min_dist))
00621 return true;
00622
00623 if(selfDistanceRecurse(nodes, root->children[1], cdata, callback, min_dist))
00624 return true;
00625
00626 if(distanceRecurse(nodes, root->children[0], nodes, root->children[1], cdata, callback, min_dist))
00627 return true;
00628
00629 return false;
00630 }
00631
00632
00633 #if FCL_HAVE_OCTOMAP
00634 bool collisionRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id, const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& root2_bv, const Transform3f& tf2, void* cdata, CollisionCallBack callback)
00635 {
00636 if(tf2.getQuatRotation().isIdentity())
00637 return collisionRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2.getTranslation(), cdata, callback);
00638 else
00639 return collisionRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2, cdata, callback);
00640 }
00641
00642
00643 bool distanceRecurse(DynamicAABBTreeCollisionManager_Array::DynamicAABBNode* nodes1, size_t root1_id, const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& root2_bv, const Transform3f& tf2, void* cdata, DistanceCallBack callback, FCL_REAL& min_dist)
00644 {
00645 if(tf2.getQuatRotation().isIdentity())
00646 return distanceRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2.getTranslation(), cdata, callback, min_dist);
00647 else
00648 return distanceRecurse_(nodes1, root1_id, tree2, root2, root2_bv, tf2, cdata, callback, min_dist);
00649 }
00650
00651 #endif
00652
00653 }
00654
00655 }
00656
00657
00658 void DynamicAABBTreeCollisionManager_Array::registerObjects(const std::vector<CollisionObject*>& other_objs)
00659 {
00660 if(size() > 0)
00661 {
00662 BroadPhaseCollisionManager::registerObjects(other_objs);
00663 }
00664 else
00665 {
00666 DynamicAABBNode* leaves = new DynamicAABBNode[other_objs.size()];
00667 table.rehash(other_objs.size());
00668 for(size_t i = 0, size = other_objs.size(); i < size; ++i)
00669 {
00670 leaves[i].bv = other_objs[i]->getAABB();
00671 leaves[i].parent = dtree.NULL_NODE;
00672 leaves[i].children[1] = dtree.NULL_NODE;
00673 leaves[i].data = other_objs[i];
00674 table[other_objs[i]] = i;
00675 }
00676
00677 int n_leaves = other_objs.size();
00678
00679 dtree.init(leaves, n_leaves, tree_init_level);
00680
00681 setup_ = true;
00682 }
00683 }
00684
00685 void DynamicAABBTreeCollisionManager_Array::registerObject(CollisionObject* obj)
00686 {
00687 size_t node = dtree.insert(obj->getAABB(), obj);
00688 table[obj] = node;
00689 }
00690
00691 void DynamicAABBTreeCollisionManager_Array::unregisterObject(CollisionObject* obj)
00692 {
00693 size_t node = table[obj];
00694 table.erase(obj);
00695 dtree.remove(node);
00696 }
00697
00698 void DynamicAABBTreeCollisionManager_Array::setup()
00699 {
00700 if(!setup_)
00701 {
00702 int num = dtree.size();
00703 if(num == 0)
00704 {
00705 setup_ = true;
00706 return;
00707 }
00708
00709 int height = dtree.getMaxHeight();
00710
00711
00712 if(height - std::log((FCL_REAL)num) / std::log(2.0) < max_tree_nonbalanced_level)
00713 dtree.balanceIncremental(tree_incremental_balance_pass);
00714 else
00715 dtree.balanceTopdown();
00716
00717 setup_ = true;
00718 }
00719 }
00720
00721
00722 void DynamicAABBTreeCollisionManager_Array::update()
00723 {
00724 for(DynamicAABBTable::const_iterator it = table.begin(), end = table.end(); it != end; ++it)
00725 {
00726 CollisionObject* obj = it->first;
00727 size_t node = it->second;
00728 dtree.getNodes()[node].bv = obj->getAABB();
00729 }
00730
00731 dtree.refit();
00732 setup_ = false;
00733
00734 setup();
00735 }
00736
00737 void DynamicAABBTreeCollisionManager_Array::update_(CollisionObject* updated_obj)
00738 {
00739 DynamicAABBTable::const_iterator it = table.find(updated_obj);
00740 if(it != table.end())
00741 {
00742 size_t node = it->second;
00743 if(!dtree.getNodes()[node].bv.equal(updated_obj->getAABB()))
00744 dtree.update(node, updated_obj->getAABB());
00745 }
00746 setup_ = false;
00747 }
00748
00749 void DynamicAABBTreeCollisionManager_Array::update(CollisionObject* updated_obj)
00750 {
00751 update_(updated_obj);
00752 setup();
00753 }
00754
00755 void DynamicAABBTreeCollisionManager_Array::update(const std::vector<CollisionObject*>& updated_objs)
00756 {
00757 for(size_t i = 0, size = updated_objs.size(); i < size; ++i)
00758 update_(updated_objs[i]);
00759 setup();
00760 }
00761
00762
00763
00764 void DynamicAABBTreeCollisionManager_Array::collide(CollisionObject* obj, void* cdata, CollisionCallBack callback) const
00765 {
00766 if(size() == 0) return;
00767 switch(obj->getCollisionGeometry()->getNodeType())
00768 {
00769 #if FCL_HAVE_OCTOMAP
00770 case GEOM_OCTREE:
00771 {
00772 if(!octree_as_geometry_collide)
00773 {
00774 const OcTree* octree = static_cast<const OcTree*>(obj->getCollisionGeometry());
00775 details::dynamic_AABB_tree_array::collisionRecurse(dtree.getNodes(), dtree.getRoot(), octree, octree->getRoot(), octree->getRootBV(), obj->getTransform(), cdata, callback);
00776 }
00777 else
00778 details::dynamic_AABB_tree_array::collisionRecurse(dtree.getNodes(), dtree.getRoot(), obj, cdata, callback);
00779 }
00780 break;
00781 #endif
00782 default:
00783 details::dynamic_AABB_tree_array::collisionRecurse(dtree.getNodes(), dtree.getRoot(), obj, cdata, callback);
00784 }
00785 }
00786
00787 void DynamicAABBTreeCollisionManager_Array::distance(CollisionObject* obj, void* cdata, DistanceCallBack callback) const
00788 {
00789 if(size() == 0) return;
00790 FCL_REAL min_dist = std::numeric_limits<FCL_REAL>::max();
00791 switch(obj->getCollisionGeometry()->getNodeType())
00792 {
00793 #if FCL_HAVE_OCTOMAP
00794 case GEOM_OCTREE:
00795 {
00796 if(!octree_as_geometry_distance)
00797 {
00798 const OcTree* octree = static_cast<const OcTree*>(obj->getCollisionGeometry());
00799 details::dynamic_AABB_tree_array::distanceRecurse(dtree.getNodes(), dtree.getRoot(), octree, octree->getRoot(), octree->getRootBV(), obj->getTransform(), cdata, callback, min_dist);
00800 }
00801 else
00802 details::dynamic_AABB_tree_array::distanceRecurse(dtree.getNodes(), dtree.getRoot(), obj, cdata, callback, min_dist);
00803 }
00804 break;
00805 #endif
00806 default:
00807 details::dynamic_AABB_tree_array::distanceRecurse(dtree.getNodes(), dtree.getRoot(), obj, cdata, callback, min_dist);
00808 }
00809 }
00810
00811 void DynamicAABBTreeCollisionManager_Array::collide(void* cdata, CollisionCallBack callback) const
00812 {
00813 if(size() == 0) return;
00814 details::dynamic_AABB_tree_array::selfCollisionRecurse(dtree.getNodes(), dtree.getRoot(), cdata, callback);
00815 }
00816
00817 void DynamicAABBTreeCollisionManager_Array::distance(void* cdata, DistanceCallBack callback) const
00818 {
00819 if(size() == 0) return;
00820 FCL_REAL min_dist = std::numeric_limits<FCL_REAL>::max();
00821 details::dynamic_AABB_tree_array::selfDistanceRecurse(dtree.getNodes(), dtree.getRoot(), cdata, callback, min_dist);
00822 }
00823
00824 void DynamicAABBTreeCollisionManager_Array::collide(BroadPhaseCollisionManager* other_manager_, void* cdata, CollisionCallBack callback) const
00825 {
00826 DynamicAABBTreeCollisionManager_Array* other_manager = static_cast<DynamicAABBTreeCollisionManager_Array*>(other_manager_);
00827 if((size() == 0) || (other_manager->size() == 0)) return;
00828 details::dynamic_AABB_tree_array::collisionRecurse(dtree.getNodes(), dtree.getRoot(), other_manager->dtree.getNodes(), other_manager->dtree.getRoot(), cdata, callback);
00829 }
00830
00831 void DynamicAABBTreeCollisionManager_Array::distance(BroadPhaseCollisionManager* other_manager_, void* cdata, DistanceCallBack callback) const
00832 {
00833 DynamicAABBTreeCollisionManager_Array* other_manager = static_cast<DynamicAABBTreeCollisionManager_Array*>(other_manager_);
00834 if((size() == 0) || (other_manager->size() == 0)) return;
00835 FCL_REAL min_dist = std::numeric_limits<FCL_REAL>::max();
00836 details::dynamic_AABB_tree_array::distanceRecurse(dtree.getNodes(), dtree.getRoot(), other_manager->dtree.getNodes(), other_manager->dtree.getRoot(), cdata, callback, min_dist);
00837 }
00838
00839
00840
00841
00842 }