38 #ifndef FCL_BROAD_PHASE_SAP_INL_H 
   39 #define FCL_BROAD_PHASE_SAP_INL_H 
   55   for(
auto end = 
AABB_arr.end(); it != end; ++it)
 
   70   for(
int coord = 0; coord < 3; ++coord)
 
   73     if(curr->lo->prev[coord] == 
nullptr)
 
   74       elist[coord] = curr->lo->next[coord];
 
   76       curr->lo->prev[coord]->next[coord] = curr->lo->next[coord];
 
   78     curr->lo->next[coord]->prev[coord] = curr->lo->prev[coord];
 
   81     if(curr->hi->prev[coord] == 
nullptr)
 
   82       elist[coord] = curr->hi->next[coord];
 
   84       curr->hi->prev[coord]->next[coord] = curr->hi->next[coord];
 
   86     if(curr->hi->next[coord] != 
nullptr)
 
   87       curr->hi->next[coord]->prev[coord] = curr->hi->prev[coord];
 
  109 template <
typename S>
 
  116 template <
typename S>
 
  119   if(other_objs.empty()) 
return;
 
  125     std::vector<EndPoint*> endpoints(2 * other_objs.size());
 
  127     for(
size_t i = 0; i < other_objs.size(); ++i)
 
  129       SaPAABB* sapaabb = 
new SaPAABB();
 
  130       sapaabb->obj = other_objs[i];
 
  131       sapaabb->lo = 
new EndPoint();
 
  132       sapaabb->hi = 
new EndPoint();
 
  133       sapaabb->cached = other_objs[i]->getAABB();
 
  134       endpoints[2 * i] = sapaabb->lo;
 
  135       endpoints[2 * i + 1] = sapaabb->hi;
 
  136       sapaabb->lo->minmax = 0;
 
  137       sapaabb->hi->minmax = 1;
 
  138       sapaabb->lo->aabb = sapaabb;
 
  139       sapaabb->hi->aabb = sapaabb;
 
  146     for(
size_t coord = 0; coord < 3; ++coord)
 
  148       std::sort(endpoints.begin(), endpoints.end(),
 
  149                 std::bind(std::less<S>(),
 
  150                             std::bind(
static_cast<S (EndPoint::*)(
size_t) 
const >(&EndPoint::getVal), std::placeholders::_1, coord),
 
  151                             std::bind(
static_cast<S (EndPoint::*)(
size_t) 
const >(&EndPoint::getVal), std::placeholders::_2, coord)));
 
  153       endpoints[0]->prev[coord] = 
nullptr;
 
  154       endpoints[0]->next[coord] = endpoints[1];
 
  155       for(
size_t i = 1; i < endpoints.size() - 1; ++i)
 
  157         endpoints[i]->prev[coord] = endpoints[i-1];
 
  158         endpoints[i]->next[coord] = endpoints[i+1];
 
  160       endpoints[endpoints.size() - 1]->prev[coord] = endpoints[endpoints.size() - 2];
 
  161       endpoints[endpoints.size() - 1]->next[coord] = 
nullptr;
 
  163       elist[coord] = endpoints[0];
 
  165       scale[coord] = endpoints.back()->aabb->cached.max_[coord] - endpoints[0]->aabb->cached.min_[coord];
 
  169     if(scale[axis] < scale[1]) axis = 1;
 
  170     if(scale[axis] < scale[2]) axis = 2;
 
  172     EndPoint* pos = 
elist[axis];
 
  174     while(pos != 
nullptr)
 
  176       EndPoint* pos_next = 
nullptr;
 
  177       SaPAABB* 
aabb = pos->aabb;
 
  178       EndPoint* pos_it = pos->next[axis];
 
  180       while(pos_it != 
nullptr)
 
  182         if(pos_it->aabb == 
aabb)
 
  184           if(pos_next == 
nullptr) pos_next = pos_it;
 
  188         if(pos_it->minmax == 0)
 
  190           if(pos_next == 
nullptr) pos_next = pos_it;
 
  191           if(pos_it->aabb->cached.overlap(
aabb->cached))
 
  194         pos_it = pos_it->next[axis];
 
  205 template <
