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>
165 template <
typename S>
178 template <
typename S>
186 template <
typename S>
196 template <
typename S>
199 objs.resize(
objs_x.size());
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;
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;
337 unsigned int d1 = pos_end1 - pos_start1;
339 bool dist_res =
false;
344 unsigned int d2 = pos_end2 - pos_start2;
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)
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)
450 template <
typename S>
453 if(
size() == 0)
return;
455 typename std::vector<CollisionObject<S>*>::const_iterator pos, run_pos, pos_end;
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])
495 if(callback(obj, obj2, cdata))
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;
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>
587 template <
typename S>
bool operator()(const CollisionObject< S > *a, const CollisionObject< S > *b) const
void unregisterObject(CollisionObject< S > *obj)
add one object to the manager
bool empty() const
whether the manager is empty
const AABB< S > & getAABB() const
get the AABB in world space
bool setup_
tag about whether the environment is maintained suitably (i.e., the objs_x, objs_y, objs_z are sorted correctly
std::vector< CollisionObject< S > * > objs_x
Objects sorted according to lower x value.
bool checkDis(typename std::vector< CollisionObject< S > *>::const_iterator pos_start, typename std::vector< CollisionObject< S > *>::const_iterator pos_end, CollisionObject< S > *obj, void *cdata, DistanceCallBack< S > callback, S &min_dist) const
check distance between one object and a list of objects, return value is whether stop is possible ...
bool operator()(const CollisionObject< S > *a, const CollisionObject< S > *b) const
Functor sorting objects according to the AABB<S> lower x bound.
static size_t selectOptimalAxis(const std::vector< CollisionObject< S > *> &objs_x, const std::vector< CollisionObject< S > *> &objs_y, const std::vector< CollisionObject< S > *> &objs_z, typename std::vector< CollisionObject< S > *>::const_iterator &it_beg, typename std::vector< CollisionObject< S > *>::const_iterator &it_end)
void collide(CollisionObject< S > *obj, void *cdata, CollisionCallBack< S > callback) const
perform collision test between one object and all the objects belonging to the manager ...
Vector3< S > max_
The max point in the AABB.
Eigen::Matrix< S, 3, 1 > Vector3
SaPCollisionManager< S >::SaPAABB * aabb
back pointer to SAP interval
bool distance_(CollisionObject< S > *obj, void *cdata, DistanceCallBack< S > callback, S &min_dist) const
std::vector< CollisionObject< S > * > objs_z
Objects sorted according to lower z value.
The geometry for the object for collision or distance computation.
bool collide_(CollisionObject< S > *obj, void *cdata, CollisionCallBack< S > callback) const
bool(*)(CollisionObject< S > *o1, CollisionObject< S > *o2, void *cdata) CollisionCallBack
Callback for collision between two objects. Return value is whether can stop now. ...
void distance(CollisionObject< S > *obj, void *cdata, DistanceCallBack< S > callback) const
perform distance computation between one object and all the objects belonging to the manager ...
Dummy collision object with a point AABB<S>
bool(*)(CollisionObject< S > *o1, CollisionObject< S > *o2, void *cdata, S &dist) DistanceCallBack
Callback for distance between two objects, Return value is whether can stop now, also return the mini...
template class FCL_EXPORT SSaPCollisionManager< double >
Functor sorting objects according to the AABB<S> lower z bound.
void clear()
clear the manager
Functor sorting objects according to the AABB<S> lower y bound.
Simple SAP collision manager.
Vector3< S > min_
The min point in the AABB.
bool checkColl(typename std::vector< CollisionObject< S > *>::const_iterator pos_start, typename std::vector< CollisionObject< S > *>::const_iterator pos_end, CollisionObject< S > *obj, void *cdata, CollisionCallBack< S > callback) const
check collision between one object and a list of objects, return value is whether stop is possible ...
void update()
update the condition of manager
the object for collision or distance computation, contains the geometry and the transform information...
std::vector< CollisionObject< S > * > objs_y
Objects sorted according to lower y value.
CollisionObject< S > * obj2
size_t size() const
the number of objects managed by the manager
Base class for broad phase collision. It helps to accelerate the collision/distance between N objects...
CollisionObject< S > * obj
object
void setup()
initialize the manager, related with the specific type of manager
void registerObject(CollisionObject< S > *obj)
remove one object from the manager
bool operator()(const CollisionObject< S > *a, const CollisionObject< S > *b) const
DummyCollisionObject(const AABB< S > &aabb_)
void getObjects(std::vector< CollisionObject< S > *> &objs) const
return the objects managed by the manager