newton.CollisionPipeline#
- class newton.CollisionPipeline(model, *, reduce_contacts=True, body_pair_reduction=None, rigid_contact_max=None, max_triangle_pairs=None, 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, dynamic_shape_scale=False, publish_capacity=True)[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.- class BodyPairReductionConfig(*, cell_size=0.25, hashtable_size_factor=1.0, material_attributes=None)#
Bases:
objectConfigure body-pair contact reduction.
Bodies built from many colliders produce one manifold per shape pair. The narrow phase then reduces its primitive and convex contacts per group of
(body or static shape, other body or static shape, normal bin, spatial cell): each group keeps one depth representative, up to six sampled footprint extremes over all its contacts and up to six more over its touching contacts (canonical separation<= 0). Shapes on one body share a group only when theirshape_material_*values andmaterial_attributesmatch exactly. Selection is memoryless. Mesh and heightfield contacts keep the per-shape-pair reduction thatreduce_contactsselects.It is an approximation with scene-dependent support error and possible upward torsional-friction bias; validate tipping- and yaw-sensitive tasks. Only solvers with
supports_body_pair_reduced_contactsaccept the reduced buffers. Sticky contact matching and hydroelastic contacts are rejected at construction.Experimental
Experimental feature. API, behavior, defaults, and supported use cases may change without prior notice.
- __init__(*, cell_size=0.25, hashtable_size_factor=1.0, material_attributes=None)#
- cell_size: float = 0.25#
Spatial cell edge [m] that keeps separated same-normal patches of one body pair independently represented.
- hashtable_size_factor: float = 1.0#
Multiplier on the group-table capacity, which is derived from the model’s contact-pair topology rather than from
max_triangle_pairs. If the table is too small, the affected frames keep every primitive and convex contact, sorigid_contact_countstays near its unreduced value.
- __init__(model, *, reduce_contacts=True, body_pair_reduction=None, rigid_contact_max=None, max_triangle_pairs=None, 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, dynamic_shape_scale=False, publish_capacity=True)#
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.
body_pair_reduction (BodyPairReductionConfig | None) – Reduce contacts per body pair in the narrow phase.
None(default) disables it. SeeCollisionPipeline.BodyPairReductionConfig.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 is not None, use the model value (including zero). - 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. Withbody_pair_reduction, this sizes the reduced output. The raw primitive and convex contacts are staged in a buffer of the automatic estimate or this value, whichever is larger; contacts beyond it are dropped for that frame.max_triangle_pairs (int | None) – Maximum number of triangle pairs allocated by narrow phase for mesh and heightfield collisions; also the capacity of the global contact reducer shared by all worlds. Increase this when scenes with large/complex meshes or heightfields report triangle-pair or contact-reduction overflow warnings. If None (the default), estimate it from the model: each world budgets 128 candidates per candidate mesh, heightfield, or planar-SDF pair, limited in aggregate to 6 neighbors per participating shape, and the per-world budgets are summed. Explicit mode uses its configured pair list. NXN and SAP count pairs per world from shape masks, which can overcount, even when
model.shape_contact_pairshas already been built. The estimate never falls below 1,000,000 and warns when its buffers require at least 256 MiB. With deterministic contact reduction (deterministic=Trueor contact matching) it is limited to2**20 - 1and warns when that drops part of the estimate. It is a heuristic that assumes small contact patches, so dense meshes under convex shapes may still need an explicit value. Ignored whennarrow_phaseis provided.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. Full-surface mesh storage is estimated; dense patches may require a larger explicit capacity to avoid incomplete contacts on overflow.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 surfaces, in addition to the per-vertex (particle) contacts. Catches rigid features that pass between soft vertices (e.g. a thin box edge or heightfield cell inside a coarse cloth triangle), which the per-particle path misses. Meshes use exact feature contacts without requiring a volume SDF and report every vertex-face, face-vertex, and edge-edge pair within the contact band, including redundant representations of one surface patch, inactive soft features, and pairs with unresolved mesh sign. All rigid triangle edges participate, including edges omitted from SDF preprocessing. The consuming solver selects the pairs it applies forces to. Only meshes with
COLLIDE_PARTICLESset at construction get them, others keep per-particle contact. These full-surface contacts are 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. Fine meshes and large contact bands can generate many more records than particle-only contacts or SDF minimization, increasing contact storage and collision/solver time. Setsoft_contact_maxto size storage explicitly; this does not reduce the number of feature pairs queried. See Full-surface mesh contact costs.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. If its voxel-resolution table is omitted, use the model’s table. A supplied table must match the model’s shape count and device.
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. Limits the shape count; see Deterministic Contact Ordering.
contact_matching (Literal['disabled', 'latest', 'sticky']) –
Frame-to-frame contact matching mode. One of
"disabled","latest", or"sticky". Any non-disabled mode impliesdeterministic=True, including its shape-count limit, and 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. In sticky mode, instead compare each saved body-local witness, transformed by the current body pose, with its fresh contact point. The contact is broken if either witness moves farther than this distance. 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.dynamic_shape_scale (bool) – Query texture SDFs built without a baked scale with the current
Model.shape_scaleon every call, which is slower. Enable this when such a shape’s scale changes after construction. WhenFalseand every such shape has unit scale at construction, these queries are compiled for unit scale; routing a rescaled shape through mesh-SDF collision makes the device print a warning once and a latercollide()call outside graph capture raiseRuntimeError. Mesh-plane and mesh-convex contacts are unaffected. This option does not update derived collision bounds. After rescaling meshes, convex meshes, or heightfields, also updateModel.shape_collision_radius,Model.shape_collision_aabb_lower, andModel.shape_collision_aabb_upperto match the new scale, or broadphase culling can miss contacts. It does not rebuild baked SDFs or heightfield collision data. Recreate affected shapes at the new scale on aModelBuilder, then finalize a new model and construct a new collision pipeline. For explicitly prebuilt mesh SDFs, first rerunMesh.build_sdf()with the new scale. Ignored whennarrow_phaseis provided. Defaults toFalse.publish_capacity (bool) – Whether to publish the resolved capacities as the model’s default
rigid_contact_maxandsoft_contact_max. PassFalsefor a private pipeline, such as a solver’s internal one. Defaults toTrue.
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.
- refresh_body_pair_reduction_groups()#
Rebuild body-pair reduction groups from the model’s current shape materials.
Groups are built at construction. Call this outside CUDA graph capture after changing
shape_material_*or a grouped per-shape attribute. No-op when body-pair reduction is disabled.Experimental
Experimental feature. API, behavior, defaults, and supported use cases may change without prior notice.
- 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 body_pair_reduction: BodyPairReductionConfig | None#
Body-pair reduction configuration, fixed at construction, or
Nonewhen disabled.Experimental
Experimental feature. API, behavior, defaults, and supported use cases may change without prior notice.
- 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. With that flag, mesh and convex-mesh shapes are excluded here: their particle contacts come from the full-surface mesh pass.
- property soft_rigid_contact_pair_count: int#
Deprecated alias of
soft_contact_pair_count.