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 :
// 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.0
f);
// 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 :
// 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 :
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 :
#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 :
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 :
// É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.