3 Punkte von GN⁺ 2024-02-29 | 1 Kommentare | Auf WhatsApp teilen
  • Rapier ist eine Sammlung Rust-basierter Physik-Engines für Anwendungen, die Echtzeit-Physik benötigen, etwa Spiele, Animationen und Robotik
  • Sie zielt auf schnelle Ausführung und Stabilität ab und unterstützt bei Bedarf optional plattformübergreifende Determinismus
  • Sie bietet Funktionen für Physiksimulationen wie Kollisionen und Kräfte von Starrkörpern, Joint-Constraints, Kontakt-Events und Sensoren sowie Snapshots
  • Dank JavaScript-Bindings lässt sich Rapier auch in Umgebungen außerhalb von Rust nutzen
  • Rapier ist kostenlose Open Source unter der Apache-2.0-Lizenz, wird von Dimforge entwickelt und über GitHub Sponsors finanziell unterstützt

Einsatzbereiche, auf die Rapier abzielt

  • Rapier ist eine Sammlung von 2D- und 3D-Physik-Engines, geschrieben in Rust
  • Hauptzielgruppe sind Anwendungen, die Echtzeit-Physikverarbeitung benötigen
    • Videospiele
    • Animationen
    • Robotik
  • Designziel ist ein schneller und stabiler Betrieb, optional mit Unterstützung für plattformübergreifenden Determinismus

Funktionen und Bereitstellung

  • Enthält zentrale Funktionen für Physiksimulationen
    • Starrkörperkollisionen und Kräfte
    • Joint-Constraints
    • Kontakt-Events und Sensoren
    • Snapshots
    • Optionaler plattformübergreifender Determinismus
    • JavaScript-Bindings
  • Rapier ist kostenlose Open Source und wird unter der Apache-2.0-Lizenz verteilt
  • Entwickelt wird es vom Open-Source-Unternehmen Dimforge
  • Unterstützung ist über GitHub Sponsors möglich

