38 #ifndef FCL_BROADPHASE_BROADPAHSESPATIALHASH_INL_H 
   39 #define FCL_BROADPHASE_BROADPAHSESPATIALHASH_INL_H 
   48 class FCL_EXPORT SpatialHashingCollisionManager<
 
   50     detail::SimpleHashTable<
 
   54 template<
typename S, 
typename HashTable>
 
   59     unsigned int default_table_size)
 
   60   : scene_limit(
AABB<S>(scene_min, scene_max)),
 
   61     hash_table(new HashTable(detail::SpatialHash<S>(scene_limit, cell_size)))
 
   67 template<
typename S, 
typename HashTable>
 
   74 template<
typename S, 
typename HashTable>
 
   83   if(scene_limit.overlap(obj_aabb, overlap_aabb))
 
   85     if(!scene_limit.contain(obj_aabb))
 
   86       objs_partially_penetrating_scene_limit.push_back(
obj);
 
   88     hash_table->insert(overlap_aabb, 
obj);
 
   92     objs_outside_scene_limit.push_back(
obj);
 
   95   obj_aabb_map[
obj] = obj_aabb;
 
   99 template<
typename S, 
typename HashTable>
 
  107   if(scene_limit.overlap(obj_aabb, overlap_aabb))
 
  109     if(!scene_limit.contain(obj_aabb))
 
  110       objs_partially_penetrating_scene_limit.remove(
obj);
 
  112     hash_table->remove(overlap_aabb, 
obj);
 
  116     objs_outside_scene_limit.remove(
obj);
 
  119   obj_aabb_map.erase(
obj);
 
  123 template<
typename S, 
typename HashTable>
 
  130 template<
typename S, 
typename HashTable>
 
  134   objs_partially_penetrating_scene_limit.clear();
 
  135   objs_outside_scene_limit.clear();
 
  137   for(
auto it = objs.cbegin(), end = objs.cend(); it != end; ++it)
 
  143     if(scene_limit.overlap(obj_aabb, overlap_aabb))
 
  145       if(!scene_limit.contain(obj_aabb))
 
  146         objs_partially_penetrating_scene_limit.push_back(
obj);
 
  148       hash_table->insert(overlap_aabb, 
obj);
 
  152       objs_outside_scene_limit.push_back(
obj);
 
  155     obj_aabb_map[
obj] = obj_aabb;
 
  160 template<
typename S, 
typename HashTable>
 
  164   const AABB<S>& old_aabb = obj_aabb_map[updated_obj];
 
  167   const auto is_old_aabb_overlapping
 
  168       = scene_limit.
overlap(old_aabb, old_overlap_aabb);
 
  169   if(is_old_aabb_overlapping)
 
  170     hash_table->remove(old_overlap_aabb, updated_obj);
 
  173   const auto is_new_aabb_overlapping
 
  174       = scene_limit.
