Voir la version complète : deplacement sur un terrain heightmap
Bonjour à tous,
Je suis tout nouveau et ceci est mon premier post.
Débutant en programmation C++, pour commencer, je n'ai trouvé rien de mieux que de me lancer dans un moteur 3D (c'est vraiment tres instructif, et contrairement à ce que l'on pourrait croire, il existe de tres bon tutoriels. Au passage merci pour les post de ce forum, ils m'ont été d'une grande utilitée).
Mon programme genère un objet map qui contient les parametre de mon terrain (hauteur min, max, width, height, la display liste et un tableau contenant les coordonnées et la normale de chaque triangle constituant la heightmap).
j'ai un objet boule définit par 3 vecteurs, un vecteur de position, un vecteur de mouvement et un vecteur d'acceleration.
Je dispose également d'une fonction simulation qui détecte la collision eventuelle entre un objet et un triangle de map. Et à ma grande surprise, ça marche. Un objet boule rebondit sur la map et ce, en n'importe quel endroit de map.
Mon probleme est le suivant: plutot que de faire rebondir mon objet sur le terrain, je voudrais qu'il glice, c'est à dire que le vecteur mouvement s'inscrive dans le plan du triangle sur lequel se trouve mon objet. Et là, mes lacunes en maths me bloquent.
J'ai put trouver des exemples d'équations pour faire rebondir sur un plan, mais pas pour glisser le long d'un plan, aussi, est ce que vous pourriez me donner des pistes.
Avec le coordonné de tes vertices de ta heightmap tu peut trouver le vecteur normal au plan, avec ce vecteur et le vecteur vitesse (direction de ton mouvement) tu peut trouver un vecteur colinéaire au plan qui sera ton nouveau vecteur de mouvement. Voila d'après moi ce que je ferais, si tu veut plus de précision dit le.
C'est bien ce que je pensais, mais comment faire?
Mathématiquement, comment traduirais tu celà?
Tu es en quelle classe au fait ?
En 1ère ou Terminale S t'apprends que l'équation cartésienne d'un plan dans l'espace est de la forme : ax + by + cz + d = 0. (a, b, c et d sont des constantes réels ; x,y et z sont les coordonnées du point appartenant au plan).
Il existe un vecteur normal (orthogonal) à tout vecteur contenu dans ce plan, et un vecteur normal au plan ci-dessus est de coordonnées (a,b,c).
(Par produit scalaire dans l'espace tu peux vérifier).
Note que tout vecteur colinéaire à ce vecteur normal est un vecteur normal à ce plan, il en existe donc une infinité.
Comment trouver les coordonnées de ce plan ?
Un truc très utile pas enseigné dans le secondaire (à tort!) c'est le produit vectoriel.
Plutôt que de résoudre un système de 3 équations linéaires, tu peux trouver un vecteur normal en appliquant le produit vectoriel à 2 vecteurs non colinéaires contenus dans le plan (donc parallèles au plan).
Soit u(x1, y1, z1) et v(x2, y2, z2) les 2 vecteurs.
Le produit vectoriel se note '^', et tu fais le produit vectoriel de u et v :
u^v = (y1.z2 - z1.y2, z1.x2 - x1.z2, x1.y2 - y1.x2)
Fais attention, le produit vectoriel est non commutatif, ça veut dire u^v != v^u.
En fait, u^v = -v^u.
Voilà voilà, si n = u^v, alors n est perpendiculaire à u et à v !
Ah oui, par contre selon l'orientation de ton repère (droitier ou gaucher), le vecteur normal aura pas le même sens.
J'espère que ça t'a un peu aidé.
Je te remercie pour ta réponse, mais je ne crois pas que cela resolve mon probleme. Si j'ai bien compris, tu m'explique comment trouver la normale de deux vecteurs, mais mon probleme est le suivant:
le deplacement d'un objet est défini par un vecteur mouvement, appelons le V.
Un plan, définit pas un vecteur P et une normale au plan N.
Comment transformer mon vecteur V en un vecteur inscrit dans le plan P?
Voila, j'espere que j'ai été aussi clair que possible, si ta réponse contient bien la solution, peut tu me l'expliquer autrement.
Sinon, ça fait longtemp que j'ai quitté les banc de l'école, mais j'ai suivi une filière technique, d'où quelques lacune en math.
alors c'est tres simple : tu passes ton temps a faire des produits vectoriels et des produits scalaires.
le but est de laisser l'objet aller jusqu'a la surface et ensuite de "recuperer" ou "redresser" son mouvement pour qu'il suive "une" perpendiculaire a la normale du plan.
Techniquement je pourrais m'etendre la dessus mais je crois qu'il vaut mieux y aller doucement.
Tu maitrises les vecteurs ? (calcul de normale, produit(s) scalaire/vectoriel) et la geometrie euclienne ? (hauteur, pytagore, plus courte distance entre un point et un plan, etc)
Je maitrise ces notions, mais je ne voit pas comment les agencer pour arriver au resultat. Ca fait deux jours que je fait des schemas et des calculs sans réussir à trouver quoique ce soit.
Pourrait tu me decrire les differnte etape du calcul, dans les grandes lignes?
Je crois que je viens de comprendre:
1: je calcule la normale N' entre mon vecteur mouvement V et la normale du terrain N.
2: le vecteur nouveau mouvement V' est donc egale à la normale du plan NN'.
Par contre, à quoi te sert le produit scalaire?
...Pour normaliser les vecteurs.
Merci beaucoup pour tes explications, j'y vois un peu plus clair.
Bonne journée.
Bonjour,
Mainrenant que j'ai bien avancé, je vais prendre quelques minutes pour vous expliquer comment je m'y prend pour deplacer un objet sur ma heightmap.
Tout d'abord, j'ai laissé tombé le test de collisions entre les objets et la map, je le réserve uniquement pour les objets projectils.
Donc plutot que de tester si l'objet entre en collision avec le sol, vu que je connais les coordonnées X et Z de mon objet, et vu que je connais également le plan et la normale du triangle sur lequel se trouve l'objet, je calcule uniquement la hauteur Y de mon objet.
En explicant autrement, le vecteur mouvement de l'objet est définit par un vecteur colinéaire au plan XZ (pas de hauteur), la seul inconnue est donc la hauteur, que je determine avec le plan et la normale du triangle sur lequel se trouve l'objet.
J'espère que jusque là tout le monde suit.
Voici les calculs:
Determinons les coordonnées d'un point I inscrit dans un triangle ABC, dans un repère à trois dimensions XYZ (un des triangles qui constitu le terrain):
- Soit I' le projeté orthogonale du point I sur le plan XZ (horizontal) {xI', zI',0}, le point I à donc pour vecteur {xI',yI',zI}, où zI est notre inconnue.
- Soit vecN, la normale au plan formé par le triangle ABC.
Nous savons que le produit vectoriel vecAI*vecN=0
xI' - xA xN
si vecAI= zI' - yA et vecN = yN alors:
yI - yA zN
xI' - xA xN
zI' - yA * yN = 0 => xN(xI'-xA )+ yN(yI'-yA) +zN(zI-yA) = 0
yI - yA zN
yI =( ( (xN(xI'-xA )+ zN(zI'-zA) ) / yN ) - yA
Voila, avec juste une formule mathématique, je trouve la hauteur Y de mon objet en connaissant juste ses coordonnées XZ.
En remerciant le copain pour ses explications en math, et en esperant que ça inspirera quelqu'un.
Ced
Pourquoi il faut etre calé en math pour faire des jeux 3D :( ouinnnnnnnnnnn
je suis ultra nul en math et un objet qui glisse je ne vois pas ce quil y a de compliqué ?
.X..X..X..X..X..X..X..X..X..X
Y.....chouette je glisse.------>........................
il n'y a que X qui varie quand il glisse non ?
Si on se deplace sur un terrain tout plat, oui...
Mais dans mon cas, le terrain est en 3D, donc, quand la direction ( ou position) change, la hauteur change aussi.
Sinon, pour les maths, moi aussi je suis nul, et je me suis fais expliquer le problème par un ami calé en math. Mais pour l'implementation, seule la formule est necessaire, pas besoin de tout comprendre (quoi que ça aide). Il se trouve que là ça mache, je dirais même plus ça glisse!
Si il y a d'autres choses que tu ne comprend pas, n'hésite pas à me poser des questions.
remram44
29/10/2005, 16h02
Ah zut, j'avais raté ce sujet.
Quand j'étais en seconde (l'année dernière), j'avais fais ce petit exemple : http://remram44.free.fr/hyper/terrain-fdf.zip
Ca pourrait t'aider ;)
Le problème maintenant c'est que même s'il y a une falaise, il va la franchir avec la même vitesse horizontale que s'il n'y en avait pas ;).
bein à mon avis, hum...sans math^^ le perso glisse en ayant simplement la base de ses pieds à la meme hauteur que le terrain qu'il rencontre, mais il ne doit pas pouvoir glisser si la cote (inverse de pente) qu'il rencontre est trop abrupte.
ces deux parametres : hauteur du terrain et sa cote doivent pouvoir se mesurer dans un objet 3D surement...
Salut,
Tu as raison HanLee, si il ya a une pente, avec cette formule, la vitesse de deplacement horizontale est toujours la même, c'est pour cela que dans mon programme, dans la formule de deplacement, j'ai rajouté un coefficient proportionnel à la normale du terrain:
vecteur nouvelle position = vecteur position courante + vecteur mouvement * par un coeff
plus la composante Y ( axe vertical dans OpenGL) de la normale est importante (plus le plan est horizontal), plus mon coefficient est important et donc plus je vais vite, et inversement. On pourrait même trouver à partir de la normale un coefficient qui tienne compte du sens de la pente, plus lent dans les montées, plus rapide dans les descente.
Sinon, pour parler des falaises, je ne devrais pas avoir ce genre de problème, car je travail sur l'implementation d'un algorythme de recherche de chemin (A star), toujours avec comme objectif de ne pas avoir à faire de detection de collision, ni de chute.
Après c'est sure que cette solution n'est pas parfaite, mais elle est rapide et nécessite peut de calcul par objet à deplacer, alors que la detection de collision demande en peu plus de ressource. D'ailleur, si quelqu'un a d'autre solutions encore plus rapide, je reste ouvert.
et voila j'ai encore laisse passer un sujet interessant
pour le coup de "ca glisse":
il faut une force de frottement de l'air retranchee au vecteur vitesse, c'est rapide efficace et pas cher.
pour la falaise et la vitesse :
si tu calcule le resultat de l'impact de l'objet sur la falaise tu redresse le vecteur et tout et tout, du coup ca va en avant :)
Et c'est la que la gravite, que nous gerons tous par "y = sol + ma hauteur" devient ta meilleure amie: elle appuie l'objet vers le bas en la combinant au deplacement avec la meme methode que pour le deplacement seul et non pas avec sol + ma hauteur (ou presque, parce qu'avec des decors de batard comme j'ai ca accroche souvent aux asperites et aux jonctions de poly quand je colle l'objet au sol, chacun ses soucis).
donc calcul redressement deplacement + calcul redressement gravite, et voila l'objet qui va moins vite en montant.
La je le reconnais j'ai un enorme pb, parce que ma methode fait que l'objet avance (par exemple sur une pente a 45°) et qu'il retombe aussi sec quand j'applique la gravite derriere (a croire qu'il faudrait appliquer la gravite avant pour ca, mais j'ai peur qu'il flotte un peu) c'est a cause de ca que j'ai des problemes avec les asperites : si je laisse tel quel, je ne monte plus les pentes.
je me demande aussi si il ne faut pas "doser" la gravite ou mettre un frein fixe a un angle de pente donnee pour regler le pb : au dela d'une certaine pente on ne franchit plus.
s'ajoute le souci de choix : (ca depend du design) est on dans un jeu de billes ou les elements roulent sur eux meme en montant les pentes, ou dans un jeu ou les perso restent droits comme des I en montant (ils levent les genous les gueux...)
edit oula je passe ma vie a editer ... et bien j'avais loupe le dernier post de cedced sur la derniere page... qui m'aide pas mal meme si je dois reflechir encore un peu avant de l'adopter.
Et cela dit cedced, parce que j'aime bien reveiller les threads qui dorment ce soir, je suis en train de ruminer un astar 3D qui permettrait de tomber dans les trous et de monter les escalier sans s'envoler sans raison valable. Je vomis des trucs verts depuis que j'ai cette idee, mais ca avance doucement, si j'ai des resultats qui me plaisent, pourquoi ne pas en parler ? :)
vBulletin® v.3.6.5, Copyright ©2000-2009, Jelsoft Enterprises Ltd. Tous droits réservés - Version française vbulletin-fr.org