Skip to content
bullet-physics-playgroundPublic

About

Physics simulation experiments

Topics

Resources

Stars

38 stars

Watchers

5 watching

Forks

Latest commit

 

History

1,942 Commits

Folders and files

Repository files navigation

The Bullet Physics Playground

A simple physics simulation software for prototyping and experimenting with the Bullet Physics library. It provides a graphical user interface (GUI) for real-time interaction and a command-line interface (CLI) for batch processing and scripting.

GitHub last commit GitHub commit activity GitHub issues

Features

  • Physics Simulation: Powered by the robust and widely-used Bullet Physics library.
  • Cross-Platform: Builds and runs on Linux, Windows, and macOS.
  • GUI: An OpenGL-based GUI for visualizing and interacting with the simulations in real-time.
  • Scripting: Extend and control simulations using Lua scripting.
  • Import/Export:
    • Import models from OpenSCAD.
    • Export scenes to POV-Ray for high-quality rendering.
  • Command-Line Interface: A powerful CLI for running simulations, rendering animations, and piping data to other tools like gnuplot.

Videos on YouTube

Bullet Physics Playground

Download

Release builds are attached to each release. The macOS disk images bundle their Homebrew dependencies, so each one requires at least the macOS version its build machine used:

Disk image Requires
bpp-<version>-macos-arm64.dmg (Apple Silicon) macOS 14 or later
bpp-<version>-macos-x86_64.dmg (Intel) macOS 15 or later

On an older macOS, build from source instead.

Build

Select your operating system:

Optional: embedded POV-Ray VFE rendering (experimental)

By default, F6 quick-render shells out to an external povray/pvengine executable, same as it always has. There is an experimental alternative build flag, USE_VFE, that instead embeds POV-Ray's own VFE (Virtual Front End) API directly into bpp, so F6 renders in-process with a live pixel preview inside the 3D view, and a real cancel (Esc) instead of only killing a subprocess.

USE_VFE defaults to 0 (off) and building bpp normally is unaffected by it either way. Turning it on requires a sibling POV-Ray source checkout and a prebuilt static library — see povray-mingw/README.md (Windows/MSYS2 MinGW-w64) or povray-linux/README.md (Linux) for the full build steps. Once that's in place:

qmake "USE_VFE=1" bpp.pro

This is a prototype, and statically linking POV-Ray's AGPLv3-licensed core into bpp's AGPLv3 binary means the resulting binary is bound by AGPLv3 obligations — worth deciding deliberately before shipping a USE_VFE=1 build beyond a local build.

The Linux build has been verified end-to-end (builds, links, and renders via F6 without crashing); see povray-linux/README.md for the gotchas that took to get there. The Windows/MSYS2 path is untested beyond compiling — see povray-mingw/README.md.

Docker

The Dockerfile packages bpp as a headless worker for running on a server or a Kubernetes cluster (Talos Linux included). It needs no display: it runs a Lua script and, with -e, exports the frames as POV-Ray scenes for a renderer such as povomatic. The image ships the demos under /usr/share/bpp/demo, plus OpenSCAD and POV-Ray.

mkdir -p out
docker run --rm --user "$(id -u):$(id -g)" -v "$PWD/out:/work" koppi/bpp \
    -n 278 -e -f /usr/share/bpp/demo/basic/00-hello.lua   # writes out/export/00-hello/

Arguments are the command-line ones, and without any the image prints --help. To run your own script, mount it and pass its path. The container runs as the unprivileged uid 10001 and /work is its working directory and home, where the export (/work/export) and bpp's settings and cache go. That is the only place it writes, so it also runs with a read-only root filesystem and all capabilities dropped. /work must be writable by the container's user: hence --user above, or fsGroup on a Kubernetes volume.

A headless -f run starts in the container's working directory, not in the script's folder, so a script that loads files lying next to it (the meshes of the Dzhanibekov demo, say) fails with ... not found unless its folder is the working directory. Without -e, set that with -w, which is workingDir in a Kubernetes container:

docker run --rm -w /usr/share/bpp/demo/WyomingWill/EulersGallery/exhibits/Dzhanibekov koppi/bpp \
    -n 100 -f dzhanibekov.lua

An export is written to export/ below the working directory, which has to be writable, and the installed demos are not. So with -e, mount the script's folder (or a copy of it) as /work instead:

docker run --rm --user "$(id -u):$(id -g)" \
    -v "$PWD/demo/WyomingWill/EulersGallery/exhibits/Dzhanibekov:/work" koppi/bpp \
    -n 278 -e -f dzhanibekov.lua      # writes demo/WyomingWill/EulersGallery/exhibits/Dzhanibekov/export/

On Kubernetes, a Job that runs under the restricted Pod Security profile:

