framrate dependant (probleme de math algo plus que de C/C++...)

framrate dependant (probleme de math algo plus que de C/C++...) - Algo - Programmation

Marsh Posté le 10-10-2006 à 13:51:02    

voila dans mon prog je fais avancer un vehicule:

Code :
  1. vel = 2;
  2. pos += vel;


 
mais je veux que se soit framerate dependant...
 

Code :
  1. vel = 2;
  2. pos += vel*frametime;


ou frametime =  le temps ecoule entre 2 frames
 
le probleme c si vel varie ex :  
 

Code :
  1. if(keyinput_something) vel += 2; //accelerate
  2. vel *=  0.998; //add friction
  3. pos += vel;


 
la je ne c plus ou mettre frametime
rien que le vel* = 0.998 pose probleme  
ca peut etre simulé par vel* = pow(0.998,frametime) mais ca donne pas tout a fait la meme chose , et comme c pour integrer dans une demo tout decalage nest pas envisageable (du tout)


Message édité par red faction le 10-10-2006 à 14:07:06
Reply

Marsh Posté le 10-10-2006 à 13:51:02   

Reply

Marsh Posté le 10-10-2006 à 14:19:03    

à la base ce serait plus "simple" de faire deux threads :
1/ 1 qui calcule le mouvement, handle le clavier et toussa
2/ 1 qui ne s'occupe que de l'affichage
 
=> Ainsi, le mouvement est calculé de façon totalement indépendante du framerate.
 
C'est d'ailleurs le modèle "classique" de n'importe quelle application de ce type.
A noter que généralement, la gestion clavier/souris tourne dans un 3° thread.
 
=> C'est pour ça que sous Windows, quand c'est complètement parti en vrille, quand tu bouges la souris, il t'affiche bien la souris qui bouge : les traîtements et l'affichage sont dans des threads séparés au niveau de la GUI.


Message édité par MagicBuzz le 10-10-2006 à 14:20:46
Reply

Marsh Posté le 10-10-2006 à 17:04:26    

ok j'y avais pense mais je trouvais ca un peu sale
sinon javais deja vu le meme genre de chose dans Duke3D sauf que la il utilisent un timer a la bonne veille facon dos
 
bon ca c qd les calculs sont simples.... mais qd faut gerer rigid body et autres calculs lourd on tappe tout dans une thread aussi ????
 
=> C'est pour ça que sous Windows, quand c'est complètement parti en vrille, quand tu bouges la souris, il t'affiche bien la souris qui bouge : les traîtements et l'affichage sont dans des threads séparés au niveau de la GUI.
 
enfin la je dirais plus que ca se passe comme ca :  
 
tu bouge la souris => le matos genere une interruption => l'os la capte, interomp le programme courant et execute du code pour soccuper de la souris => la carte graphique qui gere nativement le pointeur redessine ce dernier.
 

Message cité 1 fois
Message édité par red faction le 10-10-2006 à 17:06:13
Reply

Marsh Posté le 10-10-2006 à 20:34:16    

Citation :

Code :
  1. vel = 2;
  2. pos += vel*frametime;


ou frametime =  le temps ecoule entre 2 frames
 
le probleme c si vel varie ex :  

Code :
  1. if(keyinput_something) vel += 2; //accelerate
  2. vel *=  0.998; //add friction
  3. pos += vel;


la je ne c plus ou mettre frametime


 
Alors découpe en fonctions. :-)
 

Code :
  1. float delta_v(float vel, float framerate)
  2. {
  3.   return framerate * vel;
  4. }
  5. // Premier cas :
  6. vel = 2;
  7. pos += delta_v(vel, framerate);
  8. // Deuxième cas :
  9. if(keyinput_something)
  10.   vel += 2;
  11. vel *=  0.998; //add friction
  12. pos += delta_v(vel, framerate);



---------------
Viendez vous battre à Prologin \o/
Reply

