38 #ifndef FCL_BROAD_PHASE_INTERVAL_TREE_INL_H 39 #define FCL_BROAD_PHASE_INTERVAL_TREE_INL_H 41 #include "fcl/broadphase/broadphase_interval_tree.h" 48 class IntervalTreeCollisionManager<double>;
59 auto start1 = std::lower_bound(endpoints[0].begin(), endpoints[0].end(), p);
61 auto end1 = std::upper_bound(start1, endpoints[0].end(), p);
65 unsigned int start_id = start1 - endpoints[0].begin();
66 unsigned int end_id = end1 - endpoints[0].begin();
67 unsigned int cur_id = start_id;
68 for(
unsigned int i = start_id; i < end_id; ++i)
70 if(endpoints[0][i].obj != obj)
72 if(i == cur_id) cur_id++;
75 endpoints[0][cur_id] = endpoints[0][i];
81 endpoints[0].resize(endpoints[0].size() - 2);
85 auto start2 = std::lower_bound(endpoints[1].begin(), endpoints[1].end(), p);
87 auto end2 = std::upper_bound(start2, endpoints[1].end(), p);
91 unsigned int start_id = start2 - endpoints[1].begin();
92 unsigned int end_id = end2 - endpoints[1].begin();
93 unsigned int cur_id = start_id;
94 for(
unsigned int i = start_id; i < end_id; ++i)
96 if(endpoints[1][i].obj != obj)
98 if(i == cur_id) cur_id++;
101 endpoints[1][cur_id] = endpoints[1][i];
107 endpoints[1].resize(endpoints[1].size() - 2);
112 auto start3 = std::lower_bound(endpoints[2].begin(), endpoints[2].end(), p);
114 auto end3 = std::upper_bound(start3, endpoints[2].end(), p);
118 unsigned int start_id = start3 - endpoints[2].begin();
119 unsigned int end_id = end3 - endpoints[2].begin();
120 unsigned int cur_id = start_id;
121 for(
unsigned int i = start_id; i < end_id; ++i)
123 if(endpoints[2][i].obj != obj)
125 if(i == cur_id) cur_id++;
128 endpoints[2][cur_id] = endpoints[2][i];
134 endpoints[2].resize(endpoints[2].size() - 2);
138 if(obj_interval_maps[0].find(obj) != obj_interval_maps[0].end())
144 interval_trees[0]->deleteNode(ivl1);
145 interval_trees[1]->deleteNode(ivl2);
146 interval_trees[2]->deleteNode(ivl3);
152 obj_interval_maps[0].erase(obj);
153 obj_interval_maps[1].erase(obj);
154 obj_interval_maps[2].erase(obj);
159 template <
typename S>
162 for(
int i = 0; i < 3; ++i)
163 interval_trees[i] =
nullptr;
167 template <
typename S>
174 template <
typename S>
185 endpoints[0].push_back(p);
186 endpoints[0].push_back(q);
190 endpoints[1].push_back(p);
191 endpoints[1].push_back(q);
195 endpoints[2].push_back(p);
196 endpoints[2].push_back(q);
201 template <
typename S>
206 std::sort(endpoints[0].begin(), endpoints[0].end());
207 std::sort(endpoints[1].begin(), endpoints[1].end());
208 std::sort(endpoints[2].begin(), endpoints[2].end());
210 for(
int i = 0; i < 3; ++i)
211 delete interval_trees[i];
213 for(
int i = 0; i < 3; ++i)
216 for(
unsigned int i = 0, size = endpoints[0].size(); i < size; ++i)
226 interval_trees[0]->insert(ivl1);
227 interval_trees[1]->insert(ivl2);
228 interval_trees[2]->insert(ivl3);
230 obj_interval_maps[0][obj] = ivl1;
231 obj_interval_maps[1][obj] = ivl2;
232 obj_interval_maps[2][obj] = ivl3;
241 template <
typename S>
246 for(
unsigned int i = 0, size = endpoints[0].size(); i < size; ++i)
248 if(endpoints[0][i].minmax == 0)
249 endpoints[0][i].value = endpoints[0][i].obj->getAABB().min_[0];
251 endpoints[0][i].value = endpoints[0][i].obj->getAABB().max_[0];
254 for(
unsigned int i = 0, size = endpoints[1].size(); i < size; ++i)
256 if(endpoints[1][i].minmax == 0)
257 endpoints[1][i].value = endpoints[1][i].obj->getAABB().min_[1];
259 endpoints[1][i].value = endpoints[1][i].obj->getAABB().max_[1];
262 for(
unsigned int i = 0, size = endpoints[2].size(); i < size; ++i)
264 if(endpoints[2][i].minmax == 0)
265 endpoints[2][i].value = endpoints[2][i].obj->getAABB().min_[2];
267 endpoints[2][i].value = endpoints[2][i].obj->getAABB().max_[2];
275 template <
typename S>
280 for(
int i = 0; i < 3; ++i)
282 const auto it = obj_interval_maps[i].find(updated_obj);
283 interval_trees[i]->deleteNode(it->second);
284 old_aabb.
min_[i] = it->second->low;
285 old_aabb.
max_[i] = it->second->high;
286 it->second->low = new_aabb.
min_[i];
287 it->second->high = new_aabb.
max_[i];
288 interval_trees[i]->insert(it->second);
292 typename std::vector<EndPoint>::iterator it;
293 for(
int i = 0; i < 3; ++i)
296 it = std::lower_bound(endpoints[i].begin(), endpoints[i].end(), dummy);
297 for(; it != endpoints[i].end(); ++it)
299 if(it->obj == updated_obj && it->minmax == 0)
301 it->value = new_aabb.
min_[i];
307 it = std::lower_bound(endpoints[i].begin(), endpoints[i].end(), dummy);
308 for(; it != endpoints[i].end(); ++it)
310 if(it->obj == updated_obj && it->minmax == 0)
312 it->value = new_aabb.
max_[i];
317 std::sort(endpoints[i].begin(), endpoints[i].end());
322 template <
typename S>
325 for(
size_t i = 0; i < updated_objs.size(); ++i)
326 update(updated_objs[i]);
330 template <
typename S>
333 endpoints[0].clear();
334 endpoints[1].clear();
335 endpoints[2].clear();
337 delete interval_trees[0]; interval_trees[0] =
nullptr;
338 delete interval_trees[1]; interval_trees[1] =
nullptr;
339 delete interval_trees[2]; interval_trees[2] =
nullptr;
341 for(
int i = 0; i < 3; ++i)
343 for(
auto it = obj_interval_maps[i].cbegin(), end = obj_interval_maps[i].cend();
350 for(
int i = 0; i < 3; ++i)
351 obj_interval_maps[i].clear();
357 template <
typename S>
360 objs.resize(endpoints[0].size() / 2);
362 for(
unsigned int i = 0, size = endpoints[0].size(); i < size; ++i)
364 if(endpoints[0][i].minmax == 0)
366 objs[j] = endpoints[0][i].obj; j++;
372 template <
typename S>
375 if(size() == 0)
return;
376 collide_(obj, cdata, callback);
380 template <
typename S>
383 static const unsigned int CUTOFF = 100;
385 std::deque<detail::SimpleInterval<S>*> results0, results1, results2;
388 if(results0.size() > CUTOFF)
391 if(results1.size() > CUTOFF)
394 if(results2.size() > CUTOFF)
396 int d1 = results0.
size();
397 int d2 = results1.size();
398 int d3 = results2.size();
400 if(d1 >= d2 && d1 >= d3)
401 return checkColl(results0.begin(), results0.end(), obj, cdata, callback);
402 else if(d2 >= d1 && d2 >= d3)
403 return checkColl(results1.begin(), results1.end(), obj, cdata, callback);
405 return checkColl(results2.begin(), results2.end(), obj, cdata, callback);
408 return checkColl(results2.begin(), results2.end(), obj, cdata, callback);
411 return checkColl(results1.begin(), results1.end(), obj, cdata, callback);
414 return checkColl(results0.begin(), results0.end(), obj, cdata, callback);
418 template <
typename S>
421 if(size() == 0)
return;
422 S min_dist = std::numeric_limits<S>::max();
423 distance_(obj, cdata, callback, min_dist);
427 template <
typename S>
430 static const unsigned int CUTOFF = 100;
434 if(min_dist < std::numeric_limits<S>::max())
436 Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
437 aabb.
expand(min_dist_delta);
445 bool dist_res =
false;
447 old_min_distance = min_dist;
449 std::deque<detail::SimpleInterval<S>*> results0, results1, results2;
451 results0 = interval_trees[0]->query(aabb.
min_[0], aabb.
max_[0]);
452 if(results0.size() > CUTOFF)
454 results1 = interval_trees[1]->query(aabb.
min_[1], aabb.
max_[1]);
455 if(results1.size() > CUTOFF)
457 results2 = interval_trees[2]->query(aabb.
min_[2], aabb.
max_[2]);
458 if(results2.size() > CUTOFF)
460 int d1 = results0.
size();
461 int d2 = results1.size();
462 int d3 = results2.size();
464 if(d1 >= d2 && d1 >= d3)
465 dist_res = checkDist(results0.begin(), results0.end(), obj, cdata, callback, min_dist);
466 else if(d2 >= d1 && d2 >= d3)
467 dist_res = checkDist(results1.begin(), results1.end(), obj, cdata, callback, min_dist);
469 dist_res = checkDist(results2.begin(), results2.end(), obj, cdata, callback, min_dist);
472 dist_res = checkDist(results2.begin(), results2.end(), obj, cdata, callback, min_dist);
475 dist_res = checkDist(results1.begin(), results1.end(), obj, cdata, callback, min_dist);
478 dist_res = checkDist(results0.begin(), results0.end(), obj, cdata, callback, min_dist);
480 if(dist_res)
return true;
488 if(old_min_distance < std::numeric_limits<S>::max())
492 if(min_dist < old_min_distance)
494 Vector3<S> min_dist_delta(min_dist, min_dist, min_dist);
515 template <
typename S>
518 if(size() == 0)
return;
520 std::set<CollisionObject<S>*> active;
522 unsigned int n = endpoints[0].size();
523 S diff_x = endpoints[0][0].value - endpoints[0][n-1].value;
524 S diff_y = endpoints[1][0].value - endpoints[1][n-1].value;
525 S diff_z = endpoints[2][0].value - endpoints[2][n-1].value;
528 if(diff_y > diff_x && diff_y > diff_z)
530 else if(diff_z > diff_y && diff_z > diff_x)
533 for(
unsigned int i = 0; i < n; ++i)
535 const EndPoint& endpoint = endpoints[axis][i];
539 auto iter = active.begin();
540 auto end = active.end();
541 for(; iter != end; ++iter)
547 int axis2 = (axis + 1) % 3;
548 int axis3 = (axis + 2) % 3;
552 std::pair<typename std::set<std::pair<CollisionObject<S>*,
CollisionObject<S>*> >::iterator,
bool> insert_res;
553 if(active_index < index)
554 insert_res = overlap.insert(std::make_pair(active_index, index));
556 insert_res = overlap.insert(std::make_pair(index, active_index));
558 if(insert_res.second)
560 if(callback(active_index, index, cdata))
565 active.insert(index);
574 template <
typename S>
577 if(size() == 0)
return;
579 this->enable_tested_set_ =
true;
580 this->tested_set.clear();
581 S min_dist = std::numeric_limits<S>::max();
583 for(
size_t i = 0; i < endpoints[0].size(); ++i)
584 if(distance_(endpoints[0][i].obj, cdata, callback, min_dist))
break;
586 this->enable_tested_set_ =
false;
587 this->tested_set.clear();
591 template <
typename S>
596 if((size() == 0) || (other_manager->
size() == 0))
return;
598 if(
this == other_manager)
600 collide(cdata, callback);
604 if(this->size() < other_manager->
size())
606 for(
size_t i = 0, size = endpoints[0].size(); i < size; ++i)
607 if(other_manager->collide_(endpoints[0][i].obj, cdata, callback))
return;
611 for(
size_t i = 0, size = other_manager->
endpoints[0].size(); i < size; ++i)
612 if(collide_(other_manager->
endpoints[0][i].obj, cdata, callback))
return;
617 template <
typename S>
622 if((size() == 0) || (other_manager->
size() == 0))
return;
624 if(
this == other_manager)
630 S min_dist = std::numeric_limits<S>::max();
632 if(this->size() < other_manager->
size())
634 for(
size_t i = 0, size = endpoints[0].size(); i < size; ++i)
635 if(other_manager->distance_(endpoints[0][i].obj, cdata, callback, min_dist))
return;
639 for(
size_t i = 0, size = other_manager->
endpoints[0].size(); i < size; ++i)
640 if(distance_(other_manager->
endpoints[0][i].obj, cdata, callback, min_dist))
return;
645 template <
typename S>
648 return endpoints[0].empty();
652 template <
typename S>
655 return endpoints[0].size() / 2;
659 template <
typename S>
667 while(pos_start < pos_end)
672 if(ivl->obj->getAABB().overlap(obj->
getAABB()))
674 if(callback(ivl->obj, obj, cdata))
686 template <
typename S>
695 while(pos_start < pos_end)
700 if(!this->enable_tested_set_)
702 if(ivl->obj->getAABB().distance(obj->
getAABB()) < min_dist)
704 if(callback(ivl->obj, obj, cdata, min_dist))
710 if(!this->inTestedSet(ivl->obj, obj))
712 if(ivl->obj->getAABB().distance(obj->
getAABB()) < min_dist)
714 if(callback(ivl->obj, obj, cdata, min_dist))
718 this->insertTestedSet(ivl->obj, obj);
730 template <
typename S>
738 template <
typename S>
std::vector< EndPoint > endpoints[3]
vector stores all the end points
Definition: broadphase_interval_tree.h:134
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
S size() const
Size of the AABB (used in BV_Splitter to order two AABBs)
Definition: AABB-inl.h:216
bool axisOverlap(const AABB< S > &other, int axis_id) const
Check whether two AABB are overlapped along specific axis.
Definition: AABB-inl.h:124
void unregisterObject(CollisionObject< S > *obj)
add one object to the manager
Definition: broadphase_interval_tree-inl.h:52
bool overlap(const Eigen::MatrixBase< DerivedA > &R0, const Eigen::MatrixBase< DerivedB > &T0, const kIOS< S > &b1, const kIOS< S > &b2)
Check collision between two kIOSs, b1 is in configuration (R0, T0) and b2 is in identity.
Definition: kIOS-inl.h:249
bool equal(const AABB< S > &other) const
whether two AABB are equal
Definition: AABB-inl.h:319
void getObjects(std::vector< CollisionObject< S > * > &objs) const
return the objects managed by the manager
Definition: broadphase_interval_tree-inl.h:358
Vector3< S > max_
The max point in the AABB.
Definition: AABB.h:59
bool empty() const
whether the manager is empty
Definition: broadphase_interval_tree-inl.h:646
SAP end point.
Definition: broadphase_interval_tree.h:150
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
Interval trees implemented using red-black-trees as described in the book Introduction_To_Algorithms_...
Definition: simple_interval.h:50
CollisionObject< S > * obj
object related with the end point
Definition: broadphase_interval_tree.h:153
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
S value
end point value
Definition: broadphase_interval_tree.h:156
void clear()
clear the manager
Definition: broadphase_interval_tree-inl.h:331
Extention interval tree's interval to SAP interval, adding more information.
Definition: broadphase_interval_tree.h:166
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_interval_tree-inl.h:419
size_t size() const
the number of objects managed by the manager
Definition: broadphase_interval_tree-inl.h:653
Vector3< S > min_
The min point in the AABB.
Definition: AABB.h:56
const AABB< S > & getAABB() const
get the AABB in world space
Definition: collision_object-inl.h:111
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_interval_tree-inl.h:175
Collision manager based on interval tree.
Definition: broadphase_interval_tree.h:51
void setup()
initialize the manager, related with the specific type of manager
Definition: broadphase_interval_tree-inl.h:202
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
Base class for broad phase collision. It helps to accelerate the collision/distance between N objects...
Definition: broadphase_collision_manager.h:66
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
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_interval_tree-inl.h:373
Interval tree.
Definition: interval_tree.h:72
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_interval_tree.h:159
void update()
update the condition of manager
Definition: broadphase_interval_tree-inl.h:242