newton.CollisionPipeline#
- class newton.CollisionPipeline(model, *, reduce_contacts=True, rigid_contact_max=None, max_triangle_pairs=1000000, shape_pairs_filtered=None, include_static_kinematic_pairs=True, soft_contact_max=None, soft_contact_gap=None, soft_contact_margin=None, enable_rigid_soft_full_surface_contact=False, requires_grad=None, broad_phase=None, narrow_phase=None, sdf_hydroelastic_config=None, shape_pairs_max=None, deterministic=False, contact_matching='disabled', contact_matching_pos_threshold=0.0005, contact_matching_normal_dot_threshold=0.995, contact_report=False, verify_buffers=True, contact_reduction_hashtable_size_factor=0.25, speculative_contact_gap_max=None)[source]#
Bases:
objectFull-featured collision pipeline with GJK/MPR narrow phase and pluggable broad phase.
- Key features:
GJK/MPR algorithms for convex-convex collision detection
Multiple broad phase options: NXN (all-pairs), SAP (sweep-and-prune), EXPLICIT (precomputed pairs)
Mesh-mesh collision via SDF with contact reduction
Optional hydroelastic contact model for compliant surfaces
For most users, construct with
CollisionPipeline(model, ...).Experimental
Differentiable rigid-contact kinematics computed by
newton.eval_rigid_contact_kinematics()may change without prior notice. The narrow phase stays frozen and gradients are a tangent approximation; validate accuracy and usefulness on your workflow before relying on them in optimization loops.- __init__(model, *, reduce_contacts=True, rigid_contact_max=None, max_triangle_pairs=1000000, shape_pairs_filtered=None, include_static_kinematic_pairs=True, soft_contact_max=None, soft_contact_gap=None, soft_contact_margin=None, enable_rigid_soft_full_surface_contact=False, requires_grad=None, broad_phase=None, narrow_phase=None, sdf_hydroelastic_config=None, shape_pairs_max=None, deterministic=False, contact_matching='disabled', contact_matching_pos_threshold=0.0005, contact_matching_normal_dot_threshold=0.995, contact_report=False, verify_buffers=True, contact_reduction_hashtable_size_factor=0.25, speculative_contact_gap_max=None)#
Initialize the CollisionPipeline (expert API).
- Parameters:
model (Model) – The simulation model.
reduce_contacts (bool) – Whether to reduce contacts for mesh-mesh collisions. Defaults to True.
rigid_contact_max (int | None) – Maximum number of rigid contacts to allocate. Resolution order: - If provided, use this value. - Else if
model.rigid_contact_max > 0, use the model value. - Else estimate automatically from model shape and pair metadata. The automatic estimate is a conservative heuristic that generally grows linearly with replicated worlds, but it is not a guaranteed worst-case bound. A warning reports automatic estimates whose base rigid-contact buffers require at least 256 MiB. Pass an explicit value to select the memory budget and silence the warning.max_triangle_pairs (int) – Maximum number of triangle pairs allocated by narrow phase for mesh and heightfield collisions. Increase this when scenes with large/complex meshes or heightfields report triangle-pair overflow warnings.
contact_reduction_hashtable_size_factor (float) – Multiplier applied to
max_triangle_pairswhen allocating the global contact reduction hashtable. Increase this if hashtable fill/failure warnings appear. Defaults to0.25for memory compatibility.soft_contact_max (int | None) – Maximum number of soft contacts to allocate. If None, defaults to
soft_contact_pair_count, the number of precomputed soft-rigid (particle-shape) pairs launched for soft contact generation, plus the full-surface edge/face headroom whenenable_rigid_soft_full_surface_contactis set.soft_contact_gap (float | None) – Detection-only distance [m] added to the per-particle radius for particle-shape (soft) contact queries. Defaults to 0.01.
soft_contact_margin (float | None) – Deprecated alias of
soft_contact_gap(the value is detection-only slack on top of the particle radius, i.e. a gap under the margin/gap convention).enable_rigid_soft_full_surface_contact (bool) – Generate soft contacts over the full soft-mesh surface – the edges and triangle interiors – against rigid SDFs, in addition to the per-vertex (particle) contacts. Catches rigid features that pass between soft vertices (e.g. a thin box edge through a coarse cloth cell), which the per-particle path misses. Requires an SDF on every participating rigid mesh/convex shape (provision via
ModelBuilder.ShapeConfig.configure_sdf(), e.g.configure_sdf(force_sdf=True)on the builder’sdefault_shape_cfg), and is consumed only bySolverVBD; other solvers raise on such contacts. Records are emitted intoContacts.soft_contact_indices. Defaults to False. Fixed at construction because it sizes the soft-contact buffer headroom.requires_grad (bool | None) – Whether pipeline-generated soft contacts and the deprecated automatic rigid-contact outputs require gradients. If None, uses
model.requires_grad. Explicit calls tonewton.eval_rigid_contact_kinematics()do not depend on this flag.broad_phase (Literal['nxn', 'sap', 'explicit'] | ~newton._src.geometry.broad_phase_nxn.BroadPhaseAllPairs | ~newton._src.geometry.broad_phase_sap.BroadPhaseSAP | ~newton._src.geometry.broad_phase_nxn.BroadPhaseExplicit | None) – Either a broad phase mode string (“explicit”, “nxn”, “sap”) or a prebuilt broad phase instance for expert usage.
narrow_phase (NarrowPhase | None) – Optional prebuilt narrow phase instance. Must be provided together with a broad phase instance for expert usage.
shape_pairs_filtered (wp.array[wp.vec2i] | None) – Precomputed shape pairs for EXPLICIT mode. When broad_phase is “explicit”, uses model.shape_contact_pairs if not provided. For “nxn”/”sap” modes, ignored. The pair count and shape-type routing are used to size and specialize internal buffers at construction, so do not modify or resize the array while the pipeline is in use. Rebuild the pipeline after changing the pairs.
include_static_kinematic_pairs (bool) – Whether to generate contacts for static-kinematic and kinematic-kinematic pairs. Set to
Falseto filter those pairs. Static-static pairs are always filtered. Defaults toTruefor backward compatibility.sdf_hydroelastic_config (Config | None) – Configuration for hydroelastic collision handling. Defaults to None.
shape_pairs_max (int | None) – Override for the broad-phase candidate-pair buffer capacity used by the
"nxn"and"sap"modes. Defaults to the worst-caseN*(N-1)/2per-world bound, which is rarely hit by either"nxn"or"sap"in practice –"nxn"still applies AABB overlap, group, and excluded-pair filtering insideBroadPhaseAllPairsbefore writing, and"sap"is sparse by design – so the default sizing is typically 10-100x larger than what gets emitted on real scenes. Set this to a tighter value (e.g. measured peak with ~25% headroom) to avoid multi-GB allocations on large scenes; a too-small value triggers a buffer overflow warning at runtime. Ignored for the"explicit"mode (which uses the filtered pair list length directly) and for expert paths that pass a pre-builtnarrow_phase.deterministic (bool) – Sort contacts after the narrow phase so that results are independent of GPU thread scheduling. This also enables deterministic hydroelastic accumulation and contact allocation. Adds a radix sort + gather pass.
contact_matching (Literal['disabled', 'latest', 'sticky']) –
Frame-to-frame contact matching mode. One of
"disabled","latest", or"sticky". Any non-disabled mode impliesdeterministic=Trueand populatesContacts.rigid_contact_match_index. Defaults to"disabled".Experimental
The
"sticky"mode may change without prior notice.contact_matching_pos_threshold (float) – World-space distance threshold [m] between the previous and current contact midpoints
0.5 * (world(point0) + world(point1)). Contacts whose midpoint moves more than this are considered broken. Defaults to0.0005.contact_matching_normal_dot_threshold (float) – Minimum dot product between old and new contact normals for a match.
contact_report (bool) – Allocate
rigid_contact_new_indices/rigid_contact_new_count/rigid_contact_broken_indices/rigid_contact_broken_counton theContactscontainer, populated each frame. Requires a non-disabledcontact_matchingmode.verify_buffers (bool) – Run a
dim=[1]diagnostic kernel at the end of the narrow phase that prints warnings on any intermediate candidate-pair or final rigid contact buffer overflow; seeNarrowPhasefor the full counter list. Defaults toTrue. Overhead is one extra kernel launch per collision pass; disable in hot loops or CUDA graph capture once buffer sizes are known to be adequate.speculative_contact_gap_max (float | None) – Cap on the velocity-derived rigid-contact detection gap [m]. The effective gap is the larger of the authored gap and the capped velocity-derived gap. Must be a non-negative finite number or
None.Nonedisables speculative contacts;0.0enables them without enlarging authored gaps. Defaults toNone. See Speculative contacts.
Experimental
Rigid-contact autodiff via
newton.eval_rigid_contact_kinematics()may change without prior notice; seecollide().
- collide(state, contacts, *, soft_contact_margin=None, soft_self_contact=False, dt=None)#
Run the collision pipeline using NarrowPhase.
Safe to call inside a
wp.Tapecontext. The non-differentiable broad-phase and narrow-phase kernels are launched with tape recording hardcodedrecord_tape=Falseinternally. The differentiable kernels (soft-contact generation and rigid-contact augmentation) are recorded on the tape so that gradients flow throughstate.body_qandstate.particle_q.For backward compatibility, when
requires_grad=Truethe deprecatedcontacts.rigid_contact_diff_*arrays are populated by a lightweight augmentation kernel. New code should callnewton.eval_rigid_contact_kinematics()explicitly after collision detection to reconstruct only the quantities it needs.Experimental
This rigid-contact gradient path may change without prior notice. Usefulness and numerical behaviour are still being assessed across real-world scenarios.
- Parameters:
state (newton.State) – The current simulation state.
contacts (Contacts) – The contacts buffer to populate (will be cleared first).
soft_contact_margin (float | None) – Deprecated; set
soft_contact_gapon theCollisionPipelineconstructor instead. When notNone, the value is still honored for this call and aDeprecationWarningis emitted.soft_self_contact (bool) – Also run soft (cloth) self-contact detection into
contacts.soft_self_contact_data. Requiresinit_soft_self_contact()to have been called. The self-contact BVHs are refitted tostate.particle_qbefore detection. Userefit_soft_self_contact_bvh()directly when an explicit full rebuild is needed.dt (float | None) – Collision-update horizon [s]. Required when speculative contacts are enabled.
0.0disables velocity adaptation for this call. Ignored when speculative contacts are disabled. See Speculative contacts.
- contacts()#
Allocate and return a new
newton.Contactsobject for this pipeline.The returned buffer uses this pipeline’s
requires_gradflag (resolved at construction from the argument ormodel.requires_grad).- Returns:
A newly allocated contacts buffer sized for this pipeline.
- Return type:
Experimental
If
requires_gradis true, deprecated rigid-contact distance and point compatibility arrays are allocated. New code should allocate only the outputs it needs and pass them tonewton.eval_rigid_contact_kinematics().
- init_soft_self_contact(*, margin=0.2, gap=0.0, rest_shape_exclusion_radius=0.0, vertex_buffer_pre_alloc=32, edge_buffer_pre_alloc=64, edge_edge_parallel_epsilon=1e-5, record_triangle_contacting_vertices=False, topological_filter_threshold=2, external_vertex_filter_map=None, external_edge_filter_map=None)#
Configure soft (cloth) self-contact detection on this pipeline.
After configuration,
contacts()allocates the self-contact result buffers (Contacts.soft_self_contact_data) on every returned buffer, andcollide()runs vertex-triangle and edge-edge detection into them when called withsoft_self_contact=True.This is the configuration entry point for standalone pipeline use; a solver that owns the pipeline calls this internally, seeded from its own self-contact parameters.
- Parameters:
margin (float) – Self-contact interaction distance [m] (surface offset at which force terms begin to act), consumed by solver force terms.
gap (float) – Additional detection-only distance [m]; detection queries use
margin + gap, mirroring theShapeConfig.margin/ShapeConfig.gapconvention.rest_shape_exclusion_radius (float) – Pairs closer than this distance [m] in the rest shape (
model.particle_q) are excluded from detection — for meshes whose regions are close by design (layered cloth, seams).0disables the filter.vertex_buffer_pre_alloc (int) – Per-vertex collision buffer capacity; pairs beyond it are silently dropped during detection.
edge_buffer_pre_alloc (int) – Per-edge collision buffer capacity; pairs beyond it are silently dropped during detection.
edge_edge_parallel_epsilon (float) – Near-parallel edge-pair threshold.
record_triangle_contacting_vertices (bool) – Also record per-triangle contacting vertices.
topological_filter_threshold (int) – Ring distance under which candidate pairs are filtered out.
external_vertex_filter_map (dict | None) – Extra vertex-triangle exclusions.
external_edge_filter_map (dict | None) – Extra edge-edge exclusions.
- refit_soft_self_contact_bvh(new_pos, *, rebuild=False)#
Refit (or fully rebuild) the soft self-contact BVHs to
new_pos.collide()automatically refits before self-contact detection. Call this method directly to update the trees without detecting, or passrebuild=Trueto rebuild them from scratch when repeated refitting has degraded their quality under large deformation.- Parameters:
new_pos (wp.array[wp.vec3f]) – Particle positions [m] to fit the BVHs to, e.g.
state.particle_q.rebuild (bool) – Rebuild the trees instead of refitting them.
- reset_contact_matching(world_mask=None)#
Clear all or reset-selected previous-frame contact history.
Masked selections accumulate until the next
collide()call consumes them.Experimental
Experimental feature. API, behavior, defaults, and supported use cases may change without prior notice.
- Parameters:
world_mask (wp.array[wp.bool] | None) – Optional one-dimensional Warp boolean mask on the model device with shape
(model.world_count + 1,). The final entry selects global entities whose world index is-1. IfNone, clear all previous-frame contact history immediately.
- set_collision_detection_range(*, soft_contact_gap=None, soft_self_contact_margin=None, soft_self_contact_gap=None)#
Update the detection ranges consumed by
collide().Only the values provided are changed;
Nonekeeps the current setting, and changes take effect at the nextcollide()call. Rigid (shape-shape) ranges are per-shape model data (Model.shape_margin,Model.shape_gap) and are not covered here. A solver that owns the pipeline drives self-contact detection from its own parameters, so this setter affects standalonecollide()use.- Parameters:
soft_contact_gap (float | None) – Detection-only distance [m] added to the per-particle radius for particle-shape contact queries.
soft_self_contact_margin (float | None) – Self-contact interaction distance [m]; requires
init_soft_self_contact()to have been called.soft_self_contact_gap (float | None) – Additional detection-only self-contact distance [m] (queries use
margin + gap); requiresinit_soft_self_contact()to have been called.
- property soft_contact_pair_count: int#
Number of precomputed (particle, shape) pairs launched for soft contacts.
This is the base of the default
soft_contact_max, which additionally reserves edge/face headroom whenenable_rigid_soft_full_surface_contactis set.
- property soft_rigid_contact_pair_count: int#
Deprecated alias of
soft_contact_pair_count.