38 #ifndef FCL_BROAD_PHASE_SSAP_INL_H 
   39 #define FCL_BROAD_PHASE_SSAP_INL_H 
  100 template <
typename S>
 
  107   auto pos_start1 = objs_x.begin();
 
  108   auto pos_end1 = std::upper_bound(pos_start1, objs_x.end(), &dummyHigh, 
SortByXLow<S>());
 
  110   while(pos_start1 < pos_end1)
 
  112     if(*pos_start1 == 
obj)
 
  114       objs_x.erase(pos_start1);
 
  120   auto pos_start2 = objs_y.begin();
 
  121   auto pos_end2 = std::upper_bound(pos_start2, objs_y.end(), &dummyHigh, 
SortByYLow<S>());
 
  123   while(pos_start2 < pos_end2)
 
  125     if(*pos_start2 == 
obj)
 
  127       objs_y.erase(pos_start2);
 
  133   auto pos_start3 = objs_z.begin();
 
  134   auto pos_end3 = std::upper_bound(pos_start3, objs_z.end(), &dummyHigh, 
SortByZLow<S>());
 
  136   while(pos_start3 < pos_end3)
 
  138     if(*pos_start3 == 
obj)
 
  140       objs_z.erase(pos_start3);
 
  148 template <
typename S>
 
  155 template <
typename S>
 
  158   objs_x.push_back(
obj);
 
  159   objs_y.push_back(
obj);
 
  160   objs_z.push_back(
obj);
 
  165 template <
typename S>
 
  178 template <
typename S>
 
  186 template <
typename S>
 
  196 template <
typename S>
 
  199   objs.resize(objs_x.size());
 
  200   std::copy(objs_x.begin(), objs_x.end(), objs.begin());
 
  204 template <
typename S>
 
  208   while(pos_start < pos_end)
 
  210     if(*pos_start != 
obj) 
 
  212       if((*pos_start)->getAABB().overlap(
obj->getAABB()))
 
  214         if(callback(*pos_start, 
obj, cdata))
 
  224 template <
typename S>
 
  227   while(pos_start < pos_end)
 
  229     if(*pos_start != 
obj) 
 
  231       if((*pos_start)->getAABB().distance(
obj->getAABB()) < min_dist)
 
  233         if(callback(*pos_start, 
obj, cdata, min_dist))
 
  244 template <
typename S>
 
  247   if(size() == 0) 
return;
 
  249   collide_(
obj, cdata, callback);
 
  253 template <
typename S>
 
  256   static const unsigned int CUTOFF = 100;
 
  259   bool coll_res = 
false;
 
  261   const auto pos_start1 = objs_x.begin();
 
  262   const auto pos_end1 = std::upper_bound(pos_start1, objs_x.end(), &dummyHigh, 
SortByXLow<S>());
 
  263   unsigned int d1 = pos_end1 - pos_start1;
 
  267     const auto pos_start2 = objs_y.begin();
 
  268     const auto pos_end2 = std::upper_bound(pos_start2, objs_y.end(), &dummyHigh, 
SortByYLow<S>());
 
  269     unsigned int d2 = pos_end2 - pos_start2;
 
  273       const auto pos_start3 = objs_z.begin();
 
  274       const auto pos_end3 = std::upper_bound(pos_start3, objs_z.end(), &dummyHigh, 
SortByZLow<S>());
 
  275       unsigned int d3 = pos_end3 - pos_start3;
 
  279         if(d3 <= d2 && d3 <= d1)
 
  280           coll_res = checkColl(pos_start3, pos_end3, 
obj, cdata, callback);
 
  283           if(d2 <= d3 && d2 <= d1)
 
  284             coll_res = checkColl(pos_start2, pos_end2, 
obj, cdata, callback);
 
  286             coll_res = checkColl(pos_start1, pos_end1, 
obj, cdata, callback);
 
  290         coll_res = checkColl(pos_start3, pos_end3, 
obj, cdata, callback);
 
  293       coll_res = checkColl(pos_start2, pos_end2, 
obj, cdata, callback);
 
  296     coll_res = checkColl(pos_start1, pos_end1, 
obj, cdata, callback);
 
  302 template <
typename S>
 
  305   if(size() == 0) 
return;
 
  308   distance_(
obj, cdata, callback, min_dist);
 
  312 template <
typename S>
 
  315   static const unsigned int CUTOFF = 100;
 
  319     dummy_vector += 
Vector3<S>(min_dist, min_dist, min_dist);
 
  321   typename std::vector<CollisionObject<S>*>::const_iterator pos_start1 = objs_x.begin();
 
  322   typename std::vector<CollisionObject<S>*>::const_iterator pos_start2 = objs_y.begin();
 
  323   typename std::vector<CollisionObject<S>*>::const_iterator pos_start3 = objs_z.begin();
 
  324   typename std::vector<CollisionObject<S>*>::const_iterator pos_end1 = objs_x.end();
 
  325   typename std::vector<CollisionObject<S>*>::const_iterator pos_end2 = objs_y.end();
 
  326   typename std::vector<CollisionObject<S>*>::const_iterator pos_end3 = objs_z.end();
 
  333     old_min_distance = min_dist;
 
  336     pos_end1 = std::upper_bound(pos_start1, objs_x.end(), &dummyHigh, 
SortByXLow<S>());
 
  337     unsigned int d1 = pos_end1 - pos_start1;
 
  339     bool dist_res = 
