Skip to content

Broad phase collision API#286

Merged
nvtw merged 9 commits into
newton-physics:mainfrom
nvtw:dev/tw/broad_phase_collision_api
Jul 11, 2025
Merged

Broad phase collision API#286
nvtw merged 9 commits into
newton-physics:mainfrom
nvtw:dev/tw/broad_phase_collision_api

Conversation

@nvtw

@nvtw nvtw commented Jun 27, 2025

Copy link
Copy Markdown
Member

Description

This PR adds three broad phase collision detection strategies:

  1. NxN Broad Phase: The brute force approach that checks all possible pairs for AABB overlaps. It's optimized with:

    • Lower triangular matrix to avoid duplicate checks
    • Support for collision groups and cutoffs
  2. Explicit Pairs Broad Phase:

    • Only tests specific pairs you give it
  3. SAP (Sweep and Prune):

    • Support for collision groups and cutoffs

Added unit tests with random boxes, collision groups, and cutoffs. Everything is validated against a numpy reference implementation. Debug output is there if you need it.

Before your PR is "Ready for review"

  • All commits are signed-off to indicate that your contribution adheres to the Developer Certificate of Origin requirements
  • I understand that GitHub does not perform any GPU testing of this pull request
  • Necessary tests have been added
  • Documentation is up-to-date
  • Code passes formatting and linting checks with pre-commit run -a

Summary by CodeRabbit

  • New Features

    • Introduced multiple broad phase collision detection algorithms, including All-Pairs, Explicit Pairs, and Sweep and Prune (SAP), for efficient geometry overlap testing.
    • Added support for collision group filtering and cutoff distances in overlap detection.
    • Provided GPU-accelerated implementations for improved performance.
  • Tests

    • Added comprehensive test suite to validate the correctness of all broad phase algorithms against reference results.

nvtw added 2 commits June 27, 2025 10:19
Signed-off-by: twidmer <twidmer@nvidia.com>
Signed-off-by: twidmer <twidmer@nvidia.com>
@nvtw nvtw requested review from eric-heiden and mmacklin June 27, 2025 08:46
Signed-off-by: twidmer <twidmer@nvidia.com>
@nvtw nvtw changed the title Draft: First draft of broad phase collision API Broad phase collision API Jun 30, 2025
@nvtw nvtw self-assigned this Jul 1, 2025
Comment thread newton/geometry/__init__.py Outdated
Comment thread newton/__init__.py Outdated
Comment thread newton/geometry/broad_phase_sap.py Outdated
Comment thread newton/geometry/broad_phase_blocks.py Outdated
Comment thread newton/geometry/broad_phase_nxn.py Outdated
Comment thread newton/geometry/broad_phase_sap.py Outdated
Comment thread newton/tests/test_broad_phase.py Outdated
Comment thread newton/geometry/broad_phase_blocks.py
@mmacklin

mmacklin commented Jul 4, 2025

Copy link
Copy Markdown
Member

Thanks Tobi, looks good! Just added a few cosmetic comments.

Signed-off-by: twidmer <twidmer@nvidia.com>
@nvtw nvtw force-pushed the dev/tw/broad_phase_collision_api branch from 9bb488a to 813b330 Compare July 7, 2025 06:39
@eric-heiden

Copy link
Copy Markdown
Member

I think you can remove the examples you are adding in this PR since MuJoCoSolver doesn't use this broadphase anyway and we have a test for example_rigid.py in test_rigid_contact.py.

Comment thread newton/geometry/broad_phase_nxn.py Outdated
@nvtw nvtw force-pushed the dev/tw/broad_phase_collision_api branch from 3b08fc5 to d39b1ab Compare July 9, 2025 15:27
Signed-off-by: twidmer <twidmer@nvidia.com>
@nvtw nvtw force-pushed the dev/tw/broad_phase_collision_api branch from d39b1ab to 295761c Compare July 9, 2025 15:31
Signed-off-by: twidmer <twidmer@nvidia.com>
@coderabbitai