typename S>
 
  208   SaPAABB* curr = 
new SaPAABB;
 
  209   curr->cached = 
obj->getAABB();
 
  211   curr->lo = 
new EndPoint;
 
  212   curr->lo->minmax = 0;
 
  213   curr->lo->aabb = curr;
 
  215   curr->hi = 
new EndPoint;
 
  216   curr->hi->minmax = 1;
 
  217   curr->hi->aabb = curr;
 
  219   for(
int coord = 0; coord < 3; ++coord)
 
  221     EndPoint* current = 
elist[coord];
 
  224     if(current == 
nullptr) 
 
  226       elist[coord] = curr->lo;
 
  227       curr->lo->prev[coord] = curr->lo->next[coord] = 
nullptr;
 
  231       EndPoint* curr_lo = curr->lo;
 
  232       S curr_lo_val = curr_lo->getVal()[coord];
 
  233       while((current->getVal()[coord] < curr_lo_val) && (current->next[coord] != 
nullptr))
 
  234         current = current->next[coord];
 
  236       if(current->getVal()[coord] >= curr_lo_val)
 
  238         curr_lo->prev[coord] = current->prev[coord];
 
  239         curr_lo->next[coord] = current;
 
  240         if(current->prev[coord] == 
nullptr)
 
  241           elist[coord] = curr_lo;
 
  243           current->prev[coord]->next[coord] = curr_lo;
 
  245         current->prev[coord] = curr_lo;
 
  249         curr_lo->prev[coord] = current;
 
  250         curr_lo->next[coord] = 
nullptr;
 
  251         current->next[coord] = curr_lo;
 
  258     EndPoint* curr_hi = curr->hi;
 
  259     S curr_hi_val = curr_hi->getVal()[coord];
 
  263       while((current->getVal()[coord] < curr_hi_val) && (current->next[coord] != 
nullptr))
 
  265         if(current != curr->lo)
 
  266           if(current->aabb->cached.overlap(curr->cached))
 
  269         current = current->next[coord];
 
  274       while((current->getVal()[coord] < curr_hi_val) && (current->next[coord] != 
nullptr))
 
  275         current = current->next[coord];
 
  278     if(current->getVal()[coord] >= curr_hi_val)
 
  280       curr_hi->prev[coord] = current->prev[coord];
 
  281       curr_hi->next[coord] = current;
 
  282       if(current->prev[coord] == 
nullptr)
 
  283         elist[coord] = curr_hi;
 
  285         current->prev[coord]->next[coord] = curr_hi;
 
  287       current->prev[coord] = curr_hi;
 
  291       curr_hi->prev[coord] = current;
 
  292       curr_hi->next[coord] = 
nullptr;
 
  293       current->next[coord] = curr_hi;
 
  305 template <
typename S>
 
  308   if(
size() == 0) 
return;
 
  311   scale[0] = (
velist[0].back())->getVal(0) - 
velist[0][0]->getVal(0);
 
  312   scale[1] = (
velist[1].back())->getVal(1) - 
velist[1][0]->getVal(1);;
 
  313   scale[2] = (
velist[2].back())->getVal(2) - 
velist[2][0]->getVal(2);
 
  315   if(scale[axis] < scale[1]) axis = 1;
 
  316   if(scale[axis] < scale[2]) axis = 2;
 
  321 template <
typename S>
 
  324   if(updated_aabb->cached.equal(updated_aabb->obj->getAABB()))
 
  327   SaPAABB* current = updated_aabb;
 
  329   Vector3<S> new_min = current->obj->getAABB().min_;
 
  330   Vector3<S> new_max = current->obj->getAABB().max_;
 
  333   dummy.cached = current->obj->getAABB();
 
  335   for(
int coord = 0; coord < 3; ++coord)
 
  340     if(current->lo->getVal(coord) > new_min[coord])
 
  342     else if(current->lo->getVal(coord) < new_min[coord])
 
  349       if(current->lo->prev[coord] != 
nullptr)
 
  352         while((temp != 
nullptr) && (temp->getVal(coord) > new_min[coord]))
 
  354           if(temp->minmax == 1)
 
  355             if(temp->aabb->cached.overlap(dummy.cached))
 
  357           temp = temp->prev[coord];
 
  362           current->lo->prev[coord]->next[coord] = current->lo->next[coord];
 
  363           current->lo->next[coord]->prev[coord] = current->lo->prev[coord];
 
  364           current->lo->prev[coord] = 
