IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

OpenGL Discussion :

faire pick objet opengl


Sujet :

OpenGL

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Mai 2011
    Messages : 926
    Par défaut faire pick objet opengl
    Bonjour,
    Je voudrais faire le picking objet opengl selon le curseur de la souris.

    J'ai trouver un exemple qui ne fonctionne pas du tout et je conseille au developper d'aller ailleurs.

    Code qui fonctionne mal !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
     
    // Compute O and D in object coordinates
    glm::vec4 origin = mvp_inverse * glm::vec4(
            (x-half_width)/half_width, (half_height-y)/half_height, -1, 1);
    glm::vec4 dir = mvp_inverse * glm::vec4(0, 0, 1, 0);
    O = glm::vec3(origin.x, origin.y, origin.z);
    D = glm::normalize(glm::vec3(dir.x, dir.y, dir.z));
    // Iterate through the figures in the model
    tmin = 1000.0;
    for(i=0; i<num_objects; i++) {
       data_array = (float*)geom_vec[i].map["POSITION"].data;
       // Iterate through the triangles in the figure
       for(j=0; j<geom_vec[i].index_count; j+=3) {
          index = geom_vec[i].indices[j]*3;
          // Read the first point of Triangle KLM
          K = glm::vec3(data_array[index],
                        data_array[index+1],
                        data_array[index+2]);
          // Read the second point of Triangle KLM
          index = geom_vec[i].indices[j+1]*3;
          L = glm::vec3(data_array[index],
                        data_array[index+1],
                        data_array[index+2]);
          // Read the third point of Triangle KLM
          index = geom_vec[i].indices[j+2]*3;
          M = glm::vec3(data_array[index],
                        data_array[index+1],
                        data_array[index+2]);
          // Compute vectors E, F, and G
          E = K - M;
          F = L - M;
          G = O - M;
          // Compute the vector containing t and the coordinates k and l
          tkl = 1/glm::dot(glm::cross(D, F), E) *
                   glm::vec3(glm::dot(glm::cross(G, E), F),
                             glm::dot(glm::cross(D, F), G),
                             glm::dot(glm::cross(G, E), D));
          // Check if t and the intersection point (k, l) are acceptable
          if(tkl.x < tmin[i] && tkl.y > 0.0f && tkl.z > 0.0f && (tkl.y + tkl.z) < 1) {
             tmin = tkl.x;
             sphere = i;
          }
       }
    }
    trouver sur le site 'https://www.codeproject.com/articles...ngl-and-opencl'

    D'ailleur 'mvp_inverse' c'est l'inverse de la matrice 'mvp' !
    Mais c'est quoi 'mvp' ??? matrice générale ? matrice model ?? on ne sait pas !
    Il y a un bug 'tmin[i]' ce n'est pas bon ! il s'agit d'un entier et non d'un tableau !

    glm : version 0.95
    info : glm v0.95 admet des degrés,mais le code source ne parle pas d'angle donc pas besoin de mettre à jour.

    Ou trouver un code source qui marche permettant détecte la collision de primitives ?

    J'en avais déjà écrit un , il bug mais fonctionne bien mieux !

    Je vais continuer à bien vérifier mais à mon avis ... , je ne vais pas perdre trop de temps.

    Merci

  2. #2
    Expert confirmé
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 226
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 226
    Par défaut
    Le picking n'est pas très compliqué , il faut refaire l'opération que fait le GPU (qu'on appelle transformation perspective qui consiste en gros a faire la matrice MVP*vecteur + division/mul ,) pour avoir les même coordonnées que lui , ensuite c'est un simple test point/triangle qu'il faut faire

    Mais c'est quoi 'mvp' ??? matrice générale ? matrice model ?? on ne sait pas !
    Sur ce coup , c'est pas la faute du gars qui poste le code source , là on parle de b.a.ba de la 3D...
    Il faut relire les cours sur le net , MVP = ModelViewProjection , normalement tu as toujours 3 Matrices , celui de ton Model 3D (un perso/ennemi etc etc) , la Matrice View (la Camera) , et la Projection (qui défini la perspective et l'angle de vue) à ton rendu.
    On multiplie c'est 3 Matrices ensemble et qu'on nomme MVP , ensuite celle ci est multiplier par chaque vecteur de ton model 3D ce qui donne de la perspective (y'a une division quand même).

  3. #3
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Mai 2011
    Messages : 926
    Par défaut
    J'ai pu résoudre le probléme grace au site :
    https://laptrinhx.com/raycast-in-3d-3878626911/

  4. #4
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Mai 2011
    Messages : 926
    Par défaut
    Voici un extrait de code qui ne fonctionne pas du tout !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    bool gcapture(POpengl opengl,bool click, int mx, int my)
    {
    	bool bret = false;
    	PTVERTEX ret = NULL;
    	RECT rc;
    	GetClientRect(opengl->hWnd, &rc);
    	int half_width = rc.right / 2;
    	int half_height = rc.bottom / 2;
    	int x = mx;
    	int y = my;
    	float tmin = 10000.0;
    	// Compute O and D in object coordinates
    	HANDLE hiterator_1 = opengl->hrefcapture;
    	while (hiterator_1 != NULL)
    	{
    		PHANDLE_PLAY pp = (PHANDLE_PLAY)Stack_Next(hiterator_1, true); //Stack_Next Fonctionne mais fonction privé
     
    		if (pp->capture == false) //il est égal à true
    			continue;
     
    		glm::mat4 mvp_inverse;
    		mvp_inverse = glm::inverse(pp->lastmat); //lastmat= matrice général
    		/*glm::vec4 origin = mvp_inverse * glm::vec4(
    			(x - half_width) / half_width, (half_height - y) / half_height, -1, 1);*/
    		glm::vec4 origin = glm::vec4(1,camera.cameraPos);
    		glm::vec4 dir = mvp_inverse * glm::vec4(0, 0, 1, 0);
    		glm::vec3 O = glm::vec3(origin.x, origin.y, origin.z);
    		glm::vec3 D = glm::normalize(glm::vec3(dir.x, dir.y, dir.z));
     
    		Ray ray;
    		ray.Origin = origin;
    		ray.Direction = D;
     
    		HANDLE hiterator_2 = pp->hlist;
    		while (hiterator_2 != NULL)
    		{
    			PINTERNALVTX pp = (PINTERNALVTX)Stack_Next(hiterator_2, true); //Stack_Next Fonctionne
     
    			// Read the first point of Triangle KLM
    			glm::vec3	 K = glm::vec3(pp->vv.x[0], pp->vv.y[0], pp->vv.z[0]);;
    			// Read the second point of Triangle KLM
    			glm::vec3	 L = glm::vec3(pp->vv.x[1], pp->vv.y[1], pp->vv.z[1]);;
    			// Read the third point of Triangle KLM
    			glm::vec3	 M = glm::vec3(pp->vv.x[2], pp->vv.y[2], pp->vv.z[2]);;
     
    			// Compute vectors E, F, and G
     
    			glm::vec3 centroid = K;
    //#error toremove
    			//if (IntersectTriangle(ray, K, L, M))
    			/*glm::vec3 N = glm::cross(L - K, M - K);
    			float k0 = glm::dot(N, K);
    			float ks = glm::dot(N, L) - k0;
    			float kt = glm::dot(N, M) - k0;
    			glm::vec3 result = (kt * S - ks * T) / (kt - ks);*/
    			glm::vec3 intersect;
    			bool result = glm::intersectRayTriangle(ray.Origin, ray.Direction, K, L, M, intersect);
    			if (result)
    			{
    				float dd = sqrt(sqr(origin.x - intersect.x) + sqr(origin.y - intersect.y) + sqr(origin.z - intersect.z));
    				if (dd < tmin)
    				{
    					tmin = dd;
    					ret = &pp->vv;
    				}
    			}
     
     
     
    		}
    	}
    	if (opengl->drhint != NULL)
    	{
    		bret=opengl->drhint(opengl->param,click, ret)==1;
    	}
    	return bret;
    }
    Je me demande si la fonction intersectRayTriangle fonctionne bien ???

  5. #5
    Membre extrêmement actif
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    926
    Détails du profil
    Informations personnelles :
    Localisation : France, Vienne (Poitou Charente)

    Informations forums :
    Inscription : Mai 2011
    Messages : 926
    Par défaut
    Un bug corriger ,
    mais ca ne marche toujours pas !
    probléme non resolut !
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
     
    bool gcapture(POpengl opengl,bool click, int mx, int my)
    {
    	bool bret = false;
    	PTVERTEX ret = NULL;
    	RECT rc;
    	GetClientRect(opengl->hWnd, &rc);
    	int half_width = rc.right / 2;
    	int half_height = rc.bottom / 2;
    	int x = mx;
    	int y = my;
    	float tmin = 10000.0;
    	// Compute O and D in object coordinates
    	HANDLE hiterator_1 = opengl->hrefcapture;
    	while (hiterator_1 != NULL)
    	{
    		PHANDLE_PLAY pp = (PHANDLE_PLAY)Stack_Next(hiterator_1, true); //Stack_Next Fonctionne mais fonction privé
     
    		if (pp->capture == false) //il est égal à true
    			continue;
     
    		glm::mat4 mvp_inverse;
    		mvp_inverse = glm::inverse(pp->lastmat); //lastmat= matrice général
    		glm::vec4 origin = mvp_inverse * glm::vec4(
    			(x - half_width) / half_width, (half_height - y) / half_height, -1, 1);
     
    		glm::vec4 dir = mvp_inverse * glm::vec4(0, 0, 1, 0);
    		glm::vec3 O = glm::vec3(origin.x, origin.y, origin.z);
    		glm::vec3 D = glm::normalize(glm::vec3(dir.x, dir.y, dir.z));
     
    		Ray ray;
    		ray.Origin = origin;
    		ray.Direction = D;
     
    		HANDLE hiterator_2 = pp->hlist;
    		while (hiterator_2 != NULL)
    		{
    			PINTERNALVTX pp = (PINTERNALVTX)Stack_Next(hiterator_2, true); //Stack_Next Fonctionne
     
    			// Read the first point of Triangle KLM
    			glm::vec3	 K = glm::vec3(pp->vv.x[0], pp->vv.y[0], pp->vv.z[0]);;
    			// Read the second point of Triangle KLM
    			glm::vec3	 L = glm::vec3(pp->vv.x[1], pp->vv.y[1], pp->vv.z[1]);;
    			// Read the third point of Triangle KLM
    			glm::vec3	 M = glm::vec3(pp->vv.x[2], pp->vv.y[2], pp->vv.z[2]);;
     
    			// Compute vectors E, F, and G
     
    			glm::vec3 centroid = K;
    //#error toremove
    			//if (IntersectTriangle(ray, K, L, M))
    			/*glm::vec3 N = glm::cross(L - K, M - K);
    			float k0 = glm::dot(N, K);
    			float ks = glm::dot(N, L) - k0;
    			float kt = glm::dot(N, M) - k0;
    			glm::vec3 result = (kt * S - ks * T) / (kt - ks);*/
    			glm::vec3 intersect;
    			bool result = glm::intersectRayTriangle(ray.Origin, ray.Direction, K, L, M, intersect);
    			if (result)
    			{
    				float dd = sqrt(sqr(origin.x - intersect.x) + sqr(origin.y - intersect.y) + sqr(origin.z - intersect.z));
    				if (dd < tmin)
    				{
    					tmin = dd;
    					ret = &pp->vv;
    				}
    			}
     
     
     
    		}
    	}
    	if (opengl->drhint != NULL)
    	{
    		bret=opengl->drhint(opengl->param,click, ret)==1;
    	}
    	return bret;
    }
    Pour information : mx et my sont des variables coordonnées écran 2D position de souris

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. faire des objets en 3D avec openGL
    Par membreComplexe12 dans le forum OpenGL
    Réponses: 4
    Dernier message: 08/04/2012, 13h07
  2. picking avec opengl
    Par refka_eei dans le forum OpenGL
    Réponses: 0
    Dernier message: 11/04/2008, 13h52
  3. picking en opengl es
    Par ra_haja501 dans le forum Développement 2D, 3D et Jeux
    Réponses: 1
    Dernier message: 12/09/2007, 10h42
  4. récuperer un objet, OPENGL-GLUT
    Par Haage dans le forum OpenGL
    Réponses: 7
    Dernier message: 21/07/2007, 19h23
  5. [Debutant] Faire un objet redimensionnable
    Par deboll_s dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 04/07/2005, 21h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo