Partage
  • Partager sur Facebook
  • Partager sur Twitter

pyOpenGL

rotation 3D camera freefly

    18 mai 2011 à 14:29:47

    Bonjour à tous,

    Tout d'abord, désolé si ce post n'est pas au bon endroit....openGL serait peut être mieux mais je n'ai pas trouvé?
    Voilà, je m'arrache les cheveux sur l'équivalent du "Free-fly" (la ptite abeille...) qui est exposé dans le tuto d'OpenGL sur le SDZ. J'utilise python 2.7, pyQt et pyOpenGL.

    Dans le code ci-dessous, les déplacements X,Y, et Z fonctionnent bien, mais la rotation en X,Y et Z s'effectue toujours sur l'origine [0,0,0].
    Ce que je voudrais, c'est que la rotation s'effectue par rapport à la position propre de la camera (que je récupère grâce à glGetFloatv(GL_MODELVIEW_MATRIX ), mais après ça, je n'arrive pas à faire ma rotation en fonction de ce point. Donc à vot' bon coeur!

    Voilà, je laisse ci-dessous ma fonction PaintGL qui effectue le traitement, et ensuite l'intégralité de mon code (on ne sait jamais, ça peut servir à des plus que zéros que moi!! :ange: )

    Merci d'avance ! :)
    D'ailleurs, je me demande également si je ne ferai pas mieux d'utiliser Vpython plutôt que pyOpenGL (je n'ai pas trouvé de comparatif sur le Web, donc pour l'instant je tâtonne en pyOpenGL) :euh::euh:

    def paintGL(self):
    		print "paintGL"
    		#the drawing function
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    		glMatrixMode(GL_MODELVIEW ) #mode de visu, à mettre avant de réinitilaiser la matrice
    		glLoadIdentity() #réinitialise la matrice
    		
    		
    		"""
    		#zoom "factice" qui réduit juste la fenetre de vision (type snipper dans un jeu)
    		gluLookAt(self.zoom,0,0,
    		0,0,0,
    		0,0,1)
    		"""
    		glTranslated(0,0,self.haut)
    		glTranslated(0,0,-self.bas)
    		glTranslated(0,self.droite,0)
    		glTranslated(0,-self.gauche,0)
    		glTranslated(self.avant,0,0)
    		glTranslated(-self.arriere,0,0)
    		
    		
    		mon_point_actuel = glGetFloatv(GL_MODELVIEW_MATRIX )
    		print "position X=%s Y=%s Z=%s" % (mon_point_actuel[3][0],mon_point_actuel[3][1],mon_point_actuel[3][2])
    		print mon_point_actuel
    		
    		glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) #glRotated ( thêta, x , y, z );
    		glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) #glRotated ( thêta, x , y, z );
    		glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) #glRotated ( thêta, x , y, z );
    		
    		glCallList(self.mon_dessin())
    


    Et ici mon code complet: touches QSDZ et flêches haut bas + clics souris pour le rotate en [0,0,0]
    #!/usr/bin/env python
    
    # -*- coding: utf-8 -*-
    
    #http://www.developpez.net/forums/d719073/autres-langages/python-zope/gui/pyside-pyqt/aide-opengl/
    #http://www.webfractales.org/lsystemthreading/doc/classGLBox.html
    #http://www.digitalfanatics.org/projects/qt_tutorial/fr/chapter14.html
    #http://cep.xor.aps.anl.gov/software/qt4-x11-4.2.2-browser/da/d10/class_g_l_widget.html#b2035753b19b46105020d6045ac75a79
    #les bases:   http://www-evasion.imag.fr/Membres/Antoine.Bouthors/teaching/opengl/opengl1.html
    #GLUT http://pyopensourceforge.net/documentation/manual/reference-html
    #tuto http://fhalgand.developpez.com/tutoriels/qt/integration-opengl/01-premiere-application/#LIII
    
    #PROJECTION: glOrtho et glPerspective
    #MODELVIEW: gluLookAt, étant utilisé dans le placement de la caméra
    
    
    
    
    from PyQt4 import QtCore, QtGui, QtOpenGL,Qt
    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    
    import numpy
    
    #import physique #biblio perso qui me fait quelques calculs
    
    import time
    
    
    class myGLAttractor(QtOpenGL.QGLWidget):
    	def __init__(self, parent):
    		QtOpenGL.QGLWidget.__init__(self, parent)
    		self.object = 0
    		self.xRot = 0
    		self.yRot = 0
    		self.zRot = 0
    		self.xBox = 25
    		self.yBox = 25
    		self.zBox = 25
    		self.zoom = 20
    		self.gauche = 0
    		self.droite = 0
    		self.haut = 0
    		self.bas = 0
    		self.avant = 0
    		self.arriere = 0
    		
    		self.centre=numpy.array([0,0,0])
    		self.lastPos2D = QtCore.QPoint()
    		self.trolltechGreen = QtGui.QColor.fromCmykF(0.40, 0.0, 1.0, 0.0)
    		self.trolltechPurple = QtGui.QColor.fromCmykF(0.39, 0.39, 0.0, 0.0)
    		self.setFocusPolicy(QtCore.Qt.StrongFocus) #permet de prendre n compte les événements clavier, sinon, ca marche pas!
    		
    		self.viewport = glGetIntegerv(GL_VIEWPORT)
    		
    	def xRotation(self):
    		return self.xRot
    
    	def yRotation(self):
    		return self.yRot
    
    	def zRotation(self):
    		return self.zRot
    
    	def zoom(self):
    		return self.zoom
    
    	def setXRotation(self, angle):
    		angle = self.normalizeAngle(angle)
    		if angle != self.xRot:
    			self.xRot = angle
    		        self.emit(QtCore.SIGNAL("xRotationChanged(int)"), angle)
    			self.updateGL()
    
    	def setYRotation(self, angle):
    		angle = self.normalizeAngle(angle)
    		if angle != self.yRot:
    			self.yRot = angle
    			self.emit(QtCore.SIGNAL("yRotationChanged(int)"), angle)
    			self.updateGL()
    
    	def setZRotation(self, angle):
    		angle = self.normalizeAngle(angle)
    		if angle != self.zRot:
    			self.zRot = angle
    			self.emit(QtCore.SIGNAL("zRotationChanged(int)"), angle)
    			self.updateGL()
    
    	def setZoom(self, angle):
    		#angle = self.normalizeAngle(angle)
    		self.zoom = angle
    		self.emit(QtCore.SIGNAL("zoomChanged(int)"), angle)
    		self.updateGL()
    
    	def initializeGL(self):
    		self.qglClearColor(self.trolltechPurple.dark())
    		glShadeModel(GL_FLAT)
    		glEnable(GL_DEPTH_TEST)
    		glEnable(GL_CULL_FACE)
    
    	def paintGL(self):
    		print "paintGL"
    		#the drawing function
    		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    		glMatrixMode(GL_MODELVIEW ) #mode de visu, à mettre avant de réinitilaiser la matrice
    		glLoadIdentity() #réinitialise la matrice
    		
    		
    		"""
    		#zoom "factice" qui réduit juste la fenetre de vision (type snipper dans un jeu)
    		gluLookAt(self.zoom,0,0,
    		0,0,0,
    		0,0,1)
    		"""
    		glTranslated(0,0,self.haut)
    		glTranslated(0,0,-self.bas)
    		glTranslated(0,self.droite,0)
    		glTranslated(0,-self.gauche,0)
    		glTranslated(self.avant,0,0)
    		glTranslated(-self.arriere,0,0)
    		
    		
    		mon_point_actuel = glGetFloatv(GL_MODELVIEW_MATRIX )
    		print "position X=%s Y=%s Z=%s" % (mon_point_actuel[3][0],mon_point_actuel[3][1],mon_point_actuel[3][2])
    		print mon_point_actuel
    		
    		glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) #glRotated ( thêta, x , y, z );
    		glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) #glRotated ( thêta, x , y, z );
    		glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) #glRotated ( thêta, x , y, z );
    		
    		glCallList(self.mon_dessin())
    		
    
    	def resizeGL(self, width, height): #fonction appellée en permanence
    		print "resizeGL"
    		#still in work
    		
    		side = min(width, height)
    		glViewport((width - side) / 2, (height - side) / 2, side, side)
    		glMatrixMode(GL_PROJECTION)
    		glLoadIdentity()
    		glOrtho(-self.xBox, self.xBox, self.yBox, -self.yBox, -self.zBox, self.zBox)
    		
    		#Debut
    		glMatrixMode(GL_PROJECTION)
    		glLoadIdentity()
    		gluPerspective(70, width/height, 1, 1000) #//....Permet d'avoir une belle perspective et éviter le rognage sinon, le zoom déconne
    		glEnable(GL_DEPTH_TEST)
    		#fin
    		
    
    		glMatrixMode(GL_MODELVIEW)
    
    	def mousePressEvent(self, event): #simpleclic
    		self.lastPos2D = QtCore.QPoint(event.pos())
    		print "self.lastPos2D"
    		print self.lastPos2D
    		print self.lastPos2D.x()
    		print self.lastPos2D.y()
    		self.picking()
    	
    	
    	def picking(self):
    		print "picking"
    		
    		
    		
    	def mouseMoveEvent(self, event):
    		dx = event.x() - self.lastPos2D.x()
    		dy = event.y() - self.lastPos2D.y()
    
    		if event.buttons() & QtCore.Qt.LeftButton:
    			self.setXRotation(self.xRot + 8 * dy)
    			self.setYRotation(self.yRot + 8 * dx)
    
    		elif event.buttons() & QtCore.Qt.RightButton:
    			self.setXRotation(self.xRot + 8 * dy)
    			self.setZRotation(self.zRot + 8 * dx)
    
    		self.lastPos2D = QtCore.QPoint(event.pos())
    
    	def wheelEvent (self, event):
    		self.lastPos2D = QtCore.QPoint(event.pos())
    		print "self.lastPos2D"
    		print self.lastPos2D
    		print "roulette"
    		numDegrees = event.delta()/8
    		numSteps = numDegrees/15
    		if numDegrees > 0:
    			print "haut"
    			self.setZoom(self.zoom - 1)
    		else:
    			print "bas"
    			self.setZoom(self.zoom + 1)
    		print "self.zoom"
    		print self.zoom
    
    	def keyPressEvent(self, event):
    		if event.key() == QtCore.Qt.Key_S:
    			print "touche_droite"
    			self.droite = self.droite + 1.0
    			
    		if event.key() == QtCore.Qt.Key_Z:
    			print "touche_gauche"
    			self.gauche = self.gauche + 1.0
    			
    		if event.key() == QtCore.Qt.Key_Up:
    			print "touche_haut"
    			self.haut = self.haut + 1.0
    			
    		if event.key() == QtCore.Qt.Key_Down:
    			print "touche_bas"
    			self.bas = self.bas + 1.0
    		
    		if event.key() == QtCore.Qt.Key_Q:
    			print "touche_avant"
    			self.avant = self.avant + 1.0
    			
    		if event.key() == QtCore.Qt.Key_D:
    			print "touche_arriere"
    			self.arriere = self.arriere + 1.0
    			
    		if event.key() == QtCore.Qt.Key_P:
    			print "touche_P"
    		
    		self.updateGL() #reappelle la fonction PAINT pour mise a jour
    
    	def mouseDoubleClickEvent(self,event):
    		print "double clic"
    
    		
    
    	def mon_dessin(self):
    		#la partie à afficher, cela pourrait être remplacé par n'importe quoi
    		#self.myAttractor=[[1,2,3,4],[44,12,13,42],[6,7,8,9]]
    		x=0
    		y=0
    		z=0
    		i=1
    		genList = glGenLists(1)
    		glNewList(genList, GL_COMPILE)
    		glPushMatrix()	#sauvegarde la matrice actuelle
    		
    		glBegin(GL_QUADS)
    		
    		glColor3ub(100,50,0)  #//plan z=0
    		glVertex3d(10,10,-1)
    		glVertex3d(-10,10,-1)
    		glVertex3d(-10,-10,-1)
    		glVertex3d(10,-10,-1)
    		
    		
    		
    		###DEBUT carre 1
    		
    		glColor3ub(255,0,0)  #//face rouge
    		glVertex3d(1,1,1)
    		glVertex3d(1,1,-1)
    		glVertex3d(-1,1,-1)
    		glVertex3d(-1,1,1)
    		
    		glColor3ub(0,255,0) #//face verte
    		glVertex3d(1,-1,1)
    		glVertex3d(1,-1,-1)
    		glVertex3d(1,1,-1)
    		glVertex3d(1,1,1)
    		
    		glColor3ub(0,0,255) #//face bleue
    		glVertex3d(-1,-1,1)
    		glVertex3d(-1,-1,-1)
    		glVertex3d(1,-1,-1)
    		glVertex3d(1,-1,1)
    		
    		glColor3ub(255,255,0) #//face jaune
    		glVertex3d(-1,1,1)
    		glVertex3d(-1,1,-1)
    		glVertex3d(-1,-1,-1)
    		glVertex3d(-1,-1,1)
    		
    		glColor3ub(0,255,255) #//face cyan
    		glVertex3d(1,1,-1)
    		glVertex3d(1,-1,-1)
    		glVertex3d(-1,-1,-1)
    		glVertex3d(-1,1,-1)
    		
    		glColor3ub(255,0,255) #//face magenta
    		glVertex3d(1,-1,1)
    		glVertex3d(1,1,1)
    		glVertex3d(-1,1,1)
    		glVertex3d(-1,-1,1)
    		###FIN carre 1
    		
    		###DEBUT carre 2
    		glColor3ub(255,0,0)  #//face rouge
    		glVertex3d(4,4,4)
    		glVertex3d(4,4,2)
    		glVertex3d(2,4,2)
    		glVertex3d(2,4,4)
    		
    		glColor3ub(0,255,0) #//face verte
    		glVertex3d(4,2,4)
    		glVertex3d(4,2,2)
    		glVertex3d(4,4,2)
    		glVertex3d(4,4,4)
    		
    		glColor3ub(0,0,255) #//face bleue
    		glVertex3d(2,2,4)
    		glVertex3d(2,2,2)
    		glVertex3d(4,2,2)
    		glVertex3d(4,2,4)
    		
    		glColor3ub(255,255,0) #//face jaune
    		glVertex3d(2,4,4)
    		glVertex3d(2,4,2)
    		glVertex3d(2,2,2)
    		glVertex3d(2,2,4)
    		
    		glColor3ub(0,255,255) #//face cyan
    		glVertex3d(4,4,2)
    		glVertex3d(4,2,2)
    		glVertex3d(2,2,2)
    		glVertex3d(2,4,2)
    		
    		glColor3ub(255,0,255) #//face magenta
    		glVertex3d(4,2,4)
    		glVertex3d(4,4,4)
    		glVertex3d(2,4,4)
    		glVertex3d(2,2,4)
    		###FIN carre 2
    		
    		glEnd()
    		
    		"""
    		glRasterPos3f(5.0, 0.0, 0.0)
    		glColor3ub(50, 100, 100)
    		glutBitmapCharacter(GLUT_BITMAP_8_BY_13, "" )
    		glFlush()
    		"""
    		
    	
    
    		glPopMatrix() #restitue la matrice actuelle
    		glLineWidth(1.)
    		glEndList()
    		return genList
    
    	def normalizeAngle(self, angle):
    		while angle < 0:
    		      angle += 360 * 16
    		while angle > 360 * 16:
    			angle -= 360 * 16
    		return angle
    
    if __name__ == "__main__":
    	import sys
    	#"infos systeme"
    	print "infos systeme"
    	print "version de python:"
    	print sys.version_info
    	chemin_fichier_courant = sys.argv[0]
    	print chemin_fichier_courant
    	list_chemin_fichier = []
    	list_chemin_fichier = chemin_fichier_courant.split('\\')
    	print list_chemin_fichier[-1] #dernier élément d'un list
    	nom_fichier = list_chemin_fichier[-1] #dernier élément d'un list
    	
    	#fenetre principale
    	app = QtGui.QApplication(sys.argv)
    	MainWindow = QtGui.QMainWindow()
    	exec("MainWindow.setWindowTitle('boubou')")
    	mon_objet = myGLAttractor(MainWindow)
    	mon_objet.initializeGL()
    	#mon_objet.mon_dessin(50, 1000)
    	mon_objet.setFixedSize(400,400)
    	
    	#mon_button = QtGui.QPushButton('polit', MainWindow)
    	#centrage de la fenetre	MAINWINDOW
    	mon_widget_ecran = QtGui.QApplication.desktop()
    	largeur_ecran = mon_widget_ecran.width()
    	hauteur_ecran = mon_widget_ecran.height()
    	largeur_mainwindow = MainWindow.width()
    	hauteur_mainwindow = MainWindow.height()
    	print "MainWindow.pos()"
    	print MainWindow.pos()
    	print MainWindow.geometry()
    	MainWindow.setGeometry((largeur_ecran-largeur_mainwindow)/4,\
    	(hauteur_ecran-hauteur_mainwindow)/2,\
    	largeur_mainwindow,hauteur_mainwindow)
    	print "MainWindow.pos()"
    	print MainWindow.pos()
    	print MainWindow.geometry()
    	MainWindow.setFixedSize(largeur_mainwindow,hauteur_mainwindow) #taille fixe
    	MainWindow.show()         # On affiche l'interface
    	sys.exit(app.exec_())
    
    • Partager sur Facebook
    • Partager sur Twitter
      18 mai 2011 à 20:30:43

      Salut,

      pour se faire, je sauvegardais le derniere matrice OpenGL de ma camera que je rechargais avant de faire mes deplacements avec ma camera.

      Voila mon code pour faire ca :
      from Math import *
      from PySFML import sf
      from OpenGL.GL import *
      from OpenGL.GLU import *
      import numpy
      import math
      
      class CameraAbstract:
              
              def __init__(self):
                      self.eye = Vector3(1, 1, 1)
                      self.target = Vector3(0, 0, 0)
                      self.up = Vector3(0, 0, 1)
              
      #       def Initialize(self):
      #               """Must be implemented"""
      #               pass
      #       
      #       #def OnEvent(self, Event):
      #       #       """Must be implemented"""
      #       
      #       def GetView(self):
      #               """Must be implemented"""
      #               pass
                      
      class CameraFly(CameraAbstract):
              def __init__(self):
                      CameraAbstract.__init__(self)
                      self.look_speed = 0.2
                      self.move_speed = 15
                      self.trackMouse = False
                      self.posMouse = None
                      
              def Initialize(self):
                      glMatrixMode(GL_MODELVIEW)
                      gluLookAt(self.eye.x, self.eye.y, self.eye.z, self.target.x, self.target.y, self.target.z, self.up.x, self.up.y, self.up.z)
                      self.buffer = glGetDoublev(GL_MODELVIEW_MATRIX)
                      self.posMouse = (0, 0)
                      glLoadIdentity()
      
              def OnUpdate(self, App):
                      #CameraAbstract.OnEvent(self, Event)
                      delta = App.GetFrameTime()
                      input = App.GetInput()
                      
                      glMatrixMode(GL_MODELVIEW)
                      glPushMatrix()
                      glLoadMatrixf(self.buffer)
                      
                      self.trackMouse = input.IsMouseButtonDown(sf.Mouse.Left)
                      
                      if(self.trackMouse):
                              if(not self.posMouse):
                                      self.posMouse = (input.GetMouseX(), input.GetMouseY())
                              else:
                                      x1, y1 = self.posMouse
                                      self.posMouse = (input.GetMouseX(), input.GetMouseY())
                                      x2, y2 = self.posMouse
                                      c = (-1 * numpy.mat(self.buffer[:3, :3]) * \
                                         numpy.mat(self.buffer[3, :3]).T).reshape(3, 1)
                                      ##c is camera center in absolute coordinates, 
                                      ##we need to move it back to (0,0,0) 
                                      ##before rotating the camera
                                      glTranslate(c[0], c[1], c[2])
                                      m = self.buffer.flatten()
                                      glRotate((x2 - x1) * self.look_speed, m[1], m[5], m[9])
                                      glRotate((y2 - y1) * self.look_speed, m[0], m[4], m[8])
                                      
                                      ##compensate roll
                                      glRotated(-math.atan2(-m[4], m[5]) * \
                                      57.295779513082320876798154814105 , m[2], m[6], m[10])
                                      glTranslate(-c[0], -c[1], -c[2])
                      else:
                              self.posMouse = None
                              
                      fwd = 0
                      strafe = 0
                      
                      if(input.IsKeyDown(sf.Key.Z)):
                              fwd = self.move_speed * delta
                      if(input.IsKeyDown(sf.Key.S)):
                              fwd = -self.move_speed * delta
                      if(input.IsKeyDown(sf.Key.Q)):
                              strafe = self.move_speed * delta
                      if(input.IsKeyDown(sf.Key.D)):
                              strafe = -self.move_speed * delta
                      
                      m = self.buffer.flatten()
                      glTranslate(fwd * m[2], fwd * m[6], fwd * m[10])
                      glTranslate(strafe * m[0], strafe * m[4], strafe * m[8])
              
                      self.buffer = glGetDoublev(GL_MODELVIEW_MATRIX)
                      glPopMatrix()
                      return True
      
              def GetView(self):
                      glMatrixMode(GL_MODELVIEW)
                      glMultMatrixf(self.buffer)
      


      La methode OnUpdate pour mettre a jour ma vue et GetView pour appliquer la transformation de la camera.

      ps: La base du code n'est pas de moi, je l'avais pris sur internet.
      • Partager sur Facebook
      • Partager sur Twitter

      pyOpenGL

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown