IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Programmation multimédia/Jeux Python Discussion :

Problème d'identification d'un cube dans une scène (labyrinthe)


Sujet :

Programmation multimédia/Jeux Python

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2011
    Messages : 136
    Points : 68
    Points
    68
    Par défaut Problème d'identification d'un cube dans une scène (labyrinthe)
    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.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    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 ne comprends pas bien et j'ai l'impression que vous êtes partis dans le mauvais sens.
    D'après moi, il faut toujours conserver la position du joueur (ou de la caméra, c'est équivalent), qui correspond à la position dans le labyrinthe. Vous l'utilisez pour les tests de collision (OpenGL ne gère pas les collisions , OpenGL ne fait que le graphisme).
    Une fois que vous voulez faire l'affichage, vous utilisez sa position (et une orientation) que vous utilisez pour faire un glRotate()/glTranslate() adéquat pour "simuler" la caméra.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2011
    Messages : 136
    Points : 68
    Points
    68
    Par défaut
    Bonjour,
    Merci pour votre réponse.
    Effectivement, j'utilise OpenGL uniquement pour l'affichage. J'essaye de gérer la position du joueur avec le pas donné à chaque translate mais dans mes tests, les "bonnes" positions m'amènent parfois DANS un mur (procédure _defRealPos). Ex : en partant d'une position x=2, après un certain nombre de steps, j'arrive à une position x=2.65 et visuellement, je suis dans un mur, mur qui doit être à la position x=3 !)
    J'ai dû louper quelque chose mais je ne sais pas quoi...

  4. #4
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Peut être vous placez mal la caméra ? Sinon, il y aurait un décalage entre la position pour les collisions et l'affichage. C'est pour cela que je disais de partir de la position pour les collisions, afin de calculer la position de la caméra.
    Sinon, vous êtes dans le mur visuellement, mais cela ne veut pas dire que vous le collez, si ?
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2011
    Messages : 136
    Points : 68
    Points
    68
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Peut être vous placez mal la caméra ? Sinon, il y aurait un décalage entre la position pour les collisions et l'affichage. C'est pour cela que je disais de partir de la position pour les collisions, afin de calculer la position de la caméra.
    Sinon, vous êtes dans le mur visuellement, mais cela ne veut pas dire que vous le collez, si ?
    Effectivement, quand je suis dans le mur, je ne le colle pas.
    Quand vous dites 'caméra', est-ce réellement un objet caméra que l'on manipule ou bien est-ce un objet virtuel issu des transformations d'affichage (rotations, translations,...) ?

    Auriez-vous un exemple de code qui m'aiguillerait pour mon problème ?

    En regardant mon code, y-a-t-il quelque chose qui vous parraitrait incorrect ?

  6. #6
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Quand vous dites 'caméra', est-ce réellement un objet caméra que l'on manipule ou bien est-ce un objet virtuel issu des transformations d'affichage (rotations, translations,...) ?
    Pour moi, les deux sont la même chose. C'est juste une organisation du code.

    Je pensais que printPosCam allait afficher la position de la caméra, mais ce n'est pas le cas.
    Aussi vous utilisez le GL_MODELVIEW_MATRIX, mais il ne faut pas oublier que cela prend en compte la matrice du modèle.

    Aussi, je crains qu'il manque des glPushMatrix/glPopMatrix. Sans ça, les opérations sur les matrices sont cumulatives, c'est peut être d'ailleurs la raison que la caméra est bien plus loin que ce que vous pensez.

    Moi, ce que je ferais, en pseudo code :
    Boucle de jeu:
    Reset des matrices (glClearMatrix, si je ne dis pas bêtise)
    Placement de la caméra (le glTransalte(xCam, yCam, zCam) et le glRotate suivant l'inclinaison/rotation)
    Affichage
    Mise à jour de la position de la caméra suivant les input (on met à jour les xCam, yCam, zCam et l'inclinaison/rotation)
    Ainsi, vous êtes sûr qu'à chaque instant T, vous avez la caméra, exactement à la position xCam, yCam, zCam.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Avril 2011
    Messages : 136
    Points : 68
    Points
    68
    Par défaut
    Merci beaucoup pour vos remarque. Je vais étudier ça de plus près...

Discussions similaires

  1. fixer un objet dans une scène en rotation
    Par amine84 dans le forum 3D
    Réponses: 1
    Dernier message: 30/08/2009, 03h39
  2. identification d'objets dans une image par java
    Par boutha dans le forum Débuter avec Java
    Réponses: 0
    Dernier message: 11/02/2009, 11h16
  3. Réponses: 10
    Dernier message: 12/05/2008, 18h10
  4. Réponses: 0
    Dernier message: 27/03/2008, 00h18
  5. Problème création d'un objet dans une Form
    Par helico2 dans le forum C++/CLI
    Réponses: 7
    Dernier message: 02/01/2008, 16h32

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo