PGE (Plegat Graphic Engine) - Définition des caméras et de leur manipulation

par Jean-Michel BORLOT (Site DVP.com)
Date de publication : 03/12/2011 Dernière mise à jour :

Second article de la série de tutoriels sur la création de mon moteur graphique PGE (Plegat Graphic Engine). Nous aborderons ici la définition d'une caméra permettant de définir la vue sur notre monde 3D, ainsi que la manière de la piloter par code et par interaction avec la souris.

PGE (Plegat Graphic Engine) - Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.com)

1 - Comment voir ce que l'on dessine ?..................................................................................................................... 3 2 - Les opérations matricielles.................................................................................................................................... 3 2-A - Opérations de base...................................................................................................................................... 3 2-B - La classe Point3d......................................................................................................................................... 4 2-C - La classe Vector3d....................................................................................................................................... 5 2-D - La classe Matrix3..........................................................................................................................................8 2-E - La classe Matrix4........................................................................................................................................ 11 2-F - Références.................................................................................................................................................. 12 3 - Le quaternion....................................................................................................................................................... 12 3-A - Utilité et utilisation....................................................................................................................................... 12 3-B - La classe Quaternion.................................................................................................................................. 12 3-C - Références.................................................................................................................................................. 16 4 - La caméra............................................................................................................................................................ 16 4-A - Description de la caméra............................................................................................................................16 4-B - La classe Camera....................................................................................................................................... 17 5 - Manipulation de la caméra à la souris................................................................................................................ 19 5-A - Définition de la classe MouseCameraManager.......................................................................................... 19 5-B - Détermination du mode d'interaction.......................................................................................................... 20 5-C - Gestion du déplacement actif de la souris................................................................................................. 21 6 - Intégration de la caméra dans le panneau 3D de PGE...................................................................................... 21 7 - Conclusion............................................................................................................................................................23 8 - Remerciements.................................................................................................................................................... 23

-2Les sources présentées sur cette pages sont libres de droits, et vous pouvez les utiliser à votre convenance. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2011 - JM BORLOT. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.
http://plegat.developpez.com/tutoriels/jogl/pge-camera/

com) 1 . documents. ni à utiliser une classe d'une bibliothèque mathématique déjà existante.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. etc sans l'autorisation expresse de l'auteur. cible. le net regorge de suffisamment d'information à ce sujet.. matrice de transformation.) et 4x4 (quaternions et matrices OpenGL). même partielle. Les paramètres sont fixes. à savoir le point (classe Point3d) et le vecteur (classe Vector3d) -3Les sources présentées sur cette pages sont libres de droits. Afin d'éviter les calculs trigonométriques et le "gimbal lock". affectation de valeurs des éléments . la position de la cible (vers où se dirige le regard) .Les opérations matricielles 2-A . conversion en buffer OpenGL.Comment voir ce que l'on dessine ? Dans l'article précédent (1) . écrits en dur dans le code. est assez laborieuse à gérer et amène souvent à rencontrer le fameux problème de "gimbal lock" ou blocage de cardan (2) . Le nom fait souvent peur mais nous verrons que son utilisation est relativement simple et qu'il serait dommage de s'en priver.. nous utiliserons principalement des matrices 3x3 (rotations. il est donc intéressant de travailler directement sur des matrices. Les principales opérations implémentées sont : • • • • initialisation (tableau. quoique simple en apparence (les translations sont facilement définies. Le calcul matriciel peut paraitre assez lourd.com/tutoriels/jogl/pge-camera/ . Une première méthode afin de pouvoir déplacer le point de vue consiste à modifier les trois paramètres de la caméra : • • • sa position (où l'on se trouve dans le monde 3D) .. L'affichage OpenGL utilise des opérations matricielles pour définir toutes les manipulations de l'espace 3D. Aucune reproduction.Opérations de base Nous n'allons pas aborder en détail toute la théorie du calcul matriciel ici. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. et à les passer à la méthode gluLookAt afin de redéfinir la caméra.) . que l'on passe ensuite à OpenGL pour définir la vision que l'on désire avoir. nous créons également les classes pour les objets qui seront manipulés par ces matrices. Copyright © 2011 . Le faible nombre de méthodes à définir ne m'a pas poussé à créer une classe générique de matrice NxN à étendre pour obtenir ces deux classes.developpez. La seconde méthode se passe de la gestion de ces trois points. 2 . ainsi que de l'utilisation de gluLookAt. et vous pouvez les utiliser à votre convenance. orientation).) . En amont de ces deux classes de matrices. Dans PGE. images.JM BORLOT. multiplication (matrice x matrice. L'expérience montre que cette méthode.. mais les rotations amènent à de savants calculs à coups de sinus et cosinus).. matrice identité.. Je vous renvoie néanmoins vers la FAQ Mathématiques pour les Jeux du site qui renferme tout ce qu'il faut savoir sur les matrices. Il n'y a donc pas de possibilité de se déplacer dans le monde 3D afin d'atteindre un point de vue plus adapté à notre besoin. ne peut être faite de ce site et de l'ensemble de son contenu : textes. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. http://plegat. son orientation (où est le haut?) . changement de repère. nous nous servirons également d'un outil mathématique "magique" : le quaternion. mais nous n'utiliserons que des opérations simples ici. matrice x vecteur. surtout si on n'a pas suffisamment de bagage technique ou d'expérience de manipulation.PGE (Plegat Graphic Engine) . l'affichage de notre monde 3D est défini grâce à l'utilisation de l'instruction gluLookAt pour positionner la caméra (position.