false;
 
  343       pos_end2 = std::upper_bound(pos_start2, objs_y.end(), &dummyHigh, 
SortByYLow<S>());
 
  344       unsigned int d2 = pos_end2 - pos_start2;
 
  348         pos_end3 = std::upper_bound(pos_start3, objs_z.end(), &dummyHigh, 
SortByZLow<S>());
 
  349         unsigned int d3 = pos_end3 - pos_start3;
 
  353           if(d3 <= d2 && d3 <= d1)
 
  354             dist_res = checkDis(pos_start3, pos_end3, 
obj, cdata, callback, min_dist);
 
  357             if(d2 <= d3 && d2 <= d1)
 
  358               dist_res = checkDis(pos_start2, pos_end2, 
obj, cdata, callback, min_dist);
 
  360               dist_res = checkDis(pos_start1, pos_end1, 
obj, cdata, callback, min_dist);
 
  364           dist_res = checkDis(pos_start3, pos_end3, 
obj, cdata, callback, min_dist);
 
  367         dist_res = checkDis(pos_start2, pos_end2, 
obj, cdata, callback, min_dist);
 
  371       dist_res = checkDis(pos_start1, pos_end1, 
obj, cdata, callback, min_dist);
 
  374     if(dist_res) 
return true;
 
  384         if(min_dist < old_min_distance)
 
  386           dummy_vector = 
obj->getAABB().max_ + 
Vector3<S>(min_dist, min_dist, min_dist);
 
  392             dummy_vector = dummy_vector + delta;
 
  394             dummy_vector = dummy_vector * 2 - 
obj->getAABB().max_;
 
  411 template <
typename S>
 
  420   S delta_x = (objs_x[objs_x.size() - 1])->getAABB().min_[0] - (objs_x[0])->getAABB().min_[0];
 
  421   S delta_y = (objs_x[objs_y.size() - 1])->getAABB().min_[1] - (objs_y[0])->getAABB().min_[1];
 
  422   S delta_z = (objs_z[objs_z.size() - 1])->getAABB().min_[2] - (objs_z[0])->getAABB().min_[2];
 
  425   if(delta_y > delta_x && delta_y > delta_z)
 
  427   else if(delta_z > delta_y && delta_z > delta_x)
 
  433     it_beg = objs_x.begin();
 
  434     it_end = objs_x.end();
 
  437     it_beg = objs_y.begin();
 
  438     it_end = objs_y.end();
 
  441     it_beg = objs_z.begin();
 
  442     it_end = objs_z.end();
 
  450 template <
typename S>
 
  453   if(size() == 0) 
return;
 
  455   typename std::vector<CollisionObject<S>*>::const_iterator pos, run_pos, pos_end;
 
  456   size_t axis = selectOptimalAxis(objs_x, objs_y, objs_z,
 
  458   size_t axis2 = (axis + 1 > 2) ? 0 : (axis + 1);
 
  459   size_t axis3 = (axis2 + 1 > 2) ? 0 : (axis2 + 1);
 
  463   while((run_pos < pos_end) && (pos < pos_end))
 
  469       if((*run_pos)->getAABB().min_[axis] < 
obj->getAABB().min_[axis])
 
  472         if(run_pos == pos_end) 
break;
 
  482     if(run_pos < pos_end)
 
  484       typename std::vector<CollisionObject<S>*>::const_iterator run_pos2 = run_pos;
 
  486       while((*run_pos2)->getAABB().min_[axis] <= 
obj->getAABB().max_[axis])
 
  491         if((
obj->getAABB().max_[axis2] >= 
obj2->getAABB().min_[axis2]) && (
obj2->getAABB().max_[axis2] >= 
obj->getAABB().min_[axis2]))
 
  493           if((
obj->getAABB().max_[axis3] >= 
obj2->getAABB().min_[axis3]) && (
obj2->getAABB().max_[axis3] >= 
obj->getAABB().min_[axis3]))
 
  500         if(run_pos2 == pos_end) 
break;
 
  507 template <
typename S>
 
  510   if(size() == 0) 
return;
 
  512   typename std::vector<CollisionObject<S>*>::const_iterator it, it_end;
 
  513   selectOptimalAxis(objs_x, objs_y, objs_z, it, it_end);
 
  516   for(; it != it_end; ++it)
 
  518     if(distance_(*it, cdata, callback, min_dist))
 
  524 template <
typename S>
 
  529   if((size() == 0) || (other_manager->
size() == 0)) 
return;
 
  531   if(
this == other_manager)
 
  538   typename std::vector<CollisionObject<S>*>::const_iterator it, end;
 
  539   if(this->size() < other_manager->
size())
 
  541     for(it = objs_x.begin(), end = objs_x.end(); it != end; ++it)
 
  542       if(other_manager->
collide_(*it, cdata, callback)) 
return;
 
  546     for(it = other_manager->
objs_x.begin(), end = other_manager->
objs_x.end(); it != end; ++it)
 
  547       if(collide_(*it, cdata, callback)) 
return;
 
  552 template <
typename S>
 
  557   if((size() == 0) || (other_manager->
size() == 0)) 
return;
 
  559   if(
this == other_manager)
 
  566   typename std::vector<CollisionObject<S>*>::const_iterator it, end;
 
  567   if(this->size() < other_manager->
size())
 
  569     for(it = objs_x.begin(), end = objs_x.end(); it != end; ++it)
 
  570       if(other_manager->
distance_(*it, cdata, callback, min_dist)) 
return;
 
  574     for(it = other_manager->
objs_x.begin(), end = other_manager->
objs_x.end(); it != end; ++it)
 
  575       if(distance_(*it, cdata, callback, min_dist)) 
return;
 
  580 template <
typename S>
 
  583   return objs_x.empty();
 
  587 template <
typename S>
 
  590   return objs_x.size();