Jeux Libres
       
           

» Les Forums » Aide à propos de la création de jeux vidéo » [Théorique 3D] Définir la souris 2D dans l'espace 3D


Aller à la page : 1.

[Théorique 3D] Définir la souris 2D dans l'espace 3D
Brouilles



Grade : Habitué
Inscrit le: 04 Fev 2012, 17:40
Ecrit le: 23 Jan 2015, 21:13             Message non corrigé

Bonjour à tous;
Je me suis mis à la 3 dimensions avec DirectX 9 et Win32 et non OpenGl et SDL. Mais je mheurte à un problème depuis déjà plusieurs jours. Mon problème nest pas au niveau du code ni de lAPI mais plus théorique.

Je mexplique. Jai mon rendu 3D, ma caméra, mon chargeur de format .OBJ qui fonctionne à peu près (me reste le support des textures pour quil soit un minimum utilisable) mais voilà, jaimerais mettre en place une « grille » de jeu, comme dans nimporte quel jeu de stratégie. Je déclare donc un tableau à 2 dimensions basiques int mapArray[5][5];et le remplit de façon à ce que 0 correspond au modèle du sol et 1 à une maison. Jusque la tout va bien mais voilà,  je suis confronté à un problème de taille : comment faire en sorte que la souris, quand elle survole une « case » sélectionne la bonne. Mon explication nest peu être pas très claire, prenons un jeu de stratégie comme Civilization, la carte et faite dhexagone, ont peu, tout naturellement grâce à la souris sélectionner une de ces cases.

Niveau théorique je bloque complètement, javais eu comme idée de prendre le centre de lécran de jeu et dy définir le repère de laxe pour la souris et de rajouter la position de la souris au point de vision de ma caméra donc lookAt, donc par exemple ma souris est à +10 du repère de ma fenêtre de jeu, donc je fais lookAt.(x ;y ou z en fonction du besoin) + 10. Mais de toute évidence cette solution nest pas fiable et perd en précision si on séloigne sur les bords. Même si elle fonctionne quand on reste près du lookAt.

Si vous avez une solution, je suis preneur. Cela risque de me bloquer une fois mon chargeur de modèle .obj sera fini. Et je narrive pas du tout à men sortir. Si vraiment mais explications sont mauvaises nhésiter pas à me le dire. Je ferais de mon possible.

Merci davance de vos réponses,
Cordialement.


________
Site personnel et Portfolio.
  Profil
Lo



Grade : Maître
Inscrit le: 26 Dec 2007, 17:33
Ecrit le: 23 Jan 2015, 22:29             Message non corrigé

Tu es dans un univers en 3D donc ?

Si le plan éloigné de la caméra est situé a 1000 unité par exemple, tu prends ce point si (x, y, 1000) où x et y sont la position de la caméra.

Je multiplie ensuite ce point par la matrice inverse de la matrice de viewport, je passe alors en coordonnées normalisées sur le plan éloigné de la caméra, ensuite, je multiplie par l'inverse de la matrice de projection, pour avoir la coordonnée dans l'espace "clip".
Ensuite tu divises les coordonnées par la valeur absolue de w pour avoir la coordonnée vue.
Ensuite, si je ne me trompe pas, il faut multiplier par l'inverse de la matrice de vue pour avoir la position de la souris en coordonnées monde sur le plan éloigné de la caméra.

Avec opengl tu peux récupérer ces 3 matrices.

Ensuite, tu n'as plus qu'à créer un rayon entre ce point là, et la position de ta caméra dans le monde.

Et enfin tu cherches les hexagones qui sont en intersection avec le rayon.

Voilà en espérant que ça pu t'aider, c'est la même technique que j'utilise pour le frustrum culling dans un espace 3D, je fais aussi l'inverse (conversion de coordonnées monde en coordonnées fenêtre) pour avoir la position des lumières dans le fragment shader et effectuer l'atténuation.
Voici les formules que j'utilise :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
math::Vec3f RenderTarget::mapPixelToCoords(const math::Vec3f& point, View& view)
       {
           ViewportMatrix vpm;
           vpm.setViewport(math::Vec3f(view.getViewport().getPosition().x, view.getViewport().getPosition().y, -view.getViewport().getDepth()), math::Vec3f(view.getViewport().getWidth(), view.getViewport().getHeight(), view.getViewport().getDepth()));
           math::Vec3f coords = vpm.toNormalizedCoordinates(point);
           coords = view.getProjMatrix().unProject(coords);
           coords /= math::Math::abs(coords.w);
           coords = view.getViewMatrix().inverseTransform(coords);
           return coords;
       }
 
       math::Vec3f RenderTarget::mapCoordsToPixel(const math::Vec3f& point)
       {
           return mapCoordsToPixel(point, getView());
       }
 
 
       math::Vec3f RenderTarget::mapCoordsToPixel(const math::Vec3f& point, View& view)
       {
           ViewportMatrix vpm;
           vpm.setViewport(math::Vec3f(view.getViewport().getPosition().x, view.getViewport().getPosition().y, -view.getDepth()),
           math::Vec3f(view.getViewport().getWidth(), view.getViewport().getHeight(), view.getDepth()));
           math::Vec3f coords = view.getViewMatrix().transform(point);
           coords = view.getProjMatrix().project(coords);
           //J'inverse y et z car chez moi, c'est l'axe z qui pointe vers le haut!
           float tmp = coords.y;
           coords.y = coords.z;
           coords.z = -tmp;
           coords = vpm.toViewportCoordinates(coords);
           coords /= math::Math::abs(coords.w);
           
       }

Donc pour avoir la position de la souris en coordonnées monde tu fais :

math::Vec3f farMousePos(sourisX, sourisY, 1000);
math::Vec3f worldFarMousePos = window.mapPixelToCoords(point, camera);
Ray ray(camera.getCenter(), worldFarMousePos);

//Et tu recherche les intersections entre le rayon et les polygones.




________
Parce qu'on ne peut s'exprimer que par nos créations. ^^
  Profil
Brouilles



Grade : Habitué
Inscrit le: 04 Fev 2012, 17:40
Ecrit le: 26 Jan 2015, 18:50             Message non corrigé

Bonjour,
Merci de ta réponse, je te tien au courant. Pour le moment je n'ai pas de temps libre mais j'espère en trouvais rapidement pour mettre en uvre ta saluions !
Cordialement.

________
Site personnel et Portfolio.
  Profil
 


Aller à la page : 1.


Hébergeur du site : David
Version PHP : 5.4.45-0+deb7u2
Uptime : 354 jours 20 heures 42 minutes
Espace libre : 1514 Mo
Dernière sauvegarde : 13/11/2019
Taille de la sauvegarde : 1115 Mo


5644848 pages ont été consultées sur le site !
Dont 3213 pages pendant les 24 dernières heures.

Page générée en 1.304 secondes


Nos sites préférés
- Création d'un jeu de plateforme de A à Z avec SDL
- Zelda ROTH : Jeux amateurs sur le thème de Zelda
- Zeste de Savoir : la connaissance pour tous et sans pépins
- YunoHost : s'héberger soi-même en toute simplicité
- Site de Fvirtman : recueil de projets et de codes en C et C++
- Par ici la sortie : le site des idées de sorties


  © 2005-2019 linor.fr - Toute reproduction totale ou partielle du contenu de ce site est strictement interdite.