1 Kommentare

 
GN⁺ 2024-02-29
Meinungen auf Hacker News
  • Ich habe mit dem Determinismus-Modus von Rapier ein Online-Multiplayer-Spiel gebaut.
    Die Spieler rammen abwechselnd Käfer in Richtung des gegnerischen Teams und versuchen, einen Hügel einzunehmen.
    Einen Singleplayer-Modus gibt es noch nicht, und die KI zu schreiben ist schwieriger als bei den schachähnlichen Spielen, die ich zuvor gebaut habe.
    Das Spiel ist unter https://evrimzone.itch.io/crittershowdown zu sehen, und der Quellcode für Physik-/Spiellogik liegt unter https://github.com/evrimoztamur/crittershowdown/blob/e4d9a19....
    Ich plane später aufzuschreiben, wie ich alles verdrahtet habe und was ich gelernt habe; insgesamt ist es eine sehr solide Library, und dank des Rust-typischen API-Designs konnte ich alles umsetzen, was ich brauchte.

    • Sieht spaßig aus. Ich frage mich, ob es einfach war, es auf einer Website zu deployen.
      Mich würde interessieren, ob es zu WebAssembly kompiliert wurde oder ob die gesamte Logik über einen lokalen Server gehostet wird.
    • Ich habe angefangen, Rapier2D zu verwenden, um ein serverseitiges Multiplayer-Spiel zu bauen; es wäre schön, wenn der entsprechende Artikel bald erscheint.
  • Vor ein paar Monaten bin ich in geometrische Algebra (Geometric Algebra) eingetaucht, und sie wirkte wie eine erstaunlich knappe und intuitive Art, sehr unterschiedliche Geometrien zu behandeln: 2D, 3D, 4D und höher, nicht-euklidisch usw.
    Daher habe ich mich gefragt, ob geometrische Algebra eine gute Grundlage für eine Physics Engine sein könnte.
    Es gibt ein paar interessant aussehende Rust-Libraries [1][2], aber keine davon scheint viel Aufmerksamkeit zu bekommen.
    Ich frage mich, ob sich jemand damit beschäftigt hat.
    [1]: https://crates.io/keywords/geometric-algebra
    [2]: https://github.com/Lichtso/geometric_algebra
    Wenn man einsteigen möchte, könnte Freya Holmérs „Why can't you multiply vectors?“ ein guter Einstieg sein: https://www.youtube.com/watch?v=htYh-Tq7ZBI sowie https://bivector.net/index.html

    • Fun Fact: Excalidraw hat geometrische Algebra verwendet und treibt damit bis heute einige Interaktionen an: https://github.com/excalidraw/excalidraw/blob/master/package...
    • Der am wenigsten interessante Teil einer Physics Engine ist die Vektordarstellung.
      Geometrische Algebra ist isomorph zur „klassischen“ Vektoralgebra nach Heaviside; die schwierigen Probleme liegen eher bei Kollisionsbehandlung, Energieerhaltung, Stabilität und Ähnlichem.
    • Ich bin in dasselbe Rabbit Hole der geometrischen Algebra geraten und außerdem in Clojure, eine weitere „erstaunlich knappe und intuitive Art“.
      Deshalb habe ich eine Library gebaut, mit der man beliebige geometrische Algebren erzeugen und allerlei interessante Operationen ausführen kann; sie könnte auch als Grundlage für eine Physics Engine dienen.
      Falls es interessiert, hier ist sie: https://cljdoc.org/d/net.clojars.jordibc/geometric-algebra/
    • Zugehöriges Tutorial: https://www.youtube.com/watch?v=5R2sv9GCwz0
    • Die stärker beachtete Library ist diese hier: https://github.com/fu5ha/ultraviolet
  • Ich habe einen Guide zum Bevy-Rapier-Plugin für Rust geschrieben: https://taintedcoders.com/bevy/rapier/
    Als interessante Alternative im Bevy-Umfeld gibt es auch Bevy XPBD, das ich ebenfalls aufgeschrieben habe: https://taintedcoders.com/bevy/xpbd/

    • Ein System, das langsam bewegte Objekte als unbewegt behandelt, macht mich nervös.
      „Sleeping“ sei eine Technik, die die Simulationskosten unbewegter Objekte senkt und so die Performance verbessert, und lasse sich über die Ressource SleepingThreshold anpassen.
      Als Beispiel für Standardwerte werden linear: 0.1 und angular: 0.2 genannt.
    • Ich baue gerade mit xpbd ein physikbasiertes 2D-Fighting-Game, und bisher gefällt es mir ziemlich gut.
      Bislang gab es einmal das Problem, dass einige Kollisionen für einen Frame verschwanden, aber so etwas lässt sich leicht umgehen – oder noch besser melden, damit es behoben wird.
    • XPBD ist ziemlich interessant; ich habe ein paar Testimplementierungen gemacht und in mein jüngstes Game-Jam-Projekt eine AABB-only-Variante von XPBD eingebaut.
      Nur Rotation habe ich noch nicht richtig hinbekommen, der Rest fühlt sich an, als würde die Komplexität dahinschmelzen.
      Lineare Algebra? Nicht nötig. Es ist einfach Vec3. Matrizen? Solver? Man erfüllt einfach alle Constraints iterativ, als wäre man zurück im Jahr 1998.
      Kollisionsmarge? Skill issue. Broad Phase? GJK? Nicht zu viel nachdenken, einfach der modernen CPU überlassen.
      Nachdem man collect_pairs optimiert hat und merkt, dass der eigentliche Bottleneck malloc war, und das behebt, schafft es locker etwa 100 Objekte. Bullet braucht man nicht.
      Der Schritt zur Geschwindigkeitskorrektur war anfangs auch verwirrend, aber nachdem ich ihn mit AABB prototypisch umgesetzt habe, scheint er sich auch wieder auf allgemeine Formen übertragen zu lassen.
      Anfangs hatte ich diesen Schritt übersprungen, woraufhin sich alle Kollisionen leicht elastisch verhielten.
  • Dimforge leistet wirklich Großartiges
    Wenn nalgebra + Rust in Bereichen wie Lokalisierung und Kartierung in der Robotik Eigen + C++ ersetzen könnten, wäre das wirklich spannend

    • Ich mache inzwischen die meisten Robotikprojekte in Rust, und die Zeit, die die Branche mit C++-typischen Idiomen verschwendet, ist absurd groß
      In Rust funktionieren viele Dinge einfach. Schade ist nur, dass es eine alte Garde gibt, die sich keinen Millimeter bewegt und Investitionen in Rust ablehnt
      Ehrlich gesagt verstehe ich die Gründe, schließlich gibt es rund um C++-Robotikcode eine riesige Industrie
    • Ich würde das gern Wirklichkeit werden lassen
      Ich frage mich, ob es derzeit brauchbare Robotik-Frameworks für Rust gibt
      Ich habe gehört, dass ROS2 Rust langsam aufnimmt [1], weiß aber nicht genau, wie weit das gediehen ist
      Da Hardware-Integration/-Abstraktion bereits in C++ vorhanden ist, könnte ROS ein guter Einstieg in Sensorfusion, Kartierung und Lokalisierung sein
      Mich würde auch interessieren, ob Unternehmen das einsetzen
      [1] https://github.com/ros2-rust/ros2_rust
  • Soweit ich mich erinnere, war Stacking ein sehr schwieriges Problem, als ich vor Jahrzehnten eine Rigid-Body-Physics-Engine gebaut habe
    Die damals beste Lösung, um zu vermeiden, dass Objekte im Boden versinken, bestand darin, vom Boden aus einen gerichteten azyklischen Graphen zu erstellen, der die Objekte nach außen drückt
    Für die Konvergenz musste man mehrfach iterieren, und es fühlte sich ziemlich hacky an
    Ich frage mich, ob dieses Problem heute gelöst ist. In diesem Projekt habe ich keine Erwähnung von Stacking gefunden

    • Der Autor von Box2D hat genau zu diesem Thema einen hervorragenden Beitrag veröffentlicht: https://box2d.org/posts/2024/02/solver2d/
      Das am Ende des Beitrags verlinkte Video des Autors zeigt, wie die verschiedenen Solver mehrere schwierige Stacking-Probleme behandeln: https://youtu.be/sKHf_o_UCzI
    • Heutzutage funktioniert Stacking gut
      Man braucht keinen azyklischen Graphen, und mit ausreichend hoher Anzahl an Solver-Iterationen konvergiert es
      Angesichts der Zahl von Kontakt- und Reibungsconstraints ist mehrfaches Iterieren naheliegend; wenn man das maximale Residuum verfolgt, kann man so lange laufen lassen, bis es fast 0 erreicht
      Der etwas kaputte Teil ist, dass Kollisionen und Solver nur mit einer begrenzten Update-Rate laufen
      Wenn man von Anfang an in einem durchdrungenen Zustand startet, muss das aufgelöst werden; reale Objekte durchdringen sich aber nicht so, daher ist das eine eher „künstliche“ Behandlung, die zusätzliche Bewegung erzeugt und die Stabilität von Stapeln verringern kann
      Trotzdem gibt es mehrere Möglichkeiten, das zu umgehen, und populäre Physics-Engines haben jeweils auf irgendeine Weise eine Lösung dafür
  • Rust scheint die Klischees immer wieder zu bestätigen
    Mir fällt der Witz ein: Es gibt 50 in Rust geschriebene Game-Engines, aber nur 5 in Rust geschriebene Spiele

    • Ich wünschte, es gäbe wenigstens 50 Physics-Engines
      Rapier erfüllt nicht genau die Anforderungen, die ich brauche, aber es gibt keine gute Alternative
    • Ein Spiel, das ich kürzlich mit Spaß gespielt habe, war, soweit ich mich erinnere, in Rust geschrieben: (the) Gnorp Apologue (https://gnorp.dev/)
      Für kleine 2D-Spiele, die nicht viel Engine-Code benötigen, scheint es also machbar zu sein
      Dieses Spiel erledigte den Großteil über SDL
  • Ich habe mit Rapier auch eine kleine Web-Demo gebaut: https://github.com/iErcann/NotRoblox
    Rust habe ich dabei nicht verwendet
    Was mir gefallen hat: Die Dokumentation ist besser als bei AmmoJS. Bei AmmoJS musste ich pybullet lesen
    Es ist relativ aktuell und kann sowohl auf dem Server (Node) als auch auf dem Client (Browser) laufen
    Hier läuft es serverseitig, aber man könnte es auch auf beiden Seiten laufen lassen und Client Prediction sowie Korrektur implementieren
    Auch das Bundle ist klein. AmmoJS lag, glaube ich, bei etwa 2 MB

    • Für die Rust-Seite ist die Rapier-Dokumentation meines Wissens nicht auf dem neuesten Stand
      Zum Glück ist sie an eine ältere Version gebunden, also ist es nicht allzu schlimm
  • Auch die JavaScript-Interoperabilität ist wirklich gut: https://www.rapier.rs/docs/user_guides/javascript/getting-st...

  • Dimforge hatte früher eine Physics-Engine namens nphysics, die Soft Bodies und Multibodies unterstützte
    Sie wurde nun zugunsten von Rapier eingestellt, aber Rapier unterstützt nicht einmal die Hälfte dieser Funktionen oder anderer Dinge, die nphysics konnte
    Im Ergebnis ist nphysics zu alt, um im modernen Ökosystem gut nutzbar zu sein, und Rapier ist zu neu, sodass ihm deutlich mehr Funktionen fehlen
    Ähnliches gab es schon einmal. Eine Fluid-Simulationsbibliothek namens Salva unterstützte bidirektionale Kopplung mit nphysics und lief auf allen GPUs/CPUs, wurde nun aber zugunsten von Sparkl eingestellt
    Sparkl hat diese Funktionen jedoch nicht und unterstützt nur CUDA. Damit ist Salva genauso veraltet wie nphysics, während Sparkl zu neu ist, viel weniger Funktionen hat und keine Cross-Platform-Unterstützung bietet
    Es wirkt sogar absichtlich so. Im Grunde wurde „der Code neu geschrieben, um ihn weniger Cross-Platform zu machen“
    Ich hoffe, dass das ständige Neuschreiben irgendwann aufhört und man sich auf etwas einpendelt, das tatsächlich alle benötigten Funktionen unterstützt
    Wenn aber bei jedem Rewrite Funktionen verloren gehen, weiß ich nicht, ob das Dimforge-Ökosystem für mich passt
    Woher soll man wissen, ob Rapier nicht irgendwann zugunsten von etwas noch Neuerem eingestellt wird und diese neue Engine dann nicht einmal die Hälfte der Rapier-Funktionen unterstützt
    Ich verstehe, dass ein neues Projekt nicht alle Funktionen des ausgereiften nphysics unterstützen kann
    Das Problem ist aber, dass genau dieses ausgereifte nphysics vollständig eingestellt wurde und nicht mehr gewartet wird
    Wenn es bei Dimforge diesen Präzedenzfall nicht schon gäbe, wäre das eine unrealistische Sorge, aber es gibt ihn
    Vielleicht erreicht Rapier irgendwann den Funktionsumfang, den nphysics schon vor 5 Jahren hatte; für Entwickler, die auf den derzeit fehlenden Funktionen etwas aufbauen möchten, fühlt es sich aber wie ein willkürlicher Rückschritt um 5 Jahre an