1

Hello ^^
Pour un projet à l'école je fais une sorte de Worms mais avec des tanks (donc rectangulaires).
J'ai fait une ébauche pour donner une idée:
[URL=http://img10.imageshack.us/my.php?image=img032.png][IMG]http://img10.imageshack.us/img10/8373/img032.png[/IMG][/URL]
La map est de type "pixel": pas de formes ou quoi que ce soit, c'est une bête matrice.

J'ai défini mon char comme un rectangle pouvant être tourné d'un certain angle. J'aimerais maintenant gérer la physique avec cette map, et je vois mal comment faire (faut dire que je suis une daube en physique). Actuellement pour ma détection de collisions je fais:
Parcours le long des arêtes du rectangle dans un plan transformé par rapport au rectangle (translaté, roté), et test des pixels. En gros je parcours les bords du rectangle et je teste les pixels, quoi. Si j'en trouve un, cela signifie une collision, mais voilà: quand je rencontre un pixel, faut-il revenir sur la gauche, la droite, en haut? Difficile à dire puisqu'il n'y a pas de notion d'angle (à cause de la map pixel).

      ###
      ###
     ####
   x#####
#########
#########
#########

Je touche l'endroit marqué d'un x. Que faire? On pourrait aller à gauche ou à droite. Pas moyen de bêtement annuler le dernier mouvement étant donné qu'une rotation provoque un mouvement local des pixels, donc à moins de revenir systématiquement en arrière, que ce soit à une rotation ou à un mouvement (solution vraiment pas terrible qui rend super mal en plus...) je vois pas comment faire sad
Quelqu'un aurait des conseils? smile
Merci d'avance ^^
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

2

J'ai pas envie de me faire le godwin facil dès le premier post, mais ton char, c'est un Tigre Royal de la WW2 trioui

3

Oué bon les gfx... google sprite tank et même pas réfléchi, et un gribouillis sous gimp pour la terre tongue
Au pif je pensais que ça venait de Metal Slug, mais en fait on dirait que non ^^
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

4

Je pense qu'il faut que tu puisse calculer les normales au sol; c'est faisable en mode bitmap, mais le plus simple c'est que tu stoque le terrain sous une forme mathématique: Tu sais qu'au point "x" de ta sinusoide, la normale est quelque chose comme {sin(x*coeff);cos(x*coeff)}

Si tu préfère utilise les bitmaps (si la destruction du terrain crée des formes trop compliquées à modéliser mathematiquement), tu peux calculer les angles de cette manière:
tu prend un cercle près de la surface. Tu compte les pixels "blancs" de ce cercle, et tu fais la moyenne de leurs angles par rapport au centre du cercle (bien sur les valeurs des angles des pixels seront précalculées grin)

illustration rapide:tromb Fichier joint : ypSn (coll.PNG)

5

Merci bcp, génial l'idée smile

En attendant je m'étais arrangé temporairement avec un terrain mathématique (dans la version finale effectivement ce sera du bitmap car c'est difficile à calculer les murs détruits, même en utilisant des polygones). Et j'ai rencontré un problème qui peut sembler vraiment basique mais que je n'arrive pas à résoudre sad

Prenons ce cas:
img034e.png
Une collision a lieu au point rouge. Grâce à ta méthode, je vais pouvoir trouver l'angle de la pente, marquée d'un trait rouge. Je vais aussi pouvoir me servir de la normale pour sortir le tank de la pente en lui appliquant une force parallèle à N (n'est-ce pas? déjà là ça me paraît un poil louche, étant donné que vu l'angle du tank la Fp devrait être purement verticale)
Une fois que le tank est sur la pente, alors on va pouvoir le faire basculer pour refléter l'angle de la pente. Comme la méthode donne une moyenne, il se peut que l'angle calculé ne soit pas parfaitement précis et qu'on se retrouve dans le cas suivant:
img035.png
Le moteur de collisions va alors voir une collision sur la gauche et soit remonter le tank:
img036t.png
Soit (imaginons que ce soit possible) faire basculer le tank:
img037.png
Mais dans ce cas on risque de rencontrer à nouveau une collision sur la pente, qui va reconduire au même problème. Sans compter qu'à chaque fois le moteur de collision va repousser le tank en utilisant une force qui ici ne sera pas parallèle à Oy. Donc le tank va bouger sur la gauche et "branler". En prenant la moyenne par rapport au milieu du tank, ça rend un poil mieux mais le problème est toujours là. Cf ce petit test (il faut Windows & le .NET framework 2):
http://brunni.dev-fr.org/tmp/Canon.7z
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

