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

OpenGL Discussion :

Rotation : erreur de translation (décalage) [OpenGL 1.x]


Sujet :

OpenGL

  1. #1
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut Rotation : erreur de translation (décalage)
    Bonjour,

    J'ai un problème sur lequel je butte... J'utilise PushMatrix pour faire des rotations optionnelles de certaines parties de mon dessin autour des axes X ou Y au moment de l'affichage autour du point CX, CY, CZ, selon le principe suivant :

    Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
                '... dessin normal
                GL.PushMatrix()
                GL.Translate(CX, CY, CZ)
                GL.Rotate(RX, 1, 0, 0)
                GL.Rotate(RY, 0, 1, 0)
                GL.Translate(-CX, -CY, -CZ)
                '... dessin avec rotation
                GL.PopMatrix()
                '... dessin normal

    Ca fonctionne presque mais la translation n'est pas bonne ; autrement dit, le centre de rotation est décalé

    Je pensais que le problème vient du fait que ma translation s'accumule aux matrices précédentes liées aux paramètres de ma vue 3D, et du coup il y a un décalage...
    Il faudrait que je retrouve ces valeurs de décalage et que j'en tienne compte
    Mais bizarrement les translation et rotations à la souris n'affectent pas le décalage... du coup je ne voit pas d'où il peut venir...

    Voici le code complet avec, dans l'ordre, les appels des différentes fonctions OPEN GL :

    Code VB : 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
    	'Code d'affichage OPENGL :
    	GlControl3D.MakeCurrent()
     
    	'Nettoyage -----------------------------------------------------------------
    	GL.Clear(ClearBufferMask.ColorBufferBit)
    	GL.Clear(ClearBufferMask.DepthBufferBit)
     
    	'Taille de la fenêtre ------------------------------------------------------
    	GL.Viewport(0, 0, GlControl3D.Width, GlControl3D.Height)
     
    	'** Degradé en fond d'écran ------------------------------------------------
    	GL.ShadeModel(ShadingModel.Smooth)
    	GL.MatrixMode(MatrixMode.Projection)
    	GL.LoadIdentity()
    	GL.MatrixMode(MatrixMode.Modelview)
    	GL.LoadIdentity()
    	GL.Disable(EnableCap.DepthTest)
    	GL.Disable(EnableCap.Lighting)
    	GL.Begin(BeginMode.Quads)
    	GL.Color3(CoulDegGB3D)
    	GL.Vertex2(-1.0, -1.0)
    	GL.Color3(CoulDegDB3D)
    	GL.Vertex2(1.0, -1.0)
    	GL.Color3(CoulDegDH3D)
    	GL.Vertex2(1.0, 1.0)
    	GL.Color3(CoulDegGH3D)
    	GL.Vertex2(-1.0, 1.0)
    	GL.End()
    	'---
    	GL.ShadeModel(ShadingModel.Flat)
    	GL.MatrixMode(MatrixMode.Projection) 'Load Perspective
    	GL.LoadMatrix(Perspective3D) 'Setup Perspective 
    	GL.MatrixMode(MatrixMode.Modelview) 'Load Camera
    	GL.Enable(EnableCap.DepthTest)
    	GL.Enable(EnableCap.Lighting)
    	'** -----------------------------------------------------------------------
     
    	'Préparation ---------------------------------------------------------------
    	GL.LoadMatrix(Lookat3D)
     
    	'Choix de la position de la pièce (permet navigation à la souris) ------------------------------------------
    	GL.Translate(PX3D, PY3D, PZ3D)
    	GL.Rotate(AZ3D, 0, 0, 1)
    	GL.Rotate(AX3D, 0, 1, 0)
    	GL.Rotate(AY3D, 1, 0, 0)
     
    	'Lumière *******************************************************************
    	GL.Light(LightName.Light0, LightParameter.Position, New Single() {LumX3D, LumY3D, 0})
    	GL.Light(LightName.Light1, LightParameter.Position, New Single() {-LumX3D, -LumY3D, -0.5!})
    	GL.Light(LightName.Light2, LightParameter.Position, New Single() {0!, 0!, 1.0!})
     
     
    	'Dessin de la pièce --------------------------------------------------------
    	'Affichage STL "libre" (pour imprimante 3D) $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
     
    	If AfficherFlippedTriangles Then '24/12/2018
    		GL.Enable(EnableCap.CullFace)
    		GL.CullFace(CullFaceMode.Front)
    		GL.Color3(Color.Red)
    		Call Peindre_Visu3D_STL()
    		GL.CullFace(CullFaceMode.Back)
    		GL.Color3(Color.Green)
    		Call Peindre_Visu3D_STL()
    	Else
    		GL.Disable(EnableCap.CullFace)
    		Call Peindre_Visu3D_STL(True)
    	End If
    	If AfficherWireFrame Then
    		GL.Disable(EnableCap.Lighting)
    		GL.Disable(EnableCap.CullFace)
    		GL.Color3(Color.Black)
    		GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line)
    		Call Peindre_Visu3D_STL()
    		GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill)
    	End If
     
    	GlControl3D.MakeCurrent()
    	GlControl3D.SwapBuffers()
     
        Private Sub Peindre_Visu3D_STL(Optional Colored As Boolean = False)
            Dim i As Integer, j As Integer, k As Integer, n As Integer
            GL.Begin(BeginMode.Triangles)
            If Colored Then
                For j = 0 To STL_ListeT.Count - 1
                    STL_ListeT_Current = STL_ListeT.Item(j)
                    STL_ListeColor3_Current = STL_ListeColor3.Item(j)
                    n = STL_ListeT_Current.Count \ 12
                    For i = 0 To n - 1
                        GL.Color3(STL_ListeColor3_Current.Item(i))
                        k = 12 * i
                        GL.Normal3(STL_ListeT_Current.Item(k), STL_ListeT_Current.Item(k + 1), STL_ListeT_Current.Item(k + 2))
                        GL.Vertex3(STL_ListeT_Current.Item(k + 3) + dtx3D, STL_ListeT_Current(k + 4) + dty3D, STL_ListeT_Current.Item(k + 5) + dtz3D)
                        GL.Vertex3(STL_ListeT_Current.Item(k + 6) + dtx3D, STL_ListeT_Current.Item(k + 7) + dty3D, STL_ListeT_Current.Item(k + 8) + dtz3D)
                        GL.Vertex3(STL_ListeT_Current.Item(k + 9) + dtx3D, STL_ListeT_Current.Item(k + 10) + dty3D, STL_ListeT_Current.Item(k + 11) + dtz3D)
                    Next
                Next
            Else
                For j = 0 To STL_ListeT.Count - 1
                    STL_ListeT_Current = STL_ListeT.Item(j)
                    n = STL_ListeT_Current.Count \ 12
                    For i = 0 To n - 1
                        k = 12 * i
                        GL.Normal3(STL_ListeT_Current.Item(k), STL_ListeT_Current.Item(k + 1), STL_ListeT_Current.Item(k + 2))
                        GL.Vertex3(STL_ListeT_Current.Item(k + 3) + dtx3D, STL_ListeT_Current(k + 4) + dty3D, STL_ListeT_Current.Item(k + 5) + dtz3D)
                        GL.Vertex3(STL_ListeT_Current.Item(k + 6) + dtx3D, STL_ListeT_Current.Item(k + 7) + dty3D, STL_ListeT_Current.Item(k + 8) + dtz3D)
                        GL.Vertex3(STL_ListeT_Current.Item(k + 9) + dtx3D, STL_ListeT_Current.Item(k + 10) + dty3D, STL_ListeT_Current.Item(k + 11) + dtz3D)
                    Next
                Next
            End If
            For i = 0 To GL_Liste_LotTri2D.Count - 1
                GL_Liste_LotTri2D.Item(i).GL_Paint(Colored)
            Next
            For i = 0 To GL_Liste_LotTri3D.Count - 1
                GL_Liste_LotTri3D.Item(i).GL_Paint(Colored)
            Next
            GL.End()
            For i = 0 To GL_Liste_TriFan3D.Count - 1
                GL_Liste_TriFan3D.Item(i).GL_Paint(Colored)
            Next
            For i = 0 To GL_Liste_TriFan2D.Count - 1
                GL_Liste_TriFan2D.Item(i).GL_Paint(Colored)
            Next
            For i = 0 To GL_Liste_TriStrip3D.Count - 1
                GL_Liste_TriStrip3D.Item(i).GL_Paint(Colored)
            Next
            'For i = 0 To GL_Liste_ColTriStrip3D.Count - 1
            '    GL_Liste_ColTriStrip3D.Item(i).GL_Paint(Colored)
            'Next
            For i = 0 To GL_Liste_TriStrip25D.Count - 1
                GL_Liste_TriStrip25D.Item(i).GL_Paint(Colored)
            Next
            For i = 0 To GL_Liste_TriStrip2D.Count - 1
                GL_Liste_TriStrip2D.Item(i).GL_Paint(Colored)
            Next
        End Sub
     
     
    	'Code de GL_Liste_LotTri2D.Item(i).GL_Paint(Colored) :
        Public Sub GL_Paint(Optional Colored As Boolean = False)
            Dim i As Integer, k As Integer, n As Integer
            n = ListeXY.Count \ 6
            If n < 1 Then Exit Sub
            If Colored Then GL.Color3(Couleur)
     
            Dim DoRotate As Boolean = RX <> 0 OrElse RY <> 0
            If DoRotate Then
                GL.End()
                GL.PushMatrix()
                GL.Translate(CX, CY, CZ)
                GL.Rotate(RX, 1, 0, 0)
                GL.Rotate(RY, 0, 1, 0)
                GL.Translate(-CX, -CY, -CZ)
                GL.Begin(BeginMode.Triangles)
            End If
     
            'GL.Begin(BeginMode.Triangles)
            GL.Normal3(0.0!, 0.0!, NZ)
            For i = 0 To n - 1
                k = 6 * i
                GL.Vertex3(ListeXY.Item(k + 0) + dtx3D, ListeXY.Item(k + 1) + dty3D, Z + dtz3D)
                GL.Vertex3(ListeXY.Item(k + 2) + dtx3D, ListeXY.Item(k + 3) + dty3D, Z + dtz3D)
                GL.Vertex3(ListeXY.Item(k + 4) + dtx3D, ListeXY.Item(k + 5) + dty3D, Z + dtz3D)
            Next
            'GL.End()
     
            If DoRotate Then
                GL.End()
                GL.PopMatrix()
                GL.Begin(BeginMode.Triangles)
            End If
     
        End Sub

    Voici une vue du bug : l'étoile bleue devrait être la rotation de l'étoile rose autour de son centre mais on voit que non :

    Nom : 2022_06_27_RotationOpenGL.jpg
