38 #ifndef FCL_BROAD_PHASE_SAP_INL_H 39 #define FCL_BROAD_PHASE_SAP_INL_H 41 #include "fcl/broadphase/broadphase_SaP.h" 48 class SaPCollisionManager<double>;
54 auto it = AABB_arr.begin();
55 for(
auto end = AABB_arr.end(); it != end; ++it)
62 obj_aabb_map.erase(obj);
64 if(it == AABB_arr.end())
70 for(
int coord = 0; coord < 3; ++coord)
73 if(curr->
lo->
prev[coord] ==
nullptr)
74 elist[coord] = curr->
lo->
next[coord];
81 if(curr->
hi->
prev[coord] ==
nullptr)
82 elist[coord] = curr->
hi->
next[coord];
86 if(curr->
hi->
next[coord] !=
nullptr)
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)
130 sapaabb->
obj = other_objs[i];
133 sapaabb->
cached = other_objs[i]->getAABB();
134 endpoints[2 * i] = sapaabb->
lo;
135 endpoints[2 * i + 1] = sapaabb->
hi;
138 sapaabb->
lo->
aabb = sapaabb;
139 sapaabb->
hi->
aabb = sapaabb;
140 AABB_arr.push_back(sapaabb);
141 obj_aabb_map[other_objs[i]] = 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;
174 while(pos !=
nullptr)
180 while(pos_it !=
nullptr)
182 if(pos_it->
aabb == aabb)
184 if(pos_next ==
nullptr) pos_next = pos_it;
190 if(pos_next ==
nullptr) pos_next = pos_it;
192 overlap_pairs.emplace_back(pos_it->
aabb->
obj, aabb->
obj);
194 pos_it = pos_it->
next[axis];
205 template <
typename S>
219 for(
int coord = 0; coord < 3; ++coord)
224 if(current ==
nullptr)
226 elist[coord] = curr->
lo;
227 curr->
lo->
prev[coord] = curr->
lo->
next[coord] =
nullptr;
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;
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)
267 overlap_pairs.emplace_back(current->
aabb->
obj, obj);
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;
297 AABB_arr.push_back(curr);
299 obj_aabb_map[obj] = curr;
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>
327 SaPAABB* current = updated_aabb;
329 Vector3<S> new_min = current->
obj->getAABB().min_;
330 Vector3<S> new_max = current->
obj->getAABB().max_;
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]))
357 temp = temp->
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;
373 current->
lo->
prev[coord] = temp;
376 temp->
next[coord] = current->
lo;
380 current->
lo->
getVal(coord) = new_min[coord];
384 while(temp->
getVal(coord) > new_max[coord])
388 temp = temp->
prev[coord];
392 if(current->
hi->
next[coord] !=
nullptr)
394 current->
hi->
prev[coord] = temp;
396 if(temp->
next[coord] !=
nullptr)
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]))
413 temp = temp->
next[coord];
416 if(temp->
getVal(coord) < new_max[coord])
420 current->
hi->
prev[coord] = temp;
421 current->
hi->
next[coord] =
nullptr;
422 temp->
next[coord] = current->
hi;
429 current->
hi->
next[coord] = temp;
431 temp->
prev[coord] = current->
hi;
435 current->
hi->
getVal(coord) = new_max[coord];
440 while(temp->
getVal(coord) < new_min[coord])
444 temp = temp->
next[coord];
447 if(current->
lo->
prev[coord] !=
nullptr)
450 elist[coord] = current->
lo->
next[coord];
453 current->
lo->
next[coord] = temp;
454 if(temp->
prev[coord] !=
nullptr)
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)
470 velist[coord].resize(size() * 2);
475 velist[coord][id] = current;
476 current = current->
next[coord];
483 template <
typename S>
486 update_(obj_aabb_map[updated_obj]);
494 template <
typename S>
497 for(
size_t i = 0; i < updated_objs.size(); ++i)
498 update_(obj_aabb_map[updated_objs[i]]);
506 template <
typename S>
509 for(
auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it)
520 template <
typename S>
523 for(
auto it = AABB_arr.begin(), end = AABB_arr.end(); it != end; ++it)
532 overlap_pairs.clear();
542 obj_aabb_map.clear();
546 template <
typename S>
549 objs.resize(AABB_arr.size());
551 for(
auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it, ++i)
553 objs[i] = (*it)->obj;
558 template <
typename S>
561 size_t axis = optimal_axis;
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)));
580 if(res_it != velist[axis].end())
585 while(pos != end_pos)
592 if(callback(obj, pos->
aabb->
obj, cdata))
596 pos = pos->
next[axis];
603 template <
typename S>
607 bool repeated =
false;
608 for(
auto it = overlap_pairs.begin(), end = overlap_pairs.end(); it != end; ++it)
618 overlap_pairs.push_back(p);
622 template <
typename S>
626 for(
auto it = overlap_pairs.begin(), end = overlap_pairs.end();
632 overlap_pairs.erase(it);
641 template <
typename S>
644 if(size() == 0)
return;
646 collide_(obj, cdata, callback);
650 template <
typename S>
656 if(min_dist < std::numeric_limits<S>::max())
658 Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
659 aabb.
expand(min_dist_delta);
662 size_t axis = optimal_axis;
671 old_min_distance = min_dist;
672 S min_val = aabb.
min_[axis];
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)));
688 if(res_it != velist[axis].end())
693 while(pos != end_pos)
702 if(!this->enable_tested_set_)
706 if(callback(curr_obj, obj, cdata, min_dist))
712 if(!this->inTestedSet(curr_obj, obj))
716 if(callback(curr_obj, obj, cdata, min_dist))
720 this->insertTestedSet(curr_obj, obj);
726 pos = pos->
next[axis];
731 if(old_min_distance < std::numeric_limits<S>::max())
735 if(min_dist < old_min_distance)
737 Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
758 template <
typename S>
761 if(size() == 0)
return;
763 S min_dist = std::numeric_limits<S>::max();
765 distance_(obj, cdata, callback, min_dist);
769 template <
typename S>
772 if(size() == 0)
return;
774 for(
auto it = overlap_pairs.cbegin(), end = overlap_pairs.cend(); it != end; ++it)
779 if(callback(obj1, obj2, cdata))
785 template <
typename S>
788 if(size() == 0)
return;
790 this->enable_tested_set_ =
true;
791 this->tested_set.clear();
793 S min_dist = std::numeric_limits<S>::max();
795 for(
auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it)
797 if(distance_((*it)->obj, cdata, callback, min_dist))
801 this->enable_tested_set_ =
false;
802 this->tested_set.clear();
806 template <
typename S>
811 if((size() == 0) || (other_manager->
size() == 0))
return;
813 if(
this == other_manager)
815 collide(cdata, callback);
819 if(this->size() < other_manager->
size())
821 for(
auto it = AABB_arr.cbegin(); it != AABB_arr.cend(); ++it)
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)
851 S min_dist = std::numeric_limits<S>::max();
853 if(this->size() < other_manager->
size())
855 for(
auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it)
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>
875 return AABB_arr.size();
879 template <
typename S>
882 return AABB_arr.size();
886 template <
typename S>
894 template <
typename S>
902 template <
typename S>
912 template <
typename S>
922 template <
typename S>
938 template <
typename S>
941 return ((obj1 == other.obj1) && (obj2 == other.obj2));
945 template <
typename S>
950 template <
typename S>
953 return (pair.obj1 == obj) || (pair.obj2 == obj);
957 template <
typename S>
965 template <
typename S>
968 return (pair.obj1 == obj1) && (pair.obj2 == obj2);
End point for an interval.
Definition: broadphase_SaP.h:178
const Vector3< S > & getVal() const
get the value of the end point
Definition: broadphase_SaP-inl.h:887
void clear()
clear the manager
Definition: broadphase_SaP-inl.h:521
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
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 ...
Definition: broadphase_SaP-inl.h:759
size_t size() const
the number of objects managed by the manager
Definition: broadphase_SaP-inl.h:880
EndPoint * prev[3]
the previous end point in the end point list
Definition: broadphase_SaP.h:187
SaPCollisionManager< S >::EndPoint * hi
higher bound end point of the interval
Definition: broadphase_SaP.h:170
SAP interval for one object.
Definition: broadphase_SaP.h:161
bool equal(const AABB< S > &other) const
whether two AABB are equal
Definition: AABB-inl.h:319
char minmax
tag for whether it is a lower bound or higher bound of an interval, 0 for lo, and 1 for hi ...
Definition: broadphase_SaP.h:181
bool overlap(const AABB< S > &other) const
Check whether two AABB are overlap.
Definition: AABB-inl.h:98
SaPCollisionManager< S >::SaPAABB * aabb
back pointer to SAP interval
Definition: broadphase_SaP.h:184
Vector3< S > max_
The max point in the AABB.
Definition: AABB.h:59
EndPoint * next[3]
the next end point in the end point list
Definition: broadphase_SaP.h:190
std::list< SaPAABB * > AABB_arr
SAP interval list.
Definition: broadphase_SaP.h:138
Functor to help unregister one object.
Definition: broadphase_SaP.h:218
bool(*)(CollisionObject< S > *o1, CollisionObject< S > *o2, void *cdata) CollisionCallBack
Callback for collision between two objects. Return value is whether can stop now. ...
Definition: broadphase_collision_manager.h:53
void update()
update the condition of manager
Definition: broadphase_SaP-inl.h:507
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...
Definition: broadphase_collision_manager.h:60
Vector3< S > min_
The min point in the AABB.
Definition: AABB.h:56
CollisionObject< S > * obj
object
Definition: broadphase_SaP.h:164
const AABB< S > & getAABB() const
get the AABB in world space
Definition: collision_object-inl.h:111
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 ...
Definition: broadphase_SaP-inl.h:642
AABB< S > cached
cached AABB<S> value
Definition: broadphase_SaP.h:173
bool empty() const
whether the manager is empty
Definition: broadphase_SaP-inl.h:873
the object for collision or distance computation, contains the geometry and the transform information...
Definition: collision_object.h:51
void registerObject(CollisionObject< S > *obj)
remove one object from the manager
Definition: broadphase_SaP-inl.h:206
void setup()
initialize the manager, related with the specific type of manager
Definition: broadphase_SaP-inl.h:306
void unregisterObject(CollisionObject< S > *obj)
add one object to the manager
Definition: broadphase_SaP-inl.h:52
void registerObjects(const std::vector< CollisionObject< S > * > &other_objs)
add objects to the manager
Definition: broadphase_SaP-inl.h:117
S distance(const Eigen::MatrixBase< DerivedA > &R0, const Eigen::MatrixBase< DerivedB > &T0, const kIOS< S > &b1, const kIOS< S > &b2, Vector3< S > *P, Vector3< S > *Q)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS-inl.h:266
SaPCollisionManager< S >::EndPoint * lo
lower bound end point of the interval
Definition: broadphase_SaP.h:167
Base class for broad phase collision. It helps to accelerate the collision/distance between N objects...
Definition: broadphase_collision_manager.h:66
A pair of objects that are not culling away and should further check collision.
Definition: broadphase_SaP.h:206
AABB< S > & expand(const Vector3< S > &delta)
expand the half size of the AABB by delta, and keep the center unchanged.
Definition: AABB-inl.h:327
S distance(const AABB< S > &other, Vector3< S > *P, Vector3< S > *Q) const
Distance between two AABBs; P and Q, should not be nullptr, return the nearest points.
Definition: AABB-inl.h:237
Rigorous SAP collision manager.
Definition: broadphase_SaP.h:51
void getObjects(std::vector< CollisionObject< S > * > &objs) const
return the objects managed by the manager
Definition: broadphase_SaP-inl.h:547