6

Peut-être qu'utiliser une transparence pour le fond de l'image de ton tank (ça n'a pas l'air d'être le cas, d'après les images que tu postes), ou un masque de collision (mais il faut le générer...), donnerait un moteur plus "physique" ?
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

7

Hmm... je ne pense pas que ce soit vraiment différent, que je prenne un rectangle ou un masque.
Au contraire là j'ai un problème qui est pourtant basique et que n'importe qui ayant fait un jeu un jour (du moins en 3D) a dû avoir: ton perso est une boîte, et il faut détecter les collisions avec un sol incliné... c'est ça qui me fait rager sad
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

8

!call momotte
--- Call : momotte appelé(e) sur ce topic ...
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

9

rrzzz ?

hum.
comme dit Jyaif, avoir la normale de ton terrain peut aider.

en gros ce que tu cherche, c'est la normale a la derivee de la courbe representant ta bitmap en un point donne. pour un terrain sans formations concaves (genre trous ou galleries), une facon rapide d'obtenir ca est de prendre la hauteur du pixel a gauche (P-1) et du pixel a droite (P+1) de celui que tu intersectes (P), de calculer les vecteurs [P-1, P] et [P, P+1], qui auront pour coordonnee {1, hauteur(P) - hauteur(P-1)} et {1, hauteur(P+1) - hauteur(P)}, de faire leur moyenne (tu peux faire une moyenne ponderee par les longueurs des deux vecteurs suivant comment tu veux approximer la courbure de ton terrain), et de calculer la normale au vecteur tangent resultant (normale.x = -tangente.y, normale.y = tangente.x).

mais bon juste avoir une normale ca va pas t'amener tres loin (et visiblement c'est deja plus ou moins bon pour ce qui est de la normale grin)

la ca va surtout dependre de comment tu modelises ton tank.
une suggestion, assez simple, mais qui devrait fonctionner pas trop mal:

tu peux le modeliser avec les proprietes suivantes:
- centre de gravite
- vitesse lineaire
- vitesse angulaire (un seul angle en 2D)
- une liste de points "solides" de contact. si tu modelise une brique, il te faut 4 points pour chaque cote, pour une forme plus complexe tu peux en mettre plus, mais bon c'est pas oblige...

bon. alors une fois que t'as ca, a chaque update de ton tank, tu parcours la liste de ses points de contact (techniquement c'est pas vraiment des points de contacts, c'est plutot des "sommets" d'une enveloppe convexe qui englobe ton tank, mais on s'en fout c'est plus simple dit comme ca).
pour chaque point de contact, tu regarde si il est dans ton terrain ou pas.
une fois que t'as la liste des points qui penetrent le terrain, il faut que tu trouves un moyen d'estimer la profondeur de penetration.
typiquement, un truc qui marche bien pour des heightmaps comme ca, c'est juste de regarder la hauteur qu'a le terrain a la coordonnee x de la ou se trouve le point.

une fois que t'as la profondeur de penetration, tu peux calculer une force a appliquer a ce point (plus de details plus bas), qui va affecter la vitesse angulaire.
tu veux a priori aussi replacer le tank en dehors du terrain. pour faire ca, c'est juste prendre le point qui a la plus grande profondeur de penetration, et remonter ton tank de sorte que ce point soit sur le terrain. la modification de la vitesse angulaire par les forces appliquees par les autres points se chargera de faire pivoter le tank comme il faut.

apres, le reste de l'update du tank, ca reste simple, c'est juste, avec un integrateur d'euler trivial:

position += dt * velocity;
angle += dt * angularVelocity;