setZ(this. + b).getY()). Définition de la classe Point3d public class Point3d { public String id.La classe Point3d Cette classe définit un point de l'espace 3D. return _chaine.getX() + vector.getX() this.setX(this. } public Point3d(double a.y = b. ainsi que les opérations de translation. } public void ratio(double r) this. public void add(Vector3d vector) { this.setX(0).setX(this.JM BORLOT. etc sans l'autorisation expresse de l'auteur.id = "noname".developpez.setZ(this.getZ() } double b.com) 2-B .setZ(0).getX() / this. this.getX()). this.x = a.setZ(this. } public void setX(double x) { this. Aucune reproduction.getZ() / } { r). et vous pouvez les utiliser à votre convenance. this.getZ() + vector. + c). } public final void init() { this. } public double getY() { return y. } public void add(double a. this. Un nom et les coordonnées du point sont définis. documents. this. private double x.x = x. double c) { + a). double c) { init(). même partielle.getZ(). Copyright © 2011 .setY(this. } public double getX() { return x. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.getZ()). private double y. ne peut être faite de ce site et de l'ensemble de son contenu : textes. private double z. this.getY() this.setY(this.getY() + " z=" + this.com/tutoriels/jogl/pge-camera/ .getY() + vector.PGE (Plegat Graphic Engine) . double b.z = c.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. this. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. this. images. } public void setY(double y) { -4Les sources présentées sur cette pages sont libres de droits.setY(0).setX(this. public Point3d() { init(). http://plegat. @Override public String toString() { String _chaine = "x=" + this. r).setY(this. r).getY() / this.getX() + " y=" + this. this.

Définition de la classe Vector3d public class Vector3d { private double x. } } 2-C .x=x.double y.getX() + vector.y.getY() + ty).setZ(this. } public void setZ(double z) { this. associé à un angle (nous verrons son utilisation lors de la définition de la classe Quaternion).double z) { this.getY() + vector.z=z. combinaison linéaire . } public Point3d translate(Vector3d vector) { Point3d temp=new Point3d(). temp. Aucune reproduction. temp.com/tutoriels/jogl/pge-camera/ . ne peut être faite de ce site et de l'ensemble de son contenu : textes. documents. clonage. temp.getY()).setY(this. private double z. affectation et récupération des composantes . public Vector3d() { this.La classe Vector3d Cette classe définit un vecteur de l'espace 3D. conversion vers String . Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.x.z = z.y = y.developpez.JM BORLOT. produits scalaire et vectoriel .getZ() + tz).double tz) { Point3d temp=new Point3d(). etc sans l'autorisation expresse de l'auteur. Copyright © 2011 .double ty. normalisation du vecteur . temp.y=vec. images. -5Les sources présentées sur cette pages sont libres de droits. initialisation . } public Vector3d(Vector3d vec) { this. this. public double getZ() { return z. return temp. même partielle. this.getX()). return temp. temp. private double angle.setX(this.x=vec. Les opérations implémentées dans cette classe sont les suivantes : • • • • • • • • définition. temp.setY(this. et vous pouvez les utiliser à votre convenance. } public Vector3d(double x. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. échelle .angle=0.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.setX(this.init().com) Définition de la classe Point3d } this.PGE (Plegat Graphic Engine) .getX() + tx).y=y.getZ()). http://plegat. this. } public Point3d translate(double tx.setZ(this. this.getZ() + vector. private double y.

y=b.Point3d b) { this. this. this.z = z.getY().x=a. même partielle.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.getX(). this. etc sans l'autorisation expresse de l'auteur. } public final void init() { this. } public void setZ(double z) { this. images.z=a. Aucune reproduction.JM BORLOT. public Vector3d(Point3d a. this.angle=0. if (norm>0) { this. http://plegat.setAngle(0).x=b.getY()-a. this. this.angle=vec.getX()-a. Copyright © 2011 . } public void setX(double x) { this.y=a.getZ() / norm). this.setX(this.angle.setZ(0).z=b.PGE (Plegat Graphic Engine) .z. } public double getAngle() { return angle. et vous pouvez les utiliser à votre convenance. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.com) Définition de la classe Vector3d } this. documents. this. -6Les sources présentées sur cette pages sont libres de droits. } public void setY(double y) { this.setX(0).getY(). this.setY(this.z=vec. } } Normalisation d'un Vector3d public void normalize() { double norm=Math. } public double getZ() { return z. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.setZ(this.setY(0).sqrt(getX()*getX()+getY()*getY()+getZ()*getZ()). } } Affectation et récupération des composantes public double getX() { return x. } public double getY() { return y.getZ()-a.getZ().y = y.getX().developpez.getX() / norm). this.getZ(). this.angle=0.getY() / norm).com/tutoriels/jogl/pge-camera/ . this. ne peut être faite de ce site et de l'ensemble de son contenu : textes.x = x. } public Vector3d(Point3d a) { this.

getZ() + z).PGE (Plegat Graphic Engine) .getY(). } else if (i==2) { this.x*b.developpez. this.setX(a.getX() + vect.setY(val).getY() + y).getZ() + vect.getZ() . Vector3d b) { Vector3d temp=new Vector3d(). this.setZ(this.z. http://plegat. } public void add(double x.getY()).setX(val). images.y=this. } public double getComponent(int i) { if ((i>=0)&&(i<3)) { if (i==0) { return this.z=this. } Mise à l'échelle d'un Vector3d public void mult(double value) { this. } else if (i==1) { this.setZ(this. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. -7Les sources présentées sur cette pages sont libres de droits. Copyright © 2011 . documents.z*b. this.getAngle() + vect.y*value. } } else { return 0.com) Affectation et récupération des composantes } public void setAngle(double angle) { this.getZ()). this.getY()).angle = angle.setX(this. } } Addition de Vector3d public void add(Vector3d vect) { this. } } public void setComponent(int i.com/tutoriels/jogl/pge-camera/ .x+a.getAngle()). Aucune reproduction.getZ().setX(this. même partielle.x*value.getX().z*value. this. Vector3d b) { } return a.x=this. public static Vector3d crossProduct(Vector3d a.getX()). Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. } else { return this.getY() * b. this.setY(this.getX() + x). } else if (i==1) { return this. et vous pouvez les utiliser à votre convenance.double z) { this.y*b.a.setY(this.setAngle(this. ne peut être faite de ce site et de l'ensemble de son contenu : textes. temp.JM BORLOT.setZ(val).getY() + vect.getZ() * b.double val) { if (i==0) { this.y+a. etc sans l'autorisation expresse de l'auteur. this. } Produits scalaire et vectoriel de Vector3d public static double scalarProduct(Vector3d a.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.double y.

private double[][] coef = new double[3][3].y*valB.z). compY.coef[0][0] = m11. double m22.getAngle(). http://plegat.com) Produits scalaire et vectoriel de Vector3d temp.z*valB. double m33) { this.La classe Matrix3 Un objet Matrix3 est représenté par un tableau à deux dimensions.y. compZ). Combinaison linéaire de deux Vector3d public static Vector3d getCombination(Vector3d vectA. temp.com/tutoriels/jogl/pge-camera/ . documents. et vous pouvez les utiliser à votre convenance.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. } public Matrix3(double m11. this. double m12. "+this.getY()+". double compY=vectA. Copyright © 2011 .z*valA+vectB. double m31. double compZ=vectA. sur lequel les méthodes de la classe vont travailler.getZ() * b.setY(a.x*valB. images. return new Vector3d(compX. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.getX() * b. etc sans l'autorisation expresse de l'auteur.x.getX() . constructeur par passage de tous les éléments individuellement .getX()).getY() . "+this.getX()+".x*valA+vectB. temp.PGE (Plegat Graphic Engine) .double valB) { double compX=vectA.getX() * b. double m13.getZ()+". ne peut être faite de ce site et de l'ensemble de son contenu : textes.double valA. constructeur par tableau de valeurs . double m23. même partielle.setZ(a. constructeur par passage de trois vecteurs (matrice de changement de repère) .developpez.Vector3d vectB. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. } Clonage d'un Vector3d public Vector3d copy() { return new Vector3d(this. double m21.JM BORLOT. } return temp. "+this.setAngle(0).a. -8Les sources présentées sur cette pages sont libres de droits.init(). Les différents constructeurs permettent de définir la matrice de la manière la plus appropriée : • • • • • constructeur par défaut (matrice nulle) . } Conversion en String @Override public String toString() { return this. Aucune reproduction.getY() * b.a. constructeur par passage d'un buffer OpenGL. } 2-D . double m32. Ces différents constructeurs sont présentés dans le code ci-après : Définition de la classe Matrix3 public class Matrix3 { private static int SIZE=3. public Matrix3() { this.y*valA+vectB.getZ()). this.

getZ().coef[2][1] = v2. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.getZ(). } } } } Les opérations de base sont définies dans les méthodes suivantes : • • • • • récupérer toutes les valeurs ou une seule .coef[2][2] = v3. j < SIZE.com/tutoriels/jogl/pge-camera/ . i++) { for (int j = 0. j++) { this. } } } } public final void init() { for (int i = 0. this.coef[1][1] = v2. this.coef[1][0] = v1. Aucune reproduction.coef.getX(). j++) { this. this. -9Les sources présentées sur cette pages sont libres de droits.coef[2][0] = m13.coef[1][2] = m32. etc sans l'autorisation expresse de l'auteur. i++) { for (int j = 0.coef[0][2] = m31. images.coef[0][1] = m21.coef[1][1] = m22.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.coef[0][1] = v2.init().length != (SIZE*SIZE)) { this. Copyright © 2011 . } public Matrix3(double[][] values) { this.developpez.PGE (Plegat Graphic Engine) .coef[1][0] = m12.coef[2][2] = m33. même partielle.Vector3d v3) { this. et vous pouvez les utiliser à votre convenance. calculer la trace de la matrice .coef[i][j] = 0. ne peut être faite de ce site et de l'ensemble de son contenu : textes.getY().com) Définition de la classe Matrix3 this. i < SIZE. documents. i < SIZE. multiplication Matrix3 x Matrix3 . this. } else { for (int i = 0.get(i * SIZE + j).coef[0][0] = v1. multiplication Matrix3 x Vector3d.getX(). this. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.getX().coef[2][1] = m23.coef[0][2] = v3. this.array(). this. this. this. this. http://plegat. j < SIZE. this.Vector3d v2.getY().coef[j][i] = buff. this.coef[1][2] = v3. Opérations de base sur objet Matrix3 public double[][] getValues() { return this.coef[2][0] = v1. this. } public Matrix3(Vector3d v1.coef = values.JM BORLOT. } public Matrix3(FloatBuffer buff) { if (buff. initialiser la matrice à la matrice identité . this.getY(). this.getZ().

som). même partielle.coef[row][column]. documents.coef[k][j]. j++) { str. for (int i = 0. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. for (int k = 0. i < SIZE.developpez. j < SIZE. . } temp.com/tutoriels/jogl/pge-camera/ . for (int i = 0.10 Les sources présentées sur cette pages sont libres de droits. } } return temp. public Vector3d mult(Vector3d vect) { Vector3d temp = new Vector3d(). Enfin.PGE (Plegat Graphic Engine) .init(). temp.coef[0][0]+this.coef[i][j] = som. i++) { double som = 0. for (int i = 0. k++) { som = som + this. } str. et vous pouvez les utiliser à votre convenance.com) Opérations de base sur objet Matrix3 } public double getValue(int row. les méthodes de conversion permettent d'obtenir l'équivalent en String et FloatBuffer de notre matrice : Opérations de conversion de la classe Matrix3 @Override public String toString() { StringBuilder str=new StringBuilder().coef[2][2]. } public double getTrace() { return this. Aucune reproduction.append(this.coef[i][i] = 1. etc sans l'autorisation expresse de l'auteur. } } public Matrix3 mult(Matrix3 mult) { Matrix3 temp = new Matrix3(). i++) { this.coef[1][1]+this. } public void setIdentity() { this.coef[i][j]).append(" | ").int column) { return this. j++) { double som = 0. } } } return temp. temp.JM BORLOT. http://plegat. k < SIZE.init(). j < SIZE. i++) { for (int j = 0.getComponent(k). for (int i = 0.init(). k < SIZE.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. Copyright © 2011 . i < SIZE. images. ne peut être faite de ce site et de l'ensemble de son contenu : textes. i++) { for (int j = 0.setComponent(i. i < SIZE.coef[i][k] * vect. k++) { som = som + this.coef[i][k] * mult.append(" "). for (int k = 0. } temp. i < SIZE.

} } return mat.getComponent(i) * factor.coef[1][1]). i++) { mat. (float) this. et vous pouvez les utiliser à votre convenance.put(3. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.coef[0][2]). (float) this. ne peut être faite de ce site et de l'ensemble de son contenu : textes. même partielle.setIdentity().developpez. Aucune reproduction.getComponent(i). temp. } } return mat.coef[i][3] = vect.coef[1][0]).11 Les sources présentées sur cette pages sont libres de droits.put(6.put(5.coef[2][1]).La classe Matrix4 La classe Matrix4 est en tous points similaire à la classe Matrix3 (à l'adaptation près à une dimension supplémentaire). i < 3.coef[i][3] = vect.toString(). (float) this. mat.JM BORLOT. (float) this.setIdentity().coef[2][0]).coef[0][1]). mat. i++) { mat.PGE (Plegat Graphic Engine) .put(4. public static Matrix4 getScaleMatrix(double s) { Matrix4 mat = new Matrix4(). temp. public static Matrix4 getTranslationMatrix(Vector3d vect.com) Opérations de conversion de la classe Matrix3 } return str.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. documents.com/tutoriels/jogl/pge-camera/ . i < 3.put(0.put(1. for (int i = 0. (float) this. (float) this. double factor) { Matrix4 mat = new Matrix4(). etc sans l'autorisation expresse de l'auteur. temp. ces trois méthodes sont statiques. temp.allocate(SIZE*SIZE). Elles permettent d'obtenir les matrices de translation et d'échelle directement d'après les paramètres fournis. Trois méthodes d'initialisation de matrice sont cependant disponibles dans cette classe. } public FloatBuffer toFloatBuffer() { FloatBuffer temp = FloatBuffer. 2-E . Copyright © 2011 .coef[0][0]). temp. http://plegat.put(7.put(2.coef[2][2]). Méthodes supplémentaires de la classe Matrix4 public static Matrix4 getTranslationMatrix(Vector3d vect) { Matrix4 mat = new Matrix4(). images. for (int i = 0. temp. temp.put(8. (float) this. i < 3. i++) { . (float) this.coef[1][2]). for (int i = 0. temp. (float) this. Attention. } return temp. temp. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.

Aucune reproduction. Matrices 3 .com . Plutôt que d'utiliser trois rotations. auxquelles s'ajoutent les opérations de conversion quaternion/matrice. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. autour de trois axes. et également l'opération d'interpolation entre deux quaternions. est un outil magique très compliqué qu'il ne pourra jamais ni comprendre ni utiliser.La classe Quaternion La classe Quaternion définit notre objet quaternion ainsi que les principales opérations et transformations qui seront utilisées dans PGE. 2-F . même partielle. documents. le quaternion résume la transformation en une seule et unique rotation autour d'un axe défini par un vecteur (d'où la présence d'une propriété angle dans notre classe Vector3d). L'équivalence quaternion/ matrice nous amène aux mêmes opérations sur le quaternion que sur les matrices : • • • • conjugué .Le quaternion 3-A .coef[3][3] = 1. donnant un résultat plus ou moins correct au final. Copyright © 2011 . Non. http://plegat. en général. et couplé avec l'utilisation des matrices. et pas de translation. des cosinus et des sinus. multiplication.PGE (Plegat Graphic Engine) . Définition de la classe Quaternion public class Quaternion { .Références Vous trouverez d'excellentes informations dans la FAQ Mathématiques pour les Jeux du site Développez. normalisation . dans un ordre bien défini. le cosinus de la moitié de l'angle).coef[i][i] = s.com/tutoriels/jogl/pge-camera/ . pour le néophyte. il se retrouve avec des équations complexes utilisant les angles d'Euler. la quatrième définissant l'angle de la rotation (en fait.Mathématiques pour les Jeux. } return mat. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. au chapitre Matrices : FAQ Développez.com) Méthodes supplémentaires de la classe Matrix4 } mat. images. Trois de ces valeurs peuvent être interprétées comme les composantes du vecteur définissant l'axe de la rotation.com.Utilité et utilisation Le quaternion. inverse .developpez. et vous pouvez les utiliser à votre convenance. de la caméra. Simple non ? Un quaternion est défini par quatre valeurs. il peut être converti en une matrice de rotation 3x3.JM BORLOT. Le quaternion représentant une rotation. cela résout la rotation de caméra mobile de manière très rapide.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. c'est très simple. mat.12 Les sources présentées sur cette pages sont libres de droits. 3-B . C'est pourquoi. ne peut être faite de ce site et de l'ensemble de son contenu : textes. comme utilisé avec les angles d'Euler. une de ses utilisations consiste en la représentation d'une rotation dans l'espace. Il est vraiment dommage de se priver de l'utilisation du quaternion sous prétexte que c'est "trop compliqué". etc sans l'autorisation expresse de l'auteur. Si on regarde la définition du quaternion dans une encyclopédie. Je parle bien de rotation.

this. 2). m22)). 1). etc sans l'autorisation expresse de l'auteur. this. y.getValue(0.getValue(2.getValue(0.abs(max-m00)<1e-5) { s=2*Math.sqrt(1-m00+m11-m22). this. documents. this. 0).normalize().getTrace()+1.getValue(0.normalize().y=(m12+m21)/s.getValue(2.max(m00. Aucune reproduction. double z. 2))*s. Copyright © 2011 . this. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.getValue(1. 2)-mat. if (Math. this. this. this. même partielle. m21=mat.w = w. this.x=(mat. } else if (Math.x=(m01+m10)/s.z=(mat.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.getValue(1. double double double double double double m01=mat.sqrt(t)).w=0.y=(m01+m10)/s. 2).com) Définition de la classe Quaternion private private private private double double double double x.normalize(). this. this.com/tutoriels/jogl/pge-camera/ .z=s/4. z. double s. 0). .getValue(0.getValue(0. images.w=1/(4*s).PGE (Plegat Graphic Engine) . this. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. 1). this. http://plegat. m02=mat.abs(max-m11)<1e-5) { s=2*Math.sqrt(1+m00-m11-m22).abs(max-m22)<1e-5) { s=2*Math. et vous pouvez les utiliser à votre convenance.normalize(). this. ne peut être faite de ce site et de l'ensemble de son contenu : textes.x = x. } else if (Math.y=(mat. this. this. } public Quaternion(double x. Math. this.13 Les sources présentées sur cette pages sont libres de droits. this. double y.init().x=s/4. double m22=mat.getValue(1.z=(m12+m21)/s. m20=mat.x=(m02+m20)/s. this. 1))*s. double w) { this.getValue(2.getValue(2. if (t>1e-5) { s=1/(2*Math.z = z.getValue(2. 0))*s.getValue(1.JM BORLOT. } } else { this. this. } else if (Math.y = y.z=(m02+m20)/s.getValue(1. w. 0).w=0.y=s/4. m12=mat. double m11=mat.init(). double max=Math. this. 1)-mat. this.sqrt(1-m00-m11+m22).developpez. 0)-mat.abs(t)<=1e-5) { double m00=mat. m10=mat.max(m11. public Quaternion() { this.w=0. 1). 2). this. } public Quaternion(Matrix3 mat) { double t=mat.

vecQuat.x = this.14 Les sources présentées sur cette pages sont libres de droits. vecQuat.y.getY().z. Quaternion vecQuat = new Quaternion().PGE (Plegat Graphic Engine) . et vous pouvez les utiliser à votre convenance.y + x x y z * * * * quat.getConjugate().normalize().w = 1.x.z = vn.y this. Copyright © 2011 . -z. quat. images.y quat.normalize().println("erreur d'initialisation du quaternion !"). this.y = vn.w } 0) { = this.w.normalize().y = this. @Override public String toString() { return this.z . resQuat.z+" / "+this.x+" / "+this. norm. vecQuat.y result.getX().w + x w * quat.z = 1.z).x. } public Vector3d mult(Vector3d vec) { Vector3d vn = new Vector3d(vec).x quat. resQuat = vecQuat.z + z * quat.mult(resQuat). quat. Aucune reproduction.w .x . resQuat.x * quat. quat.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. vecQuat. this. etc sans l'autorisation expresse de l'auteur.x = 1.com/tutoriels/jogl/pge-camera/ . Quaternion resQuat.z).com) Définition de la classe Quaternion } } public final void init() { this.getZ(). } } Normalisation et conjugué du quaternion public final void normalize() { double norm = Math.w = 0. } public Quaternion getConjugate() { return new Quaternion(-x. } return new Vector3d(resQuat. http://plegat.0f.x = vn. norm.w + z w * quat.y+" / "+this.z * quat. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. { * * * * quat. this. resQuat = this. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.w / / / / norm. norm. même partielle.x quat. this. } System.out. documents.x this. } Multiplication public Quaternion mult(Quaternion quat) Quaternion result= new Quaternion(w w * quat. -y. .y + y * quat.y = 1.z this. w).JM BORLOT.sqrt(x * x + y * y + z * z+w*w).z = this. if (norm > this. ne peut être faite de ce site et de l'ensemble de son contenu : textes. vn. return result.w + y * quat.y.developpez.

wy).w } sinp siny sinr cosp cosy cosr = = = = = = = = = = Math. Math.0f. sinr cosr cosr cosr this.z this. double roll) { double PIOVER180 = Math.15 Les sources présentées sur cette pages sont libres de droits. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.0. (vn. } return axis. (vn.PI / 180.PGE (Plegat Graphic Engine) . axis.0f * (xz + wy). cosy. angle *= 0.0f * (y2 + z2).wx). Conversions quaternion/matrice public Matrix4 getMatrix() { double x2 = x * x. double z2 = z * z. même partielle. 0.2. } .z this. 0.0f. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. documents.w } = = = = (vn.0. siny. etc sans l'autorisation expresse de l'auteur. double angle) { double sinAngle. double wy = w * y. ne peut être faite de ce site et de l'ensemble de son contenu : textes.getY() * sinAngle). 2.cos(pdeg). double scale = Math.0f . Math.developpez. 0. double yz = y * z.setAngle(Math.y this. return new Matrix4(1.0f. 2.0f 2. 2. 2. axis. 0. double wx = w * x. sinAngle = Math. 0. double xz = x * z.normalize(). et vous pouvez les utiliser à votre convenance.0f * (xy .y this.0f * (xz . axis.0f * (xy + wz). double wz = w * z. double yaw.2. vn.0.getZ() * sinAngle). double xy = x * y.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. http://plegat. double pdeg = pitch * PIOVER180 / 2. 1. public Vector3d getAxisAngle() { Vector3d axis = new Vector3d().0).cos(angle).0f * (x2 + z2). Math. Math.setX(x / scale). * * * * cosp sinp cosp cosp * * * * cosy cosy siny cosy + + cosr sinr sinr sinr * * * * sinp cosp sinp sinp * * * * siny. axis. public void FromEuler(double pitch.getX() * sinAngle). Copyright © 2011 . double rdeg = roll * PIOVER180 / 2.cos(rdeg). 1. double double double double double double this.0. 2. Vector3d vn = new Vector3d(v). double y2 = y * y.0f . Math.0f).x this.0f * (yz + wx).normalize(). 1. images.sin(pdeg). siny.JM BORLOT.0f.wz).sqrt(x * x + y * y + z * z).0f * (x2 + y2). Math.sin(ydeg).com/tutoriels/jogl/pge-camera/ .5f.setY(y / scale). double ydeg = yaw * PIOVER180 / 2.sin(rdeg).setZ(z / scale). 2.com) Conversions quaternion/vecteur public void FromAxis(Vector3d v. this. 0.cos(ydeg). Aucune reproduction.0f.0f * (yz .acos(w) * 2.sin(angle).x this. this.0f.normalize().

PGE (Plegat Graphic Engine) .0f . La rotation se fera par rapport à un point de l'espace prédéfini auparavant par l'utilisateur. et ne sera pas obligatoirement sur l'axe de visée de la caméra. double yz = y * z. 2.com .0f * (xy + wz). zoom . y. } return temp.wx). 2. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.Mathématiques pour les Jeux. 2. y.JM BORLOT.getRotMatrix().0f * (x2 + y2)).2. nous avons besoin des fonctions suivantes : • • • translation (x et y écran) . return new Matrix3(1.2. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. } return quatInv. et de le remplacer par la redéfinition de la matrice MODELVIEW. même partielle. -w). 2. double xy = x * y. Pour le logiciel.0f * (yz + wx). rotation.0f * (xy . z. Nous allons donc avoir besoin de données suivantes pour définir notre caméra : • • un point de positionnement de la caméra . Copyright © 2011 .0f * (xz + wy). double xz = x * z.0f * (yz . documents.wz). 2. double y2 = y * y.La caméra 4-A . -w). . 1.2. en notant que le zoom peut être vu comme une translation suivant l'axe z de l'écran.0f * (x2 + z2).0f * (y2 + z2).Description de la caméra Maintenant nous avons tous les outils pour définir notre objet Camera.getMatrix(). Le but est de supprimer l'appel à gluLookAt. double z2 = z * z.wy). 2.com/tutoriels/jogl/pge-camera/ . public Matrix3 getRotMatrix() { double x2 = x * x. 1.0f .Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.0f * (xz . images. Mais comment calculer cette matrice ? Il nous faut tout d'abord définir le comportement de notre caméra. Aucune reproduction.Références FAQ Développez. Quaternions The Game Programming Wiki 4 . et vous pouvez les utiliser à votre convenance. etc sans l'autorisation expresse de l'auteur. } public Matrix3 getRotMatrixInv() { Quaternion quatInv=new Quaternion(x. double wz = w * z. double wx = w * x.developpez. z.0f . 3-C . ne peut être faite de ce site et de l'ensemble de son contenu : textes. double wy = w * y. un point de visée .com) Conversions quaternion/matrice public Matrix4 getMatrixInv() { Quaternion temp=new Quaternion(x. http://plegat.16 Les sources présentées sur cette pages sont libres de droits.

updateTranslations(). this. Aucune reproduction. Dans notre cas ici. Ils sont utilisés afin de calculer la matrice de changement de repère permettant de déterminer le quaternion représentant la rotation de la caméra.developpez. que nous multiplierons suivant l'ordre défini ci-dessus afin d'obtenir la matrice complète MODELVIEW. translation jusqu'au point de positionnement de la caméra. Vector3d transVect.17 Les sources présentées sur cette pages sont libres de droits. En effet. Définition de la classe Camera public class Camera { private private private private private private private Quaternion quatRot. this. même partielle. Les transformations seront représentées par des vecteurs 3D pour les translations. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Point3d rotCenter) { this. et orienter le haut de la caméra tel que souhaité . etc sans l'autorisation expresse de l'auteur. l'axe Z sortant de l'écran . la caméra est positionnée sur l'origine du monde 3D. http://plegat. Point3d rotCenter. plan de la caméra parallèle au plan XY. Les opérations de conversion des classes Matrix4 et Quaternion permettront d'obtenir les matrices 4x4 correspondantes.com/tutoriels/jogl/pge-camera/ . et par un quaternion pour la rotation. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. il nous faut déterminer les transformations à appliquer pour aboutir à la vision que l'on veut avoir avec la caméra. ainsi que les deux vecteurs de translation (origine/centre de rotation. Ses coordonnées ne sont donc pas celles obtenues directement à partir des coordonnées des points fournis en paramètres.La classe Camera Le constructeur de la classe Camera prend en paramètres les trois points et le vecteur définis ci-dessus.location = loc. Point3d location.com) • • un vecteur pour orienter la caméra (nous indiquerons où se trouve le haut de la caméra) . vecteur haut orienté suivant Y. ne peut être faite de ce site et de l'ensemble de son contenu : textes. les transformations sont représentées par des matrices.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.PGE (Plegat Graphic Engine) . Vector3d transCDR. 4-B . mais doivent être transformées par application de la matrice de rotation afin de correspondre au nouveau repère. et centre de rotation/ position caméra) Attention ! Le vecteur de translation entre le centre de rotation et la position de la caméra est utilisé APRÈS l'application de la rotation de la scène 3D. this.target = targ. this. et le produit matriciel n'est (de manière générale) pas commutatif (c'est-à-dire qu'une translation suivie d'une rotation ne donne pas le même résultat que la même rotation suivie de la même translation). } public final void updateQuaternion() { . Pour définir la matrice que nous allons passer à OpenGL.JM BORLOT. et vous pouvez les utiliser à votre convenance. translation jusqu'au centre de rotation de la scène . documents. avec la matrice identité. Copyright © 2011 . l'enchainement des transformations se fait en les multipliant entre elles. sans quoi la transformation finale ne sera pas correcte. Point3d target. Il est très important de bien respecter l'ordre des transformations à appliquer. rotation afin d'aligner la vue de la caméra sur le point de visée.rotCenter = rotCenter.upVector = up. this. images. Point3d targ. elles sont définies par l'enchainement suivant : • • • • initialisation : par défaut.updateQuaternion(). Vector3d up. Vector3d upVector. public Camera(Point3d loc. un centre de rotation de notre scène 3D.

y. Matrix4 matRot = this. etc sans l'autorisation expresse de l'auteur. x1). } return matTrans. double z) { this.transCDR = vect.target. } public void setTranslation(double x.location. Copyright © 2011 . Les rotations sont définies en multipliant le quaternion courant de la caméra par un quaternion correspondant à la rotation souhaitée.toFloatBuffer(). http://plegat. y2. Opérations élémentaires sur la caméra public void rotateX(double angle) { .rotCenter.transCDR = new Vector3d(x. } public void setTranslationToRotCenter(Vector3d vect) { this.getRotMatrix(). } public void setTranslation(Vector3d vect) { this.transVect = vect.getMatrixInv().JM BORLOT.18 Les sources présentées sur cette pages sont libres de droits. même partielle.setTranslationToRotCenter(new Vector3d(this. 0. Vector3d z1 = new Vector3d(this. transVectInit = this.upVector.quatRot. double y.crossProduct(z1.mult(matCDR).Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. Aucune reproduction.normalize().crossProduct(y1.developpez.mult(transVectInit). } public void setTranslationToRotCenter(double x. 0). Quelques opérations élémentaires sur la caméra sont définies. z1). double y. z1)). Matrix4 matTrans = Matrix4.PGE (Plegat Graphic Engine) . z1. Vector3d y2 = Vector3d.quatRot = new Quaternion(new Matrix3(x1. Pour les translations. z).com) Définition de la classe Camera Vector3d y1 = this. ne peut être faite de ce site et de l'ensemble de son contenu : textes. origin)).setTranslation(transVectInit). y. } } La matrice de la caméra est obtenue en multipliant les matrices de translation et de rotation suivant l'ordre défini au paragraphe précédent (on multiplie à gauche pour le produit matriciel) : Méthode d'obtention de la matrice de la caméra public FloatBuffer getCameraMatrix() { Matrix4 matCDR = Matrix4. this.location). Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. public final void updateTranslations() { Point3d origin = new Point3d(0.transVect = new Vector3d(x.mult(matRot).quatRot. this. et Z sortant de l'écran.normalize(). et les trois translations suivant les trois axes.getTranslationMatrix(transCDR).transVect).com/tutoriels/jogl/pge-camera/ . on ajoute au vecteur translation de la caméra le vecteur correspondant à la translation souhaitée. Y vers le haut. telles que les rotations suivant les axes X et Y caméra. this.getTranslationMatrix(this.rotCenter). } this. images. this. documents. x1. On remarquera à ce stade que toutes les opérations sur le déplacement de la caméra se font en référence aux axes caméra : X orienté suivant la droite de la caméra. Vector3d transVectInit = new Vector3d(this. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. double z) { this. et vous pouvez les utiliser à votre convenance. z). Vector3d x1 = Vector3d.

com/tutoriels/jogl/pge-camera/ .normalize().transVect. on trouve : • • • panel : le panneau PGE qui déclenchera les évènements . ne peut être faite de ce site et de l'ensemble de son contenu : textes. 0. 0). etc sans l'autorisation expresse de l'auteur. MouseMotionListener { private private private private PgePanel panel. 0). et vous pouvez les utiliser à votre convenance.quatRot. même partielle. 1. 0).quatRot. Elle gère ainsi les translations. http://plegat. 1). ty. } 5 . rotations et zoom de la caméra dans le monde 3D.quatRot = this. images. l'initialisation des autres propriétés de l'objet étant effectuée directement en utilisant ce panneau PGE dans la méthode updateData via l'appel de méthodes publiques de la classe PGEPanel. rot. rot.quatRot = this.add(0.add(tx. Camera camera. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. Parmi les propriétés principales de la classe. this. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. mode : le mode d'interaction avec le monde 3D (translation. 1. this.Définition de la classe MouseCameraManager La classe MouseCameraManager est chargée de gérer tous les évènements liés à la souris. double height. 0. tz).0 * Math.PGE (Plegat Graphic Engine) . } public void translateY(double ty) { this. public void rotateY(double angle) { Quaternion rot = new Quaternion(). 0). Le constructeur prend uniquement le panneau PGE en paramètre. défini par propriétés de classe déclarées en static).transVect.quatRot. rotation ou zoom.quatRot. } this. } public void translateZ(double tz) { this.19 Les sources présentées sur cette pages sont libres de droits.mult(rot). camera : la caméra associée au panneau PGE .com) Opérations élémentaires sur la caméra Quaternion rot = new Quaternion().PI). } public void translateY() { this. Aucune reproduction.transVect.add(0. Définition de la classe MouseCameraManager public class MouseCameraManager implements MouseListener.transVect. 0). } public void translateX() { this. this.Manipulation de la caméra à la souris 5-A .transVect.PI / 180. . 0.JM BORLOT. angle / 180.FromAxis(new Vector3d(0.normalize(). } public void translateX(double tx) { this. angle * Math.add(0. double width. 0. documents.0).Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.add(0.mult(rot).developpez.FromAxis(new Vector3d(1. Elle implémente donc les interfaces MouseListener et MouseMotionListener. Copyright © 2011 .

developpez. Évènement mousePressed @Override public void mousePressed(MouseEvent e) { this.ROTATE.BUTTON1) { this. static int ZOOM=3.panel=pan. private int mode. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. } else if (button==MouseEvent. } } .getWidth(). bouton du milieu : zoom .BUTTON2) { this. if (button==MouseEvent. ne peut être faite de ce site et de l'ensemble de son contenu : textes.getButton().mode=MouseCameraManager.camera=panel.panel. static int ROTATE=2. Aucune reproduction. static int DRAG=1.mode=MouseCameraManager. this. Cela définit le point de départ de la souris qui sera utilisé dans le calcul des paramètres de transformation.Détermination du mode d'interaction L'appui sur un des boutons de la souris sélectionnera automatiquement le mode d'interaction (mémorisé par la propriété mode de l'objet) sur le monde 3D de la manière suivante : • • • bouton de gauche : rotation . xOld=e. on mémorise la position actuelle du curseur dans la fenêtre. et vous pouvez les utiliser à votre convenance.requestFocus(). même partielle. yOld.com) Définition de la classe MouseCameraManager private double xOld. http://plegat.updateData(). Copyright © 2011 .height=panel. bouton de droite : translation.width=panel.com/tutoriels/jogl/pge-camera/ . images. this.getX().getY().DRAG. this. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. } else if (button==MouseEvent.20 Les sources présentées sur cette pages sont libres de droits. etc sans l'autorisation expresse de l'auteur.getHeight(). } } 5-B .JM BORLOT.getCamera().PGE (Plegat Graphic Engine) . int button=e.mode=MouseCameraManager. private double xNew. public MouseCameraManager(PgePanel pan) { this. documents.ZOOM.BUTTON3) { this. Lors de la détection de l'appui. } public final void updateData() { this. yOld=e. yNew.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP.

ZOOM) { double deltaX=(xNew-xOld)/this. } } this. mode ZOOM : translation négative de la caméra suivant Oz.width*360). this. this. déplacement en y du curseur. xOld=xNew.abs(deltaX)>Math. initialisée précédemment lors de l'appui sur l'un des boutons. mode ROTATION : rotation de la caméra autour de l'axe Oy .Gestion du déplacement actif de la souris L'évènement mouseDragged. yNew=e. on appelle les méthodes de translation ou de rotation de la caméra : • • • • • • déplacement en x du curseur. déplacement négatif en x ou y du curseur. .display(). permet de gérer la transformation appliquée sur le monde 3D. Ceux-ci sont ici calculés comme étant des facteurs de la distance entre la position actuelle du curseur (xNew/yNew) et sa position de départ (xOld/yOld).panel.translateZ(deltaY). Copyright © 2011 . et vous pouvez les utiliser à votre convenance.height*10.com/tutoriels/jogl/pge-camera/ .rotateY(-(xNew-xOld)/this. } else if (this. Pour cela.developpez. images. déplacement en y du curseur. la classe Camera est chargée de fournir la matrice MODELVIEW à appliquer afin d'avoir la vision souhaitée sur la scène 3D.ROTATE) { this. mode ZOOM : translation positive de la caméra suivant Oz .height*10). Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs.width*10.camera. yOld=yNew. mode TRANSLATION : translation de la caméra suivant y .translateX((xNew-xOld)/this. double deltaY=(yNew-yOld)/this.camera. déplacement positif en x ou y du curseur. la position actuelle du curseur est récupérée et est ensuite utilisée pour définir les paramètres de la transformation. même partielle.camera.21 Les sources présentées sur cette pages sont libres de droits.com) 5-C .Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. appelé lors du déplacement de la souris dans la fenêtre avec appui sur un des boutons.DRAG) { this. documents.getY().rotateX(-(yNew-yOld)/this.translateZ(deltaX).camera. mode TRANSLATION : translation de la caméra suivant x . mode ROTATION : rotation de la caméra autour de l'axe Ox . if (Math. Aucune reproduction.abs(deltaY)) { this.camera.PGE (Plegat Graphic Engine) .width*10). } else { this. ne peut être faite de ce site et de l'ensemble de son contenu : textes.mode==MouseCameraManager.height*360). if (this.Intégration de la caméra dans le panneau 3D de PGE Comme expliqué dans le chapitre 4. et un appel à glLoadMatrixf pour charger la matrice de la caméra dans la matrice MODELVIEW.JM BORLOT.mode==MouseCameraManager. } else if (this. en remplaçant l'appel à gluLookAt par une création d'un objet Camera suivant les mêmes paramètres.translateY(-(yNew-yOld)/this. } 6 .mode==MouseCameraManager. En fonction du mode d'interaction. etc sans l'autorisation expresse de l'auteur. Cela se fait de manière très simple. Évènement mouseDragged @Override public void mouseDragged(MouseEvent e) { xNew=e. déplacement en x du curseur.camera. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts. http://plegat.getX().

JM BORLOT. Déclaration du MouseCameraManager et de la Camera private MouseCameraManager mcm. 5. 0.addGLEventListener(this). etc sans l'autorisation expresse de l'auteur. 0).2) . Aucune reproduction. afin de gérer les évènements souris. Vector3d up = new Vector3d(0.5.0. 0.0. this.5. .cube=new PGEUnitCube(0.com) À partir de la classe PGEPanel de l'article précédent. this. // instanciation et connexion du MouseCameraManager this.developpez.mcm). targ.setFocusable(true).camera = new Camera(loc. vecteur "up" : point (0. this. on définit tout d'abord deux propriétés supplémentaires : un MouseCameraManager.1). 0). et vous pouvez les utiliser à votre convenance. http://plegat. Point3d targ = new Point3d(0. images. this.0. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. 1). point de visée : point (0.coord=new PGEGlobalCoord().addMouseMotionListener(this. Point3d rotCenter=new Point3d(0.0. this. en passant en paramètre la matrice de la caméra. // camera associee au PGEPanel La méthode initComponents est modifiée afin de connecter le MouseCameraManager au PGEPanel : Modification de la méthode initComponents private void initComponents() { this. Copyright © 2011 . Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.PGE (Plegat Graphic Engine) .2). } } this.0.addMouseListener(this. Il ne reste plus qu'à modifier la méthode display.0) .mcm. et une Camera pour définir la caméra associée au PGEPanel. mais ici elle va permettre d'initialiser la caméra. On garde les mêmes paramètres que dans le précédent article lors de l'appel à la méthode gluLookAt : • • • position de la camera : point (3.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. if (this.0) // vecteur "up" : point (0.mcm = new MouseCameraManager(this).1) // centre de rotation de la scène : point (0. up.com/tutoriels/jogl/pge-camera/ .0) Point3d loc = new Point3d(3. Modification de la méthode init @Override public void init(GLAutoDrawable arg0) { // position de la camera : point (3.updateData(). Cette méthode n'était pas utilisée dans le précédent article. ne peut être faite de ce site et de l'ensemble de son contenu : textes. rotCenter). 0).0.22 Les sources présentées sur cette pages sont libres de droits. même partielle. } La définition de la caméra se fait dans la méthode init. Les propriétés du MouseCameraManager sont mises à jour afin de lier les listeners à la caméra.camera == null) { this.mcm). 0. Le centre de rotation de la scène est fixé arbitrairement à l'origine. documents. en remplaçant l'appel à gluLookAt par un appel à gLoadMatrixf. // Listener souris private Camera camera = null.2) // point de visée : point (0.

