46 template <
typename BV>
60 gjk.gjk.setDistanceEarlyBreak(1e-3);
64 std::vector<bool> keep_vertex(model.
num_vertices,
false);
65 std::vector<bool> keep_tri(model.
num_tris,
false);
66 unsigned int ntri = 0;
67 const std::vector<Vec3s>& model_vertices_ = *(model.
vertices);
68 const std::vector<Triangle>& model_tri_indices_ = *(model.
tri_indices);
69 for (
unsigned int i = 0; i < model.
num_tris; ++i) {
70 const Triangle&
t = model_tri_indices_[i];
73 keep_vertex[
t[0]] || keep_vertex[
t[1]] || keep_vertex[
t[2]];
76 for (
unsigned int j = 0; j < 3; ++j) {
77 if (aabb.
contain(
q * model_vertices_[
t[j]])) {
83 const TriangleP tri(model_vertices_[
t[0]], model_vertices_[
t[1]],
84 model_vertices_[
t[2]]);
85 const bool enable_nearest_points =
false;
86 const bool compute_penetration =
false;
95 (
distance <=
gjk.getDistancePrecision(compute_penetration));
97 if (!keep_this_tri && is_collision) {
102 keep_vertex[
t[0]] = keep_vertex[
t[1]] = keep_vertex[
t[2]] =
true;
108 if (ntri == 0)
return NULL;
112 std::vector<unsigned int> idxConversion(model.
num_vertices);
114 std::vector<Vec3s>& new_model_vertices_ = *(new_model->
vertices);
115 for (
unsigned int i = 0; i < keep_vertex.size(); ++i) {
116 if (keep_vertex[i]) {
118 new_model_vertices_[new_model->
num_vertices] = model_vertices_[i];
123 std::vector<Triangle>& new_model_tri_indices_ = *(new_model->
tri_indices);
124 for (
unsigned int i = 0; i < keep_tri.size(); ++i) {
126 new_model_tri_indices_[new_model->
num_tris].set(
127 idxConversion[model_tri_indices_[i][0]],
128 idxConversion[model_tri_indices_[i][1]],
129 idxConversion[model_tri_indices_[i][2]]);
184 Vec3s S1(Vec3s::Zero());
185 Vec3s S2[3] = {Vec3s::Zero(), Vec3s::Zero(), Vec3s::Zero()};
188 for (
unsigned int i = 0; i < n; ++i) {
192 const Vec3s& p2 = ps[
t[1]];
193 const Vec3s& p3 = ps[
t[2]];
195 S1[0] += (
p1[0] + p2[0] + p3[0]);
196 S1[1] += (
p1[1] + p2[1] + p3[1]);
197 S1[2] += (
p1[2] + p2[2] + p3[2]);
198 S2[0][0] += (
p1[0] *
p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
199 S2[1][1] += (
p1[1] *
p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
200 S2[2][2] += (
p1[2] *
p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
201 S2[0][1] += (
p1[0] *
p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
202 S2[0][2] += (
p1[0] *
p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
203 S2[1][2] += (
p1[1] *
p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
207 const Vec3s& p2 = ps2[
t[1]];
208 const Vec3s& p3 = ps2[
t[2]];
210 S1[0] += (
p1[0] + p2[0] + p3[0]);
211 S1[1] += (
p1[1] + p2[1] + p3[1]);
212 S1[2] += (
p1[2] + p2[2] + p3[2]);
214 S2[0][0] += (
p1[0] *
p1[0] + p2[0] * p2[0] + p3[0] * p3[0]);
215 S2[1][1] += (
p1[1] *
p1[1] + p2[1] * p2[1] + p3[1] * p3[1]);
216 S2[2][2] += (
p1[2] *
p1[2] + p2[2] * p2[2] + p3[2] * p3[2]);
217 S2[0][1] += (
p1[0] *
p1[1] + p2[0] * p2[1] + p3[0] * p3[1]);
218 S2[0][2] += (
p1[0] *
p1[2] + p2[0] * p2[2] + p3[0] * p3[2]);
219 S2[1][2] += (
p1[1] *
p1[2] + p2[1] * p2[2] + p3[1] * p3[2]);
223 for (
unsigned int i = 0; i < n; ++i) {
224 const Vec3s& p = (indices) ? ps[indices[i]] : ps[i];
226 S2[0][0] += (p[0] * p[0]);
227 S2[1][1] += (p[1] * p[1]);
228 S2[2][2] += (p[2] * p[2]);
229 S2[0][1] += (p[0] * p[1]);
230 S2[0][2] += (p[0] * p[2]);
231 S2[1][2] += (p[1] * p[2]);
235 const Vec3s& p = (indices) ? ps2[indices[i]] : ps2[i];
237 S2[0][0] += (p[0] * p[0]);
238 S2[1][1] += (p[1] * p[1]);
239 S2[2][2] += (p[2] * p[2]);
240 S2[0][1] += (p[0] * p[1]);
241 S2[0][2] += (p[0] * p[2]);
242 S2[1][2] += (p[1] * p[2]);
247 unsigned int n_points = ((ps2) ? 2 : 1) * ((
ts) ? 3 : 1) * n;
249 M(0, 0) = S2[0][0] - S1[0] * S1[0] / n_points;
250 M(1, 1) = S2[1][1] - S1[1] * S1[1] / n_points;
251 M(2, 2) = S2[2][2] - S1[2] * S1[2] / n_points;
252 M(0, 1) = S2[0][1] - S1[0] * S1[1] / n_points;
253 M(1, 2) = S2[1][2] - S1[1] * S1[2] / n_points;
254 M(0, 2) = S2[0][2] - S1[0] * S1[2] / n_points;
264 unsigned int* indices,
unsigned int n,
267 bool indirect_index =
true;
268 if (!indices) indirect_index =
false;
270 unsigned int size_P = ((ps2) ? 2 : 1) * ((
ts) ? 3 : 1) * n;
277 for (
unsigned int i = 0; i < n; ++i) {
278 unsigned int index = indirect_index ? indices[i] : i;
283 const Vec3s& p = ps[point_id];
284 Vec3s v(p[0], p[1], p[2]);
285 P[P_id][0] = axes.col(0).dot(
v);
286 P[P_id][1] = axes.col(1).dot(
v);
287 P[P_id][2] = axes.col(2).dot(
v);
294 const Vec3s& p = ps2[point_id];
296 Vec3s v(p[0], p[1], p[2]);
297 P[P_id][0] = axes.col(0).dot(
v);
298 P[P_id][1] = axes.col(0).dot(
v);
299 P[P_id][2] = axes.col(1).dot(
v);
305 for (
unsigned int i = 0; i < n; ++i) {
306 unsigned int index = indirect_index ? indices[i] : i;
309 Vec3s v(p[0], p[1], p[2]);
310 P[P_id][0] = axes.col(0).dot(
v);
311 P[P_id][1] = axes.col(1).dot(
v);
312 P[P_id][2] = axes.col(2).dot(
v);
317 P[P_id][0] = axes.col(0).dot(
v);
318 P[P_id][1] = axes.col(1).dot(
v);
319 P[P_id][2] = axes.col(2).dot(
v);
325 CoalScalar minx, maxx, miny, maxy, minz, maxz;
329 minz = maxz =
P[0][2];
331 for (
unsigned int i = 1; i < size_P; ++i) {
335 else if (z_value > maxz)
347 unsigned int minindex = 0, maxindex = 0;
349 mintmp = maxtmp =
P[0][0];
351 for (
unsigned int i = 1; i < size_P; ++i) {
353 if (x_value < mintmp) {
356 }
else if (x_value > maxtmp) {
363 dz =
P[minindex][2] - cz;
364 minx =
P[minindex][0] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
365 dz =
P[maxindex][2] - cz;
366 maxx =
P[maxindex][0] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
370 for (
unsigned int i = 0; i < size_P; ++i) {
371 if (
P[i][0] < minx) {
373 x =
P[i][0] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
374 if (
x < minx) minx =
x;
375 }
else if (
P[i][0] > maxx) {
377 x =
P[i][0] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
378 if (
x > maxx) maxx =
x;
386 minindex = maxindex = 0;
387 mintmp = maxtmp =
P[0][1];
388 for (
unsigned int i = 1; i < size_P; ++i) {
390 if (y_value < mintmp) {
393 }
else if (y_value > maxtmp) {
400 dz =
P[minindex][2] - cz;
401 miny =
P[minindex][1] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
402 dz =
P[maxindex][2] - cz;
403 maxy =
P[maxindex][1] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
407 for (
unsigned int i = 0; i < size_P; ++i) {
408 if (
P[i][1] < miny) {
410 y =
P[i][1] + std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
411 if (
y < miny) miny =
y;
412 }
else if (
P[i][1] > maxy) {
414 y =
P[i][1] - std::sqrt(std::max<CoalScalar>(radsqr - dz * dz, 0));
415 if (
y > maxy) maxy =
y;
423 for (
unsigned int i = 0; i < size_P; ++i) {
424 if (
P[i][0] > maxx) {
425 if (
P[i][1] > maxy) {
429 t = (
a * u - dx) * (
a * u - dx) + (
a * u - dy) * (
a * u - dy) +
430 (cz -
P[i][2]) * (cz -
P[i][2]);
431 u = u - std::sqrt(std::max<CoalScalar>(radsqr -
t, 0));
436 }
else if (
P[i][1] < miny) {
440 t = (
a * u - dx) * (
a * u - dx) + (-
a * u - dy) * (-
a * u - dy) +
441 (cz -
P[i][2]) * (cz -
P[i][2]);
442 u = u - std::sqrt(std::max<CoalScalar>(radsqr -
t, 0));
448 }
else if (
P[i][0] < minx) {
449 if (
P[i][1] > maxy) {
453 t = (-
a * u - dx) * (-
a * u - dx) + (
a * u - dy) * (
a * u - dy) +
454 (cz -
P[i][2]) * (cz -
P[i][2]);
455 u = u - std::sqrt(std::max<CoalScalar>(radsqr -
t, 0));
460 }
else if (
P[i][1] < miny) {
463 u = -dx *
a - dy *
a;
464 t = (-
a * u - dx) * (-
a * u - dx) + (-
a * u - dy) * (-
a * u - dy) +
465 (cz -
P[i][2]) * (cz -
P[i][2]);
466 u = u - std::sqrt(std::max<CoalScalar>(radsqr -
t, 0));
475 origin.noalias() = axes *
Vec3s(minx, miny, cz);
477 l[0] = std::max<CoalScalar>(maxx - minx, 0);
478 l[1] = std::max<CoalScalar>(maxy - miny, 0);
487 unsigned int* indices,
490 bool indirect_index =
true;
491 if (!indices) indirect_index =
false;
493 CoalScalar real_max = (std::numeric_limits<CoalScalar>::max)();
495 Vec3s min_coord(real_max, real_max, real_max);
496 Vec3s max_coord(-real_max, -real_max, -real_max);
498 for (
unsigned int i = 0; i < n; ++i) {
499 unsigned int index = indirect_index ? indices[i] : i;
502 Vec3s proj(axes.transpose() * p);
504 for (
int j = 0; j < 3; ++j) {
505 if (proj[j] > max_coord[j]) max_coord[j] = proj[j];
506 if (proj[j] < min_coord[j]) min_coord[j] = proj[j];
511 proj.noalias() = axes.transpose() *
v;
513 for (
int j = 0; j < 3; ++j) {
514 if (proj[j] > max_coord[j]) max_coord[j] = proj[j];
515 if (proj[j] < min_coord[j]) min_coord[j] = proj[j];
520 center.noalias() = axes * (max_coord + min_coord) / 2;
522 extent.noalias() = (max_coord - min_coord) / 2;
529 unsigned int* indices,
532 bool indirect_index =
true;
533 if (!indices) indirect_index =
false;
535 CoalScalar real_max = (std::numeric_limits<CoalScalar>::max)();
537 Vec3s min_coord(real_max, real_max, real_max);
538 Vec3s max_coord(-real_max, -real_max, -real_max);
540 for (
unsigned int i = 0; i < n; ++i) {
541 unsigned int index = indirect_index ? indices[i] : i;
546 const Vec3s& p = ps[point_id];
547 Vec3s proj(axes.transpose() * p);
549 for (
int k = 0; k < 3; ++k) {
550 if (proj[k] > max_coord[k]) max_coord[k] = proj[k];
551 if (proj[k] < min_coord[k]) min_coord[k] = proj[k];
558 const Vec3s& p = ps2[point_id];
559 Vec3s proj(axes.transpose() * p);
561 for (
int k = 0; k < 3; ++k) {
562 if (proj[k] > max_coord[k]) max_coord[k] = proj[k];
563 if (proj[k] < min_coord[k]) min_coord[k] = proj[k];
569 Vec3s o((max_coord + min_coord) / 2);
571 center.noalias() = axes * o;
573 extent.noalias() = (max_coord - min_coord) / 2;
577 unsigned int* indices,
unsigned int n,
Matrix3s& axes,
591 Vec3s e3 = e1.cross(e2);
593 radius = e1_len2 * e2_len2 * (e1 - e2).squaredNorm() / e3_len2;
594 radius = std::sqrt(radius) * 0.5;
596 center = (e2 * e1_len2 - e1 * e2_len2).cross(e3) * (0.5 * 1 / e3_len2) +
c;
601 unsigned int* indices,
603 const Vec3s& query) {
604 bool indirect_index =
true;
605 if (!indices) indirect_index =
false;
608 for (
unsigned int i = 0; i < n; ++i) {
609 unsigned int index = indirect_index ? indices[i] : i;
614 const Vec3s& p = ps[point_id];
617 if (
d > maxD) maxD =
d;
623 const Vec3s& p = ps2[point_id];
626 if (
d > maxD) maxD =
d;
631 return std::sqrt(maxD);
635 unsigned int* indices,
637 const Vec3s& query) {
638 bool indirect_index =
true;
639 if (!indices) indirect_index =
false;
642 for (
unsigned int i = 0; i < n; ++i) {
643 unsigned int index = indirect_index ? indices[i] : i;
647 if (
d > maxD) maxD =
d;
652 if (
d > maxD) maxD =
d;
656 return std::sqrt(maxD);
660 unsigned int* indices,
unsigned int n,
661 const Vec3s& query) {