From 51a9b8a62d04f3edd7f56626f3e0eb9dc74f88ee Mon Sep 17 00:00:00 2001
From: jpan <jpan@253336fb-580f-4252-a368-f3cef5a2a82b>
Date: Tue, 3 Jul 2012 08:39:58 +0000
Subject: [PATCH] Fix all known bugs in broadphase.

git-svn-id: https://kforge.ros.org/fcl/fcl_ros@115 253336fb-580f-4252-a368-f3cef5a2a82b
---
 trunk/fcl/include/fcl/broad_phase_collision.h | 26 +++++++-
 trunk/fcl/include/fcl/hierarchy_tree.h        | 13 ++--
 trunk/fcl/src/broad_phase_collision.cpp       | 61 ++++++++++++-------
 trunk/fcl/src/collision.cpp                   |  2 +
 trunk/fcl/src/distance.cpp                    |  2 +
 5 files changed, 71 insertions(+), 33 deletions(-)

diff --git a/trunk/fcl/include/fcl/broad_phase_collision.h b/trunk/fcl/include/fcl/broad_phase_collision.h
index 44954b3f..a7867546 100644
--- a/trunk/fcl/include/fcl/broad_phase_collision.h
+++ b/trunk/fcl/include/fcl/broad_phase_collision.h
@@ -97,6 +97,18 @@ public:
   /** \brief update the condition of manager */
   virtual void update() = 0;
 
+  /** \brief update the manager by explicitly given the object updated */
+  virtual void update(CollisionObject* updated_obj)
+  {
+    update();
+  }
+
+  /** \brief update the manager by explicitly given the set of objects update */
+  virtual void update(const std::vector<CollisionObject*>& updated_objs)
+  {
+    update();
+  }
+
   /** \brief clear the manager */
   virtual void clear() = 0;
 
@@ -129,7 +141,6 @@ public:
 
 protected:
   mutable std::set<std::pair<CollisionObject*, CollisionObject*> > tested_set;
-  mutable std::set<CollisionObject*> tested_set2;
   mutable bool enable_tested_set_;
 
 };
@@ -424,6 +435,7 @@ bool SpatialHashingCollisionManager<HashTable>::collide_(CollisionObject* obj, v
       std::list<CollisionObject*>::const_iterator it;
       for(it = objs_outside_scene_limit.begin(); it != objs_outside_scene_limit.end(); ++it)
       {
+        if(obj == *it) continue;
         if(callback(obj, *it, cdata)) return true;
       }
     }
@@ -431,6 +443,7 @@ bool SpatialHashingCollisionManager<HashTable>::collide_(CollisionObject* obj, v
     std::vector<CollisionObject*> query_result = hash_table->query(overlap_aabb);
     for(unsigned int i = 0; i < query_result.size(); ++i)
     {
+      if(obj == query_result[i]) continue;
       if(callback(obj, query_result[i], cdata)) return true;
     }
   }
@@ -439,6 +452,7 @@ bool SpatialHashingCollisionManager<HashTable>::collide_(CollisionObject* obj, v
     std::list<CollisionObject*>::const_iterator it;
     for(it = objs_outside_scene_limit.begin(); it != objs_outside_scene_limit.end(); ++it)
     {
+      if(obj == *it) continue;
       if(callback(obj, *it, cdata)) return true;
     }
   }