et "angle" sert a calculer une matrice (ou peu importe quoi d'autre) qui te sert a afficher le sprite rotate de ton tank, et a transformer les points de contact avant de faire les checks de collision et l'accumulation des forces.

juste quelques details en plus, sur le calcul de la vitesse angulaire.

lorsque t'as une penetration d'un point de contact, il faut changer la vitesse angulaire pour que le tank se reoriente comme il faut. pour faire ca, idealement, il faudrait un tenseur d'inertie specifique a un modele de tank. et pour chaque point de contact tu ferais:

tank.angularSpeed += inverseInertiaTensor * cross(contactPoint - tank.centerOfMass, impulse);

(ou bien juste, avec une acceleration angulaire):
tank.torque += cross(contactPoint - tank.centerOfMass, force);

avec impulse etant le vecteur du point de contact jusqu'a l'endroit ou il devrait etre pour qu'il n'y aie pas de penetration (en gros, dans le cas d'un terrain simple ou tu simplifie les choses en reprojetant a la verticale comme suggere au dessus, c'est juste le vecteur qui a pour coordonnees {0, profondeurDePenetration}.

en gros, le tenseur d'inertie, c'est une matrice qui represente la distribution de masse dans ton tank le long de chacun de ses deux axes principaux, pour pouvoir determiner l'inertie de l'objet le long d'un axe de rotation donne, ou pour pouvoir determiner de combien une force appliquee en un point de l'objet affecte son acceleration angulaire (d'ailleurs c'est souvent plus pratique d'avoir un tenseur d'inertie normalise (divise par la masse), et de re-multiplier par la masse de l'objet (ou la masse inverse dans la ligne de code au dessus), ca te permet de changer facilement la masse par tank, et ca simplifie quelques calculs par la suite...).

mais utiliser un tenseur d'inertie n'a pas vraiment beaucoup d'interet en 2D, vu que tu ne peux rotater que le long d'un seul axe. bref, c'etait juste a titre informatif.

la en gros tu prends ton impulse (cf plus haut pour comment le calculer)
et tu fais juste:

tank.angularSpeed += cross(contactPoint - tank.centerOfMass, impulse) * coeff;

avec cross = a.x * b.y - a.y * b.x (c'est juste la composante z du produit vectoriel 3D entre les deux vecteurs a et b)
et coeff, un coeff.. (sisi grin), plutot petit, a tweaker pour que ca se comporte bien (ca correspond a une simplification du tenseur d'inertie)

bon, j'ai pas relu, mais c'est probablement imbitable, donc v faire un schema...
avatar
HURRRR !

10

NTtU
tank sur terrain, points de contact OK en vert, points de contact en penetration avec le terrain en rouge.
centre de gravite du tank en bleu.
les vecteurs servant a sortir le tank du terrain sont en rouge (c'est les impulses a utiliser par la suite pour modifier la vitesse angulaire)

R7bR
le replacement du tank a une position valide, en utilisant le plus grand vecteur de replacement trouve dans l'etape d'avant.

gCH7
une visualisation des vecteurs necessaires a la modification de la vitesse angulaire: en rouge les impulses, en violet le vecteur "(contactPoint - tank.CenterOfMass)"
vu que tu modifies la vitesse angulaire avec "cross(contactPoint - tank.CenterOfMass, impulse)", et que tu peux voir la magnitude resultat du cross comme directement dependante la surface du triangle forme par les deux autres vecteurs (c'est la surface du parallepipede, donc deux fois la surface du triangle, bref...), tu peux voir que:

- plus l'impulse est eloigne du centre de gravite, plus l'effet sur la vitesse angulaire est fort.
- plus le vecteur de l'impulse "pointe" vers le centre de gravite, moins l'effet sur la vitesse angulaire est fort.



dans les exemples d'au dessus, t'as du voir que suivant la forme du terrain, il va rentrer dans le tank si jamais il y a une bosse entre deux points de contact.

la bonne nouvelle c'est que:
- tu peux rajouter plein de points de contact sous le tank trioui
- tu peux t'amuser a gerer ces intersections terrain/segment. le but etant de trouver le point du segment le plus profondement enfoui dans le terrain. et de rajouter ce point a une liste de points de contacts dynamiques, et la t'aura des collisions "continues" avec une vraie enveloppe quelconque autour de ton tank. tu peux meme t'amuser a dessiner les bords de ton tank avec des segments si t'as envie...
mais le truc bien c'est que tu change rien au systeme derriere.
c'est juste gerer un autre type de primitives de collisions que les points. mais ce que tu donnes a manger au coeur de ton solver physique derriere, ca reste des points de contact, ils sont juste plus statiques. apres tu peux faire ca avec des cercles, de vrais rectangles, bref... (mais juste des segments ca devrait amplement te suffire).

en attendant, pour experimenter, les points c'est le plus simple, et ca te permettra d'arriver rapidement a un truc qui marche ^^

et peut-etre sans le savoir, tu viens de faire un pas dans le monde des rigid bodies \o/
avatar
HURRRR !

11

ton perso est une boîte, et il faut détecter les collisions avec un sol incliné...

hm non ca ca a pas grand chose a voir a priori... ton perso tu veux pas qu'il bascule sur lui-meme.
tu veux juste savoir l'endroit ou il touche le plan incline, la normale du plan, projeter son vecteur vitesse le long du plan (le produit scalaire est ton ami), eventuellement diminuer la magnitude de son nouveau vecteur vitesse pour faire genre y a de la friction, et c'est tout. c'est aussi simple que ca...
avatar
HURRRR !

12

(j'ai appris des trucs moi, merci momotte ^^)

13

(je t'en prie grin (fesses?))

(Brunni> en fait si t'es un porc, tu peux aussi, au lieu des segments, faire un AND directement entre un masque de collisions pour ton tank et pour ton terrain, et pour tous les pixels qui passent, tu spawne dynamiquement un contact-point triso)
avatar
HURRRR !

14

Ha momotte! Ca fait plaisir de te revoir smile
Je n'ai malheureusement pas le temps d'implémenter ta méthode pour tester aujourd'hui, mais j'aurais juste quelques questions sur ce que tu as écrit:
momotte (./9) :
et "angle" sert a calculer une matrice (ou peu importe quoi d'autre) qui te sert a afficher le sprite rotate de ton tank, et a transformer les points de contact avant de faire les checks de collision et l'accumulation des forces.

La rotation se fait par rapport au centre? J'ai l'impression que oui puisque tu prends un centre de gravité.

Ensuite quand tu parles des impulses (vecteurs permettant de faire sortir l'objet du terrain) j'en ai plusieurs, mais je dois attendre d'avoir terminé la vérification de tous les points de contact avant d'appliquer une force pour le "sortir", c'est ça? Et j'applique uniquement la force du vecteur le plus grand. Mais dans certains cas appliquer cette force ne suffira pas à sortir l'objet (s'il touche à deux endroits qui ne sont pas sur une surface plane). Dans ce cas je vais devoir refaire une détection de collisions droit derrière? Ca me semble un peu bidouille en fait...
En fait je devrais pas faire une moyenne entre les impulses? Parce qu'imaginons que je sois sur une surface plane, je vais avoir des contacts partout, de gauche à droite...

Sinon je pense que j'ai globalement compris ton explication, juste pour être sûr, torque (collier) c'est bien l'accélération angulaire? (a += dt * torque)
Tu as appris comment tout ça? grin Tu es physicien? Y a des bons livres pour ceux que ça intéresse? (j'ai l'impression qu'il me faudrait un truc basique)
En tous cas je te remercie beaucoup smile
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

15

Bon j'ai implémenté la méthode à Jyaif et elle est meilleure que mon ancien système qui visait à trouver la distance entre le côté courant du tank et le prochain pixel à gauche et à droite, puis de constuire un triangle (pythagore) pour calculer l'angle:
1Vir
; Vérifie sur le long de l'axe "parallèle" autour de "milieu" en utilisant "perpendiculaire" comme vecteur sortant
angleTerre(point milieu, vecteur parallèle, vecteur perpendiculaire):
	entourage = largeurTank / 2		; On peut tweaker
	tolerance = 16		; tout ce qui est plus éloigné de l'objet est oublié, évite de prendre les galeries

	; Distance entre l'objet et le sol à une distance de "i" de "milieu" parallèlement à "parallèle"
	distance(i):
		point pos = milieu + parallèle * i		; € parallèle
		for j = [0 .. tolerance[ :
			if getPixel(pos + perpendiculaire * j):
				return j
		return tolerance
	
	moyenneGauche = (distance(-entourage) + distance(-entourage + 1)) / 2
	moyenneDroite = (distance(entourage) + distance(entourage - 1)) / 2
	return arctan(x = 2 * entourage, y = moyenneDroite - moyenneGauche)

Par contre juste noter qu'il ne faut pas faire une moyenne des angles mais des vecteurs wink sinon on risque de perdre de l'info, en imaginons qu'on a les angles {-2, 3, +2}, la moyenne devrait être 3 mais elle sera 1 ^^
Donc merci love Prochaine étape: ce que m'a décrit momotte smile
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

16

./14>
La rotation se fait par rapport au centre? J'ai l'impression que oui puisque tu prends un centre de gravité.

oue, la rotation, par rapport au centre de gravite de l'objet.
juste pour être sûr, torque (collier) c'est bien l'accélération angulaire? (a += dt * torque)

le torque, c'est a priori plutot "couple" en francais...
et non, c'est pas l'acceleration angulaire, ca sert a faire varier l'acceleration angulaire.
de meme qu'une force fait varier l'acceleration lineaire, un torque fait varier l'acceleration angulaire.

en gros, en generalisant, t'as un truc comme ca:

ApplyForceOnObject(vector where, vector force)
{
totalForce += force;
totalTorque += cross(where - CenterOfMass, force);
}

et ensuite dans l'update de ton objet:

linearAccel = totalForce * invMass;
angularAccel = invMasslessInertiaTensor * totalTorque * invMass;

linearVelocity += linearAccel * dt;
angularVelocity += angularAccel * dt;

position += linearVelocity * dt;
angle += angularVelocity * dt;
Ensuite quand tu parles des impulses (vecteurs permettant de faire sortir l'objet du terrain) j'en ai plusieurs, mais je dois attendre d'avoir terminé la vérification de tous les points de contact avant d'appliquer une force pour le "sortir", c'est ça? Et j'applique uniquement la force du vecteur le plus grand. Mais dans certains cas appliquer cette force ne suffira pas à sortir l'objet (s'il touche à deux endroits qui ne sont pas sur une surface plane). Dans ce cas je vais devoir refaire une détection de collisions droit derrière? Ca me semble un peu bidouille en fait...


oui donc la deja les c'est pas des impulses au sens strict. et t'applique pas une force au sens strict non plus.
la en fait le principe de prendre la plus grosse valeur de penetration pour sortir l'objet, c'est un raccourci qui permet de replacer l'objet a l'endroit ou la collision est censee avoir eu lieu. mais c'est une approximation qui assume principalement que la vitesse de deplacement du tank est purement verticale, ce qui evidemment est totalement faux, et que le tank n'a pas de vitesse de rotation (ce qui evidemment est totalement faux aussi grin)

mais.
- dans _tous_ les cas, le fait de faire ca fera toujours ressortir le tank, du moment que (comme precise dans un precedent post), ton terrain est une heightmap.
- comme pour les primitives de collision (points -> segments -> etc..) une fois que le reste marche, tu peux facilement changer ca et utiliser une technique plus complexe et meilleure pour trouver le temps d'impact, minimiser les integration, et donner a ton solver de meilleurs impulses ou forces.

la ce qu'il faut bien voir, c'est que le hack de deplacer le tank par la plus grande valeur de penetration, ca revient a essayer de trouver le dernier etat "valide" qu'avait le tank au sein de ton timestep avant d'entrer en collision.

en gros, si tu regarde l'etat de ta simulation, t'es au temps 't', et tu veux avancer la simulation a 't' + 'dt'
en 't' ton tank a une position valide ou il n'intersecte rien.
en 't + dt', ton tank a peut etre toujours une position valide, dans quel cas, tres bien, t'as rien de special a faire, mais dans le cas contraire, idealement:

A - il faut savoir quand, entre 't' et 't+dt', a eu lieu la collision. ('t+dt*0.2' ? 't+dt*0.85' ? ...)
B - il faut ensuite avancer la simulation au temps de la collision 't+dt*colTime'.
C - il faut calculer la reponse du tank a la collision. pour ce faire, tu vas soit juste reflechir le vecteur vitesse avec un coefficient d'amortissement, ou bien prendre en compte la position du point de contact par rapport au centre de gravite, et appliquer un impulse, ou bien... bref...

(note que le principe reste le meme si c'est deux objets dynamiques hein, c'est juste que les impulses appliques aux deux objets ne sont pas calcules pareil (enfin si, tu pourrais utiliser le meme code, en donnant une masse infinie a ton terrain (donc une invmass de 0, c'est, au passage, une des raisons de l'utilisation de l'inverse de la masse dans les moteurs physiques, c'est plutot rare d'avoir une masse nulle, et une invmass nulle te permet d'avoir des objets "inbougeables", et d'utiliser un codepath generique pour tout... (bref...)))

la, le fait de replacer le tank en utilisant la plus grande profondeur de penetration, ca pseudo-resout les points A et B.

pour correctement resoudre le point A, il faudrait prendre en compte le mouvement reel du tank, ses rotations, etc..
tu pourrais par exemple, une fois que t'as un truc qui marche, remplacer le hack du replacement du tank par un truc qui va, pour chaque point ou il y a une penetration, creer un segment entre la position du point a 't' et la position a 't+dt', et raytracer le terrain. (ca, ca approxime la rotation pendant le timestep comme etant une translation lineaire de chaque point du tank, mais c'est pas genant si ton dt est faible)
ou bien, recuperer la vitesse instantanee de chaque point a 't+dt', et back-tracer le terrain avec.
ou bien, decouper le timestep en 'n' sous-steps et re-tester les collisions a chaque step.
ou bien, subdiviser le timestep dichotomiquement pour trouver le temps d'intersection.
ou bien, ... bref...

apres, il faut bien voir que meme si c'est un hack, a moins que ton jeu tourne a 2 fps et que tes timesteps soient gigantesques, ou que ton tank bouge de 300 pixels par frame, l'erreur moyenne sera plutot faible.
t'aura juste un tank qui aura une legere tendance a grimper les pentes.

et compare aux autres methodes ca a l'avantage de te garantir, pour un debut, que tu n'aura pas de probleme avec des configurations invalides. ton tank sera toujours replace sur le terrain. (meme si tu commence ton jeu avec le tank entierement a l'interieur du terrain, il sera projete instantanement a la surface des la premiere update physique.
avatar
HURRRR !

17

[Edit] Cross, mais je laisse quand même en attendant

love king beer
Bon alors la méthode à momotte fonctionne parfaitement! Ca sur-déchire comment c'est beau, je pensais jamais avoir ça dans un de mes progs!
Le seul souci c'est dans le cas où j'ai plusieurs points de collision... par exemple si le tank (boîte rectangulaire) est à plat et sur une surface plane (0°). Le "plus grand vecteur" impulse est soit le plus à gauche soit le plus à droite.
tromb Fichier joint : T5wE
Du coup je ne sais pas trop quoi faire dans ce cas là, sachant qu'une moyenne donne de mauvais résultats dans pas mal d'autres cas... (je n'utilise pas une height map, pour "sortir" le tank du sol j'utilise la normale à la pente)

Il y a aussi un truc que ne comprends pas c'est le résultat du cross(pos, impulse). Ca donne le sens de rotation c'est ça? En 3D ce serait comment?
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

18

en 3d c'est un produit vectoriel, en 2d c'est sin(angle)*longueurvecteur1*longueurvecteur2

19

Nan mais je veux dire, son cross(pos, impulse) qui affecte la vitesse angulaire, je vois pas trop d'où ça vient. Je connais juste le produit vectoriel pour obtenir la normale à un plan, et l'orientation des faces, mais je vois pas quelle propriété fait que ça donne ce qu'on cherche...

Pour mon problème plus haut, je pense qu'on le voit mieux comme ça:
http://brunni.dev-fr.org/tmp/Canon.7z
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

20

je crois que ça vient de la définition du couple :

couple = vecteur[centreMasse->pointApplicationForce] ^ force appliquée à ce point.

#souvenirDePrepa#

21

Je confirme.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

22

./17> \o/

oue alors la, comme dit plus haut (dans le post que t'as cross grin), le but du processus est de revenir au moment de l'impact, et d'appliquer l'impulse du point qui a reellement impacte.
mais ca ca suppose que tu n'as qu'un point qui impacte a la fois. tu peux avoir plusieurs points qui impactent en meme temps (et effectivement quand t'as un rectangle qui tombe verticalement sur le sol, t'as tous les points de sa surface qui fait contact qui touchent le sol "en meme temps".
les impulses que tu dois appliquer, c'est les impulses generes par LES points de contact. cad que quand t'as trouve le temps de la premiere intersection, il faut que t'accumules les impulses de tous les points qui ont impacte a ce moment la. (par exemple en utilisant un epsilon pour comparer les temps de penetration. tous les points qui entrent en contact au temps 't' plus ou moins 0.001 par exemple, peuvent etre consideres comme contactant au meme moment...)

sinon, pour le cross, oue, comme dit squalyl.
et cf aussi l'exemple dans ./16 :
ApplyForceOnObject(vector where, vector force) 
{ 
  totalForce += force; 
  totalTorque += cross(where - CenterOfMass, force); 
} 


sinon, les vecteurs que t'as dessine la, c'est pas les impulses, c'est les vecteurs du point de contact au centre de gravite. la les impulses seraient verticaux (bon, en fait pour faire ca bien, ils devraient etre paralleles a la vitesse du point au moment de l'impact)


EDIT: cross
(d'ailleurs, pour info au cas ou: la vitesse d'un point de ton tank, tu l'as avec: LinearVelocity + cross(AngularVelocity, point - CenterOfMass))

(re-edit)
mais je vois pas quelle propriété fait que ça donne ce qu'on cherche...

le cross la, en gros ca te donne l'axe de rotation. l'axe perpendiculaire au plan forme par le vecteur de l'impulse et le vecteur du point au centre de gravite. l'impulse s'applique le long de ce plan, et la rotation resultant de l'application de l'impulse se produit autour de l'axe perpendiculaire au plan. (je sais pas si tu visualise le truc?)
apres, la magnitude du vecteur retourne par le cross fait qu'au final ca va tourner plus ou moins vite suivant que l'impulse est applique plus ou moins pres du centre de gravite, et qu'il est plus ou moins fort (il faut plus de force pour induire une certaine vitesse de rotation si tu l'applique pres du centre de gravite que loin.. c'est l'autre propriete que le cross apporte...) d'ailleurs tu peux deduire ca de l'equation d'au dessus pour avoir la vitesse tangentielle a partir de la vitesse angulaire (cross(angularVelocity, point - CenterOfMass))

(bon apres y a surement une demonstration qui va bien pour tout ca, chais pas... ^^)tromb

(edit3: triso)
ca sera ptetre plus simple a visualiser avec un schema:
DpCP
avatar
HURRRR !

23

Je te remercie énormément de tes explications. Je n'ai pas le temps de tester là tout de suite, mais je garde ça bien au chaud wink
momotte (./22) :
les impulses que tu dois appliquer, c'est les impulses generes par LES points de contact. cad que quand t'as trouve le temps de la premiere intersection, il faut que t'accumules les impulses de tous les points qui ont impacte a ce moment la. (par exemple en utilisant un epsilon pour comparer les temps de penetration. tous les points qui entrent en contact au temps 't' plus ou moins 0.001 par exemple, peuvent etre consideres comme contactant au meme moment...)

En fait par rapport à ce que tu me dis là, j'ai fait un petit test avec une bête moyenne, et le résultat n'est pas terrible. Du coup je pense que je vais calculer d'abord le nombre de points de contacts qui détectent une collision puis distribuer le retour du choc (les vecteurs impulse) et la modification de la vitesse angulaire via une division par leur nombre.
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

24

momotte (./16) :
le torque, c'est a priori plutot "couple" en francais...

"couple, ou "moment" ? cheeky (oui, c'est intrinsèquement lié, effectivement grin)
avatar

25

./23> bah dr ^^ tant mieux si elles servent grin

heu sinon oui, une moyenne des vecteurs c'est pas super.
tu peux approximer en faisant la moyenne des magnitudes et en renormalisant les impulses avec cette magnitude, ca sera surement mieux. (du moment que t'as pas une distribution trop heterogene de tes points autour de ton tank (genre 15 points sur la moitie droite d'une surface plane, et un seul sur la moitie gauche))
avatar
HURRRR !

26

Bon ben apparemment ce n'est pas suffisant sad L'algo marche bien, mais lorsque le tank est dans une pente par exemple il va continuer de tourner très lentement pour finalement se retourner. Apparemment il me faudrait un "poids" pour qu'il se stabilise, et surtout plus rapidement.
Mais je ne vois pas ce que je pourrais implémenter pour ça. J'ai essayé d'augmenter son poids (histoire que ce soit réaliste) mais ce n'est pas terrible: j'arrive à un point où c'est toujours lent, mais le tank tombe de façon irréaliste (extrêmement vite).
Voici un prog de test pour ceux qui ne voient pas:
http://brunni.dev-fr.org/tmp/Test.7z
(il faut détruire le terrain pour voir comment il se comporte -> cliquer avec le bouton gauche après avoir éventuellement sélectionné une arme plus forte en haut à droite)
Dans cette version je n'ai pas utilisé la détection de l'angle de la pente, peu fiable dans les bords par exemple, mais seulement l'impulse.
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741