Skip to content

Fix mesh-convex margin candidate query#2916

Merged
adenzler-nvidia merged 2 commits into
newton-physics:mainfrom
adenzler-nvidia:adenzler/fix-mesh-convex-margin-shell
May 20, 2026
Merged

Fix mesh-convex margin candidate query#2916
adenzler-nvidia merged 2 commits into
newton-physics:mainfrom
adenzler-nvidia:adenzler/fix-mesh-convex-margin-shell

Conversation

@adenzler-nvidia

@adenzler-nvidia adenzler-nvidia commented May 20, 2026

Copy link
Copy Markdown
Member

Description

Fix mesh-vs-convex and heightfield-vs-convex midphase candidate generation to query candidates using the full margin + gap contact envelope, not just gap.

This keeps the mesh BVH query and heightfield grid-cell lookup consistent with broad-phase AABB expansion and final contact acceptance. Without this, valid margin-shell contacts can be culled before narrow phase processing.

Checklist

  • New or existing tests cover these changes
  • The documentation is up to date with these changes
  • CHANGELOG.md has been updated (if user-facing change)

Test plan

uv run --extra dev -m newton.tests -k Midphase
uv run --extra dev ruff check newton/_src/geometry/collision_core.py newton/_src/geometry/narrow_phase.py newton/_src/utils/heightfield.py newton/tests/test_collision_pipeline.py
git diff --check

Bug fix

Steps to reproduce:

  1. Create a mesh-vs-sphere or heightfield-vs-sphere scene with per-shape margin=0.02, gap=0.005.
  2. Place the sphere with true surface separation 0.03.
  3. Run the Newton collision pipeline.
  4. Without this PR, no contact is generated even though 0.03 <= margin_a + margin_b + gap_a + gap_b.

The heightfield regression covers the lateral edge case where grid-cell candidate lookup can cull the contact before narrow phase. Vertical margin-shell contacts above the heightfield already reached narrow phase because the grid lookup is driven by XY cell overlap.

Minimal reproduction:

# Covered by:
# uv run --extra dev -m newton.tests -k Midphase

Summary by CodeRabbit

  • Bug Fixes
    • Fixed missing mesh–convex and heightfield–convex contacts when shapes are separated by margin but still lie within the contact envelope; contact thresholds now include per-shape margin.
  • Tests
    • Added midphase tests verifying contacts are produced for mesh/heightfield vs convex cases when margins/gaps match.

Review Change Stack

Use the full margin plus gap contact envelope when querying mesh triangle candidates for convex contacts. This keeps the mesh midphase consistent with broad phase expansion and final contact acceptance, preventing valid margin-shell contacts from being culled before narrow phase processing.

Add a CUDA regression test where a sphere is separated from a mesh by more than gap but less than margin plus gap.
@coderabbitai

coderabbitai Bot commented May 20, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

Run ID: 9ffe0099-b96e-4317-a91d-b3437c042f18

📥 Commits

Reviewing files that changed from the base of the PR and between c56385b and f38a747.

📒 Files selected for processing (4)
  • CHANGELOG.md
  • newton/_src/geometry/narrow_phase.py
  • newton/_src/utils/heightfield.py
  • newton/tests/test_collision_pipeline.py

📝 Walkthrough

Walkthrough

This PR unifies gap and per-shape margins into a single contact_threshold used by mesh- and heightfield-midphase queries; the midphase API and BVH preprocessing were updated, narrow-phase triangle culling supplies the combined threshold, and tests plus a changelog entry were added.

Changes

Mesh–Convex Margin-Shell Contact Generation

Layer / File(s) Summary
Core midphase API: contact_threshold parameter and BVH logic
newton/_src/geometry/collision_core.py
mesh_vs_convex_midphase signature changed to accept contact_threshold (replacing rigid_gap); docstring and BVH query preprocessing now compute per-axis margin vectors from the combined threshold, accounting for non-uniform mesh scale.
Triangle overlap culling: gap + per-shape margins threshold
newton/_src/geometry/narrow_phase.py
narrow-phase kernel computes contact_threshold = gap_non_mesh + gap_mesh + margin_non_mesh + margin_mesh (margins from shape_data[...,3]) and passes it to mesh_vs_convex_midphase; heightfield midphase calls now include shape_data.
Heightfield midphase: accept shape_data and inflate AABB by margin
newton/_src/utils/heightfield.py
heightfield_vs_convex_midphase signature updated to accept shape_data; midphase AABB inflation uses contact_threshold = gap_sum + margin_sum with per-shape margins from shape_data.
Tests and module imports for margin-shell validation
newton/tests/test_collision_pipeline.py
Module-level imports added for create_mesh_terrain and ShapeFlags. New CUDA tests TestMeshConvexMidphase and TestHeightfieldConvexMidphase assert rigid contacts occur when shapes are separated by margin but within the contact envelope; tests registered for CUDA devices.
Fix documentation in changelog
CHANGELOG.md
Unreleased “Fixed” entry added documenting the mesh–convex and heightfield–convex contact fix.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • newton-physics/newton#2745: Both PRs modify mesh_vs_convex_midphase in newton/_src/geometry/collision_core.pyFix bug with nonuniform scaling in mesh vs convex collisions #2745 changes the BVH AABB query to unscaled mesh-local space and introduces per-axis gap/margin handling, while the main PR reworks the threshold plumbing (rigid_gapcontact_threshold) and uses it to compute the same kind of anisotropic per-axis contact expansion.
  • newton-physics/newton#2527: Main PR updates mesh_vs_convex_midphase’s threshold semantics/signature and how per-axis margins are folded into contact_threshold, while retrieved PR also modifies mesh_vs_convex_midphase’s internal tiled BVH triangle query draining loop control flow—so both change the same midphase function at the code level.
  • newton-physics/newton#2651: Both PRs modify the heightfield-vs-convex midphase pipeline—newton/_src/utils/heightfield.py::heightfield_vs_convex_midphase and its narrow_phase.py call sites—by changing midphase culling/overlap threshold inputs (one via convex-local AABB, the other by adding per-shape margin-based contact_threshold/shape_data).

Suggested reviewers

  • eric-heiden
  • Milad-Rakhsha-NV
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 71.43% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly and clearly summarizes the main change: fixing the mesh-convex margin candidate query by incorporating margin into the midphase BVH query.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@adenzler-nvidia adenzler-nvidia requested a review from nvtw May 20, 2026 12:05
@codecov

codecov Bot commented May 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

📢 Thoughts on this report? Let us know!

@nvtw

nvtw commented May 20, 2026

Copy link
Copy Markdown
Member

I think the bugfix is correct. But can you double check - it's very likely that the heightfield code has the same problem.

Use the full margin plus gap contact envelope when querying heightfield cells for convex contacts. This keeps heightfield midphase candidate generation consistent with broad phase expansion and final contact acceptance.

Add a CUDA regression covering a sphere just outside a heightfield lateral edge, where the surface separation is larger than gap but still inside the margin shell.
@adenzler-nvidia adenzler-nvidia enabled auto-merge May 20, 2026 15:27
@adenzler-nvidia adenzler-nvidia added this pull request to the merge queue May 20, 2026
Merged via the queue into newton-physics:main with commit bf9a8f1 May 20, 2026
25 checks passed
@jcarius-nv jcarius-nv added this to the 1.2.1 Patch Release milestone May 21, 2026
jkuzmeski pushed a commit to jkuzmeski/newton that referenced this pull request Jun 2, 2026
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.

3 participants