broadphase_SaP.cpp
Go to the documentation of this file.
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2016, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
39 
40 namespace coal {
41 
42 //==============================================================================
44  auto it = AABB_arr.begin();
45  for (auto end = AABB_arr.end(); it != end; ++it) {
46  if ((*it)->obj == obj) break;
47  }
48 
49  AABB_arr.erase(it);
50  obj_aabb_map.erase(obj);
51 
52  if (it == AABB_arr.end()) return;
53 
54  SaPAABB* curr = *it;
55  *it = nullptr;
56 
57  for (int coord = 0; coord < 3; ++coord) {
58  // first delete the lo endpoint of the interval.
59  if (curr->lo->prev[coord] == nullptr)
60  elist[coord] = curr->lo->next[coord];
61  else
62  curr->lo->prev[coord]->next[coord] = curr->lo->next[coord];
63 
64  curr->lo->next[coord]->prev[coord] = curr->lo->prev[coord];
65 
66  // then, delete the "hi" endpoint.
67  if (curr->hi->prev[coord] == nullptr)
68  elist[coord] = curr->hi->next[coord];
69  else
70  curr->hi->prev[coord]->next[coord] = curr->hi->next[coord];
71 
72  if (curr->hi->next[coord] != nullptr)
73  curr->hi->next[coord]->prev[coord] = curr->hi->prev[coord];
74  }
75 
76  delete curr->lo;
77  delete curr->hi;
78  delete curr;
79 
80  overlap_pairs.remove_if(isUnregistered(obj));
81 }
82 
83 //==============================================================================
85  elist[0] = nullptr;
86  elist[1] = nullptr;
87  elist[2] = nullptr;
88 
89  optimal_axis = 0;
90 }
91 
92 //==============================================================================
94 
95 //==============================================================================
97  const std::vector<CollisionObject*>& other_objs) {
98  if (other_objs.empty()) return;
99 
100  if (size() > 0)
102  else {
103  std::vector<EndPoint*> endpoints(2 * other_objs.size());
104 
105  for (size_t i = 0; i < other_objs.size(); ++i) {
106  SaPAABB* sapaabb = new SaPAABB();
107  sapaabb->obj = other_objs[i];
108  sapaabb->lo = new EndPoint();
109  sapaabb->hi = new EndPoint();
110  sapaabb->cached = other_objs[i]->getAABB();
111  endpoints[2 * i] = sapaabb->lo;
112  endpoints[2 * i + 1] = sapaabb->hi;
113  sapaabb->lo->minmax = 0;
114  sapaabb->hi->minmax = 1;
115  sapaabb->lo->aabb = sapaabb;
116  sapaabb->hi->aabb = sapaabb;
117  AABB_arr.push_back(sapaabb);
118  obj_aabb_map[other_objs[i]] = sapaabb;
119  }
120 
121  CoalScalar scale[3];
122  for (int coord = 0; coord < 3; ++coord) {
123  std::sort(
124  endpoints.begin(), endpoints.end(),
125  std::bind(std::less<CoalScalar>(),
126  std::bind(static_cast<CoalScalar (EndPoint::*)(int) const>(
128  std::placeholders::_1, coord),
129  std::bind(static_cast<CoalScalar (EndPoint::*)(int) const>(
131  std::placeholders::_2, coord)));
132 
133  endpoints[0]->prev[coord] = nullptr;
134  endpoints[0]->next[coord] = endpoints[1];
135  for (size_t i = 1; i < endpoints.size() - 1; ++i) {
136  endpoints[i]->prev[coord] = endpoints[i - 1];
137  endpoints[i]->next[coord] = endpoints[i + 1];
138  }
139  endpoints[endpoints.size() - 1]->prev[coord] =
140  endpoints[endpoints.size() - 2];
141  endpoints[endpoints.size() - 1]->next[coord] = nullptr;
142 
143  elist[coord] = endpoints[0];
144 
145  scale[coord] = endpoints.back()->aabb->cached.max_[coord] -
146  endpoints[0]->aabb->cached.min_[coord];
147  }
148 
149  int axis = 0;
150  if (scale[axis] < scale[1]) axis = 1;
151  if (scale[axis] < scale[2]) axis = 2;
152 
153  EndPoint* pos = elist[axis];
154 
155  while (pos != nullptr) {
156  EndPoint* pos_next = nullptr;
157  SaPAABB* aabb = pos->aabb;
158  EndPoint* pos_it = pos->next[axis];
159 
160  while (pos_it != nullptr) {
161  if (pos_it->aabb == aabb) {
162  if (pos_next == nullptr) pos_next = pos_it;
163  break;
164  }
165 
166  if (pos_it->minmax == 0) {
167  if (pos_next == nullptr) pos_next = pos_it;
168  if (pos_it->aabb->cached.overlap(aabb->cached))
169  overlap_pairs.emplace_back(pos_it->aabb->obj, aabb->obj);
170  }
171  pos_it = pos_it->next[axis];
172  }
173 
174  pos = pos_next;
175  }
176  }
177 
178  updateVelist();
179 }
180 
181 //==============================================================================
183  // Initialize a new SaPAABB associated with current Collision Object
184  SaPAABB* new_sap = new SaPAABB;
185  new_sap->cached = obj->getAABB();
186  new_sap->obj = obj;
187 
188  new_sap->lo = new EndPoint;
189  new_sap->lo->minmax = 0;
190  new_sap->lo->aabb = new_sap;
191 
192  new_sap->hi = new EndPoint;
193  new_sap->hi->minmax = 1;
194  new_sap->hi->aabb = new_sap;
195  for (int coord = 0; coord < 3; ++coord) {
196  EndPoint* current = elist[coord];
197 
198  // first insert the lo end point
199  if (current == nullptr) // empty list
200  {
201  elist[coord] = new_sap->lo;
202  new_sap->lo->prev[coord] = new_sap->lo->next[coord] = nullptr;
203  } else // otherwise, find the correct location in the list and insert
204  {
205  EndPoint* curr_lo = new_sap->lo;
206  CoalScalar curr_lo_val = curr_lo->getVal()[coord];
207  while ((current->getVal()[coord] < curr_lo_val) &&
208  (current->next[coord] != nullptr))
209  current = current->next[coord];
210 
211  if (current->getVal()[coord] >= curr_lo_val) {
212  curr_lo->prev[coord] = current->prev[coord];
213  curr_lo->next[coord] = current;
214  if (current->prev[coord] == nullptr) // current was the first box
215  elist[coord] =
216  curr_lo; // new_sap->lo becomes the new first box on the axis
217  else
218  current->prev[coord]->next[coord] = curr_lo;
219 
220  current->prev[coord] =
221  curr_lo; // new_sap->lo becomes the predecessor of current
222  } else { // current->next[coord] == nullptr, so the current is just the
223  // cell before current->
224  curr_lo->prev[coord] = current;
225  curr_lo->next[coord] = nullptr;
226  current->next[coord] = curr_lo;
227  }
228  }
229 
230  // now insert hi end point
231  current = new_sap->lo;
232 
233  EndPoint* curr_hi = new_sap->hi;
234  CoalScalar curr_hi_val = curr_hi->getVal()[coord];
235 
236  if (coord == 0) {
237  while ((current->getVal()[coord] < curr_hi_val) &&
238  (current->next[coord] != nullptr)) {
239  if (current != new_sap->lo)
240  if (current->aabb->cached.overlap(new_sap->cached))
241  overlap_pairs.emplace_back(current->aabb->obj, obj);
242 
243  current = current->next[coord];
244  }
245  } else {
246  while ((current->getVal()[coord] < curr_hi_val) &&
247  (current->next[coord] != nullptr))
248  current = current->next[coord];
249  }
250 
251  if (current->getVal()[coord] >= curr_hi_val) {
252  curr_hi->prev[coord] = current->prev[coord];
253  curr_hi->next[coord] = current;
254  if (current->prev[coord] != nullptr)
255  current->prev[coord]->next[coord] = curr_hi;
256 
257  current->prev[coord] = curr_hi;
258  } else {
259  curr_hi->prev[coord] = current;
260  curr_hi->next[coord] = nullptr;
261  current->next[coord] = curr_hi;
262  }
263  }
264 
265  AABB_arr.push_back(new_sap);
266 
267  obj_aabb_map[obj] = new_sap;
268 
269  updateVelist();
270 }
271 
272 //==============================================================================
274  if (size() == 0) return;
275 
276  CoalScalar scale[3];
277  scale[0] = (velist[0].back())->getVal(0) - velist[0][0]->getVal(0);
278  scale[1] = (velist[1].back())->getVal(1) - velist[1][0]->getVal(1);
279  scale[2] = (velist[2].back())->getVal(2) - velist[2][0]->getVal(2);
280 
281  int axis = 0;
282  if (scale[axis] < scale[1]) axis = 1;
283  if (scale[axis] < scale[2]) axis = 2;
284  optimal_axis = axis;
285 }
286 
287 //==============================================================================
289  if (updated_aabb->cached == updated_aabb->obj->getAABB()) return;
290 
291  SaPAABB* current = updated_aabb;
292 
293  const AABB current_aabb = current->obj->getAABB();
294 
295  const Vec3s& new_min = current_aabb.min_;
296  const Vec3s& new_max = current_aabb.max_;
297 
298  for (int coord = 0; coord < 3; ++coord) {
299  int direction; // -1 reverse, 0 nochange, 1 forward
300  EndPoint* temp;
301 
302  if (current->lo->getVal(coord) > new_min[coord])
303  direction = -1;
304  else if (current->lo->getVal(coord) < new_min[coord])
305  direction = 1;
306  else
307  direction = 0;
308 
309  if (direction == -1) {
310  // first update the "lo" endpoint of the interval
311  if (current->lo->prev[coord] != nullptr) {
312  temp = current->lo->prev[coord];
313  while ((temp != nullptr) && (temp->getVal(coord) > new_min[coord])) {
314  if (temp->minmax == 1)
315  if (temp->aabb->cached.overlap(current_aabb))
316  addToOverlapPairs(SaPPair(temp->aabb->obj, current->obj));
317  temp = temp->prev[coord];
318  }
319 
320  if (temp == nullptr) {
321  current->lo->prev[coord]->next[coord] = current->lo->next[coord];
322  current->lo->next[coord]->prev[coord] = current->lo->prev[coord];
323  current->lo->prev[coord] = nullptr;
324  current->lo->next[coord] = elist[coord];
325  elist[coord]->prev[coord] = current->lo;
326  elist[coord] = current->lo;
327  } else {
328  current->lo->prev[coord]->next[coord] = current->lo->next[coord];
329  current->lo->next[coord]->prev[coord] = current->lo->prev[coord];
330  current->lo->prev[coord] = temp;
331  current->lo->next[coord] = temp->next[coord];
332  temp->next[coord]->prev[coord] = current->lo;
333  temp->next[coord] = current->lo;
334  }
335  }
336 
337  // Update the value of the lower bound along axis coord
338  current->lo->getVal(coord) = new_min[coord];
339 
340  // update hi end point
341  if (current->hi->prev[coord] != nullptr) {
342  temp = current->hi->prev[coord];
343 
344  while ((temp != nullptr) && (temp->getVal(coord) > new_max[coord])) {
345  if ((temp->minmax == 0) &&
346  (temp->aabb->cached.overlap(current->cached)))
347  removeFromOverlapPairs(SaPPair(temp->aabb->obj, current->obj));
348  temp = temp->prev[coord];
349  }
350 
351  current->hi->prev[coord]->next[coord] = current->hi->next[coord];
352  if (current->hi->next[coord] != nullptr)
353  current->hi->next[coord]->prev[coord] = current->hi->prev[coord];
354  current->hi->prev[coord] = temp; // Wrong line
355  current->hi->next[coord] = temp->next[coord];
356  if (temp->next[coord] != nullptr)
357  temp->next[coord]->prev[coord] = current->hi;
358  temp->next[coord] = current->hi;
359 
360  current->hi->getVal(coord) = new_max[coord];
361  }
362 
363  current->hi->getVal(coord) = new_max[coord];
364  } else if (direction == 1) {
365  // here, we first update the "hi" endpoint.
366  if (current->hi->next[coord] != nullptr) {
367  temp = current->hi->next[coord];
368  while ((temp->next[coord] != nullptr) &&
369  (temp->getVal(coord) < new_max[coord])) {
370  if (temp->minmax == 0)
371  if (temp->aabb->cached.overlap(current_aabb))
372  addToOverlapPairs(SaPPair(temp->aabb->obj, current->obj));
373  temp = temp->next[coord];
374  }
375 
376  if (temp->getVal(coord) < new_max[coord]) {
377  current->hi->prev[coord]->next[coord] = current->hi->next[coord];
378  current->hi->next[coord]->prev[coord] = current->hi->prev[coord];
379  current->hi->prev[coord] = temp;
380  current->hi->next[coord] = nullptr;
381  temp->next[coord] = current->hi;
382  } else {
383  current->hi->prev[coord]->next[coord] = current->hi->next[coord];
384  current->hi->next[coord]->prev[coord] = current->hi->prev[coord];
385  current->hi->prev[coord] = temp->prev[coord];
386  current->hi->next[coord] = temp;
387  temp->prev[coord]->next[coord] = current->hi;
388  temp->prev[coord] = current->hi;
389  }
390  }
391 
392  current->hi->getVal(coord) = new_max[coord];
393 
394  // then, update the "lo" endpoint of the interval.
395  if (current->lo->next[coord] != nullptr) {
396  temp = current->lo->next[coord];
397 
398  while ((temp->next[coord] != nullptr) &&
399  (temp->getVal(coord) < new_min[coord])) {
400  if ((temp->minmax == 1) &&
401  (temp->aabb->cached.overlap(current->cached)))
402  removeFromOverlapPairs(SaPPair(temp->aabb->obj, current->obj));
403  temp = temp->next[coord];
404  }
405 
406  if (current->lo->prev[coord] != nullptr)
407  current->lo->prev[coord]->next[coord] = current->lo->next[coord];
408  else
409  elist[coord] = current->lo->next[coord];
410  current->lo->next[coord]->prev[coord] = current->lo->prev[coord];
411  current->lo->prev[coord] = temp->prev[coord];
412  current->lo->next[coord] = temp;
413  if (temp->prev[coord] != nullptr)
414  temp->prev[coord]->next[coord] = current->lo;
415  else
416  elist[coord] = current->lo;
417  temp->prev[coord] = current->lo;
418  current->lo->getVal(coord) = new_min[coord];
419  }
420  }
421  }
422 }
423 
424 //==============================================================================
426  for (int coord = 0; coord < 3; ++coord) {
427  velist[coord].resize(size() * 2);
428  EndPoint* current = elist[coord];
429  size_t id = 0;
430  while (current) {
431  velist[coord][id] = current;
432  current = current->next[coord];
433  id++;
434  }
435  }
436 }
437 
438 //==============================================================================
440  update_(obj_aabb_map[updated_obj]);
441 
442  updateVelist();
443 
444  setup();
445 }
446 
447 //==============================================================================
449  const std::vector<CollisionObject*>& updated_objs) {
450  for (size_t i = 0; i < updated_objs.size(); ++i)
451  update_(obj_aabb_map[updated_objs[i]]);
452 
453  updateVelist();
454 
455  setup();
456 }
457 
458 //==============================================================================
460  for (auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it) {
461  update_(*it);
462  }
463 
464  updateVelist();
465 
466  setup();
467 }
468 
469 //==============================================================================
471  for (auto it = AABB_arr.begin(), end = AABB_arr.end(); it != end; ++it) {
472  delete (*it)->hi;
473  delete (*it)->lo;
474  delete *it;
475  *it = nullptr;
476  }
477 
478  AABB_arr.clear();
479  overlap_pairs.clear();
480 
481  elist[0] = nullptr;
482  elist[1] = nullptr;
483  elist[2] = nullptr;
484 
485  velist[0].clear();
486  velist[1].clear();
487  velist[2].clear();
488 
489  obj_aabb_map.clear();
490 }
491 
492 //==============================================================================
494  std::vector<CollisionObject*>& objs) const {
495  objs.resize(AABB_arr.size());
496  size_t i = 0;
497  for (auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end;
498  ++it, ++i) {
499  objs[i] = (*it)->obj;
500  }
501 }
502 
503 //==============================================================================
506  int axis = optimal_axis;
507  const AABB& obj_aabb = obj->getAABB();
508 
509  CoalScalar min_val = obj_aabb.min_[axis];
510  // CoalScalar max_val = obj_aabb.max_[axis];
511 
512  EndPoint dummy;
513  SaPAABB dummy_aabb;
514  dummy_aabb.cached = obj_aabb;
515  dummy.minmax = 1;
516  dummy.aabb = &dummy_aabb;
517 
518  // compute stop_pos by binary search, this is cheaper than check it in while
519  // iteration linearly
520  const auto res_it = std::upper_bound(
521  velist[axis].begin(), velist[axis].end(), &dummy,
522  std::bind(std::less<CoalScalar>(),
523  std::bind(static_cast<CoalScalar (EndPoint::*)(int) const>(
525  std::placeholders::_1, axis),
526  std::bind(static_cast<CoalScalar (EndPoint::*)(int) const>(
528  std::placeholders::_2, axis)));
529 
530  EndPoint* end_pos = nullptr;
531  if (res_it != velist[axis].end()) end_pos = *res_it;
532 
533  EndPoint* pos = elist[axis];
534 
535  while (pos != end_pos) {
536  if (pos->aabb->obj != obj) {
537  if ((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val)) {
538  if (pos->aabb->cached.overlap(obj->getAABB()))
539  if ((*callback)(obj, pos->aabb->obj)) return true;
540  }
541  }
542  pos = pos->next[axis];
543  }
544 
545  return false;
546 }
547 
548 //==============================================================================
550  bool repeated = false;
551  for (auto it = overlap_pairs.begin(), end = overlap_pairs.end(); it != end;
552  ++it) {
553  if (*it == p) {
554  repeated = true;
555  break;
556  }
557  }
558 
559  if (!repeated) overlap_pairs.push_back(p);
560 }
561 
562 //==============================================================================
564  for (auto it = overlap_pairs.begin(), end = overlap_pairs.end(); it != end;
565  ++it) {
566  if (*it == p) {
567  overlap_pairs.erase(it);
568  break;
569  }
570  }
571 
572  // or overlap_pairs.remove_if(isNotValidPair(p));
573 }
574 
575 //==============================================================================
578  callback->init();
579  if (size() == 0) return;
580 
581  collide_(obj, callback);
582 }
583 
584 //==============================================================================
587  CoalScalar& min_dist) const {
588  Vec3s delta = (obj->getAABB().max_ - obj->getAABB().min_) * 0.5;
589  AABB aabb = obj->getAABB();
590 
591  if (min_dist < (std::numeric_limits<CoalScalar>::max)()) {
592  Vec3s min_dist_delta(min_dist, min_dist, min_dist);
593  aabb.expand(min_dist_delta);
594  }
595 
596  int axis = optimal_axis;
597 
598  int status = 1;
599  CoalScalar old_min_distance;
600 
601  EndPoint* start_pos = elist[axis];
602 
603  while (1) {
604  old_min_distance = min_dist;
605  CoalScalar min_val = aabb.min_[axis];
606  // CoalScalar max_val = aabb.max_[axis];
607 
608  EndPoint dummy;
609  SaPAABB dummy_aabb;
610  dummy_aabb.cached = aabb;
611  dummy.minmax = 1;
612  dummy.aabb = &dummy_aabb;
613 
614  const auto res_it = std::upper_bound(
615  velist[axis].begin(), velist[axis].end(), &dummy,
616  std::bind(std::less<CoalScalar>(),
617  std::bind(static_cast<CoalScalar (EndPoint::*)(int) const>(
619  std::placeholders::_1, axis),
620  std::bind(static_cast<CoalScalar (EndPoint::*)(int) const>(
622  std::placeholders::_2, axis)));
623 
624  EndPoint* end_pos = nullptr;
625  if (res_it != velist[axis].end()) end_pos = *res_it;
626 
627  EndPoint* pos = start_pos;
628 
629  while (pos != end_pos) {
630  // can change to pos->aabb->hi->getVal(axis) >= min_val - min_dist, and
631  // then update start_pos to end_pos. but this seems slower.
632  if ((pos->minmax == 0) && (pos->aabb->hi->getVal(axis) >= min_val)) {
633  CollisionObject* curr_obj = pos->aabb->obj;
634  if (curr_obj != obj) {
635  if (!this->enable_tested_set_) {
636  if (pos->aabb->cached.distance(obj->getAABB()) < min_dist) {
637  if ((*callback)(curr_obj, obj, min_dist)) return true;
638  }
639  } else {
640  if (!this->inTestedSet(curr_obj, obj)) {
641  if (pos->aabb->cached.distance(obj->getAABB()) < min_dist) {
642  if ((*callback)(curr_obj, obj, min_dist)) return true;
643  }
644 
645  this->insertTestedSet(curr_obj, obj);
646  }
647  }
648  }
649  }
650 
651  pos = pos->next[axis];
652  }
653 
654  if (status == 1) {
655  if (old_min_distance < (std::numeric_limits<CoalScalar>::max)())
656  break;
657  else {
658  if (min_dist < old_min_distance) {
659  Vec3s min_dist_delta(min_dist, min_dist, min_dist);
660  aabb = AABB(obj->getAABB(), min_dist_delta);
661  status = 0;
662  } else {
663  if (aabb == obj->getAABB())
664  aabb.expand(delta);
665  else
666  aabb.expand(obj->getAABB(), 2.0);
667  }
668  }
669  } else if (status == 0)
670  break;
671  }
672 
673  return false;
674 }
675 
676 //==============================================================================
679  callback->init();
680  if (size() == 0) return;
681 
682  CoalScalar min_dist = (std::numeric_limits<CoalScalar>::max)();
683 
684  distance_(obj, callback, min_dist);
685 }
686 
687 //==============================================================================
689  callback->init();
690  if (size() == 0) return;
691 
692  for (auto it = overlap_pairs.cbegin(), end = overlap_pairs.cend(); it != end;
693  ++it) {
694  CollisionObject* obj1 = it->obj1;
695  CollisionObject* obj2 = it->obj2;
696 
697  if ((*callback)(obj1, obj2)) return;
698  }
699 }
700 
701 //==============================================================================
703  callback->init();
704  if (size() == 0) return;
705 
706  this->enable_tested_set_ = true;
707  this->tested_set.clear();
708 
709  CoalScalar min_dist = (std::numeric_limits<CoalScalar>::max)();
710 
711  for (auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it) {
712  if (distance_((*it)->obj, callback, min_dist)) break;
713  }
714 
715  this->enable_tested_set_ = false;
716  this->tested_set.clear();
717 }
718 
719 //==============================================================================
722  callback->init();
723  SaPCollisionManager* other_manager =
724  static_cast<SaPCollisionManager*>(other_manager_);
725 
726  if ((size() == 0) || (other_manager->size() == 0)) return;
727 
728  if (this == other_manager) {
729  collide(callback);
730  return;
731  }
732 
733  if (this->size() < other_manager->size()) {
734  for (auto it = AABB_arr.cbegin(); it != AABB_arr.cend(); ++it) {
735  if (other_manager->collide_((*it)->obj, callback)) return;
736  }
737  } else {
738  for (auto it = other_manager->AABB_arr.cbegin(),
739  end = other_manager->AABB_arr.cend();
740  it != end; ++it) {
741  if (collide_((*it)->obj, callback)) return;
742  }
743  }
744 }
745 
746 //==============================================================================
749  callback->init();
750  SaPCollisionManager* other_manager =
751  static_cast<SaPCollisionManager*>(other_manager_);
752 
753  if ((size() == 0) || (other_manager->size() == 0)) return;
754 
755  if (this == other_manager) {
757  return;
758  }
759 
760  CoalScalar min_dist = (std::numeric_limits<CoalScalar>::max)();
761 
762  if (this->size() < other_manager->size()) {
763  for (auto it = AABB_arr.cbegin(), end = AABB_arr.cend(); it != end; ++it) {
764  if (other_manager->distance_((*it)->obj, callback, min_dist)) return;
765  }
766  } else {
767  for (auto it = other_manager->AABB_arr.cbegin(),
768  end = other_manager->AABB_arr.cend();
769  it != end; ++it) {
770  if (distance_((*it)->obj, callback, min_dist)) return;
771  }
772  }
773 }
774 
775 //==============================================================================
776 bool SaPCollisionManager::empty() const { return AABB_arr.empty(); }
777 
778 //==============================================================================
779 size_t SaPCollisionManager::size() const { return AABB_arr.size(); }
780 
781 //==============================================================================
783  if (minmax)
784  return aabb->cached.max_;
785  else
786  return aabb->cached.min_;
787 }
788 
789 //==============================================================================
791  if (minmax)
792  return aabb->cached.max_;
793  else
794  return aabb->cached.min_;
795 }
796 
797 //==============================================================================
799  if (minmax)
800  return aabb->cached.max_[i];
801  else
802  return aabb->cached.min_[i];
803 }
804 
805 //==============================================================================
807  if (minmax)
808  return aabb->cached.max_[i];
809  else
810  return aabb->cached.min_[i];
811 }
812 
813 //==============================================================================
815  if (a < b) {
816  obj1 = a;
817  obj2 = b;
818  } else {
819  obj1 = b;
820  obj2 = a;
821  }
822 }
823 
824 //==============================================================================
826  return ((obj1 == other.obj1) && (obj2 == other.obj2));
827 }
828 
829 //==============================================================================
831  : obj(obj_) {}
832 
833 //==============================================================================
835  const SaPPair& pair) const {
836  return (pair.obj1 == obj) || (pair.obj2 == obj);
837 }
838 
839 //==============================================================================
841  CollisionObject* obj2_)
842  : obj1(obj1_), obj2(obj2_) {
843  // Do nothing
844 }
845 
846 //==============================================================================
848  return (pair.obj1 == obj1) && (pair.obj2 == obj2);
849 }
850 
851 } // namespace coal
coal::SaPCollisionManager::SaPAABB
SAP interval for one object.
Definition: coal/broadphase/broadphase_SaP.h:119
coal::SaPCollisionManager::registerObject
void registerObject(CollisionObject *obj)
remove one object from the manager
Definition: broadphase_SaP.cpp:182
coal::Vec3s
Eigen::Matrix< CoalScalar, 3, 1 > Vec3s
Definition: coal/data_types.h:77
coal::SaPCollisionManager::collide
void collide(CollisionObject *obj, CollisionCallBackBase *callback) const
perform collision test between one object and all the objects belonging to the manager
Definition: broadphase_SaP.cpp:576
coal::SaPCollisionManager::SaPAABB::lo
EndPoint * lo
lower bound end point of the interval
Definition: coal/broadphase/broadphase_SaP.h:124
collision_manager.callback
callback
Definition: collision_manager.py:27
coal::SaPCollisionManager::SaPCollisionManager
SaPCollisionManager()
Definition: broadphase_SaP.cpp:84
coal::SaPCollisionManager::clear
void clear()
clear the manager
Definition: broadphase_SaP.cpp:470
coal::SaPCollisionManager::empty
bool empty() const
whether the manager is empty
Definition: broadphase_SaP.cpp:776
coal::minmax
void minmax(CoalScalar a, CoalScalar b, CoalScalar &minv, CoalScalar &maxv)
Find the smaller and larger one of two values.
Definition: kDOP.cpp:47
broadphase_SaP.h
coal::SaPCollisionManager::EndPoint::aabb
SaPAABB * aabb
back pointer to SAP interval
Definition: coal/broadphase/broadphase_SaP.h:140
coal::SaPCollisionManager::AABB_arr
std::list< SaPAABB * > AABB_arr
SAP interval list.
Definition: coal/broadphase/broadphase_SaP.h:203
coal::SaPCollisionManager::SaPPair
A pair of objects that are not culling away and should further check collision.
Definition: coal/broadphase/broadphase_SaP.h:161
coal::SaPCollisionManager::SaPPair::SaPPair
SaPPair(CollisionObject *a, CollisionObject *b)
Definition: broadphase_SaP.cpp:814
coal::AABB::distance
CoalScalar distance(const AABB &other) const
Distance between two AABBs.
Definition: AABB.cpp:114
coal::BroadPhaseCollisionManager
Base class for broad phase collision. It helps to accelerate the collision/distance between N objects...
Definition: coal/broadphase/broadphase_collision_manager.h:53
coal::SaPCollisionManager::optimal_axis
int optimal_axis
Definition: coal/broadphase/broadphase_SaP.h:208
coal::SaPCollisionManager::EndPoint::prev
EndPoint * prev[3]
the previous end point in the end point list
Definition: coal/broadphase/broadphase_SaP.h:143
coal
Main namespace.
Definition: coal/broadphase/broadphase_bruteforce.h:44
coal::BroadPhaseCollisionManager::getObjects
virtual std::vector< CollisionObject * > getObjects() const
return the objects managed by the manager
Definition: coal/broadphase/broadphase_collision_manager.h:87
coal::SaPCollisionManager::isUnregistered
Functor to help unregister one object.
Definition: coal/broadphase/broadphase_SaP.h:171
coal::BroadPhaseCollisionManager::enable_tested_set_
bool enable_tested_set_
Definition: coal/broadphase/broadphase_collision_manager.h:130
coal::SaPCollisionManager::SaPAABB::cached
AABB cached
cached AABB value
Definition: coal/broadphase/broadphase_SaP.h:130
coal::BroadPhaseCollisionManager::registerObjects
virtual void registerObjects(const std::vector< CollisionObject * > &other_objs)
add objects to the manager
Definition: broadphase_collision_manager.cpp:54
coal::SaPCollisionManager::SaPAABB::hi
EndPoint * hi
higher bound end point of the interval
Definition: coal/broadphase/broadphase_SaP.h:127
coal::AABB
A class describing the AABB collision structure, which is a box in 3D space determined by two diagona...
Definition: coal/BV/AABB.h:55
a
list a
coal::SaPCollisionManager::SaPPair::obj1
CollisionObject * obj1
Definition: coal/broadphase/broadphase_SaP.h:164
coal::AABB::max_
Vec3s max_
The max point in the AABB.
Definition: coal/BV/AABB.h:60
coal::SaPCollisionManager::removeFromOverlapPairs
void removeFromOverlapPairs(const SaPPair &p)
Definition: broadphase_SaP.cpp:563
coal::SaPCollisionManager::setup
void setup()
initialize the manager, related with the specific type of manager
Definition: broadphase_SaP.cpp:273
coal::AABB::overlap
bool overlap(const AABB &other) const
Check whether two AABB are overlap.
Definition: coal/BV/AABB.h:111
coal::SaPCollisionManager::addToOverlapPairs
void addToOverlapPairs(const SaPPair &p)
Definition: broadphase_SaP.cpp:549
coal::SaPCollisionManager::registerObjects
void registerObjects(const std::vector< CollisionObject * > &other_objs)
add objects to the manager
Definition: broadphase_SaP.cpp:96
coal::SaPCollisionManager::SaPAABB::obj
CollisionObject * obj
object
Definition: coal/broadphase/broadphase_SaP.h:121
coal::DistanceCallBackBase
Base callback class for distance queries. This class can be supersed by child classes to provide desi...
Definition: coal/broadphase/broadphase_callbacks.h:72
coal::SaPCollisionManager::size
size_t size() const
the number of objects managed by the manager
Definition: broadphase_SaP.cpp:779
coal::CollisionObject
the object for collision or distance computation, contains the geometry and the transform information
Definition: coal/collision_object.h:214
octree.pos
pos
Definition: octree.py:7
coal::BroadPhaseCollisionManager::tested_set
std::set< std::pair< CollisionObject *, CollisionObject * > > tested_set
tools help to avoid repeating collision or distance callback for the pairs of objects tested before....
Definition: coal/broadphase/broadphase_collision_manager.h:129
coal::SaPCollisionManager::isUnregistered::operator()
bool operator()(const SaPPair &pair) const
Definition: broadphase_SaP.cpp:834
axis
axis
coal::SaPCollisionManager::distance
void distance(CollisionObject *obj, DistanceCallBackBase *callback) const
perform distance computation between one object and all the objects belonging to the manager
Definition: broadphase_SaP.cpp:677
coal::CollisionObject::getAABB
const AABB & getAABB() const
get the AABB in world space
Definition: coal/collision_object.h:252
coal::SaPCollisionManager::isNotValidPair::isNotValidPair
isNotValidPair(CollisionObject *obj1_, CollisionObject *obj2_)
Definition: broadphase_SaP.cpp:840
coal::SaPCollisionManager::EndPoint
End point for an interval.
Definition: coal/broadphase/broadphase_SaP.h:134
coal::AABB::min_
Vec3s min_
The min point in the AABB.
Definition: coal/BV/AABB.h:58
coal::SaPCollisionManager::obj_aabb_map
std::map< CollisionObject *, SaPAABB * > obj_aabb_map
Definition: coal/broadphase/broadphase_SaP.h:210
generate_distance_plot.b
float b
Definition: generate_distance_plot.py:7
coal::SaPCollisionManager::isUnregistered::isUnregistered
isUnregistered(CollisionObject *obj_)
Definition: broadphase_SaP.cpp:830
coal::SaPCollisionManager::elist
EndPoint * elist[3]
End point list for x, y, z coordinates.
Definition: coal/broadphase/broadphase_SaP.h:197
coal::SaPCollisionManager::isNotValidPair::operator()
bool operator()(const SaPPair &pair)
Definition: broadphase_SaP.cpp:847
coal::SaPCollisionManager::overlap_pairs
std::list< SaPPair > overlap_pairs
The pair of objects that should further check for collision.
Definition: coal/broadphase/broadphase_SaP.h:206
coal::SaPCollisionManager::unregisterObject
void unregisterObject(CollisionObject *obj)
add one object to the manager
Definition: broadphase_SaP.cpp:43
coal::SaPCollisionManager::SaPPair::obj2
CollisionObject * obj2
Definition: coal/broadphase/broadphase_SaP.h:165
coal::SaPCollisionManager::SaPPair::operator==
bool operator==(const SaPPair &other) const
Definition: broadphase_SaP.cpp:825
coal::BroadPhaseCollisionManager::insertTestedSet
void insertTestedSet(CollisionObject *a, CollisionObject *b) const
Definition: broadphase_collision_manager.cpp:84
coal::SaPCollisionManager::distance_
bool distance_(CollisionObject *obj, DistanceCallBackBase *callback, CoalScalar &min_dist) const
Definition: broadphase_SaP.cpp:585
coal::SaPCollisionManager::~SaPCollisionManager
~SaPCollisionManager()
Definition: broadphase_SaP.cpp:93
coal::SaPCollisionManager::EndPoint::minmax
char minmax
tag for whether it is a lower bound or higher bound of an interval, 0 for lo, and 1 for hi
Definition: coal/broadphase/broadphase_SaP.h:137
coal::SaPCollisionManager::EndPoint::getVal
const Vec3s & getVal() const
get the value of the end point
Definition: broadphase_SaP.cpp:782
coal::SaPCollisionManager::updateVelist
void updateVelist()
Definition: broadphase_SaP.cpp:425
coal::CollisionCallBackBase
Base callback class for collision queries. This class can be supersed by child classes to provide des...
Definition: coal/broadphase/broadphase_callbacks.h:49
coal::SaPCollisionManager::velist
std::vector< EndPoint * > velist[3]
vector version of elist, for acceleration
Definition: coal/broadphase/broadphase_SaP.h:200
coal::SaPCollisionManager::EndPoint::next
EndPoint * next[3]
the next end point in the end point list
Definition: coal/broadphase/broadphase_SaP.h:146
coal::SaPCollisionManager::update_
void update_(SaPAABB *updated_aabb)
Definition: broadphase_SaP.cpp:288
coal::CoalScalar
double CoalScalar
Definition: coal/data_types.h:76
coal::AABB::expand
AABB & expand(const Vec3s &delta)
expand the half size of the AABB by delta, and keep the center unchanged.
Definition: coal/BV/AABB.h:208
coal::BroadPhaseCollisionManager::inTestedSet
bool inTestedSet(CollisionObject *a, CollisionObject *b) const
Definition: broadphase_collision_manager.cpp:75
coal::SaPCollisionManager::collide_
bool collide_(CollisionObject *obj, CollisionCallBackBase *callback) const
Definition: broadphase_SaP.cpp:504
coal::SaPCollisionManager::update
virtual void update()
update the condition of manager
Definition: broadphase_SaP.cpp:459
coal::SaPCollisionManager
Rigorous SAP collision manager.
Definition: coal/broadphase/broadphase_SaP.h:49


hpp-fcl
Author(s):
autogenerated on Sat Nov 23 2024 03:44:57