Voir la version complète : Déplacements, rotations, rebonds...
Bonsoir,
J'essaye de coder un moteur physique à peu près correcte (sans libs externes car interdit et car sans intérêts) d’un jeu de course en 2D qui gère les déplacements d’un véhicule et les collisions avec des objets de géométrie quelconque. Je voudrais éviter de faire du bricolage du genre "la voiture tourne trop vite suite à certaines collisions, donc je majore la vitesse angulaire de mon véhicule avec un simple if", si la vitesse angulaire est absurde dans certains cas je considère que le moteur physique est mauvais, ceci pour garder un code clair et pour éviter d’avoir à traiter pleins d’exceptions.
Pour commencer je me questionne sur la façon de gérer les rotations du véhicule.
J’ai fait plusieurs essais :
1) La position du véhicule est calculée grâce à la methode d'Euler à partir d’un vecteur accélération orientable. J’ai un truc qui ressemble à :
x = … + acc*cos(a)*dt + …
y = … + acc*sin(a)*dt + …
où a est l’angle entre le vecteur vitesse et l’axe des abscisses (je crois que c’est a = arctan(vx/vy)) auquel j’ajoute une petite valeur si le joueur donne l’ordre de tourner.
Gros inconvénient : la relation étroite entre le vecteur vitesse et la rotation ne permet pas d’inverser le vecteur vitesse, par exemple pour une marche arrière ou un rebond, sans faire une rotation de 90°.
2) Même chose sauf que l’angle est indépendant du vecteur vitesse. Ici l’angle est aussi calculé par le méthode d'Euler.
Les mouvements sont assez satisfaisants : video1 (gif animé) (http://01nuclear.free.fr/video1.gif)
Par contre pour les rebonds c’est pas encore ça :
- quand ça marche à peu près : video2 (gif animé) (http://01nuclear.free.fr/video2.gif)
- quand ça bug (souvent) : video3 (gif animé) (http://01nuclear.free.fr/video3.gif)
Pour gérer les rebonds j’ai redéfini le vecteur vitesse : il devient son symétrique par rapport à la normale de la face en collision. J’ai aussi modifié la vitesse angulaire selon l’angle du rebond.
Donc si vous avez des idées ?
Je ne suis pas contre utiliser les moments cinétiques si on m’explique concrètement comment les manipuler pour les déplacements et surtout pour les rebonds. :00000023:
Lightness1024!
01/12/2005, 02h07
tu as l'air assez exigeant sur les reactions du moteur.
a mon avis il faut faire des trucs plus séparés.
genre les masses dans un coin, les accelerations dans un autre, les interties, les forces et les moments.
pour les rotations tout est plus compliqué, parce que la on parle de physique des solides. la physique des points c'est bien facile mais c'est pas utilisable dans ce cas. (enfin si mais seulement pour les translations).
pour les rotations, il te faut une matrice d'inertie.
enfin disons que tu dois appliquer le théoreme des moments cinétiques exactement comme tu faisais avec le PFD pour les forces.
et tu calcules la résultante du moment avec les forces appliquées sur ton solide avec la formule des transferts bien connue. (bras de levier pdt_vectoriel force).
un choc c'est pas facile, parce que un choc, c'est une accélération infinie.
heureusement en informatique rien n'est infinitésimal ou infini grace à la granularisation de la simulation (dt != 0).
tu pourras calculer avec précision les forces de répulsion que causent un choc sur un point de ta voiture.
(remarque: je peux confondre parfois force et acceleration, ceci est normal seule une constante masse les séparent, du moins dans le cas des translations ;) )
une collision engendre une force du mur sur la voiture, dans une direction contenue dans le cone de frottement, et d'une force suffisante pour rediriger la vitesse de la voiture en dehors de la matiere du mur.
en réalité si l'inertie est trop importante le mur est pénétré (cassé) car n'oublions pas que la force du mur sur la voiture n'est que résultante de la somme des interactions de toutes ses molécules. Elles meme s'appyant sur le sol à qui l'énergie est transférée en cas de choc.
il récupère ainsi l'énergie amputée lors de l'accélération de la voiture.
c'est d'ailleurs assez amusant philosophiquement.
c'est le théoreme du centre de masse si mes souvenirs sont bons :)
(tu peux faire bouger les composants d'un système matériel isolé, son centre de masse reste en mouvement rectiligne uniforme dans un référentiel galiléen)
c'est pourquoi le world jump day était un gros canulard décelable dans la seconde de lecture du titre.
treve de trevage :)
donc bon, déja suivre la piste de l'intertie d'entrainement et de l'intertie de coriolis, les calculs de moment au point du centre de masse pour les rotations, et la résultante pour les translations !
bon courage
le probleme majeur avec un jeu de voiture, c'est où arrete-on les approximations pour faire du réaliste (et inversement) ?
parce que, par exemple, le plus compliqué a mon avis, c'est la liaison entre les roues et le sol.
c'est super compliqué parce que elles ne sont pas isotropes. par exemple les roues arriere n'engendrent pas la meme résistance au déplacement latéral qu'au déplacement longitudinal (logique, on veut pouvoir rouler sans avoir besoin de la puissance d'un tracteur, et on veut tenir dans les virage sans se croire sur un lac glacé).
en fait, tout n'est que somme de forces ou couples de force. et le pire est a venir, dès qu'on parle de frottements !
quand déterminer que la voiture est en glissement ?
et c'est pire encore si on considère les coefficients de frottement dynamiques et statiques.
ce qui est important pour un comportement réaliste en plus !
le jeu de voiture c la pire torture physique qui existe a mon avis dans un jeu vidéo.
tu as l'air assez exigeant sur les reactions du moteur.
où arrete-on les approximations pour faire du réaliste (et inversement) ?
Mon moteur physique n’a pas besoin de reproduire fidèlement la réalité. Ca se passe dans le futur avec des voitures qui volent à quelques mètres du sol et il se rapprochera plus d’un jeu d’arcade que d’une simulation.
enfin disons que tu dois appliquer le théoreme des moments cinétiques exactement comme tu faisais avec le PFD pour les forces.
En y regardant de plus près, c’est plus ou moins ce que je fais en appliquant la méthode d’Euler sur le calcul de l’angle de rotation de mon véhicule. En fait, le moteur physique retourne en sortie les coordonnées du centre du véhicule et son angle de rotation. Donc j’ai juste besoin de connaître un angle indépendamment des moments des points du véhicule, du moins pour les déplacements.
une collision engendre une force du mur sur la voiture (...)
Jusqu’à maintenant, je modifiais le vecteur vitesse plutôt que de créer une nouvelle force, parce que pour moi cette force n’existe que pendant une durée nulle si les objets en contacts ne sont pas « élastiques ». Mais j’admets la nécessité de créer cette force.
Je crée donc une force R que j’ajoute à la résultante des forces. Pendant combien de temps dois-je appliquer cette force ?
Comment dois-je modifier l’accélération de l’angle de rotation ?
Lightness1024!
02/12/2005, 00h07
voila tout le probleme, la durée nulle du choc.
dans un moteur géométrique classique de detection des collisions, on agit sur les vitesses pour modifier les trajectoires. logique car c'est pratique.
ca va bien dans le cas d'un FPS parce que l'objet est approximé comme étant un point matériel (solide, torseur des forces intérieures nul, et seulement des translations).
dans ton cas, un choc doit engendrer un transfert d'énergie cinétique "d'entrainement" vers une énergie cinétique "de rotation".
je met entre guillement car en mécanique la définition de l'énergie cinétique c'est la somme des deux en fait. (disons que si le choc ne déforme rien, et ne casse rien, alors l'énergie cinétique de ton systeme { voiture } est constante)
je pense pas que les considérations énergétiques puissent etre super utiles pour faire des calculs appliqués mais en tout cas pour vérifier la correction d'une réaction ou pour bien voir les choses dans son esprit c'est une bonne chose IMHO.
donc, si j'en reviens aux forces, en effet, il faudra surement calculer cette force. voila ce que je préconise comme ca au pif sans plus d'études sur la question:
ton modele sait déja faire rebondir la voiture correctement si tu joues sur un changement de direction du vecteur vitesse.
et bien plutot que de passer aux forces, laisse le comme ca.
Mais faut AUSSI le calcul de la force de choc si elle existait et sers t-en pour calculer le moment du couple engendré par cette force et la force d'inertie appliquée au centre de masse.
ce moment engendrera une vitesse de rotation inversement proportionnelle a la masse. (du moins si on respecte les unités SI; nm, m, rad/s, kg)
tout ca, ca fait un peu étalage de science sans trop de details genre je fait mon gros savant lol j'aime pas trop parraitre comme ca mais donner des details quand on a pas le projet a développer soit meme demande de prendre un papier un crayon et de plancher pour avoir des resultats précis a annoncer.
alors que ce n'est meme pas notre projet :)
je dis pas que je veux pas t'aider, disons que je donne des pistes.
au fur et a mesure, si tes questions se spécialises et que tu arrives a faire le reste tout seul; de un, tu seras plus fier de toi, de deux, ca nous prendra moins de temps pour te répondre.
veuala, désolé si je suis illisible, si les phrases sont trop longues, si ya des phaûteuhs de frappe ou autre :D
ps: un conseil, n'allez pas voir "foon"
Je suis en train d'etudier le concept d'impulsion et j'en profite pour refaire plus propement ce qui a deja ete fait sur les deplacements et la detection de collision. Donc je reviendrai bientot quand j'aurais fini de coder tt ca :00000023:
Voilà, maintenant moteur physique fonctionne mieux.
J’ai essayé en manipulant la notion d’impulsion grâce aux formules décrites sur ce site : http://www.myphysicslab.com/collision.html
Ca marche bien à condition de déterminer une valeur réaliste pour chaque constante, ce qui n’est pas forcement évident. Néanmoins je risque d’avoir du mal à modifier le code parce que n’ai pas tout compris, donc j’ai aussi expérimenté une méthode géométrique simple :
- Plutôt que de calculer le symétrique du vecteur vitesse par rapport à la normale de la face en collision, j’ajoute au vecteur vitesse la projection du vecteur vitesse sur la normale. Je peux ainsi paramétrer facilement le rebond : multiplier par 1 la projection compense exactement la composante du vecteur vitesse qui rentre dans l’objet, au dessus de 1 la voiture rebondie.
- La vitesse angulaire est calculée à partir de l’angle entre le vecteur vitesse et le segment qui a pour extrémités le centre de masse et le point de collision.
Mais de temps en temps la voiture reste accrochée au mur et finie par rentrer dans l’objet.
Atréides
20/01/2006, 18h38
Hmm.. Tu as essayé de reculer ton auto jusqu'à ce qu'elle ne soit plus en collision ?
Nyx : bonne solution. C'est ce que j'ai trouve hier en gribouillant sur un papier.
Si tu as un vecteur n de normale de norme 1, la projection de ton vecteur vitesse v sur ta normale est:
v(n) = d.n
avec d le produit scalaire de v et n, c'est-a-dire:
d = x(v)x(n) +y(v)y(n)
donc, ton vecteur reflechi sera v' = v - 2d.v(n). Mais il te faut aussi calculer le point de collision, comme dit par Atreides.
J'ai le meme probleme que toi dans mon petit casse brique basique.
Tu as essayé de reculer ton auto jusqu'à ce qu'elle ne soit plus en collision ?
Je ne prends pas en compte le déplacement qui a occasionné la collision (en clair: je reviens en arrière). Ce n'est pas très précis mais ça ne se remarque pas.
Mais il te faut aussi calculer le point de collision
Je n'ai pas trouvé mieux que de calculer les coordonnées de l'intersection de la face en collision avec le vecteur vitesse appliqué au point à l'intérieur de l'obstacle.
J'ai le meme probleme que toi dans mon petit casse brique basique.
As-tu besoin de calculer des vitesses angulaires après collision ?
La technique citée plus haut n'est pas très crédible, donc si t'as des idées...
Lightness1024!
30/01/2006, 19h10
a mon avis sur un casse brique une vitesse angulaire... faire tourner un cercle sur lui meme ca peut etre scientifiquement interressant mais graphiquement la forme étant invariante par toute rotation autour de son centre........
:)
j'aurais une question, la voiture étant rectangulaire (du moins une forme englobante) ton point de collision est t-il calculé avec un vecteur vitesse qui part du centre de la voiture ou bien du point de la voiture le plus proche avec le mur.
car dans le premier cas, la voiture peut rentrer en intersection avec le mur et meme y aller encore plus si elle se met en rotation.
Je commence par détecter le point de la voiture à l'intérieur du mur (ou inversement), qui est donc à l'origine de la collision, et c'est de ce point que part mon vecteur vitesse.
Lightness1024!
30/01/2006, 21h46
as tu lu ca ?
http://www.nofrag.com/2004/oct/23/14529/
ca répond pas a grand chose mais ca souleve les désavantages des techniques auxquelles ont penses trop facilement.
Je commence tout juste à prendre connaissance de ces tuts , ça me semble génial :
Tutoriels collision et réponse (http://www.harveycartel.org/metanet/tutorials.html)
Demo1 (http://www.harveycartel.org/metanet/tutorials/diagrams/tutA_demo.html)
Demo2 (http://www.harveycartel.org/metanet/tutorials/diagrams/tutB_demo04.html)
Et le jeu N est à télécharger également , c'est excellent.
Salut
Je reviens avec de nouvelles questions :)
J’ai cherché en vain comment calculer la valeur de la vitesse angulaire sans passer par les forces de réaction. J’en ai eu marre, et j’ai tout recommencé avec les torseurs.
Le résultat est là : http://zone51da.free.fr/physikv2.zip(il faut attendre quelques secondes avant de déplacer le véhicule sinon il disparaît ).
Donc grâce à la formule des déplacements de torseurs, je pense pouvoir résoudre mes problèmes de rotations. Se pose alors le problème attendu (voir les messages précédents) du calcul de la norme de la force de réaction. J’ai récupéré mon calcul du changement du vecteur vitesse qui détermine le vecteur vitesse à ajouter afin que le véhicule rebondisse, et j’ai dérivé tout ça pour obtenir la nouvelle accélération c'est-à-dire la force de réaction.
Ca donne : F = normale(fc)*produitscalaire(normale(fc),vitesse)/delaT, traduction: la projection du vecteur vitesse sur le vecteur normale normalisé de la face de contact divisé par la différence de temps pseudo-infinitésimal. J’ajoute éventuellement la longueur de pénétration du vaisseau1 dans le vaisseau2.
Je ne suis pas sûr par contre de mon vecteur vitesse. Actuellement c’est la différence de vitesse entre les deux vaisseaux au point de contact (vitesse lineaire + rayon*vitesse angulaire).
Dois-je ajouter un moment de réaction ?
Pour en revenir aux problèmes, il arrive très souvent que les véhicules se collent puis engendrent des forces de réaction aberrantes. Si vous pensez que ça vient de ma détection de collision, je vous explique brièvement comment cela fonctionne :
Je récupère, s’il existe, le point du vaisseau1 à l’interieur du vaisseau2. (fonctionne à 100%)
Puis je détermine la face de contact en sélectionnant la face qui est la plus proche du point qui vient d’être calculé.
J’avais fait une petite erreur de calcul lors de la rotation des points composants mes vaisseaux. Cependant ça ne résout pas entièrement mes problèmes, même si l’amélioration est visible.
Je me suis tourné vers de nouvelles méthodes (encore !). Rajouter une force de réaction pour simuler les collisions va modifier la vitesse qui va modifier la position. Il existe sûrement des moyens fiables pour paramétrer cette force, mais pour moi tout ça reste très empirique. Une force mal dosée aura pour conséquence une collision molle ou des rebonds démesurés. Mes nouveaux essais consistent alors à modifier directement la position sans passer par les vitesses et les forces parfois incontrôlables. Je pars de l'hypothèse que mes véhicules peuvent se pousser les uns les autres, mais pas rebondir, ce qui est souvent le cas dans la réalité. Je suis conscient que ce n'est pas la meilleure solution mais au moins s’il existe une solution elle est rigoureuse.
Ce qu’essaye de faire mon "moteur géométrique" c’est simplement de transposer un vecteur déplacement D (issu du déplacement du vaisseau1) appliqué au point de contact, vers le vaisseau 2, et ce pour que le vaisseau1 pousse le vaisseau2 avec un mouvement crédible. Voici un aperçu du problème : http://zone51da.free.fr/deplacement.gif
Je sépare D en deux composantes. L’une est colinéaire au rayon R du vaisseau 2 (centre-point_de_contact) et l’autre est colinéaire au vecteur tangent au mouvement de rotation du vaisseau2 (cad le vecteur normal N au rayon ). Je projette D du vaisseau1 sur ces deux composantes du vaisseau 2, ce qui donne mathématiquement :
D2 = R(R.D) + N(N.D) où "." est l’opérateur du produit scalaire et sachant que R est normalisé donc N aussi.
Je demande au vaisseau2 de se deplacer en translation selon la premiere composante R(R.D). Ca l’air de fonctionner, par contre pour les rotations c’est beaucoup moins credible, j’effectue une rotation selon l’angle arctan(N.D) et cette rotation semble beaucoup trop exagérée.
vBulletin® v.3.6.5, Copyright ©2000-2009, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org