nullptr;
 
  365           current->lo->next[coord] = 
elist[coord];
 
  366           elist[coord]->prev[coord] = current->lo;
 
  367           elist[coord] = current->lo;
 
  371           current->lo->prev[coord]->next[coord] = current->lo->next[coord];
 
  372           current->lo->next[coord]->prev[coord] = current->lo->prev[coord];
 
  373           current->lo->prev[coord] = temp;
 
  374           current->lo->next[coord] = temp->next[coord];
 
  375           temp->next[coord]->prev[coord] = current->lo;
 
  376           temp->next[coord] = current->lo;
 
  380       current->lo->getVal(coord) = new_min[coord];
 
  384       while(temp->getVal(coord) > new_max[coord])
 
  386         if((temp->minmax == 0) && (temp->aabb->cached.overlap(current->cached)))
 
  388         temp = temp->prev[coord];
 
  391       current->hi->prev[coord]->next[coord] = current->hi->next[coord];
 
  392       if(current->hi->next[coord] != 
nullptr)
 
  393         current->hi->next[coord]->prev[coord] = current->hi->prev[coord];
 
  394       current->hi->prev[coord] = temp;
 
  395       current->hi->next[coord] = temp->next[coord];
 
  396       if(temp->next[coord] != 
nullptr)
 
  397         temp->next[coord]->prev[coord] = current->hi;
 
  398       temp->next[coord] = current->hi;
 
  400       current->hi->getVal(coord) = new_max[coord];
 
  402     else if(direction == 1)
 
  405       if(current->hi->next[coord] != 
nullptr)
 
  408         while((temp->next[coord] != 
nullptr) && (temp->getVal(coord) < new_max[coord]))
 
  410           if(temp->minmax == 0)
 
  411             if(temp->aabb->cached.overlap(dummy.cached))
 
  413           temp = temp->next[coord];
 
  416         if(temp->getVal(coord) < new_max[coord])
 
  418           current->hi->prev[coord]->next[coord] = current->hi->next[coord];
 
  419           current->hi->next[coord]->prev[coord] = current->hi->prev[coord];
 
  420           current->hi->prev[coord] = temp;
 
  421           current->hi->next[coord] = 
nullptr;
 
  422           temp->next[coord] = current->hi;
 
  426           current->hi->prev[coord]->next[coord] = current->hi->next[coord];
 
  427           current->hi->next[coord]->prev[coord] = current->hi->prev[coord];
 
  428           current->hi->prev[coord] = temp->prev[coord];
 
  429           current->hi->next[coord] = temp;
 
  430           temp->prev[coord]->next[coord] = current->hi;
 
  431           temp->prev[coord] = current->hi;
 
  435       current->hi->getVal(coord) = new_max[coord];
 
  440       while(temp->getVal(coord) < new_min[coord])
 
  442         if((temp->minmax == 1) && (temp->aabb->cached.overlap(current->cached)))
 
  444         temp = temp->next[coord];
 
  447       if(current->lo->prev[coord] != 
nullptr)
 
  448         current->lo->prev[coord]->next[coord] = current->lo->next[coord];
 
  450         elist[coord] = current->lo->next[coord];
 
  451       current->lo->next[coord]->prev[coord] = current->lo->prev[coord];
 
  452       current->lo->prev[coord] = temp->prev[coord];
 
  453       current->lo->next[coord] = temp;
 
  454       if(temp->prev[coord] != 
nullptr)
 
  455         temp->prev[coord]->next[coord] = current->lo;
 
  457         elist[coord] = current->lo;
 
  458       temp->prev[coord] = current->lo;
 
  459       current->lo->getVal(coord) = new_min[coord];
 
  465 template <
