SPG (short for Spring) is a research-focused C++ physics simulation library for easy implementation and comparison of solvers and mechanical energy models. It provides a common interface for solvers and energies, making all solver implementations compatible with all energies without requiring additional effort. A set of solvers and energies are already implemented in SPG. I personally use it to implement and compare interesting ideas from state-of-the-art research.
General nonlinear energies
Through the use of autodiff and templates (using TinyAD as autodiff backend), automatic first and second order derivatives are provided from a simple energy or constraint definition. This helps to keep the code to a minimum, very close to the actual formulas of the corresponding solvers and models. It is also possible to override these automatic versions with more efficient custom implementations if needed.
As an example, by providing the following constraint code for the Discrete Bending Energy, the corresponding constraint derivatives, energy, forces and force jacobians are automatically available, making it compatible with all the implemented solvers:
[...]
const Vector3T<RealT> e0 = x1 - x0;
const Vector3T<RealT> e3 = x2 - x1;
const Vector3T<RealT> e4 = x3 - x1;
const Vector3T<RealT> n1 = e0.cross(e3).normalized();
const Vector3T<RealT> n2 = -e0.cross(e4).normalized();
const auto theta = atan2((n1.cross(n2)).dot(e0.normalized()), n1.dot(n2));
const auto constraint = theta - restTheta;
[...]
- XPBD
- VBD (Vertex Block Descent) - Author's source code
- Baraff-Witkin Implicit Euler
- Robust Newton Backward Euler
- BDF2
- Preconditioned Gradient Descent
- Quasistatic equilibrium
- Static equilibrium
- Spring
- Strain-based spring
- Baraff-Witkin bending
- Quadratic bending
- Discrete bending
- Baraff-Witkin membrane
- Choi membrane
- StVK membrane
- Stable Neo-Hookean
- StVK
The current implementations are focused on parallel CPU simulation of deformables, including cloth, spring systems and finite element models. Some of the solvers meant for GPU computation may underperform, but this common framework allows to analyse and compare other important aspects such as convergence and stability properties.
This is still a experimental project, which is the best excuse I can think of to justify the lack of proper documentation and unit testing.
I intend to explore several big features in the future, in no particular order (if you are interested in contributing, let me know):
- Unified energy damping model
- Proper boundary conditions
- Collision detection
- Rigid bodies
- Differentiable simulation
- GPU support
CMake is used to generate and compile the project. It has been tested in Windows 11 with VSCode and MSVC 19, and in Ubuntu 24.04. You can configure it in your preferred IDE. The apps/
folder contains demo examples, including a small elastic pendulum simulation with the basics of setting up and simulating a scene, and a solver comparison demo that allows to set up different scenes and simulate them with multiple configurable solvers.
SPG uses Eigen and TinyAD as dependencies. The solver comparison demo also uses Polyscope for GUI and rendering. All of these come as submodules.
For a quick Terminal compilation on both Windows and Ubuntu, run:
git clone https://github.com/alexrodag/spg.git
cd spg
git submodule update --init --recursive
mkdir build
cd build
cmake ..
cmake --build . --config Release -j
Note: In Ubuntu, if there is an error when configuring polyscope, you may need to run the following (check updated instructions in https://polyscope.run/building/) )
sudo apt install xorg-dev libglu1-mesa-dev freeglut3-dev mesa-common-dev
Author: Alex Rodriguez