novaphy.Contacts¶
Device-resident structure-of-arrays contact aggregate produced by
CollisionPipeline / Model.collide and
consumed by solvers.
Allocate through a pipeline when you need contacts sized for collision:
pipeline = novaphy.CollisionPipeline(model, broad_phase="sap")
contacts = pipeline.contacts()
pipeline.collide(state, contacts)
solver.step(state, state, control, contacts, dt)
model.contacts() also returns an empty aggregate, but does not run collision
or pre-size buffers by itself.
Constructor¶
The constructor can preallocate CPU rigid and soft-contact channels directly.
Both capacities must be non-negative. For normal model-bound collision, prefer
CollisionPipeline.contacts() so capacities and optional columns match the
pipeline.
Counts and Capacity¶
| Field / Method | Description |
|---|---|
contact_counters |
Two-slot counter array: rigid count, soft-point count. |
contact_generation |
Single-slot generation counter bumped by clear() unless disabled. |
rigid_contact_max |
Allocated rigid contact capacity. |
soft_contact_max |
Allocated soft-point contact capacity. |
device |
Device that owns the bulk contact arrays. |
per_contact_shape_properties |
Whether optional stiffness/damping/friction arrays are allocated. |
contact_matching |
Whether frame-to-frame match indices are allocated. |
contact_report |
Whether new/broken contact report arrays are allocated. |
rigid_contact_count |
Single-element list containing rigid_count(). |
soft_contact_count |
Single-element list containing soft_count(). |
rigid_count() |
Number of active rigid contacts. |
soft_count() |
Number of active soft-point contacts. |
empty() |
True when both active counts are zero. |
__len__() |
rigid_count() + soft_count(). |
Rigid Contact Columns¶
Rigid contacts are exposed as parallel arrays. Active entries occupy
0:contacts.rigid_count().
| Field | Description |
|---|---|
rigid_contact_point_id |
Contact feature / persistence id. |
rigid_contact_shape0, rigid_contact_shape1 |
Shape indices for the two sides. |
rigid_contact_body0, rigid_contact_body1 |
Resolved body indices; -1 denotes world. |
rigid_contact_point0, rigid_contact_point1 |
Body-frame contact anchors on each side. |
rigid_contact_position |
World-space midpoint used by row solvers. |
rigid_contact_offset0, rigid_contact_offset1 |
Body-frame finite-thickness offsets. |
rigid_contact_normal |
World normal from side 0 toward side 1. |
rigid_contact_margin0, rigid_contact_margin1 |
Effective margin / radius per side. |
rigid_contact_penetration |
Solver-facing penetration depth. |
rigid_contact_restitution |
Combined restitution coefficient. |
rigid_contact_accumulated_normal_impulse |
Warm-start normal impulse. |
rigid_contact_accumulated_tangent_impulse0, rigid_contact_accumulated_tangent_impulse1 |
Warm-start tangent impulses. |
rigid_contact_impulse |
Solver-written world impulse vector. |
rigid_contact_adhesion |
Adhesion coefficient / cache allocated with rigid contact storage. |
rigid_contact_torsional_friction |
Torsional friction coefficient / cache allocated with rigid contact storage. |
rigid_contact_rolling_friction |
Rolling friction coefficient / cache allocated with rigid contact storage. |
rigid_contact_patch_area |
Hydroelastic contact patch area. |
rigid_contact_patch_depth |
Hydroelastic signed patch depth. |
rigid_contact_pressure |
Hydroelastic patch pressure. |
rigid_contact_tids |
Writer thread / debug ids. |
Optional rigid columns are None unless their matching allocation flag is
enabled:
| Field | Enabled By |
|---|---|
rigid_contact_stiffness, rigid_contact_damping, rigid_contact_friction |
per_contact_shape_properties=True |
rigid_contact_match_index |
contact_matching=True |
rigid_contact_new_indices, rigid_contact_broken_indices |
contact_report=True |
rigid_contact_force |
Assign a DeviceArrayVec3f to the field explicitly; optional VBD contact force on body 1. No Model.request_contact_attributes(...) token currently allocates this channel. |
rigid_contact_new_count and rigid_contact_broken_count give the active
lengths of the two report arrays. rigid_contact_force_allocated reports
whether the optional VBD force channel is present.
Soft-Point Contact Columns¶
Particle / soft-point contacts against rigid shapes use the soft_contact_*
columns. Active entries occupy 0:contacts.soft_count().
| Field | Description |
|---|---|
soft_contact_particle |
Particle / vertex index. |
soft_contact_shape |
Rigid collider shape index. |
soft_contact_body_pos |
Body-frame contact position on the rigid shape. |
soft_contact_body_vel |
Body-frame surface-velocity slot. Current CPU and CUDA collision writers populate it with zero. |
soft_contact_normal |
World normal from the rigid shape toward the soft point. |
soft_contact_tids |
Writer thread / debug ids. |
Fluid solvers consume this channel through apply_particle_coupling_contacts and apply_particle_contact_reactions.
Optional Force Channel¶
force is None unless requested through
Model.request_contact_attributes("force") or assigned explicitly. When
allocated, it stores [force, torque] rows; force_allocated reports the
allocation state.
Methods¶
| Method | Description |
|---|---|
reserve_rigid(capacity, per_contact_shape_properties=False, contact_matching=False, contact_report=False, device=Device.cpu()) |
Allocate rigid contact arrays. |
reserve_soft(capacity, device=Device.cpu()) |
Allocate soft-point contact arrays. |
ensure_rigid_capacity(capacity) |
Grow rigid contact storage if needed. |
clear(bump_generation=True) |
Reset active counts and optionally increment contact_generation. |
See Also¶
- CollisionPipeline
- Model ยท
model.collide(state, contacts)with pre-sized contacts