overlap(new_aabb, new_overlap_aabb);
 
  175   if(is_new_aabb_overlapping)
 
  176     hash_table->insert(new_overlap_aabb, updated_obj);
 
  179   if(is_old_aabb_overlapping)
 
  181     if(scene_limit.contain(old_aabb))
 
  184       old_status = PartiallyPenetrating;
 
  188     old_status = Outside;
 
  191   if(is_new_aabb_overlapping)
 
  193     if(scene_limit.contain(new_aabb))
 
  195       if (old_status == PartiallyPenetrating)
 
  201         auto find_it = std::find(objs_partially_penetrating_scene_limit.begin(),
 
  202                                  objs_partially_penetrating_scene_limit.end(),
 
  204         objs_partially_penetrating_scene_limit.erase(find_it);
 
  206       else if (old_status == Outside)
 
  212         auto find_it = std::find(objs_outside_scene_limit.begin(),
 
  213                                  objs_outside_scene_limit.end(),
 
  215         objs_outside_scene_limit.erase(find_it);
 
  220       if (old_status == Inside)
 
  226         objs_partially_penetrating_scene_limit.push_back(updated_obj);
 
  228       else if (old_status == Outside)
 
  235         auto find_it = std::find(objs_outside_scene_limit.begin(),
 
  236                                  objs_outside_scene_limit.end(),
 
  238         objs_outside_scene_limit.erase(find_it);
 
  240         objs_partially_penetrating_scene_limit.push_back(updated_obj);
 
  246     if (old_status == Inside)
 
  252       objs_outside_scene_limit.push_back(updated_obj);
 
  254     else if (old_status == PartiallyPenetrating)
 
  261       auto find_it = std::find(objs_partially_penetrating_scene_limit.begin(),
 
  262                                objs_partially_penetrating_scene_limit.end(),
 
  264       objs_partially_penetrating_scene_limit.erase(find_it);
 
  266       objs_outside_scene_limit.push_back(updated_obj);
 
  270   obj_aabb_map[updated_obj] = new_aabb;
 
  274 template<
typename S, 
typename HashTable>
 
  277   for(
size_t i = 0; i < updated_objs.size(); ++i)
 
  278     update(updated_objs[i]);
 
  282 template<
typename S, 
typename HashTable>
 
  287   objs_outside_scene_limit.clear();
 
  288   obj_aabb_map.clear();
 
  292 template<
typename S, 
typename HashTable>
 
  295   objs_.resize(objs.size());
 
  296   std::copy(objs.begin(), objs.end(), objs_.begin());
 
  300 template<
typename S, 
typename HashTable>
 
  303   if(size() == 0) 
return;
 
  304   collide_(
obj, cdata, callback);
 
  308 template<
typename S, 
typename HashTable>
 
  311   if(size() == 0) 
return;
 
  313   distance_(
obj, cdata, callback, min_dist);
 
  317 template<
typename S, 
typename HashTable>
 
  321   const auto& obj_aabb = 
obj->getAABB();
 
  324   if(scene_limit.overlap(obj_aabb, overlap_aabb))
 
  326     const auto query_result = hash_table->query(overlap_aabb);
 
  327     for(
const auto& 
obj2 : query_result)
 
  336     if(!scene_limit.contain(obj_aabb))
 
  338       for(
const auto& 
obj2 : objs_outside_scene_limit)
 
  350     for(
const auto& 
obj2 : objs_partially_penetrating_scene_limit)
 
  359     for(
const auto& 
obj2 : objs_outside_scene_limit)
 
  373 template<
typename S, 
typename HashTable>
 
  377   auto delta = (
obj->getAABB().max_ - 
obj->getAABB().min_) * 0.5;
 
  381     Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
 
  382     aabb.expand(min_dist_delta);
 
  392     old_min_distance = min_dist;
 
  394     if(scene_limit.overlap(
aabb, overlap_aabb))
 
  396       if (distanceObjectToObjects(
 
  397             obj, hash_table->query(overlap_aabb), cdata, callback, min_dist))
 
  402       if(!scene_limit.contain(
aabb))
 
  404         if (distanceObjectToObjects(
 
  405               obj, objs_outside_scene_limit, cdata, callback, min_dist))
 
  413       if (distanceObjectToObjects(
 
  414             obj, objs_partially_penetrating_scene_limit, cdata, callback, min_dist))
 
  419       if (distanceObjectToObjects(
 
  420             obj, objs_outside_scene_limit, cdata, callback, min_dist))
 
  434         if(min_dist < old_min_distance)
 
  436           Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
 
  445             aabb.expand(
obj->getAABB(), 2.0);
 
  459 template<
typename S, 
typename HashTable>
 
  466   for(
const auto& 
obj1 : objs)
 
  468     const auto& obj_aabb = 
obj1->getAABB();
 
  471     if(scene_limit.overlap(obj_aabb, overlap_aabb))
 
  473       auto query_result = hash_table->query(overlap_aabb);
 
  474       for(
const auto& 
obj2 : query_result)
 
  483       if(!scene_limit.contain(obj_aabb))
 
  485         for(
const auto& 
obj2 : objs_outside_scene_limit)
 
  497       for(
const auto& 
obj2 : objs_partially_penetrating_scene_limit)
 
  506       for(
const auto& 
obj2 : objs_outside_scene_limit)
 
  519 template<
typename S, 
typename HashTable>
 
  526   this->enable_tested_set_ = 
true;
 
  527   this->tested_set.clear();
 
  531   for(
const auto& 
obj : objs)
 
  533     if(distance_(
obj, cdata, callback, min_dist))
 
  537   this->enable_tested_set_ = 
false;
 
  538   this->tested_set.clear();
 
  542 template<
typename S, 
typename HashTable>
 
  547   if((size() == 0) || (other_manager->size() == 0))
 
  550   if(
this == other_manager)
 
  556   if(this->size() < other_manager->size())
 
  558     for(
const auto& 
obj : objs)
 
  560       if(other_manager->collide_(
obj, cdata, callback))
 
  566     for(
const auto& 
obj : other_manager->objs)
 
  568       if(collide_(
obj, cdata, callback))
 
  575 template<
typename S, 
typename HashTable>
 
  580   if((size() == 0) || (other_manager->size() == 0))
 
  583   if(
this == other_manager)
 
  591   if(this->size() < other_manager->size())
 
  593     for(
const auto& 
obj : objs)
 
  594       if(other_manager->distance_(
obj, cdata, callback, min_dist)) 
return;
 
  598     for(
const auto& 
obj : other_manager->objs)
 
  599       if(distance_(
obj, cdata, callback, min_dist)) 
return;
 
  604 template<
typename S, 
typename HashTable>
 
  611 template<
typename S, 
typename HashTable>
 
  618 template<
typename S, 
typename HashTable>
 
  623   for(
unsigned int i = 0; i < objs.size(); ++i)
 
  624     bound += objs[i]->getAABB();
 
  631 template<
typename S, 
typename HashTable>
 
  632 template<
typename Container>
 
  635     const Container& objs,
 
  640   for(
auto& 
obj2 : objs)
 
  645     if(!this->enable_tested_set_)
 
  647       if(
obj->getAABB().distance(
obj2->getAABB()) < min_dist)
 
  649         if(callback(
obj, 
obj2, cdata, min_dist))
 
  655       if(!this->inTestedSet(
obj, 
obj2))
 
  657         if(
obj->getAABB().distance(
obj2->getAABB()) < min_dist)
 
  659           if(callback(
obj, 
obj2, cdata, min_dist))
 
  663         this->insertTestedSet(
obj, 
obj2);