broadphase_dynamic_AABB_tree_array.cpp
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2011, Willow Garage, Inc.
00005  *  All rights reserved.
00006  *
00007  *  Redistribution and use in source and binary forms, with or without
00008  *  modification, are permitted provided that the following conditions
00009  *  are met:
00010  *
00011  *   * Redistributions of source code must retain the above copyright
00012  *     notice, this list of conditions and the following disclaimer.
00013  *   * Redistributions in binary form must reproduce the above
00014  *     copyright notice, this list of conditions and the following
00015  *     disclaimer in the documentation and/or other materials provided
00016  *     with the distribution.
00017  *   * Neither the name of Willow Garage, Inc. nor the names of its
00018  *     contributors may be used to endorse or promote products derived
00019  *     from this software without specific prior written permission.
00020  *
00021  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032  *  POSSIBILITY OF SUCH DAMAGE.
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 } // dynamic_AABB_tree_array
00654 
00655 } // details
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


fcl
Author(s): Jia Pan
autogenerated on Tue Jan 15 2013 16:05:30