Skip to content

Commit 442b968

Browse files
kbayescopybara-github
authored andcommitted
Improve box-box multicontact with nativeccd.
PiperOrigin-RevId: 728136635 Change-Id: I2343110e5c87b6621d5750c7ad42f0e75081d737
1 parent fb84ee4 commit 442b968

File tree

2 files changed

+40
-64
lines changed

2 files changed

+40
-64
lines changed

src/engine/engine_collision_convex.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -311,11 +311,18 @@ static void mjc_boxSupport(mjtNum res[3], mjCCDObj* obj, const mjtNum dir[3]) {
311311
mjtNum local_dir[3], tmp[3];
312312
mulMatTVec3(local_dir, mat, dir);
313313

314+
// find support point in local frame
314315
tmp[0] = (local_dir[0] >= 0 ? 1 : -1) * size[0];
315316
tmp[1] = (local_dir[1] >= 0 ? 1 : -1) * size[1];
316317
tmp[2] = (local_dir[2] >= 0 ? 1 : -1) * size[2];
317318

318-
// transform result to global frame
319+
// mark the index of the corner of the box for fast lookup
320+
obj->vertindex = 0;
321+
if (tmp[0] > 0) obj->vertindex |= 1;
322+
if (tmp[1] > 0) obj->vertindex |= 2;
323+
if (tmp[2] > 0) obj->vertindex |= 4;
324+
325+
// transform support point to global frame
319326
localToGlobal(res, mat, tmp, pos);
320327
}
321328

src/engine/engine_collision_gjk.c

Lines changed: 32 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,6 @@ static inline int equal3(const mjtNum v1[3], const mjtNum v2[3]) {
9898
mju_abs(v1[2] - v2[2]) < mjMINVAL;
9999
}
100100

