1. Introduction

Ce tutoriel a pour but de permettre à l'utilisateur d'acquérir une maîtrise basique de la classe de gestion d'événements d'OpenScenegraph. Il permettra au lecteur de pouvoir implémenter dans son propre programme, de façon simple, les événements clavier et souris.

Le programme développé a pour but simple de changer la couleur de fond de la scène à la pression d'une touche ou le double-clic de la souris.

2. Classes et fonctions utilisées

Classe :

GUIEventHandler  : c'est la classe de gestion d'événements OpenSceneGraph. Elle permet de récupérer les événements de la fenêtre pour ensuite les traiter.

Fonction :

bool handle(const osgGA::GUIEventAdapter&,osgGA::GUIActionAdapter&) : c'est la fonction principale de la classe ci-dessus. Elle permet de traiter l'événement récupéré dans le GUIEventAdapter.

3. Mise en Pratique

3-A. Mise en place du programme principal

Tout d'abord il est nécessaire d'avoir un programme de base simple afin de tester la classe.

Pour cela, prenons simplement une scène contenant un cube. On créera une fonction pour cela afin de bien séparer le code :

 
Sélectionnez
// Création de la scène : cube 
/****************************************************************************************** 
******************************************************************************************/ 
osg::Node* CreateScene() 
{ 
     // Déclare un groupe servant de nœud principal : 
     osg::Group* root = new osg::Group(); 

     // Création du cube 
     osg::Box* unitCube = new osg::Box( osg::Vec3(0,0,0), 1.0f); 

     // Met le cube dans un drawable pour pouvoir l'ajouter ensuite à la scène 
     osg::ShapeDrawable* unitCubeDrawable = new osg::ShapeDrawable(unitCube); 

     // Déclare une instance de la classe Geode 
     osg::Geode* basicShapesGeode = new osg::Geode(); 

     // Ajoute unitCubeDrawable à ce dernier 
     basicShapesGeode->addDrawable(unitCubeDrawable); 

     // Ajoute le Geode à la scène 
     root->addChild(basicShapesGeode); 

     return root; 
} 

Ensuite dans une fonction main nous allons ajouter le viewer, qui permettra de visualiser la scène, une caméra, puis notre scène. Tout d'abord, pour notre programme de tutoriel, le viewer sera déclaré en global afin de permettre à la fonction de gestion d'événements d'y accéder. Il sera donc déclaré ainsi :

 
Sélectionnez
// Création du viewer 
/***************************************************************************************** 
*****************************************************************************************/ 
osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer; 

osg::ref_ptr<osgViewer::Viewer> étant simplement la déclaration d'un pointeur vers un type viewer.

Ensuite nous créons la fonction principale qui contiendra la fenêtre dans laquelle est importée notre scène et la caméra. Cela n'est pas l'objet de ce tutoriel, pour plus de détail, se référer au tutoriel concernant le programme de base :

 
Sélectionnez
int main(int argc, char* argv[]) 
{ 
    // Crée une fenêtre de 512x512 en position 100, 100 
    viewer->setUpViewInWindow( 100, 100, 512, 512 ); 

    // Caméra 
    /*********************************************************************************** 
    ***********************************************************************************/ 

    // Change la matrice de projection 
    viewer->getCamera()->setProjectionMatrixAsPerspective( 
    45.0, 
    viewer->getCamera()->getViewport()->aspectRatio(), 
    0.1, 
    1000.0 
    ); 
    
    // Change la couleur du fond 
    viewer->getCamera()->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 0.0)); 

    // Definit la scène comme celle du viewer 
    viewer->setSceneData(CreateScene()); 

    // Exécution du programme 
    /*********************************************************************************** 
    ***********************************************************************************/ 
    viewer->realize(); 

    // Exécution manuelle de la boucle d'exécution afin de replacer la caméra par défaut 
    // (voir tutoriel sur les caméras) 
    while(!viewer->done()) 
    { 
        viewer->advance(); 
        viewer->eventTraversal(); 
        viewer->updateTraversal(); 
        viewer->getCamera()->setViewMatrixAsLookAt(osg::Vec3d(0.0, -3.0, 3.0), 
        osg::Vec3d(0.0, 0.0, 0.0), osg::Vec3d(0.0, 0.0, 1.0)); 
        viewer->renderingTraversals(); 
    } 
} 

