La physique des jeux: système masse-ressort
Jeudi 20 novembre 2008 à 18 h 55
Je termine mon école d'ingé par un choix de modules dans lequel j'ai choisi réalité virtuelle.
L'évaluation est basée sur un projet à faire en une semaine, et j'ai un sujet plutôt cool mettant en place un moteur physique masse/ressort.
Jeu + physique masse/ressort = World of Goo!

C'est ma première tentative à coder un moteur physique, et je m'étais toujours dit que les gens qui codaient ces trucs devaient être d'affreux geeks plongés dans des bouquins de maths: que neni! Tout est en fait plutôt simple. Sans comprendre grand chose à la physique, on peut s'en sortir: il suffit de connaitre les formules et de comprendre un peu comment fonctionnent des vecteurs.
Un ressort exerce une force f=-kx sur une masse. (k constante, x distance entre l'objet attaché au ressort et la position du ressort à vide)
Ce ressort est également affecté par une force de frottement f=-bv (b constante, v vitesse de l'objet - sinon le ressort ne s'arrête jamais d'osciller)
Gravité: f = -mg
Enfin, on doit savoir que somme des force = masse * accélération.
A la fin, on a du coup, pour chaque goo:
-g -kx -bv = masse du goo * acceleration.
C'est super, mais nous ce qui nous intéresse c'est de savoir: à l'image suivante, comment mon goo aura bougé, ce que ne donne pas cette équation. Là l'inconnu c'est l'accélération, et c'est une formule très moche qui fait intervenir:
1. La position de l'objet soumis au ressort
2. Sa vitesse (dérivée de la position)
3. L'accélération (dérivée de la vitesse)
Tout ça donne lieu a des calculs très complexes de résolution d'équations différentielles, mais pour un jeu vidéo, on a besoin que ça aille vite et on utilise donc une approximation. Il en existe plusieurs mais la plus connue est la méthode d'Euler:
Vitesse de l'objet à la frame suivante = vitesse courante + force/masse*interval de temps de la frame (approximation)
Position de l'objet à la frame suivante = position courante + vitesse*interval de temps de la frame (correct)
Hop on mixe tout ça dans un shaker et ça donne une tentative de World of Goo:
CLICK
Il y a une console (²) codée un peu à la va vite qui permet de modifier les constantes et ainsi tester l'influence sur le moteur physique:
springk (constante de raideur)
springkf (constante de friction)
Essayez de bidouiller, vous allez voir qu'avec une faible friction et une trop forte raideur les ressorts se mettent à osciller violemment jusqu'à ce que le système devienne instable. Ces constantes doivent être négatives.
... Mais ca ne se comporte pas comme World of Goo!
- Les tours ne s'écroulent pas: une boule seule décalée de la structure devrait faire levier sur les autres: cette force n'est pas prise en compte et je ne sais pas trop comment l'implémenter.
- Les ressorts du dessous de la tour s'affaissent progressivement sous le poids des autres masses. J'ai l'impression que les auteurs de World of Goo ont triché en mettant volontairement des constantes de rappel plus fortes pour les goos soutenant d'autres goo afin d'estomper ce phénomène d'écrasement. A creuser... Si vous avez des idées, je prends :)
L'évaluation est basée sur un projet à faire en une semaine, et j'ai un sujet plutôt cool mettant en place un moteur physique masse/ressort.
Jeu + physique masse/ressort = World of Goo!

C'est ma première tentative à coder un moteur physique, et je m'étais toujours dit que les gens qui codaient ces trucs devaient être d'affreux geeks plongés dans des bouquins de maths: que neni! Tout est en fait plutôt simple. Sans comprendre grand chose à la physique, on peut s'en sortir: il suffit de connaitre les formules et de comprendre un peu comment fonctionnent des vecteurs.
Un ressort exerce une force f=-kx sur une masse. (k constante, x distance entre l'objet attaché au ressort et la position du ressort à vide)
Ce ressort est également affecté par une force de frottement f=-bv (b constante, v vitesse de l'objet - sinon le ressort ne s'arrête jamais d'osciller)
Gravité: f = -mg
Enfin, on doit savoir que somme des force = masse * accélération.
A la fin, on a du coup, pour chaque goo:
-g -kx -bv = masse du goo * acceleration.
C'est super, mais nous ce qui nous intéresse c'est de savoir: à l'image suivante, comment mon goo aura bougé, ce que ne donne pas cette équation. Là l'inconnu c'est l'accélération, et c'est une formule très moche qui fait intervenir:
1. La position de l'objet soumis au ressort
2. Sa vitesse (dérivée de la position)
3. L'accélération (dérivée de la vitesse)
Tout ça donne lieu a des calculs très complexes de résolution d'équations différentielles, mais pour un jeu vidéo, on a besoin que ça aille vite et on utilise donc une approximation. Il en existe plusieurs mais la plus connue est la méthode d'Euler:
Vitesse de l'objet à la frame suivante = vitesse courante + force/masse*interval de temps de la frame (approximation)
Position de l'objet à la frame suivante = position courante + vitesse*interval de temps de la frame (correct)
Hop on mixe tout ça dans un shaker et ça donne une tentative de World of Goo:
CLICK
Il y a une console (²) codée un peu à la va vite qui permet de modifier les constantes et ainsi tester l'influence sur le moteur physique:
springk (constante de raideur)
springkf (constante de friction)
Essayez de bidouiller, vous allez voir qu'avec une faible friction et une trop forte raideur les ressorts se mettent à osciller violemment jusqu'à ce que le système devienne instable. Ces constantes doivent être négatives.
... Mais ca ne se comporte pas comme World of Goo!
- Les tours ne s'écroulent pas: une boule seule décalée de la structure devrait faire levier sur les autres: cette force n'est pas prise en compte et je ne sais pas trop comment l'implémenter.
- Les ressorts du dessous de la tour s'affaissent progressivement sous le poids des autres masses. J'ai l'impression que les auteurs de World of Goo ont triché en mettant volontairement des constantes de rappel plus fortes pour les goos soutenant d'autres goo afin d'estomper ce phénomène d'écrasement. A creuser... Si vous avez des idées, je prends :)
13 commentaires, dernier de El_Porico.






















