GalateaSim is a real-time volumetric soft-tissue simulator for a human leg. It replaces purely kinematic skinning with a heterogeneous tetrahedral XPBD model to preserve volume and produce plausible flesh deformation during knee flexion.
Poster · Proposal · Experiment configuration
This project received an Honorable Mention for Best Project Awards in Tsinghua University's 2026 Physics-Based Simulation course.
Anatomical Layer Tagging
- Radial-depth classification produces soft bone, muscle, fat, and skin weights.
- Blended per-tet Lamé parameters and density create a heterogeneous volumetric model.
Kinematic Control
- A two-bone FK chain drives bone-tagged anchors from exported skin weights.
- The surrounding vertices remain dynamic and respond to skeletal motion through elasticity.
XPBD Solver
- Per-tet Stable Neo-Hookean hydrostatic and deviatoric constraints.
- GPU-parallel Averaged Jacobi with inner iterations, damping, a skin membrane, and optional Chebyshev acceleration.
- Experimental vertex-triangle self-collision and two-way tight-sock coupling.
Project Engineering
- Blender/TetGen preprocessing and included coarse/dense volumetric assets.
- A readable NumPy reference backend and an NVIDIA Warp backend with CUDA Graph capture.
- Interactive Polyscope controls, layer views, diagnostics, synchronized screenshots, and LBS/DQS evaluation tools.
Requirements: Python 3.12, OpenGL, and an NVIDIA CUDA GPU for the real-time path.
conda create -n galateasim python=3.12
conda activate galateasim
python -m pip install -r requirements.txtThe project was tested with CUDA Toolkit 12.8 installed inside WSL2. The tested environment only requires the following additional library-path setting:
export LD_LIBRARY_PATH=/usr/lib/wsl/lib:$LD_LIBRARY_PATH
# Verify the Toolkit and Warp device.
nvcc --version
python -c "import warp as wp; wp.init(); print([str(d) for d in wp.get_devices()])"On some Ubuntu 24.04 WSL2 installations, Polyscope also needs Mesa's D3D12 renderer:
export GALLIUM_DRIVER=d3d12
export MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA
# Verify the OpenGL renderer.
glxinfo -B | grep "OpenGL renderer"
# [Target output]: OpenGL renderer string: D3D12 (NVIDIA GeForce RTX 5070 Ti Laptop GPU)python main.pyThe viewer opens paused. Adjust the controls, then use Play, Step 1 Frame, or Reset.
| Option | Values | Default |
|---|---|---|
--model |
leg, leg_dense |
leg_dense |
--backend |
numpy, warp |
warp |
python main.py --model leg --backend numpy
GALATEA_MODEL=leg_dense GALATEA_BACKEND=warp python main.pyThe NumPy backend is intended for reference and debugging; use Warp with CUDA for interactive performance.
The volume evaluation uses leg_dense at thigh -40° and knee 120°, with 20 sub-steps and 8 inner iterations.
| Method | Global drift | Local drift near knee |
|---|---|---|
| LBS | -2.66% | -25.62% |
| DQS | +1.91% | +3.44% |
| GalateaSim | -3.16% | -8.24% |
GalateaSim substantially reduces the local collapse of LBS. DQS preserves volume numerically but produces a kinematic joint bulge rather than a physical tissue response; volume drift alone is not a realism metric.
Current GUI performance was measured under WSL2 on a laptop with an AMD Ryzen 9 9955HX and an NVIDIA GeForce RTX 5070 Ti Laptop GPU.
- Without self-collision: ~40FPS, ~13.7ms per physics step.
- With self-collision: ~22FPS, ~27ms per physics step.
Runtime varies with the pose, active contact count, UI rendering, and solver settings.
Reproduce the main evaluation:
python scripts/compare_volume.py leg_dense
python scripts/physics_volume.py leg_dense
python scripts/plot_volume.py
python scripts/benchmark.py leg_denseUse scripts/baseline_viewer.py leg_dense for the interactive LBS/DQS comparison and scripts/convergence.py leg_dense for the convergence sweep.
- Self-collision: discrete vertex-triangle contacts only; no CCD or edge-edge handling. Deep folds can produce missed or incorrect contacts. Active contacts also fail to converge reliably, causing persistent jitter near the contact region instead of settling. The feature is therefore off by default.
- Garment coupling: the Warp-only sock may slide, penetrate, or sink into the skin. It remains an experimental feature and is off by default.
- Anatomy: material layers are inferred from radial depth, not segmented medical data; parameters are visually tuned rather than biomechanically calibrated.
- Scope: the model is a free two-bone leg without pelvis, foot, ground contact, muscles, or tendons. The NumPy backend does not provide full feature parity with Warp.
.
├── main.py # Application entry point and shared UI state
├── requirements.txt # Python dependencies
├── src
│ └── galateasim
│ ├── core
│ │ ├── cloth # Experimental garment body and kernels
│ │ ├── material # Layer tagging and material properties
│ │ └── solver # NumPy and Warp XPBD backends
│ ├── io # TetGen, landmarks, weights, and OBJ loaders
│ ├── vis # Polyscope renderer and view synchronization
│ └── utils.py
├── scripts
│ ├── baseline_viewer.py # Interactive LBS/DQS viewer
│ ├── baselines.py # LBS and DQS implementations
│ ├── benchmark.py # Runtime and stability evaluation
│ ├── blender_export.py # Blender scripts to export landmark & weight.
│ ├── compare_volume.py # LBS/DQS volume sweep
│ ├── convergence.py # Solver convergence sweep
│ ├── explore_config.py # Configuration ablation
│ ├── physics_volume.py # GalateaSim volume sweep
│ └── plot_volume.py # Evaluation plots and tables
├── data
│ ├── left-leg-without-foot # Coarse TetGen model
│ ├── left-leg-without-foot-dense # Dense TetGen model
│ └── left-leg-garment # Experimental sock mesh
└── docs
@inproceedings{macklin2016xpbd,
author = {Macklin, Miles and M{\"u}ller, Matthias and Chentanez, Nuttapong},
title = { {XPBD}: Position-Based Simulation of Compliant Constrained Dynamics},
booktitle = {Proceedings of the 9th International Conference on Motion in Games},
pages = {49--54},
year = {2016},
doi = {10.1145/2994258.2994272}
}
@inproceedings{macklin2021stable,
author = {Macklin, Miles and M{\"u}ller, Matthias},
title = {A Constraint-based Formulation of Stable Neo-Hookean Materials},
booktitle = {Motion, Interaction and Games},
articleno = {12},
numpages = {7},
year = {2021},
doi = {10.1145/3487983.3488289}
}