Bonjour à tous !
Histoire de mettre en pratique ma connaissance python, je viens de me lancer dans un projet qui me pose certains ...problèmes.
J'utilise pyOpengl sous python 3.6.1 dans un environnement windows 7.

Voici le topo:
J'ai construit un labyrinthe. Les murs sont représentés pas des cubes à l'aide de glVertex3f.
La coordonnée y de chaque cube est nulle. Je me retrouve donc avec des cubes sur un plan (x,z).
Exemple de déclaration de cubes :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
lab_cubes = [(1,1),(1,3),(2,3),(3,1),(3,2)]
L'idée est de déplacer la caméra dans le labyrinthe et de ne pas pouvoir traverser les murs.

Je suis parti d'une position donnée dans le labyrinthe (avec un glTranslatef). Pour chaque déplacement, je me translate avec un pas de 0.05.
J'essaye d'en déduire un pas de caméra mais je n'y arrive pas précisément. Je n'arrive donc pas à déduire la position d'un mur...
Je présume qu'il ne faut pas partir de ce genre de calcul...mais de quelque chose de plus 'mathématique' !

Je ne sais pas si ce que je veux se fait simplement...

Je ne sais pas non plus si j'étais clair dans mes explications mais voici le code, au cas où...

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
import os
import sys
import math
import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
 
#----------------------------------------------------
# Classe Cube
#----------------------------------------------------
class Cube:
    def __init__(self, vertices, pos=(0,0,0)):
        x,y,z = pos
        self.verts =[[x+X/2,y+Y/2,z+Z/2] for X,Y,Z in vertices]
 
#----------------------------------------------------
# Classe Labyrinthe
#----------------------------------------------------
class Labyrinthe:
 
    # Variables de classe
    vertices = ((1, -1, -1), (1, 1, -1), (-1, 1, -1), (-1, -1, -1), (1, -1, 1), (1, 1, 1), (-1, -1, 1), (-1, 1, 1))
    surfaces = ((0,1,2,3), (3,2,7,6), (6,7,5,4), (4,5,1,0), (1,5,7,2), (4,0,3,6))
 
    def __init__(self):        
        # Définition des textures
        self.texture_sol = self.loadTexture("sol")
        self.texture_cube = self.loadTexture("cube")
 
    def setVerticesLab(self, lab_points, lab_width, lab_height):
        self.points = [(x,y) for x,y in lab_points]
        self.cubes = [Cube(Labyrinthe.vertices, (x,0,-z)) for x,z in lab_points]        
        self.ground_vertices = ((0,-0.1,-(lab_width+1)), (0,-0.1,lab_height+3),(lab_width+1,-0.1,lab_height+3),(lab_width+1,-0.1,-(lab_width+1)))
 
    def loadTexture(self,pstr_obj):
        if pstr_obj == "sol":textureSurface = pygame.image.load('fond_sol4.jpg')
        elif pstr_obj == "cube":textureSurface = pygame.image.load('fond_cube2.jpg')
        textureData = pygame.image.tostring(textureSurface, "RGBA", 1)
        width = textureSurface.get_width()
        height = textureSurface.get_height()
        texid = glGenTextures(1)
        glBindTexture(GL_TEXTURE_2D,texid)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData)
        return texid
 
    def drawLab(self):
 
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
 
        # On inhibe ce que l'on ne va pas utiliser afin d'accélérer le traitement
        glDisable(GL_FOG) # on ne calcule pas le brouillard
        glDisable(GL_LIGHTING) # on ne calcule pas l'illumination
        glDisable(GL_COLOR_MATERIAL) # on ne calcule pas les couleurs        
 
        # Affichage du sol
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texture_sol)        
        glBegin(GL_QUADS)
        for vertex in self.ground_vertices:
            glTexCoord2f(0.0, 0.0); glVertex3f(self.ground_vertices[0][0],self.ground_vertices[0][1],self.ground_vertices[0][2])
            glTexCoord2f(1.0, 0.0); glVertex3f(self.ground_vertices[1][0],self.ground_vertices[1][1],self.ground_vertices[1][2])
            glTexCoord2f(1.0, 1.0); glVertex3f(self.ground_vertices[2][0],self.ground_vertices[2][1],self.ground_vertices[2][2])
            glTexCoord2f(0.0, 1.0); glVertex3f(self.ground_vertices[3][0],self.ground_vertices[3][1],self.ground_vertices[3][2])
        glEnd()
 
        # Affichage du labyrinthe
        glEnable(GL_DEPTH_TEST) # pour éliminer les faces cachées
        glDepthFunc(GL_LESS) 
        glEnable(GL_TEXTURE_2D)
        glBindTexture(GL_TEXTURE_2D, self.texture_cube)
 
        for each_cube in self.cubes:        
            glBegin(GL_QUADS)        
            for surface in Labyrinthe.surfaces:
                glTexCoord2f(0.0, 0.0); glVertex3f(each_cube.verts[surface[0]][0], each_cube.verts[surface[0]][1], each_cube.verts[surface[0]][2])
                glTexCoord2f(1.0, 0.0); glVertex3f(each_cube.verts[surface[1]][0], each_cube.verts[surface[1]][1], each_cube.verts[surface[1]][2])
                glTexCoord2f(1.0, 1.0); glVertex3f(each_cube.verts[surface[2]][0], each_cube.verts[surface[2]][1], each_cube.verts[surface[2]][2])
                glTexCoord2f(0.0, 1.0); glVertex3f(each_cube.verts[surface[3]][0], each_cube.verts[surface[3]][1], each_cube.verts[surface[3]][2])
            glEnd()
 
        pygame.display.flip()    
 
