newton.geometry.NarrowPhase#

class newton.geometry.NarrowPhase(*, max_candidate_pairs, max_triangle_pairs=1000000, max_mesh_mesh_pairs=None, max_mesh_plane_pairs=None, reduce_contacts=True, device=None, shape_aabb_lower=None, shape_aabb_upper=None, shape_voxel_resolution=None, contact_writer_warp_func=None, hydroelastic_sdf=None, has_meshes=True, has_heightfields=False, use_lean_gjk_mpr=False, convex_support_acceleration=True, has_generic_convex_pairs=True, sparse_gjk_pairs=None, split_gjk_mpr=False, candidate_pair_work_estimate=None, mesh_sdf_texture_only=False, mesh_sdf_identity_scale_only=False, sdf_texture_paired_samples=True, deterministic=False, contact_max=None, verify_buffers=True, contact_reduction_hashtable_size_factor=0.25, speculative=False, contact_writer_supports_speculative=False, _group_reduction=None)[source]#

Bases: object

Resolve broad-phase shape pairs into simulation contacts.

This class orchestrates the narrow-phase collision pipeline by launching the appropriate Warp kernels for primitive, mesh, heightfield, and SDF shape pairs. It owns the intermediate counters and pair buffers used while processing candidate pairs, then writes final contacts through a configurable contact writer function.

__init__(*, max_candidate_pairs, max_triangle_pairs=1000000, max_mesh_mesh_pairs=None, max_mesh_plane_pairs=None, reduce_contacts=True, device=None, shape_aabb_lower=None, shape_aabb_upper=None, shape_voxel_resolution=None, contact_writer_warp_func=None, hydroelastic_sdf=None, has_meshes=True, has_heightfields=False, use_lean_gjk_mpr=False, convex_support_acceleration=True, has_generic_convex_pairs=True, sparse_gjk_pairs=None, split_gjk_mpr=False, candidate_pair_work_estimate=None, mesh_sdf_texture_only=False, mesh_sdf_identity_scale_only=False, sdf_texture_paired_samples=True, deterministic=False, contact_max=None, verify_buffers=True, contact_reduction_hashtable_size_factor=0.25, speculative=False, contact_writer_supports_speculative=False, _group_reduction=None)#

Initialize NarrowPhase with pre-allocated buffers.

