Fix missing contacts for deeply penetrating boxes.
When penetration exceeds a box's smallest half-size, the midpoint between the contact surfaces can land outside both boxes. The outside- box filter in mjc_BoxBox then removed every contact of the manifold, returning nothing for a visibly overlapping pair, letting boxes fall through each other. Fixes #1800. If the filter would remove all contacts, restore the penetrating ones. This is strictly additive: configurations where any contact survives the filter are unchanged. The removed midpoints are bitwise-identical to the witness midpoints computed by mj_geomDistance for these configurations, so the positions follow the engine-wide contact position convention; re-anchoring them onto a box surface would not. Fixes #1800 PiperOrigin-RevId: 957867315 Change-Id: Ia9c858661d4badeb2a832d25455e33402936011d
This commit is contained in:
committed by
Copybara-Service
parent
8655446f25
commit
fb07a9ca50
@@ -1389,6 +1389,7 @@ int mjc_BoxBox(const mjModel* m, mjData* d, mjPreContact* con, int g1, int g2, m
|
||||
const mjtNum* size2 = m->geom_size + 3 * g2;
|
||||
|
||||
// find bad: contacts outside one of the boxes
|
||||
int nbad = 0;
|
||||
for (int i=0; i < num; i++) {
|
||||
// box sizes with margin
|
||||
mjtNum sz1[3] = {size1[0] + margin, size1[1] + margin, size1[2] + margin};
|
||||
@@ -1404,6 +1405,18 @@ int mjc_BoxBox(const mjModel* m, mjData* d, mjPreContact* con, int g1, int g2, m
|
||||
// mark as bad if outside one box and not inside the other box
|
||||
if ((out1 == 1 && out2 != -1) || (out2 == 1 && out1 != -1)) {
|
||||
dupe[i] = -1;
|
||||
nbad++;
|
||||
}
|
||||
}
|
||||
|
||||
// deep penetration can strand the midpoint-convention position outside both boxes; if
|
||||
// that removed every contact, restore the penetrating ones: an empty manifold for
|
||||
// overlapping boxes lets them pass through each other
|
||||
if (nbad && nbad == num) {
|
||||
for (int i=0; i < num; i++) {
|
||||
if (tmp[i].dist < 0) {
|
||||
dupe[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user