.glClearColor(0.GL_MODELVIEW). Les sources de cet article sont disponibles en suivant ce lien : src_PGE_article_2.0f).1.winAW / (double) this.cube.winAH. gl.0).glMatrixMode(GL2. même partielle.0f. this.draw(gl). 0. images. gl. } 7 .winAH). Copyright © 2011 . 0. Nous verrons dans le prochain article comment construire des objets plus ou moins complexes.developpez.glViewport(0. // dessin des axes du repère global this. etc sans l'autorisation expresse de l'auteur.JM BORLOT. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.GL_PROJECTION).winAW. plan de clipping "near" et "far" glu.glClear(GL2.GL_COLOR_BUFFER_BIT). Aucune reproduction. ainsi qu'à djibril pour son aide sur le KitOOoDVP.getCameraMatrix()).camera. angle 45 °.0f.camera. // définition de la matrice de projection // vue en perspective.getGL(). gl.com) Attention de bien vérifier que vous utilisez glLoadMatrixf en mode GL_MODELVIEW avec la matrice caméra.PGE (Plegat Graphic Engine) . gl.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. documents. // initialisation de la matrice modèle // couleur de fond : noir gl.23 Les sources présentées sur cette pages sont libres de droits.glMatrixMode(GL2. on rajoute également une méthode getCamera qui est utilisée par la classe MouseCameraManager : public Camera getCamera() { return this. Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. 0.draw(gl). et vous pouvez les utiliser à votre convenance.Conclusion Nous pouvons maintenant définir une caméra adaptée à nos besoins de visualisation et naviguer interactivement dans notre monde 3D par l'intermédiaire de la souris.zip (Miroir).0f.coord. Modification de la méthode display @Override public void display(GLAutoDrawable arg0) { GL2 gl = arg0.com/tutoriels/jogl/pge-camera/ . http://plegat.gluPerspective(45.glLoadMatrixf(this. GLU glu = new GLU(). (double) this.Remerciements Merci à ClaudeLELOUP pour sa relecture orthographique.glLoadIdentity(). } Pour finir. 100. // définition de la matrice MODELVIEW à partir de la matrice camera gl. ratio largeur/hauteur. // dessine un cube unitaire à l'origine du repère global this. 8 . ne peut être faite de ce site et de l'ensemble de son contenu : textes. // initialisation de la matrice de projection gl. Vous pouvez également regarder la vidéo de démonstration sur Vimeo pour voir le résultat de cet article. 0.getGL2(). 0. this.

Par contre la page de présentation de ces sources constitue une oeuvre intellectuelle protégée par les droits d'auteurs. documents.Définition des caméras et de leur manipulation par Jean-Michel BORLOT (Site DVP. Copyright © 2011 .PGE (Plegat Graphic Engine) . images.Blocage de cardan ("Gimbal lock") . même partielle.com) 1 : PGE . et vous pouvez les utiliser à votre convenance.developpez.JM BORLOT. ne peut être faite de ce site et de l'ensemble de son contenu : textes.Introduction 2 : Lien Wikipédia . Aucune reproduction.com/tutoriels/jogl/pge-camera/ . http://plegat. etc sans l'autorisation expresse de l'auteur.24 Les sources présentées sur cette pages sont libres de droits. Sinon vous encourez selon la loi jusqu'à 3 ans de prison et jusqu'à 300 000 E de dommages et intérêts.

Sign up to vote on this title
UsefulNot useful