Parameters:
  • max_candidate_pairs (int) – Maximum number of candidate pairs from broad phase

  • max_triangle_pairs (int) – Maximum number of triangle pairs for mesh and heightfield collisions (conservative estimate).

  • max_mesh_mesh_pairs (int | None) – Maximum number of routed mesh-SDF pairs. Defaults to max_candidate_pairs.

  • max_mesh_plane_pairs (int | None) – Maximum number of routed mesh-plane pairs. Defaults to max_candidate_pairs.

  • reduce_contacts (bool) – Whether to reduce contacts for mesh-mesh and mesh-plane collisions. When True, uses shared memory contact reduction to select representative contacts. This improves performance and stability for meshes with many vertices. Defaults to True.

  • device (Device | str | None) – Device to allocate buffers on

  • shape_aabb_lower (wp.array[wp.vec3f] | None) – Optional external AABB lower bounds array (if provided, AABBs won’t be computed internally)

  • shape_aabb_upper (wp.array[wp.vec3f] | None) – Optional external AABB upper bounds array (if provided, AABBs won’t be computed internally)

  • shape_voxel_resolution (wp.array[wp.vec3i] | None) – Optional per-shape voxel resolution array used for mesh/SDF and hydroelastic contact processing. When omitted, CollisionPipeline supplies the model’s table. A supplied table must match that model’s shape count and device.

  • contact_writer_warp_func (Any | None) – Optional custom contact writer function (first arg: ContactData, second arg: custom struct type)

  • hydroelastic_sdf (HydroelasticSDF | None) – Optional SDF hydroelastic instance. Set is_hydroelastic=True on shapes to enable hydroelastic collisions.

  • has_meshes (bool) – Whether the scene contains any mesh shapes (GeoType.MESH). When False, mesh-related kernel launches are skipped, improving performance for scenes with only primitive shapes. Defaults to True for safety. Set to False when constructing from a model with no meshes.

  • has_heightfields (bool) – Whether the scene contains any heightfield shapes (GeoType.HFIELD). When True, heightfield collision buffers and kernels are allocated. Defaults to False.

  • convex_support_acceleration (bool) – Whether the model contains cooked directional support data for at least one convex mesh. When False, retain the original exhaustive support map without acceleration metadata loads. Defaults to True for custom launch compatibility.

  • has_generic_convex_pairs (bool) – Whether any candidate pair can require generic GJK/MPR processing. Set to False only from a complete scene-topology proof; this omits the GJK/MPR launch entirely.

  • sparse_gjk_pairs (bool | None) – Whether GJK routing preserves broad-phase pair indices instead of compacting its work buffer. Defaults to automatic enablement for large CUDA candidate buffers.

  • split_gjk_mpr (bool) – Whether to split generic convex collision into MPR, GJK, and manifold kernels. Ignored on CPU and when generic convex processing is unnecessary.

  • candidate_pair_work_estimate (int | None) – Static upper bound on pairs that the broad phase can emit. Defaults to max_candidate_pairs.

  • mesh_sdf_texture_only (bool) – Whether every participating mesh SDF has a texture representation, allowing BVH fallback branches to be removed from mesh/SDF kernels.

  • mesh_sdf_identity_scale_only (bool) – Whether every participating texture SDF is queried with identity scale, allowing scale conversion branches to be removed. Shapes whose SDF has no baked scale must then keep unit shape_scale.

  • sdf_texture_paired_samples (bool) – Whether texture SDFs store adjacent x samples together. This is model-wide so mesh-SDF kernels require only two bounded static variants.

  • deterministic (bool) – Make contact generation and ordering independent of GPU thread scheduling. Adds deterministic hydroelastic atomics and a radix sort + gather pass. Limits the shape count; see Deterministic Contact Ordering.

  • contact_max (int | None) – Maximum number of contacts for the deterministic sort buffer. Must match the contact_pair array size passed to launch(). Defaults to max_candidate_pairs. Set this to a larger value when a single candidate pair can emit multiple contacts (e.g. up to 4 for primitive multi-contact paths).

  • verify_buffers (bool) – When True (the default), launch a dim=[1] diagnostic kernel (verify_narrow_phase_buffers()) at the end of launch() that compares each public counter on this class (gjk_candidate_pairs_count, split_gjk_work_count, split_manifold_work_count, shape_pairs_mesh_count, triangle_pairs_count, shape_pairs_mesh_plane_count, shape_pairs_mesh_mesh_count, shape_pairs_sdf_sdf_count) and the output contact_count against the capacity of its backing array, and checks the global contact reducer hashtable fill/failure counters when reduction is enabled, printing wp.printf warnings on overflow or critical hashtable load. Users who want a programmatic overflow hook can disable this and read those counters themselves. Overhead is one extra kernel launch per collision pass (roughly a few µs of launch latency on CUDA; the kernel body is a handful of scalar comparisons on one thread). Disable in hot loops or CUDA graph capture once buffer sizes are known to be adequate.

  • contact_reduction_hashtable_size_factor (float) – Multiplier applied to max_triangle_pairs when allocating the global contact reduction hashtable. Increase this if hashtable fill/failure warnings appear. Defaults to 0.25 for memory compatibility.

  • speculative (bool) – Whether the caller provides velocity-expanded search gaps and exact speculative-contact data. Defaults to False.

  • contact_writer_supports_speculative (bool) – Whether a custom contact writer performs exact speculative-contact admission. Required when speculative and contact_writer_warp_func are both provided.

launch(*, candidate_pair, candidate_pair_count, shape_types, shape_data, shape_transform, shape_source, shape_support_data=None, support_lut=None, support_vertex_offsets=None, support_neighbors=None, shape_mesh_properties=None, mesh_boundary_flags=None, shape_mesh_boundary_start=None, shape_sdf_index=None, texture_sdf_data=None, shape_gap, shape_base_gap=None, shape_collision_radius, shape_flags, shape_collision_aabb_lower=None, shape_collision_aabb_upper=None, shape_voxel_resolution, shape_interior_point=None, contact_pair, contact_position, contact_normal, contact_penetration, contact_count, contact_tangent=None, shape_linear_velocity=None, shape_angular_velocity=None, collision_update_dt=0.0, max_speculative_extension=0.0, device=None, **kwargs)#

