La Mise En Œuvre De Ray Cueillette
J'ai un moteur de rendu de l'utilisation de directx et openGL, et une scène 3d. La fenêtre et la fenêtre sont de mêmes dimensions.
Comment puis-je mettre en œuvre la cueillette donné les coordonnées de la souris en x et y dans une plate-forme indépendante de la sorte?
- Jetez un oeil à ce guide, il pourrait être utile
Vous devez vous connecter pour publier un commentaire.
Si vous le pouvez, faites la cueillette sur le CPU par le calcul d'un rayon de l'œil à travers le pointeur de la souris se croisent et s'entrecroisent avec vos modèles.
Si ce n'est pas une option, j'irais avec un certain type de l'ID de rendu. Attribuer à chaque objet que vous souhaitez sélectionner une couleur unique, rendre les objets avec ces couleurs et, enfin, la lecture de la couleur dans le framebuffer sous le pointeur de la souris.
EDIT: Si la question est de savoir comment construire les rayons à partir de la position de la souris vous avez besoin des éléments suivants: une matrice de projection P et la caméra transformer C. Si les coordonnées du pointeur de la souris est (x, y) et la taille de la fenêtre d'affichage est (largeur, hauteur) une position dans le clip de l'espace le long de la raie est:
(Remarquez que je suis retournée à l'axe des y comme souvent à l'origine des coordonnées de la souris sont dans le coin supérieur gauche)
La suite est tout aussi vrai:
Qui donne:
Nous avons maintenant:
mouse_clip = [float(x) * 2 / float(width) - 1, 1 - float(y) * 2 / float(height), -1 * near_clipping_plane, 1]
mouseWorldSpace
être divisé par sa proprew
coordonner, car il a une transformation de perspective appliquée?Voici l'affichage frustum:
Vous devez d'abord déterminer où sur la nearplane le clic de la souris qui s'est passé:
unview = (P * M).inverse() = M.inverse() * P.inverse()
, oùM
est la matrice ModelView etP
est la matrice de projection.Puis déterminer l'endroit où l'appareil photo est en worldspace, et dessiner un rayon de départ à la caméra et passant par le point que vous avez trouvé sur le nearplane.
La caméra est à
M.inverse().col(4)
, c'est à dire la dernière colonne de l'inverse de la matrice ModelView.Finale de pseudo:
gl_Position = projection * modelView * vertexPos;
, c'est le bit dans le milieu, où l'projection
de la matrice est la traduction de la caméra à la fenêtre d'affichage des coordonnées. HTH :/Bien, assez simple, la théorie derrière cela est toujours le même
1) Unproject deux fois votre 2D coordonner sur l'espace 3D. (chaque API a sa propre fonction, mais vous pouvez implémenter votre propre si vous le souhaitez). L'un au Min Z, l'un au Max de la Z.
2) Avec ces deux valeurs, calculer le vecteur qui va de Min Z et le point de Max Z.
3) Avec le vecteur et un point de calculer le rayon qui va de Min Z pour MaxZ
4) Maintenant, vous avez un rayon, et avec cela, vous pouvez faire un rayon-triangle/ray-plan/ray-quelque chose d'intersection et d'obtenir votre résultat...
J'ai peu de DirectX expérience, mais je suis sûr que c'est similaire à OpenGL. Ce que vous voulez, c'est le gluUnproject appel.
En supposant que vous avez un valide Z buffer, vous pouvez interroger le contenu de la mémoire tampon Z à une position de la souris avec:
si vous ne souhaitez pas utiliser la glu vous pouvez également mettre en œuvre les gluUnProject vous pourriez également mettre en œuvre vous-même, c'est la fonctionnalité est relativement simple et est décrite à opengl.org
Ok, ce sujet est vieux, mais il était le meilleur que j'ai trouvé sur le sujet, et il m'a aidé un peu, donc je vais poster ici pour ceux qui suivent 😉
C'est la façon dont je l'ai eu à travailler sans avoir à calculer l'inverse de la matrice de Projection:
Cela suppose une projection en perspective, mais jamais posé la question qui se pose pour les orthographiques de l'un en premier lieu.
J'ai eu la même situation avec des rayons de la cueillette, mais quelque chose est faux. J'ai effectué la unproject opération de la bonne façon, mais il ne fonctionne tout simplement pas. Je pense, j'ai fait une erreur, mais ne peut pas trouver. Mon matix multiplication , inverse et vecteur par matix multiplications tous vu bien fonctionner, j'ai testé les.
Dans mon code je suis en réagissant sur WM_LBUTTONDOWN. Donc, lParam renvoie [Y][X] coordonnées que 2 mots dans un dword. Je les extraire, puis de les convertir à l'espace normalisé, j'ai vérifié cette partie fonctionne aussi très bien. Lorsque je clique sur le coin inférieur gauche - j'obtiens des valeurs proches de -1, -1 et de bonnes valeurs pour toutes les 3 autres coins. Je suis alors à l'aide de linepoins.vtx tableau pour le débogage et Il n'est même pas proche de la réalité.