101-
// v1 == v2
102-
static inline int equalexact3(const mjtNum v1[3], const mjtNum v2[3]) {
103-
return v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2];
104-
}
105-
106101
// res = v1 + v2
107102
static inline void add3(mjtNum res[3], const mjtNum v1[3], const mjtNum v2[3]) {
108103
res[0] = v1[0] + v2[0], res[1] = v1[1] + v2[1], res[2] = v1[2] + v2[2];
@@ -538,15 +533,6 @@ static inline int sameSign2(mjtNum a, mjtNum b) {
538533

539534

540535

541-
// return 1 if all three numbers are positive, -1 if all negative and 0 otherwise
542-
static inline int sameSign3(mjtNum a, mjtNum b, mjtNum c) {
543-
if (a > 0 && b > 0 && c > 0) return 1;
544-
if (a < 0 && b < 0 && c < 0) return -1;
545-
return 0;
546-
}
547-
548-
549-
550536
// subdistance algorithm for GJK that computes the barycentric coordinates of the point in a
551537
// simplex closest to the origin
552538
// implementation adapted from Montanari et al, ToG 2017
@@ -1578,22 +1564,6 @@ static void polygonClip(mjCCDStatus* status, const mjtNum face1[3 * mjMAX_SIDES]
15781564

15791565

15801566

1581-
// compute local coordinates of a global point (g1, g2, g3)
1582-
static inline void localcoord(mjtNum res[3], const mjtNum mat[9], const mjtNum pos[3],
1583-
mjtNum g1, mjtNum g2, mjtNum g3) {
1584-
// perform matT * ((g1, g2, g3) - pos)
1585-
if (pos) {
1586-
g1 -= pos[0];
1587-
g2 -= pos[1];
1588-
g3 -= pos[2];
1589-
}
1590-
res[0] = mat[0]*g1 + mat[3]*g2 + mat[6]*g3;
1591-
res[1] = mat[1]*g1 + mat[4]*g2 + mat[7]*g3;
1592-
res[2] = mat[2]*g1 + mat[5]*g2 + mat[8]*g3;
1593-
}
1594-
1595-
1596-
15971567
// compute global coordinates of a local point (l1, l2, l3)
15981568
static inline void globalcoord(mjtNum res[3], const mjtNum mat[9], const mjtNum pos[3],
15991569
mjtNum l1, mjtNum l2, mjtNum l3) {
@@ -1612,22 +1582,15 @@ static inline void globalcoord(mjtNum res[3], const mjtNum mat[9], const mjtNum
16121582

16131583
// compute possible face normals of a box given up to 3 vertices
16141584
static int boxNormals(mjtNum res[9], int resind[3], int dim, mjCCDObj* obj,
1615-
const mjtNum v1[3], const mjtNum v2[3], const mjtNum v3[3]) {
1585+
int v1, int v2, int v3) {
16161586
// box data
16171587
int g = 3*obj->geom;
16181588
const mjtNum* mat = obj->data->geom_xmat + 3*g;
1619-
const mjtNum* pos = obj->data->geom_xpos + g;
1620-
1621-
// rotate global coordinates to geom local frame
1622-
mjtNum v1_local[3], v2_local[3], v3_local[3];
1623-
if (dim > 0) localcoord(v1_local, mat, pos, v1[0], v1[1], v1[2]);
1624-
if (dim > 1) localcoord(v2_local, mat, pos, v2[0], v2[1], v2[2]);
1625-
if (dim > 2) localcoord(v3_local, mat, pos, v3[0], v3[1], v3[2]);
16261589

16271590
if (dim == 3) {
1628-
int x = sameSign3(v1_local[0], v2_local[0], v3_local[0]);
1629-
int y = sameSign3(v1_local[1], v2_local[1], v3_local[1]);
1630-
int z = sameSign3(v1_local[2], v2_local[2], v3_local[2]);
1591+
int x = ((v1 & 1) && (v2 & 1) && (v3 & 1)) - (!(v1 & 1) && !(v2 & 1) && !(v3 & 1));
1592+
int y = ((v1 & 2) && (v2 & 2) && (v3 & 2)) - (!(v1 & 2) && !(v2 & 2) && !(v3 & 2));
1593+
int z = ((v1 & 4) && (v2 & 4) && (v3 & 4)) - (!(v1 & 4) && !(v2 & 4) && !(v3 & 4));
16311594
globalcoord(res, mat, NULL, x, y, z);
16321595
int sgn = x + y + z;
16331596
if (x) resind[0] = 0;
@@ -1638,9 +1601,9 @@ static int boxNormals(mjtNum res[9], int resind[3], int dim, mjCCDObj* obj,
16381601
}
16391602

16401603
if (dim == 2) {
1641-
int x = sameSign2(v1_local[0], v2_local[0]);
1642-
int y = sameSign2(v1_local[1], v2_local[1]);
1643-
int z = sameSign2(v1_local[2], v2_local[2]);
1604+
int x = ((v1 & 1) && (v2 & 1)) - (!(v1 & 1) && !(v2 & 1));
1605+
int y = ((v1 & 2) && (v2 & 2)) - (!(v1 & 2) && !(v2 & 2));
1606+
int z = ((v1 & 4) && (v2 & 4)) - (!(v1 & 4) && !(v2 & 4));
16441607
if (x) {
16451608
globalcoord(res, mat, NULL, x, 0, 0);
16461609
resind[0] = (x > 0) ? 0 : 1;
@@ -1658,9 +1621,9 @@ static int boxNormals(mjtNum res[9], int resind[3], int dim, mjCCDObj* obj,
16581621
}
16591622

16601623
if (dim == 1) {
1661-
mjtNum x = (v1_local[0] > 0) ? 1 : -1;
1662-
mjtNum y = (v1_local[1] > 0) ? 1 : -1;
1663-
mjtNum z = (v1_local[2] > 0) ? 1 : -1;
1624+
mjtNum x = (v1 & 1) ? 1 : -1;
1625+
mjtNum y = (v1 & 2) ? 1 : -1;
1626+
mjtNum z = (v1 & 4) ? 1 : -1;
16641627
globalcoord(res + 0, mat, NULL, x, 0, 0);
16651628
globalcoord(res + 3, mat, NULL, 0, y, 0);
16661629
globalcoord(res + 6, mat, NULL, 0, 0, z);
@@ -1743,34 +1706,40 @@ static inline int compareNorms(int res[2], const mjtNum* v, int nv,
17431706

17441707

17451708
// return number of dimensions of a feature (1, 2 or 3)
1746-
static inline int simplexDim(const mjtNum v1[3], const mjtNum v2[3], const mjtNum v3[3]) {
1747-
int i = 1;
1748-
int same1 = equalexact3(v1, v2);
1749-
int same2 = equalexact3(v1, v3);
1750-
int same3 = equalexact3(v2, v3);
1751-
if (!same1) i++;
1752-
if (!same3 && !same2) i++;
1753-
return i;
1709+
static inline int simplexDim(int* v1, int* v2, int* v3) {
1710+
int val1 = *v1;
1711+
int val2 = *v2;
1712+
int val3 = *v3;
1713+
1714+
if (val1 != val2) {
1715+
return (val3 == val1 || val3 == val2) ? 2 : 3;
1716+
}
1717+
if (val1 != val3) {
1718+
*v2 = *v3;
1719+
return 2;
1720+
}
1721+
return 1;
17541722
}
17551723

17561724

17571725

1726+
17581727
// recover multiple contacts from EPA polytope
17591728
static void multicontact(Polytope* pt, Face* face, mjCCDStatus* status,
17601729
mjCCDObj* obj1, mjCCDObj* obj2) {
17611730
mjtNum face1[mjMAX_SIDES * 3], face2[mjMAX_SIDES * 3];
17621731

17631732
// get vertices of faces from EPA
1764-
const mjtNum* v11 = pt->verts[face->verts[0]].vert1;
1765-
const mjtNum* v12 = pt->verts[face->verts[1]].vert1;
1766-
const mjtNum* v13 = pt->verts[face->verts[2]].vert1;
1767-
const mjtNum* v21 = pt->verts[face->verts[0]].vert2;
1768-
const mjtNum* v22 = pt->verts[face->verts[1]].vert2;
1769-
const mjtNum* v23 = pt->verts[face->verts[2]].vert2;
1733+
int v11 = pt->verts[face->verts[0]].index1;
1734+
int v12 = pt->verts[face->verts[1]].index1;
1735+
int v13 = pt->verts[face->verts[2]].index1;
1736+
int v21 = pt->verts[face->verts[0]].index2;
1737+
int v22 = pt->verts[face->verts[1]].index2;
1738+
int v23 = pt->verts[face->verts[2]].index2;
17701739

17711740
// get dimensions of features of geoms 1 and 2
1772-
int nface1 = simplexDim(v11, v12, v13);
1773-
int nface2 = simplexDim(v21, v22, v23);
1741+
int nface1 = simplexDim(&v11, &v12, &v13);
1742+
int nface2 = simplexDim(&v21, &v22, &v23);
17741743
int nnorms1 = 0, nnorms2 = 0;
17751744
mjtNum n1[9], n2[9]; // normals of possible face collisions
17761745
int idx1[3], idx2[3]; // indices of faces, so they can be recovered later

0 commit comments

Comments
 (0)