Launch narrow phase collision detection on candidate pairs from broad phase.

Parameters:
  • candidate_pair (wp.array[wp.vec2i]) – Array of potentially colliding shape pairs from broad phase

  • candidate_pair_count (wp.array[wp.int32]) – Single-element array containing the number of candidate pairs

  • shape_types (wp.array[wp.int32]) – Array of geometry types for all shapes

  • shape_data (wp.array[wp.vec4f]) – Array of vec4 containing scale (xyz) and margin (w) for each shape

  • shape_transform (wp.array[wp.transformf]) – Array of world-space transforms for each shape

  • shape_source (wp.array[wp.uint64]) – Array of source pointers (mesh IDs, etc.) for each shape

  • shape_support_data (wp.array[wp.vec4i] | None) – Optional per-shape wp.vec4i metadata containing packed support-LUT, vertex-offset, and support_neighbors block starts plus the LUT resolution. The block start is also set for verified hulls without acceleration. The final entry packs resolution in its low 16 bits and strict hull validity in bit 16. Zero resolution disables acceleration.

  • support_lut (wp.array[wp.int32] | None) – Optional packed octahedral-direction lookup tables whose entries select seed vertices for convex support walks.

  • support_vertex_offsets (wp.array[wp.int32] | None) – Optional packed CSR offsets delimiting each convex vertex’s entries in support_neighbors. They index past the hull’s edge records.

  • support_neighbors (wp.array[wp.int32] | None) – Optional packed per-hull blocks. A verified hull’s block starts with its edge count and one (a, b, c1, c2) vertex record per edge, whose faces cross(b - a, c1 - a) and cross(c2 - a, b - a) point outward; exact box-hull depth certificates read these records. CSR vertex-adjacency indices for support walks follow. Without the edge records, box-hull depths fall back to uncertified support-plane bounds.

  • shape_mesh_properties (wp.array[wp.int32] | None) – Per-shape mesh property bitfield.

  • mesh_boundary_flags (wp.array[wp.uint8] | None) – Optional packed per-face bits marking open-boundary edges and vertices of meshes queried with pseudo-normal signs.

  • shape_mesh_boundary_start (wp.array[wp.int32] | None) – Optional per-shape offset into mesh_boundary_flags, or -1 for shapes without boundary bits. Without both arrays, pseudo-normal signs extend past open boundaries.

  • shape_sdf_index (wp.array[wp.int32] | None) – Per-shape SDF table index (-1 for shapes without SDF)

  • texture_sdf_data (wp.array[TextureSDFData] | None) – Compact array of TextureSDFData structs

  • shape_gap (wp.array[wp.float32]) – Array of per-shape contact gaps (detection threshold) for each shape

  • shape_base_gap (wp.array[wp.float32] | None) – Authored per-shape contact gaps. Required when this narrow phase was constructed with speculative=True.

  • shape_collision_radius (wp.array[wp.float32]) – Array of collision radii for each shape (for AABB fallback for planes/meshes)

  • shape_collision_aabb_lower (wp.array[wp.vec3f] | None) – Local-space AABB lower bounds for each shape (for voxel binning)

  • shape_collision_aabb_upper (wp.array[wp.vec3f] | None) – Local-space AABB upper bounds for each shape (for voxel binning)

  • shape_voxel_resolution (wp.array[wp.vec3i]) – Voxel grid resolution for each shape (for voxel binning)

  • shape_interior_point (wp.array[wp.vec3f] | None) – Optional scaled local-space point inside each shape [m], used to cull back-facing mesh triangles and seed triangle contacts. If None, convex-mesh volume centroids are computed on each launch.

  • mesh_edge_indices – Packed mesh edge vertex pairs, passed through kwargs. Required with shape_edge_range for mesh edge contacts; omitting either disables mesh edge contacts.

  • shape_edge_range – Per-shape (start, count) into mesh_edge_indices, passed through kwargs.

  • mesh_edge_centers – Optional packed unscaled edge centers (xyz) and half-lengths (w) [m], passed through kwargs. Omit with mesh_edge_halves to read endpoints from meshes using the supplied indices and ranges.

  • mesh_edge_halves – Optional packed unscaled edge half-vectors (xyz) [m] and endpoint-ownership codes (w), passed through kwargs. Zero allows both endpoints.

  • contact_pair (wp.array[wp.vec2i]) – Output array for contact shape pairs

  • contact_position (wp.array[wp.vec3f]) – Output array for contact positions (center point)

  • contact_normal (wp.array[wp.vec3f]) – Output array for contact normals

  • contact_penetration (wp.array[wp.float32]) – Output array for penetration depths

  • contact_tangent (wp.array[wp.vec3f] | None) – Output array for contact tangents, or None to disable tangent computation

  • contact_count (wp.array[wp.int32]) – Output array (single element) for contact count

  • shape_linear_velocity (wp.array[wp.vec3f] | None) – World-space shape-origin linear velocity [m/s].

  • shape_angular_velocity (wp.array[wp.vec3f] | None) – World-space shape angular velocity [rad/s].

  • collision_update_dt (float) – Speculative collision horizon [s].

  • max_speculative_extension (float) – Maximum speculative clearance [m].

  • device (Device | str | None) – Device to launch on

