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();