coderabbitai Bot commented Jul 10, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The changes introduce a modular, GPU-accelerated broad phase collision detection system with three algorithms: all-pairs, explicit-pairs, and sweep-and-prune (SAP). Each algorithm is implemented in its own module with Warp device functions and kernels. The package's __init__.py is updated to expose the new classes, and a comprehensive test suite is added for validation.

Changes

File(s) Change Summary
newton/geometry/__init__.py Added imports and __all__ entries for BroadPhaseAllPairs, BroadPhaseExplicit, and BroadPhaseSAP.
newton/geometry/broad_phase_common.py Added utility Warp functions for AABB overlap checking, binary search, atomic pair writing, and collision group filtering.
newton/geometry/broad_phase_nxn.py Added BroadPhaseAllPairs and BroadPhaseExplicit classes with Warp kernels for all-pairs and explicit-pairs broad phase collision detection, plus helper functions.
newton/geometry/broad_phase_sap.py Implemented Sweep and Prune (SAP) broad phase algorithm with Warp kernels, device functions, and the BroadPhaseSAP class.
newton/tests/test_broad_phase.py Added unit tests for all three broad phase algorithms, including brute-force numpy reference checks and utility functions.

Sequence Diagram(s)

All-Pairs Broad Phase (BroadPhaseAllPairs)

sequenceDiagram
    participant Host
    participant BroadPhaseAllPairs
    participant WarpKernel

    Host->>BroadPhaseAllPairs: launch(geom data, ...)
    BroadPhaseAllPairs->>WarpKernel: Launch _nxn_broadphase_kernel
    loop For each unique pair (i, j)
        WarpKernel->>WarpKernel: Check collision group compatibility
        WarpKernel->>WarpKernel: Check AABB overlap with cutoffs
        alt Overlap and compatible
            WarpKernel->>WarpKernel: Atomically write pair to output
        end
    end
    WarpKernel-->>BroadPhaseAllPairs: Return candidate pairs
    BroadPhaseAllPairs-->>Host: Return results
Loading

Explicit-Pairs Broad Phase (BroadPhaseExplicit)

sequenceDiagram
    participant Host
    participant BroadPhaseExplicit
    participant WarpKernel

    Host->>BroadPhaseExplicit: launch(geom data, explicit pairs, ...)
    BroadPhaseExplicit->>WarpKernel: Launch _nxn_broadphase_precomputed_pairs
    loop For each explicit pair
        WarpKernel->>WarpKernel: Check AABB overlap with cutoffs
        alt Overlap
            WarpKernel->>WarpKernel: Atomically write pair to output
        end
    end
    WarpKernel-->>BroadPhaseExplicit: Return candidate pairs
    BroadPhaseExplicit-->>Host: Return results
Loading

Sweep and Prune Broad Phase (BroadPhaseSAP)

sequenceDiagram
    participant Host
    participant BroadPhaseSAP
    participant WarpKernels

    Host->>BroadPhaseSAP: launch(geom data, ...)
    BroadPhaseSAP->>WarpKernels: Flag group IDs, write unique IDs
    BroadPhaseSAP->>WarpKernels: Project AABBs onto sweep direction
    BroadPhaseSAP->>WarpKernels: Sort projections
    BroadPhaseSAP->>WarpKernels: Compute overlap ranges
    BroadPhaseSAP->>WarpKernels: Scan cumulative sums
    BroadPhaseSAP->>WarpKernels: Launch _sap_broadphase_kernel
    loop For each candidate pair
        WarpKernels->>WarpKernels: Filter by group, check AABB overlap
        alt Overlap and compatible
            WarpKernels->>WarpKernels: Atomically write pair to output
        end
    end
    WarpKernels-->>BroadPhaseSAP: Return candidate pairs
    BroadPhaseSAP-->>Host: Return results
Loading

📜 Recent review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f74270a and 6d93a3a.

📒 Files selected for processing (1)
  • newton/geometry/__init__.py (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • newton/geometry/init.py
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)
  • GitHub Check: run-asv-benchmarks
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
newton/geometry/broad_phase_sap.py (1)

363-366: Consider implementing adaptive sweep direction selection.

The fixed sweep direction works but could be suboptimal for certain object distributions. The TODO comment correctly identifies this optimization opportunity.

