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 #ifndef FCL_TRAVERSAL_NODE_OCTREE_H
00038 #define FCL_TRAVERSAL_NODE_OCTREE_H
00039
00040 #include "fcl/collision_data.h"
00041 #include "fcl/traversal/traversal_node_base.h"
00042 #include "fcl/narrowphase/narrowphase.h"
00043 #include "fcl/shape/geometric_shapes_utility.h"
00044 #include "fcl/octree.h"
00045 #include "fcl/BVH/BVH_model.h"
00046
00047 namespace fcl
00048 {
00049
00051 template<typename NarrowPhaseSolver>
00052 class OcTreeSolver
00053 {
00054 private:
00055 const NarrowPhaseSolver* solver;
00056
00057 mutable const CollisionRequest* crequest;
00058 mutable const DistanceRequest* drequest;
00059
00060 mutable CollisionResult* cresult;
00061 mutable DistanceResult* dresult;
00062
00063 public:
00064 OcTreeSolver(const NarrowPhaseSolver* solver_) : solver(solver_),
00065 crequest(NULL),
00066 drequest(NULL),
00067 cresult(NULL),
00068 dresult(NULL)
00069 {
00070 }
00071
00073 void OcTreeIntersect(const OcTree* tree1, const OcTree* tree2,
00074 const Transform3f& tf1, const Transform3f& tf2,
00075 const CollisionRequest& request_,
00076 CollisionResult& result_) const
00077 {
00078 crequest = &request_;
00079 cresult = &result_;
00080
00081 OcTreeIntersectRecurse(tree1, tree1->getRoot(), tree1->getRootBV(),
00082 tree2, tree2->getRoot(), tree2->getRootBV(),
00083 tf1, tf2);
00084 }
00085
00087 void OcTreeDistance(const OcTree* tree1, const OcTree* tree2,
00088 const Transform3f& tf1, const Transform3f& tf2,
00089 const DistanceRequest& request_,
00090 DistanceResult& result_) const
00091 {
00092 drequest = &request_;
00093 dresult = &result_;
00094
00095 OcTreeDistanceRecurse(tree1, tree1->getRoot(), tree1->getRootBV(),
00096 tree2, tree2->getRoot(), tree2->getRootBV(),
00097 tf1, tf2);
00098 }
00099
00101 template<typename BV>
00102 void OcTreeMeshIntersect(const OcTree* tree1, const BVHModel<BV>* tree2,
00103 const Transform3f& tf1, const Transform3f& tf2,
00104 const CollisionRequest& request_,
00105 CollisionResult& result_) const
00106 {
00107 crequest = &request_;
00108 cresult = &result_;
00109
00110 OcTreeMeshIntersectRecurse(tree1, tree1->getRoot(), tree1->getRootBV(),
00111 tree2, 0,
00112 tf1, tf2);
00113 }
00114
00116 template<typename BV>
00117 void OcTreeMeshDistance(const OcTree* tree1, const BVHModel<BV>* tree2,
00118 const Transform3f& tf1, const Transform3f& tf2,
00119 const DistanceRequest& request_,
00120 DistanceResult& result_) const
00121 {
00122 drequest = &request_;
00123 dresult = &result_;
00124
00125 OcTreeMeshDistanceRecurse(tree1, tree1->getRoot(), tree1->getRootBV(),
00126 tree2, 0,
00127 tf1, tf2);
00128 }
00129
00131 template<typename BV>
00132 void MeshOcTreeIntersect(const BVHModel<BV>* tree1, const OcTree* tree2,
00133 const Transform3f& tf1, const Transform3f& tf2,
00134 const CollisionRequest& request_,
00135 CollisionResult& result_) const
00136
00137 {
00138 crequest = &request_;
00139 cresult = &result_;
00140
00141 OcTreeMeshIntersectRecurse(tree2, tree2->getRoot(), tree2->getRootBV(),
00142 tree1, 0,
00143 tf2, tf1);
00144 }
00145
00147 template<typename BV>
00148 void MeshOcTreeDistance(const BVHModel<BV>* tree1, const OcTree* tree2,
00149 const Transform3f& tf1, const Transform3f& tf2,
00150 const DistanceRequest& request_,
00151 DistanceResult& result_) const
00152 {
00153 drequest = &request_;
00154 dresult = &result_;
00155
00156 OcTreeMeshDistanceRecurse(tree1, 0,
00157 tree2, tree2->getRoot(), tree2->getRootBV(),
00158 tf1, tf2);
00159 }
00160
00162 template<typename S>
00163 void OcTreeShapeIntersect(const OcTree* tree, const S& s,
00164 const Transform3f& tf1, const Transform3f& tf2,
00165 const CollisionRequest& request_,
00166 CollisionResult& result_) const
00167 {
00168 crequest = &request_;
00169 cresult = &result_;
00170
00171 AABB bv2;
00172 computeBV<AABB>(s, Transform3f(), bv2);
00173 OBB obb2;
00174 convertBV(bv2, tf2, obb2);
00175 OcTreeShapeIntersectRecurse(tree, tree->getRoot(), tree->getRootBV(),
00176 s, obb2,
00177 tf1, tf2);
00178
00179 }
00180
00182 template<typename S>
00183 void ShapeOcTreeIntersect(const S& s, const OcTree* tree,
00184 const Transform3f& tf1, const Transform3f& tf2,
00185 const CollisionRequest& request_,
00186 CollisionResult& result_) const
00187 {
00188 crequest = &request_;
00189 cresult = &result_;
00190
00191 AABB bv1;
00192 computeBV<AABB>(s, Transform3f(), bv1);
00193 OBB obb1;
00194 convertBV(bv1, tf1, obb1);
00195 OcTreeShapeIntersectRecurse(tree, tree->getRoot(), tree->getRootBV(),
00196 s, obb1,
00197 tf2, tf1);
00198 }
00199
00201 template<typename S>
00202 void OcTreeShapeDistance(const OcTree* tree, const S& s,
00203 const Transform3f& tf1, const Transform3f& tf2,
00204 const DistanceRequest& request_,
00205 DistanceResult& result_) const
00206 {
00207 drequest = &request_;
00208 dresult = &result_;
00209
00210 AABB aabb2;
00211 computeBV<AABB>(s, tf2, aabb2);
00212 OcTreeShapeDistanceRecurse(tree, tree->getRoot(), tree->getRootBV(),
00213 s, aabb2,
00214 tf1, tf2);
00215 }
00216
00218 template<typename S>
00219 void ShapeOcTreeDistance(const S& s, const OcTree* tree,
00220 const Transform3f& tf1, const Transform3f& tf2,
00221 const DistanceRequest& request_,
00222 DistanceResult& result_) const
00223 {
00224 drequest = &request_;
00225 dresult = &result_;
00226
00227 AABB aabb1;
00228 computeBV<AABB>(s, tf1, aabb1);
00229 OcTreeShapeDistanceRecurse(tree, tree->getRoot(), tree->getRootBV(),
00230 s, aabb1,
00231 tf2, tf1);
00232 }
00233
00234
00235 private:
00236 template<typename S>
00237 bool OcTreeShapeDistanceRecurse(const OcTree* tree1, const OcTree::OcTreeNode* root1, const AABB& bv1,
00238 const S& s, const AABB& aabb2,
00239 const Transform3f& tf1, const Transform3f& tf2) const
00240 {
00241 if(!root1->hasChildren())
00242 {
00243 if(tree1->isNodeOccupied(root1))
00244 {
00245 Box box;
00246 Transform3f box_tf;
00247 constructBox(bv1, tf1, box, box_tf);
00248
00249 FCL_REAL dist;
00250 solver->shapeDistance(box, box_tf, s, tf2, &dist);
00251
00252 dresult->update(dist, tree1, &s, root1 - tree1->getRoot(), DistanceResult::NONE);
00253
00254 return drequest->isSatisfied(*dresult);
00255 }
00256 else
00257 return false;
00258 }
00259
00260 if(!tree1->isNodeOccupied(root1)) return false;
00261
00262 for(unsigned int i = 0; i < 8; ++i)
00263 {
00264 if(root1->childExists(i))
00265 {
00266 const OcTree::OcTreeNode* child = root1->getChild(i);
00267 AABB child_bv;
00268 computeChildBV(bv1, i, child_bv);
00269
00270 AABB aabb1;
00271 convertBV(child_bv, tf1, aabb1);
00272 FCL_REAL d = aabb1.distance(aabb2);
00273 if(d < dresult->min_distance)
00274 {
00275 if(OcTreeShapeDistanceRecurse(tree1, child, child_bv, s, aabb2, tf1, tf2))
00276 return true;
00277 }
00278 }
00279 }
00280
00281 return false;
00282 }
00283
00284 template<typename S>
00285 bool OcTreeShapeIntersectRecurse(const OcTree* tree1, const OcTree::OcTreeNode* root1, const AABB& bv1,
00286 const S& s, const OBB& obb2,
00287 const Transform3f& tf1, const Transform3f& tf2) const
00288 {
00289 if(!root1)
00290 {
00291 OBB obb1;
00292 convertBV(bv1, tf1, obb1);
00293 if(obb1.overlap(obb2))
00294 {
00295 Box box;
00296 Transform3f box_tf;
00297 constructBox(bv1, tf1, box, box_tf);
00298
00299 if(solver->shapeIntersect(box, box_tf, s, tf2, NULL, NULL, NULL))
00300 {
00301 AABB overlap_part;
00302 AABB aabb1, aabb2;
00303 computeBV<AABB, Box>(box, box_tf, aabb1);
00304 computeBV<AABB, S>(s, tf2, aabb2);
00305 aabb1.overlap(aabb2, overlap_part);
00306 cresult->addCostSource(CostSource(overlap_part, tree1->getOccupancyThres() * s.cost_density), crequest->num_max_cost_sources);
00307 }
00308 }
00309
00310 return false;
00311 }
00312 else if(!root1->hasChildren())
00313 {
00314 if(tree1->isNodeOccupied(root1) && s.isOccupied())
00315 {
00316 OBB obb1;
00317 convertBV(bv1, tf1, obb1);
00318 if(obb1.overlap(obb2))
00319 {
00320 Box box;
00321 Transform3f box_tf;
00322 constructBox(bv1, tf1, box, box_tf);
00323
00324 bool is_intersect = false;
00325 if(!crequest->enable_contact)
00326 {
00327 if(solver->shapeIntersect(box, box_tf, s, tf2, NULL, NULL, NULL))
00328 {
00329 is_intersect = true;
00330 if(cresult->numContacts() < crequest->num_max_contacts)
00331 cresult->addContact(Contact(tree1, &s, root1 - tree1->getRoot(), Contact::NONE));
00332 }
00333 }
00334 else
00335 {
00336 Vec3f contact;
00337 FCL_REAL depth;
00338 Vec3f normal;
00339
00340 if(solver->shapeIntersect(box, box_tf, s, tf2, &contact, &depth, &normal))
00341 {
00342 is_intersect = true;
00343 if(cresult->numContacts() < crequest->num_max_contacts)
00344 cresult->addContact(Contact(tree1, &s, root1 - tree1->getRoot(), Contact::NONE, contact, normal, depth));
00345 }
00346 }
00347
00348 if(is_intersect && crequest->enable_cost)
00349 {
00350 AABB overlap_part;
00351 AABB aabb1, aabb2;
00352 computeBV<AABB, Box>(box, box_tf, aabb1);
00353 computeBV<AABB, S>(s, tf2, aabb2);
00354 aabb1.overlap(aabb2, overlap_part);
00355 }
00356
00357 return crequest->isSatisfied(*cresult);
00358 }
00359 else return false;
00360 }
00361 else if(!tree1->isNodeFree(root1) && !s.isFree() && crequest->enable_cost)
00362 {
00363 OBB obb1;
00364 convertBV(bv1, tf1, obb1);
00365 if(obb1.overlap(obb2))
00366 {
00367 Box box;
00368 Transform3f box_tf;
00369 constructBox(bv1, tf1, box, box_tf);
00370
00371 if(solver->shapeIntersect(box, box_tf, s, tf2, NULL, NULL, NULL))
00372 {
00373 AABB overlap_part;
00374 AABB aabb1, aabb2;
00375 computeBV<AABB, Box>(box, box_tf, aabb1);
00376 computeBV<AABB, S>(s, tf2, aabb2);
00377 aabb1.overlap(aabb2, overlap_part);
00378 }
00379 }
00380
00381 return false;
00382 }
00383 else
00384 return false;
00385 }
00386
00390 if(tree1->isNodeFree(root1) || s.isFree()) return false;
00391 else if((tree1->isNodeUncertain(root1) || s.isUncertain()) && !crequest->enable_cost) return false;
00392 else
00393 {
00394 OBB obb1;
00395 convertBV(bv1, tf1, obb1);
00396 if(!obb1.overlap(obb2)) return false;
00397 }
00398
00399 for(unsigned int i = 0; i < 8; ++i)
00400 {
00401 if(root1->childExists(i))
00402 {
00403 const OcTree::OcTreeNode* child = root1->getChild(i);
00404 AABB child_bv;
00405 computeChildBV(bv1, i, child_bv);
00406
00407 if(OcTreeShapeIntersectRecurse(tree1, child, child_bv, s, obb2, tf1, tf2))
00408 return true;
00409 }
00410 else if(!s.isFree() && crequest->enable_cost)
00411 {
00412 AABB child_bv;
00413 computeChildBV(bv1, i, child_bv);
00414
00415 if(OcTreeShapeIntersectRecurse(tree1, NULL, child_bv, s, obb2, tf1, tf2))
00416 return true;
00417 }
00418 }
00419
00420 return false;
00421 }
00422
00423 template<typename BV>
00424 bool OcTreeMeshDistanceRecurse(const OcTree* tree1, const OcTree::OcTreeNode* root1, const AABB& bv1,
00425 const BVHModel<BV>* tree2, int root2,
00426 const Transform3f& tf1, const Transform3f& tf2) const
00427 {
00428 if(!root1->hasChildren() && tree2->getBV(root2).isLeaf())
00429 {
00430 if(tree1->isNodeOccupied(root1))
00431 {
00432 Box box;
00433 Transform3f box_tf;
00434 constructBox(bv1, tf1, box, box_tf);
00435
00436 int primitive_id = tree2->getBV(root2).primitiveId();
00437 const Triangle& tri_id = tree2->tri_indices[primitive_id];
00438 const Vec3f& p1 = tree2->vertices[tri_id[0]];
00439 const Vec3f& p2 = tree2->vertices[tri_id[1]];
00440 const Vec3f& p3 = tree2->vertices[tri_id[2]];
00441
00442 FCL_REAL dist;
00443 solver->shapeTriangleDistance(box, box_tf, p1, p2, p3, tf2, &dist);
00444
00445 dresult->update(dist, tree1, tree2, root1 - tree1->getRoot(), primitive_id);
00446
00447 return drequest->isSatisfied(*dresult);
00448 }
00449 else
00450 return false;
00451 }
00452
00453 if(!tree1->isNodeOccupied(root1)) return false;
00454
00455 if(tree2->getBV(root2).isLeaf() || (root1->hasChildren() && (bv1.size() > tree2->getBV(root2).bv.size())))
00456 {
00457 for(unsigned int i = 0; i < 8; ++i)
00458 {
00459 if(root1->childExists(i))
00460 {
00461 const OcTree::OcTreeNode* child = root1->getChild(i);
00462 AABB child_bv;
00463 computeChildBV(bv1, i, child_bv);
00464
00465 FCL_REAL d;
00466 AABB aabb1, aabb2;
00467 convertBV(child_bv, tf1, aabb1);
00468 convertBV(tree2->getBV(root2).bv, tf2, aabb2);
00469 d = aabb1.distance(aabb2);
00470
00471 if(d < dresult->min_distance)
00472 {
00473 if(OcTreeMeshDistanceRecurse(tree1, child, child_bv, tree2, root2, tf1, tf2))
00474 return true;
00475 }
00476 }
00477 }
00478 }
00479 else
00480 {
00481 FCL_REAL d;
00482 AABB aabb1, aabb2;
00483 convertBV(bv1, tf1, aabb1);
00484 int child = tree2->getBV(root2).leftChild();
00485 convertBV(tree2->getBV(child).bv, tf2, aabb2);
00486 d = aabb1.distance(aabb2);
00487
00488 if(d < dresult->min_distance)
00489 {
00490 if(OcTreeMeshDistanceRecurse(tree1, root1, bv1, tree2, child, tf1, tf2))
00491 return true;
00492 }
00493
00494 child = tree2->getBV(root2).rightChild();
00495 convertBV(tree2->getBV(child).bv, tf2, aabb2);
00496 d = aabb1.distance(aabb2);
00497
00498 if(d < dresult->min_distance)
00499 {
00500 if(OcTreeMeshDistanceRecurse(tree1, root1, bv1, tree2, child, tf1, tf2))
00501 return true;
00502 }
00503 }
00504
00505 return false;
00506 }
00507
00508
00509 template<typename BV>
00510 bool OcTreeMeshIntersectRecurse(const OcTree* tree1, const OcTree::OcTreeNode* root1, const AABB& bv1,
00511 const BVHModel<BV>* tree2, int root2,
00512 const Transform3f& tf1, const Transform3f& tf2) const
00513 {
00514 if(!root1)
00515 {
00516 if(tree2->getBV(root2).isLeaf())
00517 {
00518 OBB obb1, obb2;
00519 convertBV(bv1, tf1, obb1);
00520 convertBV(tree2->getBV(root2).bv, tf2, obb2);
00521 if(obb1.overlap(obb2))
00522 {
00523 Box box;
00524 Transform3f box_tf;
00525 constructBox(bv1, tf1, box, box_tf);
00526
00527 int primitive_id = tree2->getBV(root2).primitiveId();
00528 const Triangle& tri_id = tree2->tri_indices[primitive_id];
00529 const Vec3f& p1 = tree2->vertices[tri_id[0]];
00530 const Vec3f& p2 = tree2->vertices[tri_id[1]];
00531 const Vec3f& p3 = tree2->vertices[tri_id[2]];
00532
00533 if(solver->shapeTriangleIntersect(box, box_tf, p1, p2, p3, tf2, NULL, NULL, NULL))
00534 {
00535 AABB overlap_part;
00536 AABB aabb1;
00537 computeBV<AABB, Box>(box, box_tf, aabb1);
00538 AABB aabb2(tf2.transform(p1), tf2.transform(p2), tf2.transform(p3));
00539 aabb1.overlap(aabb2, overlap_part);
00540 cresult->addCostSource(CostSource(overlap_part, tree1->getOccupancyThres() * tree2->cost_density), crequest->num_max_cost_sources);
00541 }
00542 }
00543
00544 return false;
00545 }
00546 else
00547 {
00548 if(OcTreeMeshIntersectRecurse(tree1, root1, bv1, tree2, tree2->getBV(root2).leftChild(), tf1, tf2))
00549 return true;
00550
00551 if(OcTreeMeshIntersectRecurse(tree1, root1, bv1, tree2, tree2->getBV(root2).rightChild(), tf1, tf2))
00552 return true;
00553
00554 return false;
00555 }
00556 }
00557 else if(!root1->hasChildren() && tree2->getBV(root2).isLeaf())
00558 {
00559 if(tree1->isNodeOccupied(root1) && tree2->isOccupied())
00560 {
00561 OBB obb1, obb2;
00562 convertBV(bv1, tf1, obb1);
00563 convertBV(tree2->getBV(root2).bv, tf2, obb2);
00564 if(obb1.overlap(obb2))
00565 {
00566 Box box;
00567 Transform3f box_tf;
00568 constructBox(bv1, tf1, box, box_tf);
00569
00570 int primitive_id = tree2->getBV(root2).primitiveId();
00571 const Triangle& tri_id = tree2->tri_indices[primitive_id];
00572 const Vec3f& p1 = tree2->vertices[tri_id[0]];
00573 const Vec3f& p2 = tree2->vertices[tri_id[1]];
00574 const Vec3f& p3 = tree2->vertices[tri_id[2]];
00575
00576 bool is_intersect = false;
00577 if(!crequest->enable_contact)
00578 {
00579 if(solver->shapeTriangleIntersect(box, box_tf, p1, p2, p3, tf2, NULL, NULL, NULL))
00580 {
00581 is_intersect = true;
00582 if(cresult->numContacts() < crequest->num_max_contacts)
00583 cresult->addContact(Contact(tree1, tree2, root1 - tree1->getRoot(), root2));
00584 }
00585 }
00586 else
00587 {
00588 Vec3f contact;
00589 FCL_REAL depth;
00590 Vec3f normal;
00591
00592 if(solver->shapeTriangleIntersect(box, box_tf, p1, p2, p3, tf2, &contact, &depth, &normal))
00593 {
00594 is_intersect = true;
00595 if(cresult->numContacts() < crequest->num_max_contacts)
00596 cresult->addContact(Contact(tree1, tree2, root1 - tree1->getRoot(), root2, contact, normal, depth));
00597 }
00598 }
00599
00600 if(is_intersect && crequest->enable_cost)
00601 {
00602 AABB overlap_part;
00603 AABB aabb1;
00604 computeBV<AABB, Box>(box, box_tf, aabb1);
00605 AABB aabb2(tf2.transform(p1), tf2.transform(p2), tf2.transform(p3));
00606 aabb1.overlap(aabb2, overlap_part);
00607 cresult->addCostSource(CostSource(overlap_part, root1->getOccupancy() * tree2->cost_density), crequest->num_max_cost_sources);
00608 }
00609
00610 return crequest->isSatisfied(*cresult);
00611 }
00612 else
00613 return false;
00614 }
00615 else if(!tree1->isNodeFree(root1) && !tree2->isFree() && crequest->enable_cost)
00616 {
00617 OBB obb1, obb2;
00618 convertBV(bv1, tf1, obb1);
00619 convertBV(tree2->getBV(root2).bv, tf2, obb2);
00620 if(obb1.overlap(obb2))
00621 {
00622 Box box;
00623 Transform3f box_tf;
00624 constructBox(bv1, tf1, box, box_tf);
00625
00626 int primitive_id = tree2->getBV(root2).primitiveId();
00627 const Triangle& tri_id = tree2->tri_indices[primitive_id];
00628 const Vec3f& p1 = tree2->vertices[tri_id[0]];
00629 const Vec3f& p2 = tree2->vertices[tri_id[1]];
00630 const Vec3f& p3 = tree2->vertices[tri_id[2]];
00631
00632 if(solver->shapeTriangleIntersect(box, box_tf, p1, p2, p3, tf2, NULL, NULL, NULL))
00633 {
00634 AABB overlap_part;
00635 AABB aabb1;
00636 computeBV<AABB, Box>(box, box_tf, aabb1);
00637 AABB aabb2(tf2.transform(p1), tf2.transform(p2), tf2.transform(p3));
00638 aabb1.overlap(aabb2, overlap_part);
00639 cresult->addCostSource(CostSource(overlap_part, root1->getOccupancy() * tree2->cost_density), crequest->num_max_cost_sources);
00640 }
00641 }
00642
00643 return false;
00644 }
00645 else
00646 return false;
00647 }
00648
00652 if(tree1->isNodeFree(root1) || tree2->isFree()) return false;
00653 else if((tree1->isNodeUncertain(root1) || tree2->isUncertain()) && !crequest->enable_cost) return false;
00654 else
00655 {
00656 OBB obb1, obb2;
00657 convertBV(bv1, tf1, obb1);
00658 convertBV(tree2->getBV(root2).bv, tf2, obb2);
00659 if(!obb1.overlap(obb2)) return false;
00660 }
00661
00662 if(tree2->getBV(root2).isLeaf() || (root1->hasChildren() && (bv1.size() > tree2->getBV(root2).bv.size())))
00663 {
00664 for(unsigned int i = 0; i < 8; ++i)
00665 {
00666 if(root1->childExists(i))
00667 {
00668 const OcTree::OcTreeNode* child = root1->getChild(i);
00669 AABB child_bv;
00670 computeChildBV(bv1, i, child_bv);
00671
00672 if(OcTreeMeshIntersectRecurse(tree1, child, child_bv, tree2, root2, tf1, tf2))
00673 return true;
00674 }
00675 else if(!tree2->isFree() && crequest->enable_cost)
00676 {
00677 AABB child_bv;
00678 computeChildBV(bv1, i, child_bv);
00679
00680 if(OcTreeMeshIntersectRecurse(tree1, NULL, child_bv, tree2, root2, tf1, tf2))
00681 return true;
00682 }
00683 }
00684 }
00685 else
00686 {
00687 if(OcTreeMeshIntersectRecurse(tree1, root1, bv1, tree2, tree2->getBV(root2).leftChild(), tf1, tf2))
00688 return true;
00689
00690 if(OcTreeMeshIntersectRecurse(tree1, root1, bv1, tree2, tree2->getBV(root2).rightChild(), tf1, tf2))
00691 return true;
00692
00693 }
00694
00695 return false;
00696 }
00697
00698 bool OcTreeDistanceRecurse(const OcTree* tree1, const OcTree::OcTreeNode* root1, const AABB& bv1,
00699 const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& bv2,
00700 const Transform3f& tf1, const Transform3f& tf2) const
00701 {
00702 if(!root1->hasChildren() && !root2->hasChildren())
00703 {
00704 if(tree1->isNodeOccupied(root1) && tree2->isNodeOccupied(root2))
00705 {
00706 Box box1, box2;
00707 Transform3f box1_tf, box2_tf;
00708 constructBox(bv1, tf1, box1, box1_tf);
00709 constructBox(bv2, tf2, box2, box2_tf);
00710
00711 FCL_REAL dist;
00712 solver->shapeDistance(box1, box1_tf, box2, box2_tf, &dist);
00713
00714 dresult->update(dist, tree1, tree2, root1 - tree1->getRoot(), root2 - tree2->getRoot());
00715
00716 return drequest->isSatisfied(*dresult);
00717 }
00718 else
00719 return false;
00720 }
00721
00722 if(!tree1->isNodeOccupied(root1) || !tree2->isNodeOccupied(root2)) return false;
00723
00724 if(!root2->hasChildren() || (root1->hasChildren() && (bv1.size() > bv2.size())))
00725 {
00726 for(unsigned int i = 0; i < 8; ++i)
00727 {
00728 if(root1->childExists(i))
00729 {
00730 const OcTree::OcTreeNode* child = root1->getChild(i);
00731 AABB child_bv;
00732 computeChildBV(bv1, i, child_bv);
00733
00734 FCL_REAL d;
00735 AABB aabb1, aabb2;
00736 convertBV(bv1, tf1, aabb1);
00737 convertBV(bv2, tf2, aabb2);
00738 d = aabb1.distance(aabb2);
00739
00740 if(d < dresult->min_distance)
00741 {
00742
00743 if(OcTreeDistanceRecurse(tree1, child, child_bv, tree2, root2, bv2, tf1, tf2))
00744 return true;
00745 }
00746 }
00747 }
00748 }
00749 else
00750 {
00751 for(unsigned int i = 0; i < 8; ++i)
00752 {
00753 if(root2->childExists(i))
00754 {
00755 const OcTree::OcTreeNode* child = root2->getChild(i);
00756 AABB child_bv;
00757 computeChildBV(bv2, i, child_bv);
00758
00759 FCL_REAL d;
00760 AABB aabb1, aabb2;
00761 convertBV(bv1, tf1, aabb1);
00762 convertBV(bv2, tf2, aabb2);
00763 d = aabb1.distance(aabb2);
00764
00765 if(d < dresult->min_distance)
00766 {
00767 if(OcTreeDistanceRecurse(tree1, root1, bv1, tree2, child, child_bv, tf1, tf2))
00768 return true;
00769 }
00770 }
00771 }
00772 }
00773
00774 return false;
00775 }
00776
00777
00778 bool OcTreeIntersectRecurse(const OcTree* tree1, const OcTree::OcTreeNode* root1, const AABB& bv1,
00779 const OcTree* tree2, const OcTree::OcTreeNode* root2, const AABB& bv2,
00780 const Transform3f& tf1, const Transform3f& tf2) const
00781 {
00782 if(!root1 && !root2)
00783 {
00784 OBB obb1, obb2;
00785 convertBV(bv1, tf1, obb1);
00786 convertBV(bv2, tf2, obb2);
00787
00788 if(obb1.overlap(obb2))
00789 {
00790 Box box1, box2;
00791 Transform3f box1_tf, box2_tf;
00792 constructBox(bv1, tf1, box1, box1_tf);
00793 constructBox(bv2, tf2, box2, box2_tf);
00794
00795 AABB overlap_part;
00796 AABB aabb1, aabb2;
00797 computeBV<AABB, Box>(box1, box1_tf, aabb1);
00798 computeBV<AABB, Box>(box2, box2_tf, aabb2);
00799 aabb1.overlap(aabb2, overlap_part);
00800 cresult->addCostSource(CostSource(overlap_part, tree1->getOccupancyThres() * tree2->getOccupancyThres()), crequest->num_max_cost_sources);
00801 }
00802
00803 return false;
00804 }
00805 else if(!root1 && root2)
00806 {
00807 if(root2->hasChildren())
00808 {
00809 for(unsigned int i = 0; i < 8; ++i)
00810 {
00811 if(root2->childExists(i))
00812 {
00813 const OcTree::OcTreeNode* child = root2->getChild(i);
00814 AABB child_bv;
00815 computeChildBV(bv2, i, child_bv);
00816 if(OcTreeIntersectRecurse(tree1, NULL, bv1, tree2, child, child_bv, tf1, tf2))
00817 return true;
00818 }
00819 else
00820 {
00821 AABB child_bv;
00822 computeChildBV(bv2, i, child_bv);
00823 if(OcTreeIntersectRecurse(tree1, NULL, bv1, tree2, NULL, child_bv, tf1, tf2))
00824 return true;
00825 }
00826 }
00827 }
00828 else
00829 {
00830 if(OcTreeIntersectRecurse(tree1, NULL, bv1, tree2, NULL, bv2, tf1, tf2))
00831 return true;
00832 }
00833
00834 return false;
00835 }
00836 else if(root1 && !root2)
00837 {
00838 if(root1->hasChildren())
00839 {
00840 for(unsigned int i = 0; i < 8; ++i)
00841 {
00842 if(root1->childExists(i))
00843 {
00844 const OcTree::OcTreeNode* child = root1->getChild(i);
00845 AABB child_bv;
00846 computeChildBV(bv1, i, child_bv);
00847 if(OcTreeIntersectRecurse(tree1, child, child_bv, tree2, NULL, bv2, tf1, tf2))
00848 return true;
00849 }
00850 else
00851 {
00852 AABB child_bv;
00853 computeChildBV(bv1, i, child_bv);
00854 if(OcTreeIntersectRecurse(tree1, NULL, child_bv, tree2, NULL, bv2, tf1, tf2))
00855 return true;
00856 }
00857 }
00858 }
00859 else
00860 {
00861 if(OcTreeIntersectRecurse(tree1, NULL, bv1, tree2, NULL, bv2, tf1, tf2))
00862 return true;
00863 }
00864
00865 return false;
00866 }
00867 else if(!root1->hasChildren() && !root2->hasChildren())
00868 {
00869 if(tree1->isNodeOccupied(root1) && tree2->isNodeOccupied(root2))
00870 {
00871 bool is_intersect = false;
00872 if(!crequest->enable_contact)
00873 {
00874 OBB obb1, obb2;
00875 convertBV(bv1, tf1, obb1);
00876 convertBV(bv2, tf2, obb2);
00877
00878 if(obb1.overlap(obb2))
00879 {
00880 is_intersect = true;
00881 if(cresult->numContacts() < crequest->num_max_contacts)
00882 cresult->addContact(Contact(tree1, tree2, root1 - tree1->getRoot(), root2 - tree2->getRoot()));
00883 }
00884 }
00885 else
00886 {
00887 Box box1, box2;
00888 Transform3f box1_tf, box2_tf;
00889 constructBox(bv1, tf1, box1, box1_tf);
00890 constructBox(bv2, tf2, box2, box2_tf);
00891
00892 Vec3f contact;
00893 FCL_REAL depth;
00894 Vec3f normal;
00895 if(solver->shapeIntersect(box1, box1_tf, box2, box2_tf, &contact, &depth, &normal))
00896 {
00897 is_intersect = true;
00898 if(cresult->numContacts() < crequest->num_max_contacts)
00899 cresult->addContact(Contact(tree1, tree2, root1 - tree1->getRoot(), root2 - tree2->getRoot(), contact, normal, depth));
00900 }
00901 }
00902
00903 if(is_intersect && crequest->enable_cost)
00904 {
00905 Box box1, box2;
00906 Transform3f box1_tf, box2_tf;
00907 constructBox(bv1, tf1, box1, box1_tf);
00908 constructBox(bv2, tf2, box2, box2_tf);
00909
00910 AABB overlap_part;
00911 AABB aabb1, aabb2;
00912 computeBV<AABB, Box>(box1, box1_tf, aabb1);
00913 computeBV<AABB, Box>(box2, box2_tf, aabb2);
00914 aabb1.overlap(aabb2, overlap_part);
00915 cresult->addCostSource(CostSource(overlap_part, root1->getOccupancy() * root2->getOccupancy()), crequest->num_max_cost_sources);
00916 }
00917
00918 return crequest->isSatisfied(*cresult);
00919 }
00920 else if(!tree1->isNodeFree(root1) && !tree2->isNodeFree(root2) && crequest->enable_cost)
00921 {
00922 OBB obb1, obb2;
00923 convertBV(bv1, tf1, obb1);
00924 convertBV(bv2, tf2, obb2);
00925
00926 if(obb1.overlap(obb2))
00927 {
00928 Box box1, box2;
00929 Transform3f box1_tf, box2_tf;
00930 constructBox(bv1, tf1, box1, box1_tf);
00931 constructBox(bv2, tf2, box2, box2_tf);
00932
00933 AABB overlap_part;
00934 AABB aabb1, aabb2;
00935 computeBV<AABB, Box>(box1, box1_tf, aabb1);
00936 computeBV<AABB, Box>(box2, box2_tf, aabb2);
00937 aabb1.overlap(aabb2, overlap_part);
00938 cresult->addCostSource(CostSource(overlap_part, root1->getOccupancy() * root2->getOccupancy()), crequest->num_max_cost_sources);
00939 }
00940
00941 return false;
00942 }
00943 else
00944 return false;
00945 }
00946
00950 if(tree1->isNodeFree(root1) || tree2->isNodeFree(root2)) return false;
00951 else if((tree1->isNodeUncertain(root1) || tree2->isNodeUncertain(root2)) && !crequest->enable_cost) return false;
00952 else
00953 {
00954 OBB obb1, obb2;
00955 convertBV(bv1, tf1, obb1);
00956 convertBV(bv2, tf2, obb2);
00957 if(!obb1.overlap(obb2)) return false;
00958 }
00959
00960 if(!root2->hasChildren() || (root1->hasChildren() && (bv1.size() > bv2.size())))
00961 {
00962 for(unsigned int i = 0; i < 8; ++i)
00963 {
00964 if(root1->childExists(i))
00965 {
00966 const OcTree::OcTreeNode* child = root1->getChild(i);
00967 AABB child_bv;
00968 computeChildBV(bv1, i, child_bv);
00969
00970 if(OcTreeIntersectRecurse(tree1, child, child_bv,
00971 tree2, root2, bv2,
00972 tf1, tf2))
00973 return true;
00974 }
00975 else if(!tree2->isNodeFree(root2) && crequest->enable_cost)
00976 {
00977 AABB child_bv;
00978 computeChildBV(bv1, i, child_bv);
00979
00980 if(OcTreeIntersectRecurse(tree1, NULL, child_bv,
00981 tree2, root2, bv2,
00982 tf1, tf2))
00983 return true;
00984 }
00985 }
00986 }
00987 else
00988 {
00989 for(unsigned int i = 0; i < 8; ++i)
00990 {
00991 if(root2->childExists(i))
00992 {
00993 const OcTree::OcTreeNode* child = root2->getChild(i);
00994 AABB child_bv;
00995 computeChildBV(bv2, i, child_bv);
00996
00997 if(OcTreeIntersectRecurse(tree1, root1, bv1,
00998 tree2, child, child_bv,
00999 tf1, tf2))
01000 return true;
01001 }
01002 else if(!tree1->isNodeFree(root1) && crequest->enable_cost)
01003 {
01004 AABB child_bv;
01005 computeChildBV(bv2, i, child_bv);
01006
01007 if(OcTreeIntersectRecurse(tree1, root1, bv1,
01008 tree2, NULL, child_bv,
01009 tf1, tf2))
01010 return true;
01011 }
01012 }
01013 }
01014
01015 return false;
01016 }
01017 };
01018
01019
01020
01021
01023 template<typename NarrowPhaseSolver>
01024 class OcTreeCollisionTraversalNode : public CollisionTraversalNodeBase
01025 {
01026 public:
01027 OcTreeCollisionTraversalNode()
01028 {
01029 model1 = NULL;
01030 model2 = NULL;
01031
01032 otsolver = NULL;
01033 }
01034
01035 bool BVTesting(int, int) const
01036 {
01037 return false;
01038 }
01039
01040 void leafTesting(int, int) const
01041 {
01042 otsolver->OcTreeIntersect(model1, model2, tf1, tf2, request, *result);
01043 }
01044
01045 const OcTree* model1;
01046 const OcTree* model2;
01047
01048 Transform3f tf1, tf2;
01049
01050 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01051 };
01052
01054 template<typename NarrowPhaseSolver>
01055 class OcTreeDistanceTraversalNode : public DistanceTraversalNodeBase
01056 {
01057 public:
01058 OcTreeDistanceTraversalNode()
01059 {
01060 model1 = NULL;
01061 model2 = NULL;
01062
01063 otsolver = NULL;
01064 }
01065
01066
01067 FCL_REAL BVTesting(int, int) const
01068 {
01069 return -1;
01070 }
01071
01072 void leafTesting(int, int) const
01073 {
01074 otsolver->OcTreeDistance(model1, model2, tf1, tf2, request, *result);
01075 }
01076
01077 const OcTree* model1;
01078 const OcTree* model2;
01079
01080 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01081 };
01082
01084 template<typename S, typename NarrowPhaseSolver>
01085 class ShapeOcTreeCollisionTraversalNode : public CollisionTraversalNodeBase
01086 {
01087 public:
01088 ShapeOcTreeCollisionTraversalNode()
01089 {
01090 model1 = NULL;
01091 model2 = NULL;
01092
01093 otsolver = NULL;
01094 }
01095
01096 bool BVTesting(int, int) const
01097 {
01098 return false;
01099 }
01100
01101 void leafTesting(int, int) const
01102 {
01103 otsolver->OcTreeShapeIntersect(model2, *model1, tf2, tf1, request, *result);
01104 }
01105
01106 const S* model1;
01107 const OcTree* model2;
01108
01109 Transform3f tf1, tf2;
01110
01111 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01112 };
01113
01115 template<typename S, typename NarrowPhaseSolver>
01116 class OcTreeShapeCollisionTraversalNode : public CollisionTraversalNodeBase
01117 {
01118 public:
01119 OcTreeShapeCollisionTraversalNode()
01120 {
01121 model1 = NULL;
01122 model2 = NULL;
01123
01124 otsolver = NULL;
01125 }
01126
01127 bool BVTesting(int, int) const
01128 {
01129 return false;
01130 }
01131
01132 void leafTesting(int, int) const
01133 {
01134 otsolver->OcTreeShapeIntersect(model1, *model2, tf1, tf2, request, *result);
01135 }
01136
01137 const OcTree* model1;
01138 const S* model2;
01139
01140 Transform3f tf1, tf2;
01141
01142 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01143 };
01144
01146 template<typename S, typename NarrowPhaseSolver>
01147 class ShapeOcTreeDistanceTraversalNode : public DistanceTraversalNodeBase
01148 {
01149 public:
01150 ShapeOcTreeDistanceTraversalNode()
01151 {
01152 model1 = NULL;
01153 model2 = NULL;
01154
01155 otsolver = NULL;
01156 }
01157
01158 FCL_REAL BVTesting(int, int) const
01159 {
01160 return -1;
01161 }
01162
01163 void leafTesting(int, int) const
01164 {
01165 otsolver->OcTreeShapeDistance(model2, *model1, tf2, tf1, request, *result);
01166 }
01167
01168 const S* model1;
01169 const OcTree* model2;
01170
01171 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01172 };
01173
01175 template<typename S, typename NarrowPhaseSolver>
01176 class OcTreeShapeDistanceTraversalNode : public DistanceTraversalNodeBase
01177 {
01178 public:
01179 OcTreeShapeDistanceTraversalNode()
01180 {
01181 model1 = NULL;
01182 model2 = NULL;
01183
01184 otsolver = NULL;
01185 }
01186
01187 FCL_REAL BVTesting(int, int) const
01188 {
01189 return -1;
01190 }
01191
01192 void leafTesting(int, int) const
01193 {
01194 otsolver->OcTreeShapeDistance(model1, *model2, tf1, tf2, request, *result);
01195 }
01196
01197 const OcTree* model1;
01198 const S* model2;
01199
01200 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01201 };
01202
01204 template<typename BV, typename NarrowPhaseSolver>
01205 class MeshOcTreeCollisionTraversalNode : public CollisionTraversalNodeBase
01206 {
01207 public:
01208 MeshOcTreeCollisionTraversalNode()
01209 {
01210 model1 = NULL;
01211 model2 = NULL;
01212
01213 otsolver = NULL;
01214 }
01215
01216 bool BVTesting(int, int) const
01217 {
01218 return false;
01219 }
01220
01221 void leafTesting(int, int) const
01222 {
01223 otsolver->OcTreeMeshIntersect(model2, model1, tf2, tf1, request, *result);
01224 }
01225
01226 const BVHModel<BV>* model1;
01227 const OcTree* model2;
01228
01229 Transform3f tf1, tf2;
01230
01231 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01232 };
01233
01235 template<typename BV, typename NarrowPhaseSolver>
01236 class OcTreeMeshCollisionTraversalNode : public CollisionTraversalNodeBase
01237 {
01238 public:
01239 OcTreeMeshCollisionTraversalNode()
01240 {
01241 model1 = NULL;
01242 model2 = NULL;
01243
01244 otsolver = NULL;
01245 }
01246
01247 bool BVTesting(int, int) const
01248 {
01249 return false;
01250 }
01251
01252 void leafTesting(int, int) const
01253 {
01254 otsolver->OcTreeMeshIntersect(model1, model2, tf1, tf2, request, *result);
01255 }
01256
01257 const OcTree* model1;
01258 const BVHModel<BV>* model2;
01259
01260 Transform3f tf1, tf2;
01261
01262 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01263 };
01264
01266 template<typename BV, typename NarrowPhaseSolver>
01267 class MeshOcTreeDistanceTraversalNode : public DistanceTraversalNodeBase
01268 {
01269 public:
01270 MeshOcTreeDistanceTraversalNode()
01271 {
01272 model1 = NULL;
01273 model2 = NULL;
01274
01275 otsolver = NULL;
01276 }
01277
01278 FCL_REAL BVTesting(int, int) const
01279 {
01280 return -1;
01281 }
01282
01283 void leafTesting(int, int) const
01284 {
01285 otsolver->OcTreeMeshDistance(model2, model1, tf2, tf1, request, *result);
01286 }
01287
01288 const BVHModel<BV>* model1;
01289 const OcTree* model2;
01290
01291 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01292
01293 };
01294
01296 template<typename BV, typename NarrowPhaseSolver>
01297 class OcTreeMeshDistanceTraversalNode : public DistanceTraversalNodeBase
01298 {
01299 public:
01300 OcTreeMeshDistanceTraversalNode()
01301 {
01302 model1 = NULL;
01303 model2 = NULL;
01304
01305 otsolver = NULL;
01306 }
01307
01308 FCL_REAL BVTesting(int, int) const
01309 {
01310 return -1;
01311 }
01312
01313 void leafTesting(int, int) const
01314 {
01315 otsolver->OcTreeMeshDistance(model1, model2, tf1, tf2, request, *result);
01316 }
01317
01318 const OcTree* model1;
01319 const BVHModel<BV>* model2;
01320
01321 const OcTreeSolver<NarrowPhaseSolver>* otsolver;
01322
01323 };
01324
01325
01326
01327 }
01328
01329 #endif