launch_custom_write(*, candidate_pair, candidate_pair_count, shape_types, shape_data, shape_transform, shape_source, shape_support_data=None, support_lut=None, support_vertex_offsets=None, support_neighbors=None, shape_mesh_properties=None, mesh_boundary_flags=None, shape_mesh_boundary_start=None, shape_sdf_index, shape_gap, shape_base_gap=None, shape_collision_radius, shape_flags, shape_collision_aabb_lower, shape_collision_aabb_upper, shape_voxel_resolution, shape_interior_point=None, texture_sdf_data=None, shape_heightfield_index=None, heightfield_data=None, heightfield_elevations=None, mesh_edge_indices=None, mesh_edge_centers=None, mesh_edge_halves=None, shape_edge_range=None, hydroelastic_shape_sdf_data_prepared=False, shape_linear_velocity=None, shape_angular_velocity=None, collision_update_dt=0.0, max_speculative_extension=0.0, body_q=None, shape_body=None, writer_data, device=None)#

Launch narrow phase collision detection with a custom contact writer struct.

All internal kernel launches use record_tape=False so that calls are safe inside a warp.Tape context.

Parameters:
  • candidate_pair (wp.array[wp.vec2i]) – Array of potentially colliding shape pairs from broad phase

  • candidate_pair_count (wp.array[wp.int32]) – Single-element array containing the number of candidate pairs

  • shape_types (wp.array[wp.int32]) – Array of geometry types for all shapes

  • shape_data (wp.array[wp.vec4f]) – Array of vec4 containing scale (xyz) and margin (w) for each shape

  • shape_transform (wp.array[wp.transformf]) – Array of world-space transforms for each shape

  • shape_source (wp.array[wp.uint64]) – Array of source pointers (mesh IDs, etc.) for each shape

  • shape_support_data (wp.array[wp.vec4i] | None) – Optional per-shape wp.vec4i metadata containing packed support-LUT, vertex-offset, and support_neighbors block starts plus the LUT resolution. The block start is also set for verified hulls without acceleration. The final entry packs resolution in its low 16 bits and strict hull validity in bit 16. Zero resolution disables acceleration.

  • support_lut (wp.array[wp.int32] | None) – Optional packed octahedral-direction lookup tables whose entries select seed vertices for convex support walks.

  • support_vertex_offsets (wp.array[wp.int32] | None) – Optional packed CSR offsets delimiting each convex vertex’s entries in support_neighbors. They index past the hull’s edge records.

  • support_neighbors (wp.array[wp.int32] | None) – Optional packed per-hull blocks. A verified hull’s block starts with its edge count and one (a, b, c1, c2) vertex record per edge, whose faces cross(b - a, c1 - a) and cross(c2 - a, b - a) point outward; exact box-hull depth certificates read these records. CSR vertex-adjacency indices for support walks follow. Without the edge records, box-hull depths fall back to uncertified support-plane bounds.

  • shape_mesh_properties (wp.array[wp.int32] | None) – Per-shape mesh property bitfield.

  • mesh_boundary_flags (wp.array[wp.uint8] | None) – Optional packed per-face bits marking open-boundary edges and vertices of meshes queried with pseudo-normal signs.

  • shape_mesh_boundary_start (wp.array[wp.int32] | None) – Optional per-shape offset into mesh_boundary_flags, or -1 for shapes without boundary bits. Without both arrays, pseudo-normal signs extend past open boundaries.

  • shape_sdf_index (wp.array[wp.int32]) – Per-shape SDF table index (-1 for shapes without SDF)

  • texture_sdf_data (wp.array[TextureSDFData] | None) – Compact array of TextureSDFData structs

  • shape_gap (wp.array[wp.float32]) – Array of per-shape contact gaps (detection threshold) for each shape

  • shape_base_gap (wp.array[wp.float32] | None) – Array of authored per-shape contact gaps used for exact admission and regular SDF reduction lanes.

  • shape_collision_radius (wp.array[wp.float32]) – Array of collision radii for each shape (for AABB fallback for planes/meshes)

  • shape_flags (wp.array[wp.int32]) – Array of shape flags for each shape (includes ShapeFlags.HYDROELASTIC)

  • shape_collision_aabb_lower (wp.array[wp.vec3f]) – Local-space AABB lower bounds for each shape (for voxel binning)

  • shape_collision_aabb_upper (wp.array[wp.vec3f]) – Local-space AABB upper bounds for each shape (for voxel binning)

  • shape_voxel_resolution (wp.array[wp.vec3i]) – Voxel grid resolution for each shape (for voxel binning)

  • shape_interior_point (wp.array[wp.vec3f] | None) – Optional scaled local-space point inside each shape [m], used to cull back-facing mesh triangles and seed triangle contacts. If None, convex-mesh volume centroids are computed on each launch.

  • mesh_edge_indices (wp.array[wp.vec2i] | None) – Packed array of mesh edge vertex pairs for all shapes. Required with shape_edge_range for mesh edge contacts; omitting these arrays disables mesh edge contacts rather than extracting edges from meshes.

  • mesh_edge_centers (wp.array[wp.vec4f] | None) – Packed precomputed mesh edge centers (xyz) and radii (w) in unscaled mesh coordinates [m]; the shape scale in shape_data is applied when read. Each radius is the length of the corresponding unscaled half-vector.

  • mesh_edge_halves (wp.array[wp.vec4f] | None) – Packed precomputed mesh edge half-vectors (xyz) in unscaled mesh coordinates [m] and endpoint-ownership codes (w). Set the ownership code to zero to allow both endpoints.

  • shape_edge_range (wp.array[wp.vec2i] | None) – Per-shape (start, count) into mesh_edge_indices. Required with mesh_edge_indices for mesh edge contacts.

  • hydroelastic_shape_sdf_data_prepared (bool) – Whether finalized hydroelastic SDF descriptors were cached upstream.

  • shape_linear_velocity (wp.array[wp.vec3f] | None) – Shape-origin linear velocities [m/s]. Required in speculative mode.

  • shape_angular_velocity (wp.array[wp.vec3f] | None) – Shape angular velocities [rad/s]. Required in speculative mode.

  • collision_update_dt (float) – Collision prediction horizon [s].

  • max_speculative_extension (float) – Maximum speculative clearance [m].

  • body_q (wp.array[wp.transformf] | None) – Body poses, required with group reduction (cells are measured from a body).

  • shape_body (wp.array[wp.int32] | None) – Per-shape body index, required with group reduction.

  • writer_data (Any) – Custom struct instance for contact writing (type must match the custom writer function)

  • device (Device | str | None) – Device to launch on

split_gjk_work_count#

Distance-query and overlap-refinement counts, shape [2], or None when unsplit.

Entry 0 counts distance queries; entry 1 counts overlap refinements. Their sum is the shared queue occupancy. Both reset on each collision pass.