Afin que ce programme puisse fonctionner il est nécessaire d'ajouter à notre code les bibliothèques nécessaires, ce qui se fera par les lignes suivantes placées en début de code :

 
Sélectionnez
#include <osgViewer/Viewer> 
#include <osg/Group> 
#include <osg/Geode> 
#include <osg/ShapeDrawable> 
#include <osg/Camera> 
#include <osgGA/GUIEventHandler> 
#include <iostream> 

3-B. Mise en place des évènements

Venons-en enfin à notre gestion d'événements. Pour cela il est nécessaire de dériver la classe GUIEventHandler d'OpenSceneGraph et de redéfinir la fonction bool handle (const osgGA::GUIEventAdapter&, osgGA::GUIActionAdapter&) dans notre nouvelle classe.

Cette classe, si elle est déclarée dans notre programme principal (ce qui est le cas pour ce tutoriel, sera placée avant la fonction principale (main)).

La gestion complète se fera donc par la fonction

bool handle (const osgGA::GUIEventAdapter&, osgGA::GUIActionAdapter&) que nous redéfinirons. Dans ce tutoriel seul le premier paramètre sera utilisé. C'est lui qui récupère l'événement. Nous définirons donc en fonction de chaque événement les actions à effectuer :

 
Sélectionnez
bool gestionnaireEvenements::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter& aa) 
{ 
     switch(ea.getEventType()) 
     { 
          case(osgGA::GUIEventAdapter::KEYDOWN): 
          { 
               viewer->getCamera()->setClearColor(osg::Vec4(0.0, 0.0, 0.0, 0.0)); 
               break; 
          } 
          case(osgGA::GUIEventAdapter::KEYUP): 
          { 
               switch(ea.getKey()) 
               { 
                    case 't': 
                         viewer->getCamera()->setClearColor(osg::Vec4(1.0, 0.0, 0.0, 0.0)); 
                         return false; 
                    break; 
                    case 'g': 
                         viewer->getCamera()->setClearColor(osg::Vec4(0.0, 1.0, 0.0, 0.0)); 
                         return false; 
                    break; 
                    case 'b': 
                         viewer->getCamera()->setClearColor(osg::Vec4(0.0, 0.0, 1.0, 0.0)); 
                         return false; 
                    break; 
                    case 'h': 
                         std::cout<<"t - bleu"<<std::endl 
                         <<"g - vert"<<std::endl 
                         <<"b - rouge"<<std::endl 
                         <<"autre : noir"<<endl; 
                         return false; 
                    break; 
                    default: 
                         return false; 
               } 
          } 
     case(osgGA::GUIEventAdapter::DOUBLECLICK): 
     { 

osgGA::GUIEventAdapter::KEYDOWN désigne l'action de presser une touche ;

osgGA::GUIEventAdapter::KEYUP désigne la fin de pression d'une touche ;

osgGA::GUIEventAdapter::DOUBLECLICK désigne le double-clic de la souris.

Ce tutoriel ne liste pas tous les événements possibles, pour en savoir plus se référer à la documentation OpenSceneGraph ici.

Il nous suffit ensuite d'intégrer notre gestionnaire d'événements à la fonction principale par ces lignes :

 
Sélectionnez
// Événements 
/****************************************************************************************** 
******************************************************************************************/ 
// Création de l'objet de gestion d'événements clavier 
gestionnaireEvenements* evenements = new gestionnaireEvenements(); 

// Ajout des événements au viewer 
viewer->addEventHandler(evenements); 

le gestionnaire d'événements est ainsi intégré au viewer, le programme fonctionne !

4. Remerciements

Merci jacques_jean pour les corrections.