Check hexahedron in polytope3 to make sure it contains the origin. Otherwise, EPA can return invalid results.
PiperOrigin-RevId: 671057312 Change-Id: Ieb21a77ea679ee5c18972d3a0375578d9a98405e
This commit is contained in:
committed by
Copybara-Service
parent
b502ceef00
commit
b9822e4347
@@ -595,6 +595,37 @@ static void S1D(mjtNum lambda[2], const mjtNum simplex[6]) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------- EPA ---------------------------------------------------
|
||||||
|
|
||||||
|
// helper function to test if the origin is in the same side of the plane formed by P0P1P2 as P3.
|
||||||
|
static int sameSide(const mjtNum p0[3], const mjtNum p1[3],
|
||||||
|
const mjtNum p2[3], const mjtNum p3[3]) {
|
||||||
|
mjtNum diff1[3], diff2[3], diff3[3], diff4[3], n[3];
|
||||||
|
mju_sub3(diff1, p1, p0);
|
||||||
|
mju_sub3(diff2, p2, p0);
|
||||||
|
mju_cross(n, diff1, diff2);
|
||||||
|
|
||||||
|
mju_sub3(diff3, p3, p0);
|
||||||
|
mjtNum dot1 = mju_dot3(n, diff3);
|
||||||
|
|
||||||
|
mju_scl3(diff4, p0, -1);
|
||||||
|
mjtNum dot2 = mju_dot3(n, diff4);
|
||||||
|
if (dot1 > 0 && dot2 > 0) return 1;
|
||||||
|
if (dot1 < 0 && dot2 < 0) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// determines if the origin is contained in the tetrahedron.
|
||||||
|
static int testTetra(const mjtNum p0[3], const mjtNum p1[3],
|
||||||
|
const mjtNum p2[3], const mjtNum p3[3]) {
|
||||||
|
return sameSide(p0, p1, p2, p3)
|
||||||
|
&& sameSide(p1, p2, p3, p0)
|
||||||
|
&& sameSide(p2, p3, p0, p1)
|
||||||
|
&& sameSide(p3, p0, p1, p2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// sets rotation matrix for 120 degrees along axis
|
// sets rotation matrix for 120 degrees along axis
|
||||||
@@ -804,6 +835,18 @@ static int polytope3(Polytope* pt, const mjtNum simplex1[9], const mjtNum simple
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if origin does not lie on simplex then we need to check that the hexahedron contains the
|
||||||
|
// origin
|
||||||
|
//
|
||||||
|
// TODO(kylebayes): It's possible for GJK to return a 2-simplex with the origin not contained in
|
||||||
|
// it but within tolerance from it. In that case the hexahedron could possibly be constructed
|
||||||
|
// that doesn't contain the origin, but nonetheless there is penetration depth.
|
||||||
|
mjtNum dir[3];
|
||||||
|
mju_sub3(dir, obj1->x0, obj2->x0);
|
||||||
|
if (mju_norm3(dir) > mjMINVAL && !testTetra(v1, v2, v3, v4) && !testTetra(v1, v2, v3, v5)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
// save vertices and get indices for each one
|
// save vertices and get indices for each one
|
||||||
int v1i = newVertex(pt, simplex1 + 0, simplex2 + 0);
|
int v1i = newVertex(pt, simplex1 + 0, simplex2 + 0);
|
||||||
int v2i = newVertex(pt, simplex1 + 3, simplex2 + 3);
|
int v2i = newVertex(pt, simplex1 + 3, simplex2 + 3);
|
||||||
|
|||||||
Reference in New Issue
Block a user