typename S>
 
  468   for(
int coord = 0; coord < 3; ++coord)
 
  471     EndPoint* current = 
elist[coord];
 
  475       velist[coord][id] = current;
 
  476       current = current->next[coord];
 
  483 template <
typename S>
 
  494 template <
typename S>
 
  497   for(
size_t i = 0; i < updated_objs.size(); ++i)
 
  506 template <
typename S>
 
  520 template <
typename S>
 
  546 template <
typename S>
 
  551   for(
auto it = 
AABB_arr.cbegin(), end = 
AABB_arr.cend(); it != end; ++it, ++i)
 
  553     objs[i] = (*it)->obj;
 
  558 template <
typename S>
 
  562   const AABB<S>& obj_aabb = 
obj->getAABB();
 
  564   S min_val = obj_aabb.min_[axis];
 
  569   dummy_aabb.cached = obj_aabb;
 
  571   dummy.aabb = &dummy_aabb;
 
  574   const auto res_it = std::upper_bound(
velist[axis].begin(), 
velist[axis].end(), &dummy,
 
  575                                                                    std::bind(std::less<S>(),
 
  576                                                                                std::bind(
static_cast<S (EndPoint::*)(
size_t) const
>(&EndPoint::getVal), std::placeholders::_1, axis),
 
  577                                                                                std::bind(
static_cast<S (EndPoint::*)(
size_t) const
>(&EndPoint::getVal), std::placeholders::_2, axis)));
 
  579   EndPoint* end_pos = 
nullptr;
 
  580   if(res_it != 
velist[axis].end())
 
  583   EndPoint* pos = 
elist[axis];
 
  585   while(pos != end_pos)
 
  587     if(pos->aabb->obj != 
obj)
 
  589       if((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val))
 
  591         if(pos->aabb->cached.overlap(
obj->getAABB()))
 
  592           if(callback(
obj, pos->aabb->obj, cdata))
 
  596     pos = pos->next[axis];
 
  603 template <
typename S>
 
  605     const typename SaPCollisionManager<S>::SaPPair& p)
 
  607   bool repeated = 
false;
 
  622 template <
typename S>
 
  624     const typename SaPCollisionManager<S>::SaPPair& p)
 
  641 template <
typename S>
 
  644   if(
size() == 0) 
return;
 
  650 template <
typename S>
 
  653   Vector3<S> delta = (
obj->getAABB().max_ - 
obj->getAABB().min_) * 0.5;
 
  658     Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
 
  659     aabb.expand(min_dist_delta);
 
  667   EndPoint* start_pos = 
elist[axis];
 
  671     old_min_distance = min_dist;
 
  672     S min_val = 
aabb.min_[axis];
 
  677     dummy_aabb.cached = 
aabb;
 
  679     dummy.aabb = &dummy_aabb;
 
  682     const auto res_it = std::upper_bound(
velist[axis].begin(), 
velist[axis].end(), &dummy,
 
  683                                                                      std::bind(std::less<S>(),
 
  684                                                                                  std::bind(
static_cast<S (EndPoint::*)(
size_t) const
>(&EndPoint::getVal), std::placeholders::_1, axis),
 
  685                                                                                  std::bind(
static_cast<S (EndPoint::*)(
size_t) const
>(&EndPoint::getVal), std::placeholders::_2, axis)));
 
  687     EndPoint* end_pos = 
nullptr;
 
  688     if(res_it != 
velist[axis].end())
 
  691     EndPoint* pos = start_pos;
 
  693     while(pos != end_pos)
 
  697       if((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val))
 
  699         CollisionObject<S>* curr_obj = pos->aabb->obj;
 
  704             if(pos->aabb->cached.distance(
obj->getAABB()) < min_dist)
 
  706               if(callback(curr_obj, 
obj, cdata, min_dist))
 
  714               if(pos->aabb->cached.distance(
obj->getAABB()) < min_dist)
 
  716                 if(callback(curr_obj, 
obj, cdata, min_dist))
 
  726       pos = pos->next[axis];
 
  735         if(min_dist < old_min_distance)
 
  737           Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
 
  738           aabb = AABB<S>(
obj->getAABB(), min_dist_delta);
 
  746             aabb.expand(
obj->getAABB(), 2.0);
 
  758 template <