Marsh Posté le 11-10-2006 à 01:09:19    

red faction a écrit :

tu bouge la souris => le matos genere une interruption => l'os la capte, interomp le programme courant et execute du code pour soccuper de la souris => la carte graphique qui gere nativement le pointeur redessine ce dernier.


ben tu viens de décrire le traîtement de base du multi-thread (ou multi-process).
=> dans tous les cas, au plus bas niveau, ça reste qu'une boucle sans fin qui exécute des petits bouts de code des différents process/threads les uns à la suite des autres ;) d'un point de vue atomique, ça reste ce que tu veux de faire. mais la seule différence, c'est qu'avec des threads, plutôt que de te retrouver avec un programme qui ramme quand t'as 2 FPS et est trop rapide quand tu as 2000 FPS (car les mouvements c'est pas tout, si t'as des gestions de collision et autres, notamment, ton système sera foireux, car ton traîtement ignorera tout ce qui s'est passé entre deux images, du coup tu passes à travers les objets !)
 
avec le multi-thread, tu garantis que ton thread d'interface "input" répond à 100% tout le temps. celui des calculs de fond, à vitesse constante (bien plus facile pour avoir une animation réaliste et un comportement identique quelle que soit les performances de la machine), tandis que le thread d'affichage utilise le reste du CPU dispo pour afficher une animation plus ou moins fluide selon le reste du CPU dispo.
=> en bref, pour reprendre le système que tu décris avec l'OS : le traîtement principal est déclencé toutes les X ms, et le reste du temps, il fait tourner le thread d'affichage (si tu veux faire propre, tu ne déclenches pas le thread d'affichage quand le thread principal n'a pas été ré-éxécuté), tandis qu'à la moindre interruption matériel, ton thread d'input traîte en priorité les actions de l'utilisateur aux dépends des deux autres threads.

Reply

Marsh Posté le 11-10-2006 à 01:10:38    

ce que je décris, c'est vraiment le b-a-ba de la plupart des jeux et applications modernes. ça semble lourd au premier abord, mais au final ça ne change pas grand chose au système que tu tentes de mettreen place, mise à part que c'est plus fiable et que c'est l'OS qui se charge de la partie "chiante" plutôt que toi (avec tous les défauts éventuels de ton code)

Reply

Marsh Posté le 11-10-2006 à 01:56:56    

Je vois pas trop pourquoi parceque l'affichage est séparé du calcul des positions tu aurait une garantie sur la vitesse d'exécution de ce calcul [:spamafote]
 
Et au passage, non au plus bas niveau ce n'est pas franchement une boucle sans fin sur chacun des bout de code des différents processus.
 
