45 for (
auto end =
AABB_arr.end(); it != end; ++it) {
46 if ((*it)->obj == obj)
break;
57 for (
int coord = 0; coord < 3; ++coord) {
59 if (curr->
lo->
prev[coord] ==
nullptr)
67 if (curr->
hi->
prev[coord] ==
nullptr)
72 if (curr->
hi->
next[coord] !=
nullptr)
97 const std::vector<CollisionObject*>& other_objs) {
98 if (other_objs.empty())
return;
103 std::vector<EndPoint*> endpoints(2 * other_objs.size());
105 for (
size_t i = 0; i < other_objs.size(); ++i) {
107 sapaabb->
obj = other_objs[i];
110 sapaabb->
cached = other_objs[i]->getAABB();
111 endpoints[2 * i] = sapaabb->
lo;
112 endpoints[2 * i + 1] = sapaabb->
hi;
115 sapaabb->
lo->
aabb = sapaabb;
116 sapaabb->
hi->
aabb = sapaabb;
122 for (
int coord = 0; coord < 3; ++coord) {
124 endpoints.begin(), endpoints.end(),
125 std::bind(std::less<CoalScalar>(),
128 std::placeholders::_1, coord),
131 std::placeholders::_2, coord)));
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];
139 endpoints[endpoints.size() - 1]->prev[coord] =
140 endpoints[endpoints.size() - 2];
141 endpoints[endpoints.size() - 1]->next[coord] =
nullptr;
143 elist[coord] = endpoints[0];
146 endpoints[0]->aabb->cached.min_[coord];
150 if (scale[
axis] < scale[1])
axis = 1;
151 if (scale[
axis] < scale[2])
axis = 2;
155 while (
pos !=
nullptr) {
160 while (pos_it !=
nullptr) {
161 if (pos_it->
aabb == aabb) {
162 if (pos_next ==
nullptr) pos_next = pos_it;
166 if (pos_it->
minmax == 0) {
167 if (pos_next ==
nullptr) pos_next = pos_it;
190 new_sap->
lo->
aabb = new_sap;
194 new_sap->
hi->
aabb = new_sap;
195 for (
int coord = 0; coord < 3; ++coord) {
199 if (current ==
nullptr)
202 new_sap->
lo->
prev[coord] = new_sap->
lo->
next[coord] =
nullptr;
207 while ((current->
getVal()[coord] < curr_lo_val) &&
208 (current->
next[coord] !=
nullptr))
209 current = current->
next[coord];
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)
218 current->
prev[coord]->
next[coord] = curr_lo;
220 current->
prev[coord] =
224 curr_lo->
prev[coord] = current;
225 curr_lo->
next[coord] =
nullptr;
226 current->
next[coord] = curr_lo;
231 current = new_sap->
lo;
237 while ((current->
getVal()[coord] < curr_hi_val) &&
238 (current->
next[coord] !=
nullptr)) {
239 if (current != new_sap->
lo)
243 current = current->
next[coord];
246 while ((current->
getVal()[coord] < curr_hi_val) &&
247 (current->
next[coord] !=
nullptr))
248 current = current->
next[coord];
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;
257 current->
prev[coord] = curr_hi;
259 curr_hi->
prev[coord] = current;
260 curr_hi->
next[coord] =
nullptr;
261 current->
next[coord] = curr_hi;
274 if (
size() == 0)
return;
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);
282 if (scale[
axis] < scale[1])
axis = 1;
283 if (scale[
axis] < scale[2])
axis = 2;
291 SaPAABB* current = updated_aabb;
295 const Vec3s& new_min = current_aabb.
min_;
296 const Vec3s& new_max = current_aabb.
max_;
298 for (
int coord = 0; coord < 3; ++coord) {
302 if (current->
lo->
getVal(coord) > new_min[coord])
304 else if (current->
lo->
getVal(coord) < new_min[coord])
309 if (direction == -1) {
311 if (current->
lo->
prev[coord] !=
nullptr) {
312 temp = current->
lo->
prev[coord];
313 while ((temp !=
nullptr) && (temp->
getVal(coord) > new_min[coord])) {
317 temp = temp->
prev[coord];
320 if (temp ==
nullptr) {
323 current->
lo->
prev[coord] =
nullptr;
330 current->
lo->
prev[coord] = temp;
333 temp->
next[coord] = current->
lo;
338 current->
lo->
getVal(coord) = new_min[coord];
341 if (current->
hi->
prev[coord] !=
nullptr) {
342 temp = current->
hi->
prev[coord];
344 while ((temp !=
nullptr) && (temp->
getVal(coord) > new_max[coord])) {
345 if ((temp->
minmax == 0) &&
348 temp = temp->
prev[coord];
352 if (current->
hi->
next[coord] !=
nullptr)
354 current->
hi->
prev[coord] = temp;
356 if (temp->
next[coord] !=
nullptr)
358 temp->
next[coord] = current->
hi;
360 current->
hi->
getVal(coord) = new_max[coord];
363 current->
hi->
getVal(coord) = new_max[coord];
364 }
else if (direction == 1) {
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])) {
373 temp = temp->
next[coord];
376 if (temp->
getVal(coord) < new_max[coord]) {
379 current->
hi->
prev[coord] = temp;
380 current->
hi->
next[coord] =
nullptr;
381 temp->
next[coord] = current->
hi;
386 current->
hi->
next[coord] = temp;
388 temp->
prev[coord] = current->
hi;
392 current->
hi->
getVal(coord) = new_max[coord];
395 if (current->
lo->
next[coord] !=
nullptr) {
396 temp = current->
lo->
next[coord];
398 while ((temp->
next[coord] !=
nullptr) &&
399 (temp->
getVal(coord) < new_min[coord])) {
400 if ((temp->
minmax == 1) &&
403 temp = temp->
next[coord];
406 if (current->
lo->
prev[coord] !=
nullptr)
412 current->
lo->
next[coord] = temp;
413 if (temp->
prev[coord] !=
nullptr)
417 temp->
prev[coord] = current->
lo;
418 current->
lo->
getVal(coord) = new_min[coord];
426 for (
int coord = 0; coord < 3; ++coord) {
431 velist[coord][id] = current;
432 current = current->
next[coord];
449 const std::vector<CollisionObject*>& updated_objs) {
450 for (
size_t i = 0; i < updated_objs.size(); ++i)
494 std::vector<CollisionObject*>& objs)
const {
499 objs[i] = (*it)->obj;
514 dummy_aabb.
cached = obj_aabb;
516 dummy.
aabb = &dummy_aabb;
520 const auto res_it = std::upper_bound(
522 std::bind(std::less<CoalScalar>(),
525 std::placeholders::_1,
axis),
528 std::placeholders::_2,
axis)));
531 if (res_it !=
velist[
axis].end()) end_pos = *res_it;
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()))
550 bool repeated =
false;
579 if (
size() == 0)
return;
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);
604 old_min_distance = min_dist;
612 dummy.
aabb = &dummy_aabb;
614 const auto res_it = std::upper_bound(
616 std::bind(std::less<CoalScalar>(),
619 std::placeholders::_1,
axis),
622 std::placeholders::_2,
axis)));
625 if (res_it !=
velist[
axis].end()) end_pos = *res_it;
629 while (
pos != end_pos) {
632 if ((
pos->minmax == 0) && (
pos->aabb->hi->getVal(
axis) >= min_val)) {
634 if (curr_obj != obj) {
637 if ((*
callback)(curr_obj, obj, min_dist))
return true;
641 if (
pos->aabb->cached.distance(obj->
getAABB()) < min_dist) {
642 if ((*
callback)(curr_obj, obj, min_dist))
return true;
655 if (old_min_distance < (std::numeric_limits<CoalScalar>::max)())
658 if (min_dist < old_min_distance) {
659 Vec3s min_dist_delta(min_dist, min_dist, min_dist);
669 }
else if (status == 0)
680 if (
size() == 0)
return;
682 CoalScalar min_dist = (std::numeric_limits<CoalScalar>::max)();
690 if (
size() == 0)
return;
697 if ((*
callback)(obj1, obj2))
return;
704 if (
size() == 0)
return;
709 CoalScalar min_dist = (std::numeric_limits<CoalScalar>::max)();
726 if ((
size() == 0) || (other_manager->
size() == 0))
return;
728 if (
this == other_manager) {
733 if (this->
size() < other_manager->
size()) {
738 for (
auto it = other_manager->
AABB_arr.cbegin(),
739 end = other_manager->
AABB_arr.cend();
753 if ((
size() == 0) || (other_manager->
size() == 0))
return;
755 if (
this == other_manager) {
760 CoalScalar min_dist = (std::numeric_limits<CoalScalar>::max)();
762 if (this->
size() < other_manager->
size()) {
767 for (
auto it = other_manager->
AABB_arr.cbegin(),
768 end = other_manager->
AABB_arr.cend();
792 return aabb->cached.max_;
794 return aabb->cached.min_;
800 return aabb->cached.max_[i];
802 return aabb->cached.min_[i];
808 return aabb->cached.max_[i];
810 return aabb->cached.min_[i];
826 return ((obj1 == other.
obj1) && (obj2 == other.
obj2));
836 return (pair.
obj1 == obj) || (pair.
obj2 == obj);
842 : obj1(obj1_), obj2(obj2_) {
848 return (pair.
obj1 == obj1) && (pair.
obj2 == obj2);