The year 2021 in Dimforge and our objectives for 2022

🎉🎉🎉 Happy new year 2022 everyone! 🎉🎉🎉

The year 2021 has been a very exciting for Dimforge and the Rust community at a whole! This blog post summarizes the most significant additions made in 2021 to the open-source crates for linear-algebra and physics simulation we develop for the Rust community. We also present our main objectives for 2022.

Help us sustain this work by sponsoring us on GitHub sponsors ♥
Join us on discord!

Rapier: 2D and 3D physics

rapier logo

Rapier is a 2D and 3D physics engine for games, robotics, and animation written in Rust. Our goal for 2021 was to work on the missing low-level features of Rapier: shape-casting, CCD, joint limits and motors, custom collider shapes, dominance, multibodies. We also significantly improved Rapier’s documentation by writing complete user-guides for the Rust version of Rapier, it’s Typescript bindings, as well as its Bevy plugin.

Today we released the version 0.12-alpha.0 of Rapier. This release features three significant changes:

  1. The addition of multibody joints (part of our 2021 objectives).
  2. The change of our constraint solver.
  3. A complete redesign of our joints.

Please note that this is an alpha release which still has a few known limitations we would like to address before making a proper release.

Multibody joints

The main focus of this release was to add the support for joints based on the reduced-coordinates formalism. There are basically two main ways of modeling joints:

  • The full-coordinates approach, aka. impulse-based joints, that applies forces/impulses to enforce the joint’s positional constraints.
  • The reduced-coordinates approach, aka. multibody joints, that encodes the positional constraints directly into the parametrization of the rigid-bodies positions when developing the equations of motions.

Both approaches have advantages and drawbacks. The impulse-based joints are more computationally efficient, and can sustain higher relative velocities without completely diverging. However, the constraint solver may not always be able to compute the exact forces needed to fulfill the joints requirements. This can result in a wobbly behavior, where the attached objects appear to oscillate. For example, you can observe this "wobbly" behavior here with fixed joints (top-left), limited prismatic-joints (bottom), and motorized revolute joints (top-right):

impulse joints

The multibody joints however can be less computationally efficient and do not allow joint assemblies with loops (it must form a tree). However, these joints will never be violated, avoiding any wobbly behavior. The assembly looks perfectly stiff:

multibody joints

Constraint solver change

The addition of multibody joints proved to be quite difficult considering the design of our former constraint solver. Before the version 0.12-alpha.0, Rapier used a linear velocity-based solver (with warm-starting) to solve velocity (contact and joint) constraints, followed by a non-linear position-based post-projection to correct any penetration or joint drift at the position level. This scheme proved to be quite difficult to extend (because of the non-linear nature of the position-based solver) and computationally expensive when multibodies were involved. Therefore, we changed our solver to only contain two linear velocity-based phases:

  1. A biased velocity constraint resolution, which solves for the contact and joint constraints and tries to correct penetrations and joint drifts at the same time. This will potentially add artificial energy to the mechanical system, resulting in potential jitters, and "popping" effects due to penetration.
  2. A non-biased stabilization velocity resolution, which removes most of the excessive energy introduced into the mechanical system by the previous phase.

With both phases combined, typical simulations won’t show any large "popping" effect or jitter, while feeling stiffer overall. In addition, this solver doesn't require any warm-starting, meaning that the force computation no longer rely on the complete history of the simulation to converge. In the future this should allow the implementation of rollback systems with less state needed to keep the simulation stable.

Joints redesign

One of our objectives with the introduction of multibody joints was to keep the multibody joints API as close as possible as the impulse-based joints API, despite the fact that their mathematical modeling are completely different. Before the release 0.12-alpha.0, we had different types for each impulse-based joint (RevoluteJoint, PrismaticJoint, FixedJoint and BallJoint). In the version 0.12-alpha.0, all the impulse-based joints are replaced by a single generic joint ImpulseJoint similar to "6-dofs joints" in other 3D physics engines. Similarly, the multibody joints have all been grouped into a single generic joint MultibodyJoint which can be configured to represent any combination of free/limited/motorized degrees-of-freedoms.

The structures FixedJoint, BallJoint, PrismaticJoint and SphericalJoint (formerly named BallJoint) still exist, but are only used as a simple way to build an ImpulseJoint or a MultibodyJoint. Impulse joints are added to the ImpulseJointSet (formerly named JointSet) and multibody joints are added to the MultibodyJointSet.

Why an alpha release?

For the first time in the history of rapier, we are making an alpha release. This release introduces significant changes, and still has a few bugs we are aware of:

  • Multibody joints created from a JointData directly instead of through a RevoluteJoint, PrismaticJoint, FixedJoint, SphericalJoint structure may behave oddly. We will soon make sure that the general case works properly (we finished the mathematical modeling but not the implementation yet).
  • Joint motors affecting multiple free angular degrees of freedom may behave in an unexpected way because of a few numerical issues due that we need to address.
  • We haven’t updated the user-guide yet (however all our examples have been updated).
  • The parallel version of Rapier should not be used with this alpha version.

