3 points par GN⁺ 2024-02-29 | 1 commentaires | Partager sur WhatsApp
  • Rapier est un ensemble de moteurs physiques basés sur Rust destiné aux applications nécessitant une physique en temps réel, comme les jeux, l’animation et la robotique
  • Il vise une exécution rapide et stable, avec une prise en charge optionnelle du déterminisme multiplateforme si nécessaire
  • Il fournit les fonctionnalités nécessaires à la simulation physique, notamment les collisions et forces de corps rigides, les contraintes d’articulation, les événements de contact et capteurs, ainsi que les instantanés
  • Des bindings JavaScript permettent d’utiliser Rapier dans des environnements autres que Rust
  • C’est un projet open source gratuit sous licence Apache 2.0, développé par Dimforge et soutenu via GitHub Sponsors

Cas d’usage visés par Rapier

  • Rapier est un ensemble de moteurs physiques 2D et 3D écrit en Rust
  • Il s’adresse principalement aux applications nécessitant un traitement physique en temps réel
    • Jeux vidéo
    • Animation
    • Robotique
  • Son objectif de conception est un fonctionnement rapide et stable, avec une prise en charge optionnelle du déterminisme multiplateforme

Fonctionnalités fournies et mode de distribution

  • Il inclut les principales fonctionnalités nécessaires à la simulation physique
    • Collisions de corps rigides et forces
    • Contraintes d’articulation
    • Événements de contact et capteurs
    • Instantanés
    • Déterminisme multiplateforme optionnel
    • Bindings JavaScript
  • Rapier est gratuit et open source, distribué sous licence Apache 2.0
  • Il est développé par l’entreprise open source Dimforge
  • Il est possible de le soutenir via GitHub Sponsors

