From df59e7d0f16520247e0396be187c86a0e28614b9 Mon Sep 17 00:00:00 2001 From: Alessio Quaglino Date: Mon, 11 May 2026 02:44:50 -0700 Subject: [PATCH] Fix mj_makeConstraint error for flex trilinear vs trilinear contacts. The coordinates for flex interpolation are now computed using the absolute values of the vertex weights. The sign of the first vertex weight is then applied to the resulting barycentric weights. This correctly handles cases where the flex is both the first and the second entity in the contact pair. PiperOrigin-RevId: 913590928 Change-Id: I970b35fba3d209e13b5b33bb5f945e3c6a43d487 --- src/engine/engine_core_constraint.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/engine/engine_core_constraint.c b/src/engine/engine_core_constraint.c index b74f19b2..2f94818f 100644 --- a/src/engine/engine_core_constraint.c +++ b/src/engine/engine_core_constraint.c @@ -268,10 +268,13 @@ static int mj_vertBodyWeight(const mjModel* m, const mjData* d, int f, int* v, return 0; } - // compute parametric coordinates of the vertex in [0, 1]^3 + // determine sign: vweight may be negative for side-0 of a contact pair + mjtNum sign = vweight[0] < 0 ? -1 : 1; + + // compute parametric coordinates using absolute weights mjtNum coord[3] = {0, 0, 0}; for (int i = 0; i < nw; i++) { - mju_addToScl3(coord, m->flex_vert0 + 3*v[i], vweight[i]); + mju_addToScl3(coord, m->flex_vert0 + 3*v[i], mju_abs(vweight[i])); } int order = m->flex_interp[f]; @@ -292,7 +295,7 @@ static int mj_vertBodyWeight(const mjModel* m, const mjData* d, int f, int* v, if (w < 1e-5) { continue; } - if (bweight) bweight[nb] = w; + if (bweight) bweight[nb] = sign * w; body[nb++] = m->flex_nodebodyid[nstart + nodeindices[j]]; }