typename S>
 
  761   if(
size() == 0) 
return;
 
  769 template <
typename S>
 
  772   if(
size() == 0) 
return;
 
  776     CollisionObject<S>* 
obj1 = it->obj1;
 
  777     CollisionObject<S>* 
obj2 = it->obj2;
 
  785 template <
typename S>
 
  788   if(
size() == 0) 
return;
 
  797     if(
distance_((*it)->obj, cdata, callback, min_dist))
 
  806 template <
typename S>
 
  811   if((
size() == 0) || (other_manager->size() == 0)) 
return;
 
  813   if(
this == other_manager)
 
  819   if(this->
size() < other_manager->size())
 
  823       if(other_manager->collide_((*it)->obj, cdata, callback))
 
  829     for(
auto it = other_manager->AABB_arr.cbegin(), end = other_manager->AABB_arr.cend(); it != end; ++it)
 
  831       if(
collide_((*it)->obj, cdata, callback))
 
  838 template <
typename S>
 
  843   if((
size() == 0) || (other_manager->size() == 0)) 
return;
 
  845   if(
this == other_manager)
 
  853   if(this->
size() < other_manager->size())
 
  857       if(other_manager->distance_((*it)->obj, cdata, callback, min_dist))
 
  863     for(
auto it = other_manager->AABB_arr.cbegin(), end = other_manager->AABB_arr.cend(); it != end; ++it)
 
  865       if(
distance_((*it)->obj, cdata, callback, min_dist))
 
  872 template <
typename S>
 
  879 template <
typename S>
 
  886 template <
typename S>
 
  887 const Vector3<S>&SaPCollisionManager<S>::EndPoint::getVal()
 const 
  890   else return aabb->cached.min_;
 
  894 template <
typename S>
 
  895 Vector3<S>&SaPCollisionManager<S>::EndPoint::getVal()
 
  898   else return aabb->cached.min_;
 
  902 template <
typename S>
 
  903 S SaPCollisionManager<S>::EndPoint::getVal(
size_t i)
 const 
  906     return aabb->cached.max_[i];
 
  908     return aabb->cached.min_[i];
 
  912 template <
typename S>
 
  913 S& SaPCollisionManager<S>::EndPoint::getVal(
size_t i)
 
  916     return aabb->cached.max_[i];
 
  918     return aabb->cached.min_[i];
 
  922 template <
typename S>
 
  923 SaPCollisionManager<S>::SaPPair::SaPPair(CollisionObject<S>* a, CollisionObject<S>* b)
 
  938 template <
typename S>
 
  939 bool SaPCollisionManager<S>::SaPPair::operator ==(
const typename SaPCollisionManager<S>::SaPPair& other)
 const 
  941   return ((
obj1 == other.obj1) && (
obj2 == other.obj2));
 
  945 template <
typename S>
 
  946 SaPCollisionManager<S>::isUnregistered::isUnregistered(CollisionObject<S>* obj_) : 
obj(obj_)
 
  950 template <
typename S>
 
  951 bool SaPCollisionManager<S>::isUnregistered::operator()(
const SaPPair& pair)
 const 
  953   return (pair.obj1 == 
obj) || (pair.obj2 == 
obj);
 
  957 template <
typename S>
 
  958 SaPCollisionManager<S>::isNotValidPair::isNotValidPair(CollisionObject<S>* obj1_, CollisionObject<S>* obj2_) : 
obj1(obj1_),
 
  965 template <
typename S>
 
  966 bool SaPCollisionManager<S>::isNotValidPair::operator()(
const SaPPair& pair)
 
  968   return (pair.obj1 == 
obj1) && (pair.obj2 == 
obj2);