#----------------------------------------------------
# Classe Camera
#----------------------------------------------------
class Camera:
    def __init__(self, lab, pos=(0,0,0), rot=(0,0,0,0)):
        self.pos = list(pos) 
        self.offsetMove = 0.05 # pas de déplacement en translation dans la scène
        self.offsetMoveCam = 0.068 # pas de déplacement de la caméra définit empiriquement
 
        # Définition de la position réelle
        self.xpos = pos[0]
        self.ypos = pos[2]
 
        # Définition de la position affichée
        self.translate(pos[0], pos[1], pos[2])
 
        # Définition du labyrinthe
        self.lab = lab
        self.printPosCam()
 
    def printPosCam(self):
        pos_cur = glGetDoublev(GL_MODELVIEW_MATRIX)
        camera = pos_cur[3]
 
    def events(self,event):
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 4:
                self.translate(0,0,1.0);self.lab.drawLab()                
            elif event.button == 5:
                self.translate(0,0,-1.0);self.lab.drawLab()
        elif event.type == pygame.MOUSEMOTION:
            xcam, ycam = event.rel
            # on prévoie ici de faire une rotation de la scène
 
    def _defRealPos(self,pos):
        # Conversion de la valeur de la position dans la labyrinthe
        # en coordonnée 'labyrinthe'
        # ****************
        # *** PROBLÈME ***
        # ****************
        return(pos)
 
    def checkPos(self, xp, yp):
        # On vérifie que la position n'est pas sur un mur
        return (xp, yp) not in self.lab.points
 
    def update(self, dt, key):
        if key[pygame.K_LEFT]:
            xp = self._defRealPos(self.pos[0]+self.offsetMoveCam)
            if self.checkPos(-xp,self.ypos):
                self.xpos = -xp;
                self.translate(self.offsetMove,0,0)
                self.pos[0]+=self.offsetMoveCam
                self.lab.drawLab()
        elif key[pygame.K_RIGHT]:
            xp = self._defRealPos(self.pos[0]-self.offsetMoveCam)
            if self.checkPos(-xp,self.ypos):
                self.xpos = -xp;
                self.translate(-self.offsetMove,0,0)
                self.pos[0]-=self.offsetMoveCam
                self.lab.drawLab()
        elif key[pygame.K_UP]:
            yp = self._defRealPos(self.pos[2]+self.offsetMoveCam)
            if self.checkPos(-self.xpos,yp):
                self.ypos = yp;
                self.translate(0,0,self.offsetMove)
                self.pos[2]+=self.offsetMoveCam
                self.lab.drawLab()
        elif key[pygame.K_DOWN]:
            yp = self._defRealPos(self.pos[2]-self.offsetMoveCam)
            if self.checkPos(-self.xpos,yp):
                self.ypos = yp
                self.translate(0,0,-self.offsetMove)
                self.pos[2]-=self.offsetMoveCam;
                self.lab.drawLab()
 
    def translate(self,x,y,z):        
        glTranslatef(x,y,z)        
 
    def rotate(self,angle, x, y, z):
        # Rotation autour d'un axe (x ou y ou z 1 si rotation 0 sinon) avec un angle
        # Pas encore utilisé
        glRotatef(angle, x, y, z)
 
#----------------------------------------------------
# Programme principal
#----------------------------------------------------
pygame.init()
display = (800,600)
pygame.display.set_mode(display, DOUBLEBUF|OPENGL|OPENGLBLIT)
os.environ['SLD_VIDEO_CENTERED'] = '1'
pygame.display.set_caption('Labyrinthe 3D')
gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
pygame.event.get();
pygame.mouse.get_rel()
clock=pygame.time.Clock()
 
# Définition du labyrinthe
#lab_cubes = [(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,5),(3,1),(3,5),(4,1),(4,5),(5,1),(5,2),(5,3),(5,4),(5,5)]
#lab_cubes = [(1,1),(1,3),(2,3),(3,1),(3,2)]
#lab_cubes = [(1,1),(1,2),(1,3),(1,4),(1,5),(2,1),(2,5),(3,1),(3,5),(4,1),(4,5),(5,1),(5,2),(5,3),(5,4),(5,5)]
#lab_cubes = [(1,1),(1,2),(1,3),(2,1),(2,3),(3,1),(3,2),(3,3)]
lab_cubes = [(1,2),(1,3),(1,4),(1,5),(2,2),(3,1),(3,4),(3,5),(4,3),(4,4),(5,1),(5,2),(5,3)]
lab = Labyrinthe()
 
# Position initiale de la caméra 
#cam = Camera(lab,(-3, 0, 2), (0, 0, 0, 0))
#cam = Camera(lab,(-2, 0, 2), (0, 0, 0, 0))
#cam = Camera(lab,(-3, 0, 3), (0, 0, 0, 0))
#cam = Camera(lab,(-2, 0, 2), (0, 0, 0, 0))
cam = Camera(lab,(-4, 0, 1), (0, 0, 0, 0))
 
lab.setVerticesLab(lab_cubes,5,5) # param 2 et 3 pour le sol
lab.drawLab()
 
# Boucle sur l'attente d'une touche pressée
while True:
    dt = clock.tick()/3000
    for event in pygame.event.get():
        if event.type == pygame.QUIT:pygame.quit();sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                pygame.quit(); sys.exit()
        cam.events(event)
 
    key = pygame.key.get_pressed()
    cam.update(dt, key)
 
pygame.quit()
quit()

Quelqu'un a-t-il une idée ?

Mon prochain problème sera de faire une rotation pour une position donnée.
Là aussi j'ai essayé des trucs (genre translation + rotation autour de l'axe Y) mais je n'y arrive pas.

Merci d'avance pour vos réponses.