1 commentaires

 
GN⁺ 2024-02-29
Commentaires sur Hacker News
  • J’ai créé un jeu multijoueur en ligne avec le mode déterministe de Rapier
    Le principe est que les joueurs, chacun leur tour, percutent des insectes pour les envoyer vers l’équipe adverse et capturer des collines
    Il n’y a pas encore de mode solo, et écrire l’IA est plus compliqué que pour un jeu de type échecs que j’avais fait auparavant
    Le jeu est visible sur https://evrimzone.itch.io/crittershowdown et le code source de la physique/logique de jeu se trouve sur https://github.com/evrimoztamur/crittershowdown/blob/e4d9a19...
    J’ai l’intention d’écrire plus tard un billet sur la façon dont j’ai assemblé tout ça et ce que j’ai appris, mais globalement c’est une bibliothèque très solide, et grâce à une API conçue dans l’esprit de Rust, j’ai pu implémenter tout ce dont j’avais besoin

    • Ça a l’air amusant. Je me demande si le déploiement sur le site web a été simple
      Je me demande si c’est compilé en WebAssembly, ou si toute la logique est hébergée sur un serveur local
    • J’ai commencé à utiliser Rapier2D pour créer un jeu multijoueur côté serveur, donc j’espère que l’article à ce sujet arrivera vite
  • Il y a quelques mois, je suis tombé dans le monde de l’algèbre géométrique (Geometric Algebra), et ça m’a semblé être une manière étonnamment concise et intuitive de traiter des géométries très variées, en 2D, 3D, 4D et au-delà, y compris non euclidiennes
    Du coup, je me suis demandé si l’algèbre géométrique pouvait constituer une bonne base pour un moteur physique
    Il existe quelques bibliothèques Rust qui ont l’air intéressantes [1][2], mais rien qui semble vraiment largement adopté
    Je me demande si quelqu’un ici a exploré ce sujet
    [1]: https://crates.io/keywords/geometric-algebra
    [2]: https://github.com/Lichtso/geometric_algebra
    Si vous voulez vous y mettre, “Why can't you multiply vectors?” de Freya Holmér peut être une bonne porte d’entrée : https://www.youtube.com/watch?v=htYh-Tq7ZBI et https://bivector.net/index.html

    • Fait amusant, Excalidraw a utilisé l’algèbre géométrique, et elle alimente encore certaines interactions aujourd’hui : https://github.com/excalidraw/excalidraw/blob/master/package...
    • La partie la moins intéressante dans un moteur physique, c’est la représentation des vecteurs
      L’algèbre géométrique est isomorphe à l’algèbre vectorielle « classique » de Heaviside, et les vrais problèmes difficiles concernent plutôt la gestion des collisions, la conservation de l’énergie et la stabilité
    • Je suis tombé dans le même terrier de l’algèbre géométrique, ainsi que dans Clojure, qui est lui aussi une autre manière « étonnamment concise et intuitive » de faire les choses
      J’ai donc créé une bibliothèque capable de générer une algèbre géométrique arbitraire et d’effectuer plein d’opérations intéressantes, qui peut aussi servir de base à un moteur physique
      Si ça vous intéresse, c’est ici : https://cljdoc.org/d/net.clojars.jordibc/geometric-algebra/
    • Tutoriel connexe : https://www.youtube.com/watch?v=5R2sv9GCwz0
    • La bibliothèque qui attire davantage l’attention est plutôt celle-ci : https://github.com/fu5ha/ultraviolet
  • J’ai écrit un guide sur le plugin Bevy Rapier pour Rust : https://taintedcoders.com/bevy/rapier/
    Il existe aussi Bevy XPBD comme alternative intéressante côté Bevy, et j’ai également écrit un article dessus : https://taintedcoders.com/bevy/xpbd/

    • Voir un système considérer les objets qui se déplacent lentement comme immobiles me met mal à l’aise
      Le « sleeping » est une technique qui améliore les performances en réduisant le coût de simulation des objets immobiles, et elle peut être ajustée via la ressource SleepingThreshold
      L’exemple de valeurs par défaut donne linear: 0.1, angular: 0.2
    • Je fais actuellement un jeu de combat 2D basé sur la physique avec xpbd, et jusqu’ici j’en suis plutôt content
      Jusqu’à présent, je n’ai eu qu’un seul problème où certaines collisions disparaissaient pendant une frame, mais c’est le genre de chose qu’on contourne facilement, ou mieux encore qu’on peut signaler pour correction
    • XPBD est assez intéressant, donc j’ai fait quelques implémentations d’essai, et dans un projet récent de game jam j’ai intégré un XPBD dédié aux AABB
      Je n’ai pas encore réussi à bien gérer la rotation, mais pour le reste on a l’impression que la complexité fond complètement
      Algèbre linéaire ? Inutile. C’est juste un Vec3. Des matrices ? Un solveur ? Il suffit de satisfaire toutes les contraintes de manière itérative, comme si on était revenus en 1998
      Marge de collision ? Question de compétence. Broad phase ? GJK ? Inutile de trop réfléchir, laissez les CPU modernes s’en charger
      Après avoir optimisé collect_pairs puis réalisé que le vrai goulot d’étranglement était malloc et l’avoir corrigé, ça gère sans problème une centaine d’objets. Pas besoin de Bullet
      L’étape de correction de vitesse m’a aussi embrouillé au début, mais après avoir prototypé avec des AABB, j’ai l’impression de pouvoir la retransposer à des formes plus générales
      Au départ, j’avais sauté cette étape, et du coup toutes les collisions se comportaient comme si elles étaient légèrement élastiques
  • Dimforge fait vraiment un travail impressionnant
    Si nalgebra + Rust pouvait remplacer Eigen + C++ dans des domaines comme la localisation et la cartographie en robotique, ce serait vraiment prometteur

    • Ces derniers temps, je fais la plupart de mes projets de robotique en Rust, et le temps que l’industrie gaspille avec les idiomes propres à C++ est absurde
      En Rust, beaucoup de choses fonctionnent tout simplement. C’est juste dommage qu’il y ait encore une vieille garde qui refuse d’investir dans Rust sans démordre
      Honnêtement, je comprends pourquoi, vu l’énorme industrie qui gravite autour du code de robotique en C++
    • J’aimerais vraiment contribuer à rendre ça possible
      Je me demande s’il existe actuellement un framework de robotique valable en Rust
      J’ai entendu dire que ROS2 intégrait lentement Rust [1], mais je ne sais pas vraiment où ça en est
      Comme l’intégration/l’abstraction matérielle est déjà faite en C++, ROS peut être une bonne porte d’entrée vers la fusion de capteurs, la cartographie et la localisation
      Je me demande aussi si des entreprises l’utilisent
      [1] https://github.com/ros2-rust/ros2_rust
  • De souvenir, quand je développais des moteurs de physique pour corps rigides il y a plusieurs décennies, le stacking était un problème vraiment difficile
    À l’époque, la meilleure solution que nous avions trouvée pour éviter que les objets s’enfoncent dans le sol consistait à construire un graphe orienté acyclique partant du sol et poussant les objets vers l’extérieur
    Il fallait itérer plusieurs fois pour converger, et ça donnait une impression assez bricolée
    Je me demande si ce problème a été résolu aujourd’hui. Je n’ai trouvé aucune mention du stacking dans ce projet

    • L’auteur de Box2D a justement publié un excellent article sur le sujet : https://box2d.org/posts/2024/02/solver2d/
      La vidéo de l’auteur liée en bas de l’article montre comment chaque solveur gère plusieurs problèmes de stacking difficiles : https://youtu.be/sKHf_o_UCzI
    • Aujourd’hui, le stacking fonctionne bien
      Il n’y a pas besoin de graphe acyclique, et en augmentant suffisamment le nombre d’itérations du solveur, on finit par converger
      Vu le nombre de contraintes de contact et de friction, faire plusieurs itérations est naturel, et si on suit le résidu maximal, on peut continuer jusqu’à approcher presque 0
      Le point un peu bancal, c’est que les collisions et le solveur ne tournent qu’à une fréquence de mise à jour limitée
      Si l’on commence déjà dans un état d’interpénétration, il faut le résoudre, mais comme les objets réels ne s’interpénètrent pas ainsi, le traitement est un peu « factice » et peut générer des mouvements supplémentaires qui dégradent la stabilité des piles
      Cela dit, il existe plusieurs moyens de contourner ça, et les moteurs de physique populaires ont chacun leur propre solution d’une manière ou d’une autre
  • Rust semble continuer à confirmer les stéréotypes
    Ça me rappelle la blague selon laquelle il existe 50 moteurs de jeu écrits en Rust, mais seulement 5 jeux écrits en Rust

    • J’aimerais bien qu’il y ait au moins 50 moteurs de physique
      Rapier ne couvre pas exactement mes besoins, mais il n’y a pas de bonne alternative
    • Je crois qu’un jeu auquel j’ai joué récemment avec plaisir avait été écrit en Rust : (the) Gnorp Apologue (https://gnorp.dev/)
      Donc ça semble faisable pour de petits jeux 2D qui n’ont pas besoin d’écrire beaucoup de code moteur
      Dans ce cas, le jeu s’appuyait surtout sur SDL
  • J’ai aussi réalisé une petite démo web avec Rapier : https://github.com/iErcann/NotRoblox
    Je n’ai pas utilisé Rust
    Ce qui m’a plu, c’est que la documentation est meilleure que celle d’AmmoJS. Pour AmmoJS, il fallait lire pybullet
    C’est relativement récent, et ça peut tourner à la fois côté serveur (Node) et côté client (navigateur)
    Ici je l’exécute côté serveur, mais il serait aussi possible de le faire tourner des deux côtés et d’implémenter la prédiction et la correction côté client
    Le bundle est aussi léger. Il me semble qu’AmmoJS faisait dans les 2 Mo

    • Côté Rust, il me semble que la documentation de Rapier n’est pas à jour
      Heureusement, comme elle est restée bloquée sur une ancienne version, ce n’est pas catastrophique
  • L’interopérabilité JavaScript est également vraiment bonne : https://www.rapier.rs/docs/user_guides/javascript/getting_st...

  • Chez Dimforge, il existait autrefois un moteur physique appelé nphysics, qui prenait en charge les soft bodies et les multibodies
    Il a ensuite été abandonné au profit de Rapier, mais Rapier ne prend même pas en charge la moitié de ces fonctionnalités, ni d’autres que nphysics avait
    Résultat, nphysics est aujourd’hui trop ancien pour être vraiment utilisable dans l’écosystème moderne, et Rapier est trop récent pour offrir un ensemble de fonctionnalités comparable
    Ce n’est pas la première fois que cela arrive. Il y avait aussi une bibliothèque de simulation de fluides appelée Salva, qui supportait un couplage bidirectionnel avec nphysics et fonctionnait sur GPU et CPU, mais elle a maintenant été abandonnée au profit de Sparkl
    Sauf que Sparkl n’a pas ces fonctionnalités et ne prend en charge que CUDA. Du coup, Salva est aussi obsolète que nphysics, et Sparkl est trop récent, avec beaucoup moins de fonctions et sans support multiplateforme
    On dirait même que c’est intentionnel. Comme si le code avait été « réécrit pour être moins multiplateforme »
    J’espère qu’un jour les réécritures incessantes cesseront et qu’on se stabilisera sur quelque chose qui prend réellement en charge toutes les fonctionnalités nécessaires
    Mais si chaque réécriture fait perdre des fonctionnalités, je ne sais pas si l’écosystème Dimforge me conviendra
    Comment savoir si Rapier ne sera pas lui aussi abandonné un jour au profit de quelque chose de plus récent, qui ne prendra même pas en charge la moitié des fonctionnalités de Rapier
    Je comprends qu’un nouveau projet ne puisse pas immédiatement offrir toutes les fonctionnalités du nphysics mature
    Mais le problème, c’est précisément que ce nphysics mature a été totalement abandonné et n’est plus maintenu
    Si Dimforge n’avait pas déjà des antécédents en la matière, ce serait une inquiétude irréaliste, mais il y a un historique
    Peut-être qu’un jour Rapier atteindra enfin le niveau fonctionnel que nphysics avait déjà il y a 5 ans, mais pour un développeur qui veut construire quelque chose sur les fonctionnalités manquantes aujourd’hui, cela ressemble à un retour en arrière arbitraire de 5 ans