@@ -475,6 +489,7 @@ bool SpatialHashingCollisionManager<HashTable>::distance_(CollisionObject* obj,
         std::list<CollisionObject*>::const_iterator it;
         for(it = objs_outside_scene_limit.begin(); it != objs_outside_scene_limit.end(); ++it)
         {
+          if(obj == *it) continue;
           if(obj->getAABB().distance((*it)->getAABB()) < min_dist)
             if(callback(obj, *it, cdata, min_dist)) return true;
         }
@@ -483,6 +498,7 @@ bool SpatialHashingCollisionManager<HashTable>::distance_(CollisionObject* obj,
       std::vector<CollisionObject*> query_result = hash_table->query(overlap_aabb);
       for(unsigned int i = 0; i < query_result.size(); ++i)
       {
+        if(obj == query_result[i]) continue;
         if(obj->getAABB().distance(query_result[i]->getAABB()) < min_dist)
           if(callback(obj, query_result[i], cdata, min_dist)) return true;
       }
@@ -492,6 +508,7 @@ bool SpatialHashingCollisionManager<HashTable>::distance_(CollisionObject* obj,
       std::list<CollisionObject*>::const_iterator it;
       for(it = objs_outside_scene_limit.begin(); it != objs_outside_scene_limit.end(); ++it)
       {
+        if(obj == *it) continue;
         if(obj->getAABB().distance((*it)->getAABB()) < min_dist)
           if(callback(obj, *it, cdata, min_dist)) return true;
       }
@@ -1091,8 +1108,11 @@ public:
   /** \brief update the condition of manager */
   void update();
 
-  /** \brief update a specific object */
-  void update(CollisionObject* obj);
+  /** \brief update the manager by explicitly given the object updated */
+  void update(CollisionObject* updated_obj);
+
+  /** \brief update the manager by explicitly given the set of objects update */
+  void update(const std::vector<CollisionObject*>& updated_objs);
 
   /** \brief clear the manager */
   void clear()
diff --git a/trunk/fcl/include/fcl/hierarchy_tree.h b/trunk/fcl/include/fcl/hierarchy_tree.h
index 084d4f32..fb52b150 100644
--- a/trunk/fcl/include/fcl/hierarchy_tree.h
+++ b/trunk/fcl/include/fcl/hierarchy_tree.h
@@ -270,29 +270,26 @@ public:
     return n_leaves;
   }
 
-  NodeType* getRoot() const
+  inline NodeType* getRoot() const
   {
     return root_node;
   }
 
-  NodeType*& getRoot()
+  inline NodeType*& getRoot()
   {
     return root_node;
   }
 
   void print(NodeType* root, int depth)
   {
+    for(int i = 0; i < depth; ++i)
+      std::cout << " ";
+    std::cout << " (" << root->bv.min_[0] << ", " << root->bv.min_[1] << ", " << root->bv.min_[2] << "; " << root->bv.max_[0] << ", " << root->bv.max_[1] << ", " << root->bv.max_[2] << ")" << std::endl;
     if(root->isLeaf())
     {
-      for(int i = 0; i < depth; ++i)
-        std::cout << " ";
-      std::cout << " (" << root->bv.min_[0] << ", " << root->bv.min_[1] << ", " << root->bv.min_[2] << "; " << root->bv.max_[0] << ", " << root->bv.max_[1] << ", " << root->bv.max_[2] << ")" << std::endl;
     }
     else
     {
-      for(int i = 0; i < depth; ++i)
-        std::cout << " ";
-      std::cout << " (" << root->bv.min_[0] << ", " << root->bv.min_[1] << ", " << root->bv.min_[2] << "; " << root->bv.max_[0] << ", " << root->bv.max_[1] << ", " << root->bv.max_[2] << ")" << std::endl;
       print(root->childs[0], depth+1);
       print(root->childs[1], depth+1);
     }
diff --git a/trunk/fcl/src/broad_phase_collision.cpp b/trunk/fcl/src/broad_phase_collision.cpp
index efde3b8c..1cc433b3 100644
--- a/trunk/fcl/src/broad_phase_collision.cpp
+++ b/trunk/fcl/src/broad_phase_collision.cpp
@@ -55,7 +55,8 @@ bool defaultCollisionFunction(CollisionObject* o1, CollisionObject* o2, void* cd
   if(cdata->done) return true;
 
   std::vector<Contact> contacts;
-  int num_contacts = collide(o1, o2, 1, false, false, contacts);
+  // int num_contacts = collide(o1, o2, 1, false, false, contacts);
+  int num_contacts = collide(o1, o2, cdata->num_max_contacts, cdata->exhaustive, cdata->enable_contact, contacts);
 
   cdata->is_collision = (num_contacts > 0);
   for(int i = 0; i < num_contacts; ++i)
@@ -1152,11 +1153,14 @@ bool SaPCollisionManager::collide_(CollisionObject* obj, void* cdata, CollisionC
 
   while(pos != end_pos)
   {
-    if((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val))
+    if(pos->aabb->obj != obj)
     {
-      if(pos->aabb->cached.overlap(obj->getAABB()))
-        if(callback(obj, pos->aabb->obj, cdata))
-          return true;
+      if((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val))
+      {
+        if(pos->aabb->cached.overlap(obj->getAABB()))
+          if(callback(obj, pos->aabb->obj, cdata))
+            return true;
+      }
     }
     pos = pos->next[axis];
   } 
@@ -1220,26 +1224,32 @@ bool SaPCollisionManager::distance_(CollisionObject* obj, void* cdata, DistanceC
       if((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val)) 
       {
         CollisionObject* curr_obj = pos->aabb->obj;
-        if(!enable_tested_set_)
+        if(curr_obj != obj)
         {
-          if(pos->aabb->cached.distance(obj->getAABB()) < min_dist)
-          {
-            if(callback(curr_obj, obj, cdata, min_dist))
-              return true;
-          }
-        }
-        else
-        {
-          bool not_find = (tested_set2.find(curr_obj) == tested_set2.end());
-          if(not_find)
+          if(!enable_tested_set_)
           {
             if(pos->aabb->cached.distance(obj->getAABB()) < min_dist)
             {
               if(callback(curr_obj, obj, cdata, min_dist))
                 return true;
             }
-
-            tested_set2.insert(curr_obj);
+          }
+          else
+          {
+            bool not_find;
+            if(curr_obj < obj) not_find = (tested_set.find(std::make_pair(curr_obj, obj)) == tested_set.end());
+            else not_find = (tested_set.find(std::make_pair(obj, curr_obj)) == tested_set.end());
+            if(not_find)
+            {
+              if(pos->aabb->cached.distance(obj->getAABB()) < min_dist)
+              {
+                if(callback(curr_obj, obj, cdata, min_dist))
+                  return true;
+              }
+
+              if(curr_obj < obj) tested_set.insert(std::make_pair(curr_obj, obj));
+              else tested_set.insert(std::make_pair(obj, curr_obj));
+            }
           }
         }
       }
@@ -1907,6 +1917,7 @@ void DynamicAABBTreeCollisionManager::registerObjects(const std::vector<Collisio
   else
   {
     std::vector<DynamicAABBNode*> leaves(other_objs.size());
+    table.rehash(other_objs.size());
     for(size_t i = 0; i < other_objs.size(); ++i)
     {
       DynamicAABBNode* node = new DynamicAABBNode;
@@ -1963,18 +1974,24 @@ void DynamicAABBTreeCollisionManager::update()
   setup_ = false;
 }
 
-void DynamicAABBTreeCollisionManager::update(CollisionObject* obj)
+void DynamicAABBTreeCollisionManager::update(CollisionObject* updated_obj)
 {
-  DynamicAABBTable::const_iterator it = table.find(obj);
+  DynamicAABBTable::const_iterator it = table.find(updated_obj);
   if(it != table.end())
   {
     DynamicAABBNode* node = it->second;
-    if(!node->bv.equal(obj->getAABB()))
-      dtree.update(node, obj->getAABB());
+    if(!node->bv.equal(updated_obj->getAABB()))
+      dtree.update(node, updated_obj->getAABB());
   }
   setup_ = false;
 }
 
+void DynamicAABBTreeCollisionManager::update(const std::vector<CollisionObject*>& updated_objs)
+{
+  for(size_t i = 0; i < updated_objs.size(); ++i)
+    update(updated_objs[i]);
+}
+
 bool DynamicAABBTreeCollisionManager::collisionRecurse(DynamicAABBNode* root1, DynamicAABBNode* root2, void* cdata, CollisionCallBack callback) const
 {
   if(root1->isLeaf() && root2->isLeaf())
diff --git a/trunk/fcl/src/collision.cpp b/trunk/fcl/src/collision.cpp
index 46be2c23..64a2b194 100644
--- a/trunk/fcl/src/collision.cpp
+++ b/trunk/fcl/src/collision.cpp
@@ -137,6 +137,8 @@ int collide(const CollisionGeometry* o1, const SimpleTransform& tf1,
 {
   GJKSolver_libccd solver;
   return collide<GJKSolver_libccd>(o1, tf1, o2, tf2, &solver, num_max_contacts, exhaustive, enable_contact, contacts);
+  // GJKSolver_indep solver;
+  // return collide<GJKSolver_indep>(o1, tf1, o2, tf2, &solver, num_max_contacts, exhaustive, enable_contact, contacts);
 }
 
 }
diff --git a/trunk/fcl/src/distance.cpp b/trunk/fcl/src/distance.cpp
index b3883a89..e9cfdda4 100644
--- a/trunk/fcl/src/distance.cpp
+++ b/trunk/fcl/src/distance.cpp
@@ -121,6 +121,8 @@ BVH_REAL distance(const CollisionGeometry* o1, const SimpleTransform& tf1,
 {
   GJKSolver_libccd solver;
   return distance<GJKSolver_libccd>(o1, tf1, o2, tf2, &solver);
+  // GJKSolver_indep solver;
+  // return distance<GJKSolver_indep>(o1, tf1, o2, tf2, &solver);
 }
 
 
-- 
GitLab