J'ai une projection en perspective. Lorsque l'utilisateur clique sur l'écran, je veux calculer le rayon entre les plans proche et lointain qui projette à partir du point de la souris, afin que je puisse faire du code d'intersection de rayons avec mon monde.
J'utilise mes propres classes de matrice et de vecteur et de rayon et elles fonctionnent toutes comme prévu.
Cependant, lorsque j'essaie de convertir le rayon en coordonnées universelles, mon extrême se termine toujours par 0,0,0 et mon rayon va donc du clic de la souris au centre de l'espace objet, plutôt qu'à travers lui. (Les coordonnées x et y de près et de loin sont identiques, elles ne diffèrent que par les coordonnées z où elles sont négatives l'une de l'autre)
GLint vp[4];
glGetIntegerv(GL_VIEWPORT,vp);
matrix_t mv, p;
glGetFloatv(GL_MODELVIEW_MATRIX,mv.f);
glGetFloatv(GL_PROJECTION_MATRIX,p.f);
const matrix_t inv = (mv*p).inverse();
const float
unit_x = (2.0f*((float)(x-vp[0])/(vp[2]-vp[0])))-1.0f,
unit_y = 1.0f-(2.0f*((float)(y-vp[1])/(vp[3]-vp[1])));
const vec_t near(vec_t(unit_x,unit_y,-1)*inv);
const vec_t far(vec_t(unit_x,unit_y,1)*inv);
ray = ray_t(near,far-near);
Qu'est-ce que je me suis trompé? (Comment pouvez-vous défaire le point de la souris?)
Réponses:
J'ai récemment dû résoudre ce problème moi-même pour une application WebGL. J'ai joint le code source complet, mais au cas où cela ne fonctionnerait pas immédiatement pour vous, voici quelques conseils de débogage:
De plus, pour répondre à certains commentaires ci-dessus, vous ne voulez presque jamais utiliser les API de sélection d'OpenGL. Cela vous aide à choisir des éléments existants, comme si vous créiez un menu, mais cela ne permet pas d'exécuter la plupart des scénarios du monde réel comme l'édition de modèles 3D. Où vous devez ajouter une géométrie à la suite du clic.
Voici ma mise en œuvre. Il n'y a rien de magique ici. Juste JavaScript et la bibliothèque de fermeture de Google.
gluUnProject
Usage
la source
Je ne vois aucun problème avec votre code. Je n'ai donc que quelques suggestions:
Et essayer de changer la multiplacation de la matrice en
(p*mv).inverse();
. Tout simplement parce que les glMatrices sont transposées en mémoire. (c'est un gros peut-être, désolé)Un autre raycasting
Unprojecting n'est pas seulement un moyen d'obtenir un rayon à partir du pixel. Voici mon code pour raycaster:
Vous pouvez obtenir cameraRight, Up et Direction à partir de la matrice de vue (ce qui est surtout utile dans le shader) Voir la matrice en opengl
Sélection de couleur La sélection de
couleur est une technique où vous effectuez le rendu de chaque objet cliquable avec une autre couleur (solide), puis lisez la valeur de la couleur au point cliqué. Cela a fonctionné comme GL_SELECTION en opengl. Mais il est désormais obsolète. Mais la sélection des couleurs est facile à coder en 1 passage de rendu supplémentaire.
Utilisez un tampon d'image et effectuez un rendu de texture avec la même résolution que la résolution d'écran, utilisez un simple shader qui renvoie simplement la couleur dans le fragment shader. Après "passage de couleur", lisez la valeur d'un adressage de texture avec clickedPoint x et y. Trouvez un objet avec une couleur que vous lisez. Facile et assez rapide.
la source