Pour obtenir un déplacement apparent de l'objet de droite à gauche lorsqu'on déplace la souris ddans le même sens on a le choix : soit déplacer l'objet de droite à gauche par rapport à la caméra, soit déplacer la caméra de gauche à droite. Vous pourrez donc choisir de déplacer soit l'objet, soit la caméra.
La seule difficulté consiste à calculer en mètres les valeurs de translations tx et ty. Puisque l'objet ne s'éloigne pas de la caméra mais se déplace dans un plan fronto-parallèle, la valeur de translation en Z est nulle.
Je vous ai proposé en cours de calculer les valeurs de translations
en tenant compte de la taille apparente de l'objet dans l'écran.
Si on suppose l'objet centré au milieu de l'écran, on peut
se dire : "si je dépace la souris horizontalement de gauche à
droite sur toute la largeur de l'écran, je veux que l'objet se déplace
de trois fois sa taille vers la droite. On a donc :
|
|
|
|
|
|
La valeur 3 a été choisie arbitrairement, mais on pourrait l'adapter dynamiquement en fonction du plus grand côté du rectangle contenant l'objet dans l'écran (une fois projeté), ou encore pouvoir spécifier sa valeur à l'aide d'un ascenseur dans l'interface graphique de votre application.
On utilise un raisonnement similaire pour calculer le déplacement en Y.
Implémentation :
Tout se passe dans la fonction mainloop() du fichier graphics.c. Je
vous conseille de créer une variable mode_deplacement qui pourra
prendre les valeurs TRANSLATION, ROTATION, ZOOM (définir ces macros
avec des #define), et de mettre un switch dans les différentes parties
de mainloop :
case ButtonPress :
switch(evt.xbutton.button) {
old_x = evt.xbutton.x; old_y = evt.xbutton.y;
case Button1 :
mode_deplacement = ROTATION; break;
case Button2:
mode_deplacement = TRANSLATION; break;
case Button3 :
mode_deplacement = ZOOM; break; } break;
case ButtonRelease :
mode_deplacement = AUCUN; break;
case MotionNotify :
switch(mode_deplacement) { new_x = evt.xmotion.x; new_y = evt.xmotion.y;
/* déplacement en pixels */ dx = new_x - old_x; dy = new_y - old_y;
case TRANSLATION: tx = ......; ty = ......;
TranslateObject(tx, ty, 0); UpdateLocalToCamera(...); draw_object(...); ... break;
case ROTATION: ... break;
case ZOOM: ... break; } old_x = new_x; old_y = new_y; ....
On effectuera une translation uniquement selon l'axe des Z : tx = ty
= 0. Pour calculer la valeur de tz, on utilisera un raisonnement similaire
à celui dont on s'est servi pour calculer les valeurs de translation
: si ma souris se déplace du haut vers le bas, je rapproche l'objet
de 3 fois sa taille, etc....