These issues will be our first priority for 2022. We didn't want to postpone the alpha release any further so that users that don’t rely on these specific features can already start switching to, testing, and providing feedbacks on this new version (especially regarding the new constraint solver). This also allows us to keep rapier in sync with the newer version of nalgebra we released today.

nalgebra: linear-algebra

nalgebra logo

nalgebra is a general-purpose linear-algebra library for Rust. It supports low-dimensional, high-dimensional, sparse matrices, as well as geometric transformations (rotations, isometries, etc.)

The main features added in 2021 were:

  • The release of the new nalgebra-sparse crate entirely contributed by Andreas Longva. This is a complete rewrite of our former nalgebra::sparse module.
  • The integration of const-generics, improving the ergonomics, debuggability, and generic programming, for code involving statically-sized matrices.
  • The addition of the matrix!, vector!, point!, etc. macros to construct matrices from their components more easily. They allow the easy construction of const matrices and vectors too.
  • The fix of several soundness issues, in particular by properly using MaybeUninit instead of the deprecated, unsound, mem::uninitialized().

Finally, today we released the version 0.30 of nalgebra which adds the compatibility with the recently announced rust-cuda project. This allows the usage of every no-std features of nalgebra (which are, everything, including matrix decompositions, excluding sparse matrices and dynamically-sized matrices) inside CUDA kernels written in Rust. The transfer of nalgebra structures between the RAM and VRAM is also possible.

Parry: collision-detection


In 2021, we released our new collision-detection library parry which replaces our former crate ncollide. The parry crate is more efficient than ncollide and is easier to use thanks to a much smaller amount of generics. Some notable features supported by parry that were not included in ncollide are:

  • An implementation of the VHACD algorithm for approximate convex decomposition of concave 2D and 3D shapes.
  • An implementation of an SIMD-accelerated quaternary BVH structure, much more efficient than ncollide’s BVT and DBVT structures.
  • A more versatile non-linear shape casting.
  • An implementation of the Hertel-Mehlhorn algorithm for 2D convex decomposition, fully contributed by Sven Niederberger.

Finally, today we released the version 0.8 of parry. This version allows a subset of parry to work in a no-std context. This was required to add the compatibility of this subset of parry with rust-cuda, allowing various geometric operations (including ray-casting, distance computation, intersection tests, etc.) to be used inside of a CUDA kernel written in Rust.

Salva: fluids simulation

In our roadmap for 2021, we mentioned that we would work on improving the performances of Salva with SIMD optimizations. We are sorry to announce that none of it has been done. Instead, we focused more of Rapier, and started experimenting with the Material Point Method. This experiment is important because:

  • MPM has shown to be quite promising lately, for example with the recent presentation of the blub project.
  • MPM is extremely versatile to simulate models sustaining large deformations, and a wide range of various materials, from sponges to fluids.
  • MPM is very friendly for aggressive optimizations based on multithreading, SIMD, and GPU computing.
  • MPM may end up replacing completely the SPH implemented in Salva if we get good results.

We currently have promising preliminary results using a CPU-based implementation multithreaded with rayon, or a GPU-based CUDA implementation based on rust-cuda (all our CUDA kernels are written in Rust, using nalgebra and parry). As always, we are targeting both 2D and 3D simulations. The development of this new crate is currently closed-source, with a plan to open-source it in April 2022. Here are a couple of small simulations featuring deformations, sand, fluids and fractures:

MPM 3d MPM 2d

What’s next in 2022

For 2022, we have two main objectives:

  1. Work on high-level features for Rapier.
  2. Continue our exploration of MPM for fluids and deformable bodies simulation.

By high-level features for Rapier, we mean all these features that make the user’s life easier and that have been frequently requested in 2021. This includes:

  • A more efficient handling of voxel-based worlds. We also consider experimenting with destruction on voxel-based games, similar to what can be seen in the Teardown game.
  • A sample character controller.
  • Utilities like Godot’s move_and_slide for easier control of kinematic rigid-bodies.
  • Inverse kinematics.
  • Solutions for the internal edge problem that may cause "bumps" when an object slides on a flat surface represented by multiple triangles or cubes.

These additions will bring Rapier to a very usable place for both physics beginners and experts.


Thanks

We would like to thank Croquet for sponsoring our work right from the beginning of Dimforge, as well as Fragcolor for being our new Gold sponsor for 2022! This helps us tremendously to sustain our Free and Open-Source work.


Thanks to all the former, current and new supporters through GitHub sponsors! This help is greatly appreciated and allows us to continue working on our open-source projects. Finally, a huge thanks to the whole community and code contributors!