7 #include "imstkCollisionUtils.h" 8 #include "imstkLogger.h" 12 namespace CollisionUtils
15 testLineToLineAabb(
const double x1,
const double y1,
const double z1,
16 const double x2,
const double y2,
const double z2,
17 const double x3,
const double y3,
const double z3,
18 const double x4,
const double y4,
const double z4,
19 const double prox1 ,
const double prox2 )
21 double min1_x, max1_x, min1_y, max1_y, min1_z, max1_z;
56 double min2_x, max2_x, min2_y, max2_y, min2_z, max2_z;
91 return testAabbToAabb(min1_x - prox1, max1_x + prox1, min1_y - prox1, max1_y + prox1,
92 min1_z - prox1, max1_z + prox1, min2_x - prox2, max2_x + prox2,
93 min2_y - prox2, max2_y + prox2, min2_z - prox2, max2_z + prox2);
97 pointSegmentClosestDistance(
const Vec3d& point,
const Vec3d& x1,
const Vec3d& x2)
100 double m2 = dx.squaredNorm();
103 return (point - x1).norm();
107 double s12 = dx.dot(x2 - point) / m2;
118 return (point - (s12 * x1 + (1.0 - s12) * x2)).eval().norm();
122 pointTriangleClosestDistance(
const Vec3d& point,
const Vec3d& x1,
const Vec3d& x2,
const Vec3d& x3)
125 const Vec3d closestPtOnTri = closestPointOnTriangle(point, x1, x2, x3, unusedType);
127 return (point - closestPtOnTri).norm();
131 closestPointOnSegment(
const Vec3d& point,
const Vec3d& x1,
const Vec3d& x2,
int& caseType)
134 double m2 = dx.squaredNorm();
142 double s12 = dx.dot(x2 - point) / m2;
155 return (s12 * x1 + (1.0 - s12) * x2).eval();
159 closestPointOnTriangle(
const Vec3d& p,
const Vec3d& a,
const Vec3d& b,
const Vec3d& c,
int& caseType)
163 const Vec3d ab = b - a;
164 const Vec3d ac = c - a;
165 const Vec3d ap = p - a;
167 const double d1 = ab.dot(ap);
168 const double d2 = ac.dot(ap);
172 if (d1 <= 0.0 && d2 <= 0.0)
178 const Vec3d bp = p - b;
179 const double d3 = ab.dot(bp);
180 const double d4 = ac.dot(bp);
181 if (d3 >= 0.0 && d4 <= d3)
187 const Vec3d cp = p - c;
188 const double d5 = ab.dot(cp);
189 const double d6 = ac.dot(cp);
190 if (d6 >= 0.0 && d5 <= d6)
196 const double vc = d1 * d4 - d3 * d2;
198 if (vc <= 0.0 && d1 > 0.0 && d3 < 0.0)
204 const double va = d3 * d6 - d5 * d4;
205 if (va <= 0.0 && (d4 - d3) > 0.0 && (d5 - d6) > 0.0)
211 const double vb = d5 * d2 - d1 * d6;
212 if (vb <= 0.0 && d2 > 0.0 && d6 < 0.0)
238 w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
239 return b + w * (c - b);
244 denom = 1.0 / (va + vb + vc);
247 return a + ab * v + ac * w;
249 LOG(FATAL) <<
"Unexpected casetype in closestPointOnTriangle " << caseType;
250 return Vec3d(std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN(), std::numeric_limits<double>::quiet_NaN());
256 const Vec3i& tri_a,
const Vec3i& tri_b,
257 const Vec3d& p0_a,
const Vec3d& p1_a,
const Vec3d& p2_a,
258 const Vec3d& p0_b,
const Vec3d& p1_b,
const Vec3d& p2_b,
259 std::pair<Vec2i, Vec2i>& edgeContact,
260 std::pair<int, Vec3i>& vertexTriangleContact,
261 std::pair<Vec3i, int>& triangleVertexContact)
264 int contactType = -1;
266 const std::array<Vec3d, 3> triAVerts = { p0_a, p1_a, p2_a };
267 const std::array<Vec3d, 3> triBVerts = { p0_b, p1_b, p2_b };
270 const std::pair<Vec3d, Vec3d> triAEdges[3]{
271 { triAVerts[0], triAVerts[1] },
272 { triAVerts[0], triAVerts[2] },
273 { triAVerts[1], triAVerts[2] }
277 const std::pair<Vec3d, Vec3d> triBEdges[3]{
278 { triBVerts[0], triBVerts[1] },
279 { triBVerts[0], triBVerts[2] },
280 { triBVerts[1], triBVerts[2] }
284 bool aIntersected[3];
285 for (
int i = 0; i < 3; i++)
287 aIntersected[i] = CollisionUtils::testSegmentTriangle(triAEdges[i].first, triAEdges[i].second,
288 triBVerts[0], triBVerts[1], triBVerts[2]);
292 const int numIntersectionsA = aIntersected[0] + aIntersected[1] + aIntersected[2];
293 if (numIntersectionsA == 2)
297 const int vertIdx = aIntersected[1] ? tri_a[0] : tri_a[1];
298 vertexTriangleContact = std::pair<int, Vec3i>(vertIdx, tri_b);
302 vertexTriangleContact = std::pair<int, Vec3i>(tri_a[2], tri_b);
306 else if (numIntersectionsA == 1)
311 edgeIdA = { tri_a[0], tri_a[1] };
313 else if (aIntersected[1])
315 edgeIdA = { tri_a[0], tri_a[2] };
319 edgeIdA = { tri_a[1], tri_a[2] };
326 for (
int i = 0; i < 3; i++)
328 if (CollisionUtils::testSegmentTriangle(triBEdges[i].first, triBEdges[i].second,
329 triAVerts[0], triAVerts[1], triAVerts[2]))
333 edgeIdB = { tri_b[0], tri_b[1] };
337 edgeIdB = { tri_b[0], tri_b[2] };
341 edgeIdB = { tri_b[1], tri_b[2] };
350 edgeContact = std::pair<Vec2i, Vec2i>(edgeIdA, edgeIdB);
357 bool bIntersected[3];
358 for (
int i = 0; i < 3; i++)
360 bIntersected[i] = CollisionUtils::testSegmentTriangle(triBEdges[i].first, triBEdges[i].second,
361 triAVerts[0], triAVerts[1], triAVerts[2]);
365 const int numIntersectionsB = bIntersected[0] + bIntersected[1] + bIntersected[2];
366 if (numIntersectionsB == 2)
370 const int vertIdx = bIntersected[1] ? tri_b[0] : tri_b[1];
371 triangleVertexContact = std::pair<Vec3i, int>(tri_a, vertIdx);
375 triangleVertexContact = std::pair<Vec3i, int>(tri_a, tri_b[2]);