Et pour le pb de la vitesse qui evolue en fonction du temps, la première idée qui me vient à l'esprit c'est de ne plus faire de calcul discret ( genre on update la position "d'un cran" puis on update la vitesse "d'un cran" ) mais de créer une vrai fonction nouvelleposition(ancienne, vitesse à l'ancienne position, durée) qui si ma mémoire est bonne se base sur les equadiffs.


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 11-10-2006 à 09:25:05    

0x90 a écrit :

Et pour le pb de la vitesse qui evolue en fonction du temps, la première idée qui me vient à l'esprit c'est de ne plus faire de calcul discret ( genre on update la position "d'un cran" puis on update la vitesse "d'un cran" ) mais de créer une vrai fonction nouvelleposition(ancienne, vitesse à l'ancienne position, durée) qui si ma mémoire est bonne se base sur les equadiffs.

+1
 
je ferais un truc du genre :

à chaque instant t :
  a(t) = accélération à l'instant t (donnée par l'utilisateur)
  v(t) = vitesse à l'instant t
  x(t) = position à l'instant t
 
passage de t à t+dt en intégrant les équations du mouvement (dv/dt = a et d²x/dt² = a):
  v(t+dt) = v(t) + a*dt
  x(t+dt) = x(t) + v(t)*dt + 0.5*a*dt*dt


---------------
TriScale innov
Reply

Marsh Posté le 11-10-2006 à 11:58:29    

si vous voulez vous prendre la tête pour rien sur des trucs bidons plutôt que de faire comme tout le monde :spamafote:
 
exemple décrivant parfairement le principe d'un moteur servant à gérer des objets en déplacement ainsi que leur affichage. il reprend à la lettre ce que j'ai dit depuis le début, et c'est pas un hasard si c'est le premier exemple de moteur de ce type que j'ai trouvé sur google : c'est le plus répendu, celui que tous les jeux utilisent depuis des années :spamafote:
 
http://thomas.walraet.net/tped1999/architecture.html

Message cité 2 fois
Message édité par MagicBuzz le 11-10-2006 à 12:03:04
Reply

Marsh Posté le 11-10-2006 à 12:33:05    

MagicBuzz a écrit :

exemple décrivant parfairement le principe d'un moteur servant à gérer des objets en déplacement ainsi que leur affichage. il reprend à la lettre ce que j'ai dit depuis le début, et c'est pas un hasard si c'est le premier exemple de moteur de ce type que j'ai trouvé sur google : c'est le plus répendu, celui que tous les jeux utilisent depuis des années :spamafote:


Oui, mais quelle que soit l'architecture de ton code (moteur dans un thread ou non), il faut bien que tu disposes des formules adéquates pour calculer le déplacement de ton mobile. C'est là dessus que porte (si j'ai bien compris) la question de red faction.


---------------
TriScale innov
Reply

Marsh Posté le 11-10-2006 à 12:33:05   

Reply

Marsh Posté le 11-10-2006 à 12:39:57    

MagicBuzz a écrit :

si vous voulez vous prendre la tête pour rien sur des trucs bidons plutôt que de faire comme tout le monde :spamafote:
 
exemple décrivant parfairement le principe d'un moteur servant à gérer des objets en déplacement ainsi que leur affichage. il reprend à la lettre ce que j'ai dit depuis le début, et c'est pas un hasard si c'est le premier exemple de moteur de ce type que j'ai trouvé sur google : c'est le plus répendu, celui que tous les jeux utilisent depuis des années :spamafote:
 
http://thomas.walraet.net/tped1999/architecture.html


 
Ton modèle permet une vitesse indépendante de la vitesse de rendu, mais pas de la vitesse de calcul de la machine. Encore une fois, le fait que ce soit threadé ne donne aucune garantie sur la vitesse de calcul du threads qui calcule les positions. Et enfin, les 2 techniques ne sont pas exclusives, mais ca tu l'aurais déja compris si t'avait un peu fait gaffe à ce qu'on raconte :).


---------------
Me: Django Localization, Yogo Puzzle, Chrome Grapher, C++ Signals, Brainf*ck.
Reply

Marsh Posté le 11-10-2006 à 14:59:54    

je suis désolé, mais tu ne peux pas te baser sur le principe que ton traitement ne fonctionne pas à vitesse régulière.
 
imagine un jeu de bagnole. ça ramme. et vu que ça ramme, quand j'appuie sur la touche d'accélération, le truc tambouille 2 secondes, et hop ! je suis à 200 km/h sans n'avoir rien compris. impossible à traiter.
 
pire pour l'AI, si tu gères l'AI en supposant que tu n'es pas capable de faire l'ensemble de tes traitements dans les délais impartis, alors tu vas avoir une AI de plus en plus stupide au fur et à mesure que les ressources de la machine seront amoindries. aucun intérêt.
 
si tu a un vrai souci de performances, le but du jeu n'est pas de te demander comment extrapoler de façon "rectiligne" les mouvements (qui ne seront alors plus naturels du tout) mais comment lever les alertes nécessaires afin de squizzer certains traîtements inutiles lorsque les ressources deviennent faibes.
 
et c'est notamment ce que fait le multi-thread automatiquement (jusque dans une certaine mesure).
=> tu définis le thread d'affichage avec une priorité 0, alors que tu files la priorité maxi aux traîtements : jamais l'affichage ne viendra bouffer le moindre cycle CPU réservé aux traîtements. ensuite, les traîtements, tu peux les lancer tous les X centièmes de seconde, et pour les traîtements plus lourd et qui n'ont pas besoin d'être résolus "immédiatement" (finding path par exemple) tu les lances dans un nouveau thread de façon assychrone de façon à ce qu'ils ne viennent pas perturber ton traîtement principal.
 
imagine bêtement le programme le plus simple imaginable : une balle qui rebondi sur le sol.
 
si tu ne granti pas un calcul très régulier des mouvements, alors entre t1 et t2, tu seras incapable de déterminer la position de la balle de façon cohérente.
 
si t2 - t1 = 2 secondes mettons. ma balle rebondis toutes les .5 secondes, avec un amortissement de 80% à chaque rebond. je te souhaite du courrage pour me dire où est la balle au bout des deux secondes.
 
maintenant tu rajoutes une seconde balle et tu gères les colisions... vu que lors des rebonds les balles ne se déplacent plus en ligne droite comme ton algo le suppose, tu va carrément être incapable de savoir si les balles sont entrées en collisions durant ces deux secondes. même mieux, tu risques d'inventer de fausses collisions !
 
bref, désolé, mais c'est approche de ce dire "je vais dans telle direction à une vitesse v et une accélération a à un instant t, donc en t2 j'ai qu'à retrouver une formule miracle qui me dit où je suis, c'est trop réducteur... y'a pas moyen de gérer la moindre collision ou AI avec ce système. je ne parle même pas de l'inter-action avec un utilisateur, qui va avoir un comportement de son programme très différent de ce qu'il lui demande...
 
imagine un flipper. la balle arrive à toute berzingue vers mon tampon. ça ramme un peu. je tape le tampon pour shooter dans la balle. mais entre temps, dans ton algo, t'as détecté que la balle allait tout droit puis rebondissait vers le côté. la résultante du mouvement est donc une droite qui ne passe pas à proximité du tampon. pas de chance, la balle passe gentillement à travers mon tampon. t'es sûr que ton truc il reste pas plus de 10 secondes sur le disque dur du gars qui vient de perdre...

Reply

Marsh Posté le 11-10-2006 à 15:29:56    

MagicBuzz a écrit :

bref, désolé, mais c'est approche de ce dire "je vais dans telle direction à une vitesse v et une accélération a à un instant t, donc en t2 j'ai qu'à retrouver une formule miracle qui me dit où je suis, c'est trop réducteur...

Alors comment tu fais pour calculer la position de la balle de ton flipper en fonction du temps ?
 
On est en train de parler (et limite de s'engueuler) de deux problèmes orthogonaux.
1- l'architecture du code : multi-thread vs. mono-thread (ce dont tu parles)
2- la simulation du déplacement (ce dont on parle avec 0x90, puisqu'il me semble qu'on est d'accord ; contredis moi si ce n'est pas le cas)
 
Avec 0x90, on dit que quelle que soit l'architecture, il faut un moteur pour simuler le déplacement des mobiles. Dans la plupart des cas (et c'est obligatoire si la simulation est interactive avec l'utilisateur), le moteur calcule des déplacements élémentaires sur un pas de temps et itere comme cela. Si le pas de temps est variable ( ralentissement de la machine ou bien tout simplement l'utilisateur souhaite 'accélérer' le temps dans sa simulation), il est judicieux d'employer une formule d'intégration un peu plus avancée que simplement dx=v*dt (qui ne marche que quand le pas de temps est tout petit).
 
Il n'y a pas besoin de s'énerver : les deux problèmes sont orthogonaux. Tu peux utiliser la formule que tu veux dans le type d'architecture que tu veux.


---------------
TriScale innov
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed