Skip to content

Fix flex contact filtering compaction - #3495

Open
rootkiller6788 wants to merge 1 commit into
google-deepmind:mainfrom
rootkiller6788:fix-filter-flex-contacts-compaction
Open

Fix flex contact filtering compaction#3495
rootkiller6788 wants to merge 1 commit into
google-deepmind:mainfrom
rootkiller6788:fix-filter-flex-contacts-compaction

Conversation

@rootkiller6788

Copy link
Copy Markdown

Fixes #3297.

filterFlexContacts limits the number of contacts kept per flex collision pair using farthest-point sampling. The selection loop swapped contacts[best] into the kept prefix while the loop was still running, so the selected[] / min_dist[] bookkeeping (which is indexed by array position) no longer referred to the same logical contacts after the first swap. In practice this can re-select an already-picked contact (and skip a valid one), and because the swap was intentionally skipped for the final selected contact (when nselected == mjMAXCONPAIR - 1), the truncated prefix could contain a different, unselected contact instead.

This change keeps the selected contacts in a temporary buffer and compacts them into the contact prefix only after the selection loop finishes, so the first nselected contacts after filtering are exactly the contacts selected by farthest-point sampling.

Verification:

  • engine_collision_driver.c compiles cleanly (single-file gcc -c against the in-repo headers).
  • A standalone translation of the loop logic reproduces the discrepancy on the original code (the kept prefix differs from the selected set and contains duplicate selections) and shows the fixed logic keeps exactly the selected set.

The farthest-point sampling loop in filterFlexContacts swapped contacts in
place while the selection bookkeeping (selected[]/min_dist[]) was still
indexed against the pre-swap array. This corrupted the selection (re-selecting
already-picked contacts and skipping valid candidates) and, because the swap
was skipped for the final selected contact, left a wrong contact in the kept
prefix.

Collect the selected contacts in a temporary buffer and compact them into the
contact prefix only after the selection loop finishes, so the retained prefix
is exactly the set selected by farthest-point sampling.
@rootkiller6788
rootkiller6788 marked this pull request as ready for review August 24, 2026 03:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

filterFlexContacts can keep the wrong final contact after FPS compaction

1 participant