2016-04-01 1 views
1

Je crée un lecteur d'image 360 ​​° à l'aide d'Oculus rift SDK. La scène est composée d'un cube et la caméra est posée au centre avec juste la possibilité de tourner autour du lacet, du tangage et du roulis.Relie les zones de textures d'un cube à la fenêtre Oculus actuelle

J'ai dessiné l'objet en utilisant openGL en considérant une texture 2D pour le visage de chaque cube pour créer l'effet 360 °. Je voudrais trouver la portion dans la texture d'origine qui est affichée dans la fenêtre Oculus à un certain moment. Jusqu'à présent, mon approche consistait à essayer de trouver une position de pixel approximative d'un point significatif de la fenêtre (c.-à-d. Le point central et les coins) en utilisant les angles d'Euler pour identifier certaines zones dans les textures originales. Considérant tous les problèmes d'utilisation d'Euler Angles, ne semble pas la meilleure façon de le faire.

Y a-t-il une meilleure approche pour l'accomplir?

Modifier


Je l'ai fait un petit exemple qui peut être runned dans la boucle de rendu:

 //Keep the Orientation from Oculus (Point 1) 
     OVR::Matrix4f rotation = Matrix4f(hmdState.HeadPose.ThePose); 

     //Find the vector respect to a certain point in the viewport, in this case the center (Point 2) 
     FovPort fov_viewport = FovPort::CreateFromRadians(hmdDesc.CameraFrustumHFovInRadians, hmdDesc.CameraFrustumVFovInRadians); 
     Vector2f temp2f = fov_viewport.TanAngleToRendertargetNDC(Vector2f(0.0,0.0));// this values are the tangent in the center 
     Vector3f vector_view = Vector3f(temp2f.x, temp2f.y, -1.0);// just add the third component , where is oriented 
     vector_view.Normalize(); 

     //Apply the rotation (Point 3) 
     Vector3f final_vect = rotation.Transform(vector_view);//seems the right operation. 


     //An example to check if we are looking at the front face (Partial point 4) 
     if (abs(final_vect.z) > abs(final_vect.x) && abs(final_vect.z) > abs(final_vect.y) && final_vect.z <0){ 
      system("pause"); 
     } 
  1. Est-il juste de considérer toute fenêtre ou doit être fait pour chaque oeil unique?
  2. Comment peut-on indiquer un point différent de la fenêtre par rapport au centre? Je n'ai pas vraiment compris quelles valeurs devraient être l'entrée de TanAngleToRendertargetNDC().

Répondre

1

Vous pouvez obtenir une matrice de rotation complète en passant le quaternion de pose de caméra au constructeur OVR :: Matrix4.

Vous pouvez prendre n'importe quelle position 2D dans la fenêtre de vue et la convertir en coordonnées 3D de l'espace de prise de vue en utilisant les angles de fovPort. Normaliser et vous obtenez le vecteur de direction dans l'espace de la caméra pour ce pixel.

Si vous appliquez la matrice de rotation obtenue plus tôt à ce vecteur directionnel, vous obtenez la direction réelle de ce rayon.

Maintenant, vous devez convertir de cette direction à votre texture UV. Le composant avec la valeur absolue la plus élevée dans le vecteur de direction vous donnera le visage du cube qu'il regarde. Les composants restants peuvent être utilisés pour trouver l'emplacement 2D réel sur la texture. Cela dépend de l'orientation de vos faces de cube, si elles sont inversées par x, etc.

Si vous êtes dans la partie de rendu de la visionneuse, vous devez le faire dans un shader. Si c'est pour trouver où l'utilisateur regarde dans l'image originale ou l'étendue de son champ de vision, alors seulement une poignée de rayons suffirait comme vous avez écrit.

modifier

est ici un peu de code pour passer des angles tan aux coordonnées de l'espace de la caméra.

float u = (x/eyeWidth) * (leftTan + rightTan) - leftTan; 
float v = (y/eyeHeight) * (upTan + downTan) - upTan; 
float w = 1.0f; 

x et y sont des coordonnées de pixel, eyeWidth et eyeHeight sont oeil taille de mémoire tampon, et les variables * Tan sont les valeurs fovPort. J'exprime d'abord la coordonnée de pixel dans la gamme [0..1], puis l'échelle par l'angle de tan total pour la direction, puis recentrer.

+0

D'abord, merci pour la réponse. Je pense que le premier point peut être résolu avec: OVR :: Matrix4f rotation = Matrix4f (hmdState.HeadPose.ThePose); Pour le deuxième point, je ne peux pas trouver la fonction de conversion de FovPort d'une certaine position 2D au vecteur 3D, peut-être que vous voulez dire que je dois mettre en œuvre par moi-même. Jusqu'à présent, je viens de créer le FovPort avec la fonction CreateFromRadians(). – Pelux

+0

@Pelux: si vous passez la pose entière au constructeur Matrix4f, vous obtiendrez également les données de position. Si vous voulez juste une rotation, vous devez simplement passer le composant Rotation de pose (un quaternion). Re: FovPort, oui vous devez l'implémenter. Une fois que vous comprenez ce que les valeurs d'angles de tan FovPort représentent, c'est plutôt simple. –

+0

@Pelux: édité ma réponse avec un extrait de code. –