Affichages : 78
Taille : 86,2 Ko

    Voici le bout de code de l'image exemple :

    Code VB : 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
            STL_CX = 50
     
            '... Objets précédents : pas de rotation ...
     
            'Test avec étoile normale et étoile avec rotation :
            STL_CX = 50
            STL_CY = 470
            STL_CZ = 100
            '
            F2D = sPoly2D_PolyEtoile(STL_CX, STL_CY, 120, STL_CY / 2, 5, 90).GetForme2D
            F2D = F2D.GetDifference(sPoly2D_Cercle(STL_CX, STL_CY, 10).GetForme2D)
            F2D.AddForme3D_TriangulariserH(STL_CZ, True, GetStdColor(TypeCouleurStd.Rose))
            '
            STL_RX = 0
            STL_RY = 45
            F2D.AddForme3D_TriangulariserH(STL_CZ, True, GetStdColor(TypeCouleurStd.BleuClair))
            STL_RX = 0
            STL_RY = 0
     
            'objets suivants : pas de rotation...

    Merci

    A bientôt
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

  2. #2
    Membre éprouvé Avatar de electroremy
    Homme Profil pro
    Ingénieur sécurité
    Inscrit en
    Juin 2007
    Messages
    934
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur sécurité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2007
    Messages : 934
    Points : 1 274
    Points
    1 274
    Par défaut
    Je viens de trouver

    Avoir du balayer mon code pour le poster sur le forum, et me préparer à devoir expliquer à quoi servent les variables, m'a aidé à trouver l'origine du problème

    (comment ça, mon code est cadre et manquerait de documentation )

    Donc à un moment je vais de la translation en ajoutant aux coordonnées dtx3D, dty3D, dtz3D

    Du coup je dois en tenir compte pour mon code de rotation, de la façon suivante

    Code VB : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                GL.PushMatrix()
                GL.Translate(CX + dtx3D, CY + dty3D, CZ + dtz3D)
                GL.Rotate(RX, 1, 0, 0)
                GL.Rotate(RY, 0, 1, 0)
                GL.Translate(-CX - dtx3D, -CY - dty3D, -CZ - dtz3D)

    Voilà
    Quand deux personnes échangent un euro, chacun repart avec un euro.
    Quand deux personnes échangent une idée, chacun repart avec deux idées.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. DirectX : Appliquer une rotation et une translation
    Par matpush dans le forum Windows Forms
    Réponses: 1
    Dernier message: 22/06/2009, 10h41
  2. [java 3D] translations et rotations
    Par anotherboo dans le forum 3D
    Réponses: 2
    Dernier message: 29/01/2006, 15h23
  3. Réponses: 2
    Dernier message: 09/01/2006, 16h53
  4. [3D] gérer la rotations&translations
    Par kiroukou dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 21/10/2005, 18h44
  5. Rotation erreur de calcul
    Par Speed41 dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 09/03/2005, 16h55

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