For better performance across different scenarios, consider:

  • Using principal component analysis (PCA) on the bounding box centers to find the direction of maximum variance
  • Caching and periodically updating the sweep direction based on object movement patterns
  • Allowing users to specify a custom sweep direction for domain-specific optimizations
📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 49215d2 and d409c0f.

📒 Files selected for processing (5)
  • newton/geometry/__init__.py (2 hunks)
  • newton/geometry/broad_phase_common.py (1 hunks)
  • newton/geometry/broad_phase_nxn.py (1 hunks)
  • newton/geometry/broad_phase_sap.py (1 hunks)
  • newton/tests/test_broad_phase.py (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
newton/tests/test_broad_phase.py (3)
newton/geometry/broad_phase_nxn.py (4)
  • BroadPhaseAllPairs (118-188)
  • BroadPhaseExplicit (191-251)
  • launch (137-188)
  • launch (205-251)
newton/geometry/broad_phase_sap.py (2)
  • BroadPhaseSAP (288-464)
  • launch (331-464)
newton/geometry/broad_phase_common.py (1)
  • test_group_pair (70-87)
newton/geometry/broad_phase_nxn.py (2)
newton/geometry/broad_phase_common.py (3)
  • check_aabb_overlap (22-38)
  • test_group_pair (70-87)
  • write_pair (54-65)
newton/geometry/broad_phase_sap.py (1)
  • launch (331-464)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)
  • GitHub Check: run-asv-benchmarks
🔇 Additional comments (5)
newton/geometry/__init__.py (1)

18-19: LGTM! Clean integration of the new broad phase classes.

The imports and public API exposure follow the existing patterns and use the consistent "BroadPhase" prefix as requested in previous reviews.

Also applies to: 98-100

newton/geometry/broad_phase_common.py (1)

22-87: Well-structured utility functions for broad phase operations.

The common functions are correctly implemented with proper thread safety (atomic operations) and clear collision group semantics. The AABB overlap check correctly handles cutoff distances, and the binary search provides an efficient utility for the SAP implementation.

newton/geometry/broad_phase_nxn.py (2)

55-75: Efficient lower triangular indexing implementation.

The mathematical approach to convert linear indices to triangular matrix coordinates is well-implemented with proper bounds checking. This avoids duplicate pair checks efficiently.


118-189: Well-documented BroadPhaseAllPairs implementation.

The class provides a clean API with comprehensive documentation explaining the collision detection logic, group filtering, and output format. The launch method correctly calculates the number of pairs and configures the kernel appropriately.

newton/geometry/broad_phase_sap.py (1)

22-44: Clever use of native code for sortable key generation.

The native C++ snippet efficiently converts floats to sortable integers while preserving order, which is crucial for the radix sort performance. The sort key construction properly combines collision groups with projected values.

Comment thread newton/tests/test_broad_phase.py Outdated
Signed-off-by: twidmer <twidmer@nvidia.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
newton/tests/test_broad_phase.py (3)

153-178: Consider refactoring duplicated verbose debugging code.

The verbose debugging section is duplicated across all three test methods with identical logic. This increases maintenance burden and violates the DRY principle.

Consider extracting the verbose debugging logic into a helper method:

