Tutorial 2 : interaction avec l'utilisateur : faire bouger un cube!!!
La première opération que nous allons apprendre ici est : déplacer un cube, ensuite on apprendra à le faire tourner!!
Pour réaliser cela, on va d'abord augmenter notre type énuméré:
| typedef enum { MNoOperation, MPickAndTranslate, MTranslateObject, MOUSEMOVEOPERATIONFORCEENUMSIZEINT
= RWFORCEENUMSIZEINT |
On rajoute un membre pour indiquer qu'on va faire une translation et on a changé un autre état. Maintenat il faut changer les gestionnaires d'événements de la souris pour indiquer qu'on va translater quand on clique et qu'on ne fait plus rien quand on relâche.
| static RsEventStatus HandleLeftButtonDown(RsMouseStatus *mouseStatus __RWUNUSED__) { /* Left mouse button down event handling... */ MouseMoveAction = MPickAndTranslateObject; return rsEVENTPROCESSED; static RsEventStatus return rsEVENTPROCESSED; |
Il faut maintenant écrire une fonction qui translate effectivement l'atomic:
| /** fonction pour réaliser la translation effective */ static void TranslateAtomic(void) { RwReal dx, dy; RwFrame *f; RwV3d up, right, trans; //recuperation de la frame attaché
à la camera //recuperation des vecteurs de
la camera //on applique le deplacement //recuperation de la frame de
l'atomic //on sauvegarde la position |
Il faut aussi rajouter la déclaration de OldPos au début de main.c:
| RwV2d MousePos = {0,0}; RwV2d OldPos = {0,0}; |
Maintenant, il faut changer Idle pour effectuer la translation au bon moment!
| switch(MouseMoveAction) { case MPickAndTranslateObject: PickedAtomic = RwCameraPickAtomicOnPixel(Camera,&MousePos); if(PickedAtomic) // si on trouve quelque chose { //on récupère la BB AtomicGetBBox(PickedAtomic,&PickBox); //on sauvegarde OldPos=MousePos; //on indique l'action MouseMoveAction=MTranslateObject; } else { MouseMoveAction = MNoOperation; } break; case MTranslateObject: TranslateAtomic(); break; |
C'est tout magique!!On copile, on exécute, on appuie plein de fois sur F1 et puis on déplace les cubes!

Bon maintenant qu'on sait ire un fichier dff, sélectionner un cube et le déplacer, on va apprendre à le faire tourner!! Comme pour la translation, on va rajouter des états à notre type énuméré:
| typedef
enum { MNoOperation, MPickAndTranslateObject, MOUSEMOVEOPERATIONFORCEENUMSIZEINT
= RWFORCEENUMSIZEINT |
Nous avons les nouveaux états pour la rotation. Il va falloir indiquer le moment où on veut faire une rotation. Comme tout à l'heure, on va changer les gestionnaires d'événments de la souris:
| static
RsEventStatus HandleLeftButtonDown(RsMouseStatus *mouseStatus __RWUNUSED__) { /* Left mouse button down event handling... */ //si on appuie sur maj en meme temps qu'on clique gauche if(mouseStatus->shift) { MouseMoveAction = MPickAndRotateObject; } else { MouseMoveAction = MPickAndTranslateObject; } return rsEVENTPROCESSED; |
Lorsqu'on appuie sur la touche maj quand on clique gauche on se met en état de rotation. Comme dans le cas de la translation, il faut aussi créer la fonction qui permet de "rotater" le cube.
| static
void RotateAtomic(void) { RwFrame *f; RwMatrix *worldToLocal, *tmpMatrix; RwV3d up, right; RwReal dx, dy; f = RwCameraGetFrame(Camera); dx = OldPos.x - MousePos.x; f = RpAtomicGetFrame(PickedAtomic); //on met
le vecteur up dans la monde de l'atomic choisi //on se
sert plus de la matrice /* Apply
the rotations */ |
Maintenant qu'on a la fonction pour tourner le cube : on va s'en servir!!Et ce dans la fonction Idle() (ah bon??)
| case
MTranslateObject: TranslateAtomic(); break; break; |
Comme d'habitude, on compile, on exécute, on appuie plein de fois sur F1, on clique, on déplace et on appuie sur maj!

Bon on a pas mal avancé quand même : nos cubes se déplacent et tournent!! Dnas le tutorial 3 nous allons voir comment ajouter un menu et comment faire pour bouger selon l'axe des Z. Tutorial 3