apiVersion: batch/v1
kind: Job
metadata:
  name: bpp-hello
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      securityContext:
        runAsNonRoot: true
        fsGroup: 10001
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: bpp
          image: koppi/bpp:latest
          args: ["-n", "278", "-e", "-f", "/usr/share/bpp/demo/basic/00-hello.lua"]
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: ["ALL"]
          volumeMounts:
            - name: work
              mountPath: /work
      volumes:
        - name: work
          emptyDir: {}   # use a PersistentVolumeClaim to keep the export

The published image is linux/amd64. To build it yourself, for example for another architecture, run docker build -t koppi/bpp .: a first stage builds the Debian package from debian/, the way the release workflow does, and the runtime image installs it.

Usage

GUI

Menu shortcuts

These work anywhere in the main window (including while editing the Lua script):

  • Ctrl+N: New file.
  • Ctrl+O: Open file.
  • Ctrl+S: Save file.
  • Ctrl+A: Save file as.
  • Ctrl+Q: Exit.
  • F12: Preferences.
  • Ctrl+C: Start/pause the physics simulation.
  • Ctrl+R: Restart the simulation.
  • F6: Quick render current frame with POV-Ray (or in-process via the experimental embedded VFE API, if enabled — see Optional: embedded POV-Ray VFE rendering above).
  • F11: Toggle full screen.

3D view shortcuts

These require the 3D view to have keyboard focus:

  • S: Start/stop the physics simulation.
  • P: Toggle POV-Ray export mode.
  • G: Toggle PNG screenshot saving mode.
  • A: Toggle display of the world axis.
  • F: Toggle FPS display.
  • Enter: Start/stop the animation.
  • Space: Toggle between fly and revolve camera modes; while an embedded VFE render (see above) is in progress, pauses/resumes it instead.
  • Esc: Cancel an in-progress embedded VFE render.
  • Arrow Keys: Move the camera.
  • Tab: Toggle between the single perspective view and a 4-view CAD-style layout (perspective, top, front, right). Scroll to zoom and drag to pan in the top/front/right views.
  • H: Show the QGLViewer help window.

Command-Line

The command-line interface allows you to run simulations without the GUI. For example, you can pipe the simulation data to gnuplot to visualize the results:

bpp -n 200 -f demo/basic/01-hello-cmdline.lua | \
    gnuplot -e "set terminal dumb; plot for[col=3:3] '/dev/stdin' using 1:col title columnheader(col) with lines"

Distributed rendering with povomatic

povomatic renders a POV-Ray animation across a Kubernetes cluster, one job per frame. To send it a bpp scene, export the frames and submit from the export directory:

bpp -f demo/basic/00-hello.lua -n 278 -e       # writes export/00-hello/
make -C export/00-hello povomatic              # rsync + submit via povomatic.py

make povomatic runs scripts/povomatic-job.py, which copies includes/ and POV-Ray's own standard includes (colors.inc etc., which settings.inc pulls in and the render image does not ship) to povomatic's shared asset volume, copies the exported scene to its input volume, and calls povomatic.py with the frame count and clock range read from the generated .ini (bpp exports each frame so that POV-Ray's clock equals the frame number). Pass extra options through POVOMATIC_ARGS, e.g. make -C export/00-hello povomatic POVOMATIC_ARGS="--res 1080p --priority 5"; run scripts/povomatic-job.py --help for the full list. The API URL comes from $POVOMATIC_API (or --api-url); $POVOMATIC_INPUT, $POVOMATIC_ASSETS, $POVOMATIC_REMOTE_INPUT and $POVRAY_INCLUDE_DIR override the volume and include paths.

Documentation / Wiki

Contributing

Contributions are welcome! Please feel free to submit a pull request or open an issue on the GitHub repository.

Contributions

People

Bundled third-party content

The includes/ directory bundles POV-Ray assets and lighting macros from other authors, each under its own terms; see includes/README.md for full details.

Content Author(s) License
LightSys 4 lighting macros Jaime Vives Piqueres, with Ive and Philippe Debar not stated in-repo; used with attribution
CIE XYZ color model Ive not stated in-repo; used with attribution
Skylight model Philippe Debar, adapted by Ive not stated in-repo; used with attribution
Studio Lighting Kit Jaime Vives Piqueres not stated in-repo; used with attribution
Box-of-oranges scene Jaime Vives Piqueres CC BY-SA 3.0
Citroën GS car model Jaime Vives Piqueres CC BY-SA 3.0
Nissan Micra K11 car model Rene Bui CC BY-NC 3.0
Dice model found on Wikipedia Public Domain
Humanity icon theme Canonical / Ubuntu not stated in-repo; used with attribution

A few other bundled POV-Ray assets (e.g. the LEGO buggy, Wunderbaum, and cajón meshes under includes/) carry no attribution or license information in this repository.

License

The Bullet Physics Playground itself is licensed under the GNU Affero General Public License v3. Bundled third-party content retains its own license as noted above.

About

Physics simulation experiments

Topics

Resources

Stars

38 stars

Watchers

5 watching

Forks

Releases

Sponsor this project

Contributors

Languages