+    def _print_verbose_debug(self, pairs_wp, num_candidate_pair, geom_bounding_box_lower, 
+                            geom_bounding_box_upper, np_geom_cutoff, np_collision_group=None):
+        """Helper method to print verbose debugging information for collision pairs."""
+        print("Warp contact pairs:")
+        for i in range(num_candidate_pair):
+            pair = pairs_wp[i]
+            body_a, body_b = pair[0], pair[1]
+            if np_collision_group is not None:
+                group_a = np_collision_group[body_a]
+                group_b = np_collision_group[body_b]
+                print(f"  Pair {i}: bodies ({body_a}, {body_b}) with collision groups ({group_a}, {group_b})")
+            else:
+                print(f"  Pair {i}: bodies ({body_a}, {body_b})")
+
+        print("Checking if bounding boxes actually overlap:")
+        for i in range(num_candidate_pair):
+            pair = pairs_wp[i]
+            body_a, body_b = pair[0], pair[1]
+            
+            # Get bounding boxes and cutoffs for both bodies
+            box_a_lower = geom_bounding_box_lower[body_a]
+            box_a_upper = geom_bounding_box_upper[body_a]
+            box_b_lower = geom_bounding_box_lower[body_b]
+            box_b_upper = geom_bounding_box_upper[body_b]
+            cutoff_a = np_geom_cutoff[body_a]
+            cutoff_b = np_geom_cutoff[body_b]
+            
+            overlap = check_aabb_overlap_host(
+                wp.vec3(box_a_lower[0], box_a_lower[1], box_a_lower[2]),
+                wp.vec3(box_a_upper[0], box_a_upper[1], box_a_upper[2]),
+                cutoff_a,
+                wp.vec3(box_b_lower[0], box_b_lower[1], box_b_lower[2]),
+                wp.vec3(box_b_upper[0], box_b_upper[1], box_b_upper[2]),
+                cutoff_b,
+            )
+            print(f"  Pair {i}: bodies ({body_a}, {body_b}) - overlap: {overlap}")

Then replace the verbose sections in each test with:

         if verbose:
-            print("Warp contact pairs:")
-            for i in range(num_candidate_pair):
-                # ... existing verbose code ...
+            self._print_verbose_debug(pairs_wp, num_candidate_pair, geom_bounding_box_lower, 
+                                    geom_bounding_box_upper, np_geom_cutoff, np_collision_group)

435-436: Remove commented debug code.

The commented debug print statements should be removed to keep the code clean.

-            # print("pairs_np:", pairs_np)
-            # print("pairs_wp[:num_candidate_pair]:", pairs_wp[:num_candidate_pair])

79-80: Consider using constants for magic numbers.

The repeated magic numbers (30 for ngeom, 5 for num_groups) could be extracted to class constants for better maintainability.

 class TestBroadPhase(unittest.TestCase):
+    NGEOM = 30
+    NUM_GROUPS = 5
+    
     def test_nxn_broadphase(self):
         verbose = False
         
         # Create random bounding boxes in min-max format
-        ngeom = 30
+        ngeom = self.NGEOM
         
         # ... later in the method ...
-        num_groups = 5  # The zero group does not need to be counted
+        num_groups = self.NUM_GROUPS  # The zero group does not need to be counted

Also applies to: 196-197, 324-325

📜 Review details

Configuration used: .coderabbit.yml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d409c0f and f74270a.

📒 Files selected for processing (1)
  • newton/tests/test_broad_phase.py (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-asv-benchmarks
  • GitHub Check: run-newton-tests / newton-unittests (windows-latest)
  • GitHub Check: run-newton-tests / newton-unittests (ubuntu-latest)
🔇 Additional comments (3)
newton/tests/test_broad_phase.py (3)

26-42: LGTM! Clean AABB overlap implementation.

The function correctly implements axis-aligned bounding box overlap detection with cutoff distance support. The logic properly handles the combined cutoff by taking the maximum of both cutoffs and applying it to expand the overlap check.


45-71: LGTM! Correct numpy reference implementation.

The brute-force algorithm correctly implements collision group filtering and AABB overlap detection. The lower triangular iteration pattern (i < j) efficiently avoids duplicate pair checks and self-collisions.


406-431: Confirmed: Indentation issue has been resolved.

The code block is now properly indented inside the for loop. The variables body_a and body_b are correctly defined within the loop scope before being used in the subsequent lines.

@nvtw nvtw merged commit af93df8 into newton-physics:main Jul 11, 2025
7 checks passed
@coderabbitai coderabbitai Bot mentioned this pull request Aug 14, 2025
5 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Oct 7, 2025
4 tasks
@coderabbitai coderabbitai Bot mentioned this pull request Nov 19, 2025
4 tasks
eric-heiden added a commit to eric-heiden/newton that referenced this pull request Jan 28, 2026
Signed-off-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
mmacklin pushed a commit to mmacklin/newton that referenced this pull request Apr 7, 2026
Signed-off-by: twidmer <twidmer@nvidia.com>
Co-authored-by: Eric Heiden <eheiden@nvidia.com>
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