2017-03-02 1 views
1

La tâche que je veux résoudre est simple: Charger un fichier OBJ texturé et l'afficher de façon à ce qu'il occupe un maximum d'espace image. Il n'est pas nécessaire de faire pivoter le maillage tant que la caméra regarde vers le bas de l'axe z négatif et que l'axe y est le vecteur haut. J'utilise pyglet pour faire ça. Pour régler la caméra à la position désirée, je fais ce qui suit (code voir ci-dessous): Calculer une sphère de délimitation du maillage, qui est définie par le centre du maillage et le rayon au point le plus éloigné de le centre. Ensuite, je calcule le tronc de cendres comme expliqué par exemple. here et configurer une projection orthogonale en conséquence. Ensuite, j'utilise gluLookAt pour mettre à jour la matrice modelview comme ceci: La caméra se trouve sur l'axe z positif, regarde vers le centre du maillage et l'axe y est le haut-vecteur. Le problème est que mon image rendue ne ressemble pas du tout à ce que j'attendrais d'elle, par exemple. le centre du maillage n'est pas au centre de l'image, comme vous pouvez le voir dans l'image suivante. L'image montre la boîte englobante et les axes de coordonnées provenant du centre calculé du maillage (rouge: axe des abscisses, vert: axe des y, bleu: axe des z).Pourquoi mon image rendue ne montre-t-elle pas la vue que je m'attends à voir avec gluLookAt?

enter image description here

Le code pour configurer l'appareil photo est:

# get the bounding sphere 
    center, radius = self._mesh.compute_bounding_sphere() 
    diam = radius*2.0 

    print 'center:' 
    print center 
    print 'radius: %f' % radius 

    # set up near and far clipping plane 
    z_near = 1.0 
    z_far = z_near + diam 

    # construct params for orthographic projection matrix 
    left = center[0] - radius 
    right = center[0] + radius 
    bottom = center[1] - radius 
    top = center[1] + radius 

    # if we are not rendering a square image, must correct for aspect ratio 
    aspect_ratio = float(self.width)/float(self.height) 
    if aspect_ratio < 1.0: 
     bottom /= aspect_ratio 
     top /= aspect_ratio 
    else: 
     left *= aspect_ratio 
     right *= aspect_ratio 

    print 'znear %f, zfar %f' % (z_near, z_far) 
    print 'left %f, right %f' % (left, right) 
    print 'bottom %f, top %f' % (bottom, top) 

    # specify a parallel projection with clipping planes as computed above 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 
    glOrtho(left, right, bottom, top, z_near, z_far) 
    # gluPerspective(50.0, aspect_ratio, z_near, z_far) 

    # construct a viewing transform as follows: we look at the center of the mesh, the eye is located on the 
    # positive z-axis, and the 3D y-axis is the up-vector, i.e. it will be mapped to the y-axis in image space. 
    eye = center[2] + radius 
    print 'eye:' 
    print eye 
    glMatrixMode(GL_MODELVIEW) 
    glLoadIdentity() 
    gluLookAt(0.0, 0.0, eye, center[0], center[1], center[2], 0.0, 1.0, 0.0) 

qui imprime

center: 
[ 8.51203675 -1.95199815 0.35396978] 
radius: 10.462382 
znear 1.000000, zfar 21.924764 
left -1.950345, right 18.974419 
bottom -12.414380, top 8.510384 
eye: 
10.8163515441 

Pouvez-vous me aider à identifier ce que je fais mal?

Répondre

1

Il n'est pas nécessaire de faire pivoter le maillage tant que la caméra regarde vers le bas de l'axe z négatif et que l'axe y est le vecteur haut.

Votre appareil photo ne regarde pas vers le bas l'axe z:

gluLookAt(0.0, 0.0, eye, center[0], center[1], center[2], 0.0, 1.0, 0.0) 

Ce introduiront une rotation de telle sorte que la direction de la caméra dans l'espace mondial sera (center[0], center[1], center[2] - eye) = (center[0], center[1], -radius).

Étant donné que vous avez déjà déplacé le volume de la vue en fonction de votre objet, le point lookAt sera et non sera le point qui apparaîtra au centre de l'écran. Ce que vous devez vraiment faire est simplement de regarder le long -z, il vous suffit de traduire la caméra le long +z:

gluLookAt(0.0, 0.0, eye, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0) 

Notez que sur le plan conceptuel, vous n'avez pas besoin d'une matrice de vue du tout pour votre cas d'utilisation. vous pourriez simplement calculer la boîte englobante entourée d'un objet et utiliser directement les paramètres de votre volume d'affichage (comme vous l'avez fait avec x et y, mais pour certains, et non pour z). Le seul truc serait que vous devez annuler les valeurs pour near et far, parce que la façon dont glOrtho est conçu.