Skip to content

Release v0.5.0 - #34

Merged
sebcrozet merged 1 commit into
mainfrom
release-v0.5.0
Aug 16, 2026
Merged

Release v0.5.0#34
sebcrozet merged 1 commit into
mainfrom
release-v0.5.0

Conversation

@sebcrozet

Copy link
Copy Markdown
Member

v0.5.0 (16 August 2026)

Breaking changes

  • NexusState::insert_rigid_body/insert_rigid_body_in take an extra RbdCoupling argument.
    Pass RbdCoupling::None for a rigid-body-only scene.
  • ⚠ Default solver parameters changed: contact_damping_ratio 5.010.0,
    normalized_allowed_linear_error 0.0010.005, normalized_max_corrective_velocity
    10.03.0, normalized_prediction_distance 0.0020.02.
  • ⚠ The viewer's BackendType::Rapier (CPU rapier reference backend) was removed. The remaining
    backends all run the nexus pipeline: Gpu, Cpu, Cuda, Metal.
  • ⚠ Examples are prefixed by the subsystem they exercise (boxes3rbd_boxes3). The
    bench_joints3, bench_multibody_pendulum3 and bench_urdf3 benchmarks were removed.
  • ⚠ Python: the PyPI distribution is now dimforge-nexus3d (the import name stays nexus3d).
  • Built against rapier 0.35 and parry 0.30 (was rapier 0.34/parry 0.29).

Added

  • nexus_mpm: a GPU Material Point Method solver, in 2D and 3D, behind the mpm feature.
    Particles are added and removed by chunk (NexusState::add_particles, extend_chunk,
    remove_chunk), on a sparse sorted grid with substepping and a CFL timestep bound.
  • MPM constitutive models: linear and Neo-Hookean elasticity, Drucker-Prager sand (with cohesion),
    a weakly-compressible fluid, and the Stomakhin snow model, all built through ParticleModel.
  • RbdCoupling::MpmOneWay: colliders act as moving boundaries for the particles, with per-body
    stick/slip/separate/non-reflecting conditions and optional CPIC for thin obstacles.
  • RbdCoupling::MpmTwoWay hands a body over to MPM entirely: the rigid-body pipeline treats it as
    static while MPM integrates it from the particle impulses. At most 16 coupled bodies (CPIC limit).
  • Multibody self-contacts: two links of the same multibody now collide, unless the multibody
    disables self-contacts.
  • Restitution on multibody contacts, applied as an end-of-step pass seeded from the approach
    velocity measured at the start of the step.
  • Per-link external forces/torques and gravity scale on multibody links
    (GpuMultibodySet::set_link_external_wrench), and DOF couplings between two joint axes.
  • Multibody motors can be read back and retargeted at runtime (GpuMultibodySet::set_motor,
    set_motors, motor), plus set_num_internal_pgs_iterations and set_implicit_coriolis.
  • RbdSimParams::static_contact_natural_frequency/static_contact_damping_ratio: contacts
    touching a fixed body get their own, stiffer by default, softness coefficients.
  • RbdSimParams::normalized_max_linear_velocity (default 400.0 m/s) caps the linear velocity
    after each substep so speculative contacts stay reliable. Set to f32::MAX to disable.
  • A brute-force O(n²) broad-phase, used instead of the LBVH for environments with at most
    64 colliders.
  • NexusState::rbd_world_mut_untracked: mutate a rapier world after finalize without marking
    the GPU state dirty.
  • Viewer: snap_rgb frame capture, configurable resolution, a headless mode, a vsync toggle,
    pipelined capture (render_async/render_flush) and kiss3d's GPU path tracer
    (raytrace_frame), all exposed to Python (PRs Add NexusViewer.render() to export frames off-screen #7, Add ability to generate python raytracing renderering #8 and Python: headless viewer, vsync control, pipelined frame capture #11 by @haixuanTao).
  • Python bindings for MPM (set_mpm_params, add_particles, ParticleModel, …).
  • A web-compat feature on the shader crates, enabled automatically when targeting wasm32.

Modified

  • The contact solver follows rapier's TGS-soft relax pass: the unbiased normal rhs is refreshed
    from the post-integration poses, instead of stripping CFM and bias from the constraints in place.
  • NexusState::set_rbd_gravity applies to free rigid-bodies and multibody links alike, and works
    in 2D (where the third component is ignored). It used to be 3D- and multibody-only.
  • Extensive, mostly result-identical pipeline optimizations: frame-to-frame coloring, contacts
    bucket-sorted by color, fused colored sweeps, a shared-memory multibody PGS sweep, an SoA link
    workspace, LBVH subtree pruning, and skipping the pipelines that are provably inert.

Fixed

  • RbdState::from_rapier zero-filled the velocity buffer, dropping every body's initial linear
    and angular velocity (PR fix: upload initial body velocities in the from_rapier bulk path #10 by @haixuanTao).
  • Multibody joint limits no longer emit a constraint row while the joint sits strictly inside its
    bounds, where it can never apply an impulse (PR perf(rbd): skip inactive joint-limit constraint rows #14 by @haixuanTao).
  • Contact manifold reduction now matches rapier's, including its degenerate-selection guards.
  • The fused multibody solver kernels no longer place barriers under non-uniform control flow,
    which WebGPU rejects; the loop bound is now a uniform holding the max over all multibodies.
  • Out-of-bounds writes to the polygonal-feature pair buffer, and constraint counting over the
    padded capacity instead of the real contact count.
  • The LBVH pair traversal used a while loop, which naga might miscompile on macos.

@sebcrozet
sebcrozet merged commit 5b05f4a into main Aug 16, 2026
5 checks passed
@sebcrozet
sebcrozet deleted the release-v0.5.0 branch August 16, 2026 09:59
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.

1 participant