3. LE TRAVAIL REALISE


3.1. Les moyens mis en oeuvre
3.1.1. Logiciels
3.1.2. Matériels
3.2. Démarche suivie
3.2.1. Analyse de l'existant
3.2.2. Analyse préalable
3.2.3. Définitions des besoins
3.2.4. Planification du temps de travail
3.2.5. Conception
3.3. Le modèle de propagation


3.4. L'éditeur
3.4.1. Principes
3.4.2. Algorithmes
3.4.3. Problèmes rencontrés
3.4.4. Limitations de l'éditeur
3.4.5. Améliorations possibles
3.5. Le simulateur
3.5.1. Principes
3.5.2. Algorithmes
3.5.3. Problèmes rencontrés
3.5.4. Limitations du simulateur
3.5.5. Améliorations possibles




3.1. Les moyens mis en oeuvre

Les moyens logiciels et matériels utilisés pour ce stage sont ceux utilisés par DCN Equipements navals. Dans le but d’assurer la cohérence de leur travail, ils m’ont été imposés. Néanmoins, ces choix sont parfaitement justifiables compte tenu des objectifs de la société.

3.1.1. Logiciels
3.1.1.1. Système d'exploitation

Windows NT :
De plus en plus, DCN Equipements navals se tourne vers des plate-formes PC sous Windows pour deux raisons principales :

  • Le faible coût d’une plate-forme PC par rapport à une station travail de type Silicon Graphics, qui si elle est bien équipée (carte graphique de dernière génération, processeur puissant) permet des performances tout à fait suffisantes pour les besoins de l’entreprise.

  • Une très forte demande de la part des utilisateurs finaux des environnements PC/Windows qui leur sont plus familiers.

  • 3.1.1.2. Langages et environnements de conception et de développement

    UML et Rational Rose :

    UML (Unified Modeling Language) est un langage de conception orienté objet. L’objectif de ce langage est de concevoir des applications en suivant un cycle de développement à travers différents diagrammes, du plus haut niveau d’abstraction vers un niveau plus bas (définitions des objets, de leurs attributs et de leurs méthodes, collaboration entre objets…). Ainsi la conception résultant d’une démarche UML donne une conception complètement orientée objet du logiciel et reste indépendante du langage.
    Rational Rose est un outil de conception UML permettant de réaliser l’ensemble des diagrammes à travers son interface graphique. Cet outil permet d’effectuer une conception très détaillée. En effet, chaque élément d’un diagramme (qu’il soit ou non d’un haut niveau d’abstraction) peut être commenté, et ces commentaires pourront être utilisés pour réaliser une documentation de la conception.
    Un autre point fort de Rational Rose est de permettre la génération C++ des squelettes des classes à partir des diagrammes de classes. On peut ainsi, pour une classe, définir :

  • Les propriétés des attributs : static, constant, privé, protégé, publique…
  • Les signatures et propriétés des méthodes : static, virtuelle, abstraite, constante
  • Pour un attribut, s’il faut générer les accesseurs ou modifieurs, en précisant leurs types de paramètres (par valeur ou par référence) et leurs visibilités (privés, publics…)

  • L’avantage de cet outil est qu’il permet également, dans certaines limites, de modifier la conception et de régénérer le code correspondant sans perdre l’implémentation que l’on avait déjà réalisée. Ceci permet de maintenir plus facilement la correspondance entre la conception et l’implémentation en cas de modification.

    C++ et Microsoft Visual C++ 6 :

    Le langage C++ est apprécié car c’est un langage orienté objet, compilé et relativement performant. De plus il est très courant, et de nombreuses bibliothèques libres de droit sont écrites en C ou C++.

    Microsoft Visual C++ 6 est l’environnement de développement en langage C++ sous Windows le plus utilisé à l’heure actuelle. Il propose tous les outils nécessaires au développement (environnement de gestion de projet, éditeur de code C++, débogueur …).

    3.1.1.3. Bibliothèques graphiques

    OpenGL :

    D’après le guide officiel OpenGL 1.2

    OpenGL est une interface logicielle destinée aux logiciels graphiques. Elle se compose d’environ 250 commandes distinctes (environ 200 au sein d’OpenGL et 50 autres dans OpenGL Utility Library) que l’on utilise pour définir les objets et les opérations nécessaires à la génération d’applications interactives tridimensionnelles.

    OpenGL est conçu comme une interface rationnelle, indépendante du matériel, qu’il est possible d’implémenter sur de nombreuses plate-formes matérielles différentes. La bibliothèque ne permet toutefois pas de gérer un système de fenêtrage, il est nécessaire d’utiliser un gestionnaire de fenêtres annexes. De plus elle ne permet pas de décrire des modèles d’objets tridimensionnels complexes, qui doivent être décrit à l’aide de formes géométriques primitives tel que des points, des lignes et des polygones.

    OpenGl permet de gérer les profondeurs de champs, le lissage des scènes, l’éclairage, les ombres, les textures, l’effet de flou.

    Qt de TrollTech :

    Qt est une bibliothèque de développement d’interfaces graphiques entièrement développée en C++.

    Elle est très performante, notamment pour la synthèse d’image 2D (avec le QPainter). Elle est également facilement portable sous de nombreuses plates-formes (Windows, MacOS X, Linux, Solaris…). De plus elle est facile à utiliser et permet de définir simplement de nouveaux composants à partir de ceux existant en les dérivant.

    3.1.2. Matériel

    La plate-forme utilisée pour le développement est un PC muni d’un processeur Intel Pentium III 900 Mhz, de 128 Mo de RAM, et d’une carte graphique GEForce2 MX 32Mo.

    En parallèle, j’ai eu accès à un serveur de documentation et à des imprimantes partagées, me permettant d’écrire la spécification technique logiciel (STL) du travail à réaliser, ainsi que mon rapport de stage. Enfin, un poste internet était disponible pour toutes les recherches nécessaires.

    3.2. Démarche suivie

    La démarche suivie pour la création de ce simulateur est classique : analyse, conception, implémentation.

    3.2.1. Analyse de l'existant

    Des recherches sur la création d’un simulateur de lutte contre les sinistres ont déjà eu lieu au sein de DCN toutefois, elles se sont principalement portées sur la modélisation de la propagation réaliste des sinistres et non sur leur représentation graphique, il n’y avait donc pas d’existant sur lequel basé la conception du moteur graphique.

    3.2.2 Analyse préalable

    Une analyse préalable permet d’établir quelles sont les besoins à satisfaire dans la conception du simulateur. Il est important que cette analyse se base sur l’existant du projet, ce qui permet une meilleure approche du sujet. Toutefois comme il l’a été dit précédemment aucun existant n’était disponible, l’analyse a donc été basée sur les spécifications que notre maître de stage nous a données lors de réunions préalables.

    3.2.3 Définitions des besoins

    Le premier besoin à remplir est la mise au point d’un éditeur de carte, en effet, tant qu’aucune carte n’a été définie, il est impossible de la modéliser.

    Le deuxième est d’établir un système de sauvegarde et de chargement des cartes permettant de passer de l’éditeur au simulateur, la solution la plus simple, et la plus rapide à mettre en place est très certainement la sauvegarde des données de chaque élément dans un fichier au format texte.

    Ensuite vient la mise au point du simulateur en trois dimensions.

    Enfin, le dernier besoin à remplir, est la communication entre le simulateur et le modèle de propagation de manière à afficher les éléments en fonction de leur changement d’état.

    3.2.4 Planification du temps de travail

    Quand les besoins ont été définis, les taches que chacun d’entre eux requiert peuvent être extraites et ainsi les planifier dans le temps. La planification du temps de travail est importante car elle permet tout d’abord d’évaluer l’avancement de son travail, d’autre part de détecter un éventuel retard dans une tache et ainsi permettre d’y remédier avant que le temps perdu ne soit trop important. C’est encore plus important quand le projet s’effectue en équipe et que le retard d’une personne peut occasionner une perte de temps pour le reste de l’équipe.

    3.2.5. Conception

    La conception a été pensé de manière suivante : L’application est décomposée en deux grandes parties, la première étant l’éditeur de cartes, la deuxième le simulateur. Cette dernière partie est quant à elle décomposée en deux parties : le moteur graphique et le modèle de propagation.

    Il existe une partie identique dans l’éditeur et le simulateur, il s’agit des éléments constituant un navire. Il y a tout d’abord les séparations, ce sont par exemple des portes ou des murs, ils permettent de délimiter le deuxième type d’éléments les salles. Chaque salle contient une liste des portes et des murs la composant, on y trouve aussi une liste des objets s’y trouvant. Les objets sont des éléments de décor, seul l’objet chaise est actuellement disponible. L’ensemble des salles est contenu dans un pont, les salles contiennent d’autres informations comme le volume d’oxygène présent, ou la pression de la pièce, mais ce sont des données qui sont calculées par rapport à son volume et ne sont donc pas modifiables par l’utilisateur. Par la suite les différents ponts seront regroupés dans un bâtiment.



    Figure 12 - Principe de stockage des composants d'un navire

    Il existe ensuite les sinistres, ils contiennent leur position dans le pont, une référence sur l’élément où ils vont se déclencher (cela peut être une salle ou une séparation), et une date de déclenchement qui est exprimée en seconde. Pour l’instant, seul l’incendie a été modélisé.

    3.2.5.1. L'éditeur

    La première étape de la conception a été de définir les acteurs qui seraient amenés à utiliser l’éditeur de cartes. Il y en a en fait un seul, il s’agit du concepteur de la carte. Le seul cas d’utilisation est alors la création d’une carte qui peut être décomposée en sous cas qui sont :

  • L’ajout d’éléments graphiques (murs, portes, salles, écoutilles)

  • L’ajout d’objets graphiques (chaises, tables, armoires)

  • L’ajout de sinistres (incendies)

  • La modification de ces 3 types d’éléments

  • La suppression de ces types d’éléments

  • La suppression d’un pont

  • La suppression de l’ensemble des ponts

  • La sauvegarde de la carte

  • Il est toutefois nécessaire de prévoir le cas de modification ultérieure d’une carte déjà existante.

    La conception des données de l’architecture logicielle a été décomposée en plusieurs petites parties qui sont :

  • Elément graphique qui regroupe les différents de types d’éléments qui peuvent être affichés (éléments (salles, séparations…), sinistres ou pont)

  • Elément qui regroupe les classes mères de tout élément pouvant être affiché, c’est à dire les séparations (portes, murs…), les salles et les objets.

  • Objet qui regroupe les éléments du décor à afficher.

  • Sinistre qui regroupe les avaries susceptibles de se déclencher.

  • Géométrie qui regroupe les éléments nécessaire au calcul de géométrie comme les points.

  • Externe qui permet de disposer d’un système observateur – sujet.

  • 3.2.5.2. Le simulateur

    La conception du simulateur a été plus complexe que celle de l’éditeur du fait qu’elle devait intégrer la partie du moteur graphique mais aussi celle du modèle de propagation des sinistres. Pour permettre une certaine indépendance entre ces deux parties nous nous sommes servis d’un contrôleur. Le principe est simple, le contrôleur possède une trace de tous les éléments susceptibles de changer d’état, c’est à dire de prendre feu ou d’être détruit. A chaque fois que le modèle de propagation change l’état de l’un de ses agents, qui correspond à un et un seul élément graphique, il le signale au contrôleur qui le modifie en conséquence. Et quand un élément doit être affiché, le moteur interroge le contrôleur sur son état et s’adapte au résultat renvoyé.

    Seule la partie graphique sera détaillée ici. Pour de plus amples détails sur le modèle de propagation des sinistres, je vous invite à consulter le rapport de stage de Stéphane Laporte.

    Le seul acteur du simulateur est l’utilisateur qui se déplace dans le niveau. On aurait pu aussi y ajouter le modèle de propagation puisqu’il modifie les caractéristiques des éléments à afficher, mais du fait que c’est le simulateur qui interroge le contrôleur, il ne sera pas considéré comme étant un acteur.

    Le modèle a, comme pour l’éditeur, été décomposé en plusieurs parties :

  • Géométrie qui contient les classes points et quaternion qui permettent toutes les deux de gérer des positions et des directions

  • Elément qui contient tous les éléments qui peuvent être affiché.

  • MoteurParticule qui contient les classes permettant de générer un moteur à particule servant à représenter un incendie.

  • Rendu qui contient les classes nécessaires à l’impression de réalisme du simulateur : la caméra, les textures, les sons.

  • Interface3D qui contient la gestion de la fenêtre OpenGL et l’interface QT gérant les événements claviers et souris.

  • Les diagrammes de classes de la partie graphique du simulateur sont disponibles dans l’annexe 2.

    3.3. Le modèle de propagation

    Le modèle de propagation a été réalisé par Stéphane Laporte. Avant de poursuivre dans la description du simulateur, il est intéressant d’avoir une idée de ce modèle. Il est basé sur un système multi-agents. Un agent est une entité autonome ayant connaissance de son environnement, c’est à dire de chaque agent qu’il lui est voisin. Dans notre cas la liste des voisins est mise au point à la lecture du fichier stockant la carte du niveau.

    Chaque agent représente un élément du simulateur, c’est à dire, un mur, une salle ou une porte. Les objets contenus dans une salle ne sont pas des agents mais possèdent leur propres propriétés qui sont prises en compte pour évaluer l’état de l’agent représentant la salle. Chaque agent possède une liste de propriétés qui permettent de calculer son état. Les états actuels présents dans le simulateur sont normal, en feu, et consumé. Chaque propriété d’un agent représente une mesure physique (chaleur, oxygène). Quand son état évolue il donne une partie de cette quantité aux voisins qui peuvent la recevoir. Une salle plus froide qu’une autre ne peut pas lui transmettre de la chaleur. Les voisins mettent à jour leurs quantités et en transmettent à leurs propres voisins. Et ainsi de suite. Par exemple, chaque salle contient un volume d’oxygène. Si on ouvre une porte séparant deux salles adjacentes ayant chacune une pression différente, la salle ayant la pression la plus forte va donner une partie de son oxygène à l’autre permettant ainsi l’équilibrage des pressions.

    Ce système tourne constamment dès le lancement de l’application. A chaque fois que le simulateur veut afficher un élément, il interroge le contrôleur sur l’état de l’agent lui correspondant, et adapte l’affichage en fonction de la réponse obtenue.

    Pour plus d’explications sur ce modèle, vous pouvez vous rapporter au rapport de stage de Stéphane, stagiaire de DESS Génie Logiciel de l’Université de Bordeaux I.

    3.4. L’éditeur
    3.4.1. Principes

    L’éditeur de cartes permet à l’utilisateur de créer un niveau qui pourra être sauvegardé et ainsi être chargé dans le simulateur pour être visualisé dans un environnement en trois dimensions. Il est composé d’une fenêtre OpenGL intégré dans une interface QT. Plusieurs actions sont disponibles à partir de cette interface. Il y a d’abord les trois menus permettant de créer, de modifier et de supprimer les éléments du navire, et ensuite les possibilités d’interaction avec la carte.



    Figure 13 - Editeur de cartes

    3.4.1.1. Ajouts

    Pour éviter une confusion lors de la création de la carte, il est nécessaire de sélectionner un type d’élément à ajouter avant de pouvoir interagir avec la fenêtre OpenGL. Le menu ajout permet de :

  • Dessiner les contours du pont d’un navire

  • Insérer des cloisons

  • Insérer des portes ou des écoutilles

  • Créer des salles

  • Ajouter des éléments de décors

  • Définir l’emplacement des sinistres et leur type

  • Positionner le point de départ de l’utilisateur

  • Au lancement de l’application, seul l’ajout de contour est disponible, une fois celui-ci fermé, il devient alors possible d’y insérer des murs. Quand au moins un mur a été ajouté, l’ajout de portes et la création de salles est disponible. Après la création de la première salle, il est possible d’ajouter des objets, des sinistres, des écoutilles, ainsi que de définir la position de départ de l’utilisateur. A la création, chaque élément se voit attribuer des caractéristiques par défaut, elles sont disponibles via le menu modification.



    Figure 14 - Menu Ajout de l'éditeur

    3.4.1.2. Modifications

    Chaque élément possède ses propres caractéristiques, elles sont toutes modifiables dans l’éditeur à travers le menu modification. Pour les murs, portes et salles il s’agit de :

  • La température d’origine, correspondant à la température de l’élément au lancement de la simulation.

  • La température limite, correspondant à la température à partir de laquelle l’élément est susceptible de prendre feu.

  • La capacité thermique, correspondant à la quantité d’énergie que peut absorber l’élément avant qu’il ne soit entièrement consumé.

  • Des caractéristiques plus spécifiques sont définies pour certains éléments. Pour la porte, il existe la possibilité de préciser si elle est fermée ou ouverte au lancement de l’application. Pour les incendies, on peut modifier la température d’origine ainsi que l’instant de son déclenchement.

    Pour modifier un élément, l’utilisateur choisit le type de l’élément à modifier dans le menu, puis clique sur l’élément dans la fenêtre OpenGL, cela affiche une boite de dialogue permettant l’accès aux valeurs.



    Figure 15 - Menu Modification de l'éditeur



    Figure 16 - Exemple de modification : Modification d'une salle

    3.4.1.3. Suppressions

    Chaque élément ajouté au pont peur-être supprimé dans le cas où l’utilisateur ne serait pas satisfait de sa position.



    Figure 17 - Menu Suppression de l'éditeur

    3.4.1.4. Gestion des ponts

    Une zone est réservée à la gestion des ponts, il est possible d’en ajouter, d’en supprimer et de passer de l’un à l’autre. Des options d’affichage sont aussi disponibles pour permettre de faciliter la cohésion entre les ponts. Il est possible d’afficher les contours et les murs des ponts adjacents.



    Figure 18 - Gestion des ponts de l'éditeur

    3.4.1.5. Zoom et déplacements

    Pour permettre une meilleure gestion des éléments, il est possible de se déplacer sur la carte ainsi que d’y effectuer des zooms. Cela peut se révéler très utile lors de la création d’une carte relativement complexe et étendue. De plus ces interactions sont aussi disponibles via le pavé numérique du clavier.



    Figure 19 - Zoom et déplacements de l'éditeur

    3.4.1.6. Sauvegarde

    Pour permettre l’utilisation de la carte créée dans l’éditeur par le simulateur, il est nécessaire de pouvoir la sauvegarder. La solution retenue est d’utiliser un fichier au format texte dans lequel sont stockés tous les éléments de la carte avec leurs coordonnées et leurs caractéristiques.

    La manière retenue pour organiser les données dans le fichier est un système d’encapsulation. On liste les ponts, dans chaque pont, on stocke la liste des salles, pour chaque salle, on stocke la liste des murs et des objets, et pour chaque mur on stocke la liste des portes. Quand tous les ponts ont été listés, on inscrit la liste des sinistres et leurs caractéristiques, et enfin la position de la caméra et la direction dans laquelle elle est orientée.

    Un exemple de fichier de sauvegarde est disponible en Annexe 3.

    3.4.2. Algorithmes

    Dans cette partie je vais détailler quelques algorithmes développés dans le cadre de l’éditeur de cartes.

    3.4.2.1. Intérieur d'un polygone

    Pour éviter qu’un mur, une porte ou un objet ne soit placé à l’extérieur du navire, il a fallu implémenter un algorithme permettant d’indiquer si l’on se trouvait à l’intérieur d’un contour fermé ou non. A l’origine le contour du pont dans l’éditeur pouvait être quelconque, il était possible de créer des ponts en forme d’étoile par exemple. Ultérieurement, pour simplifier le développement d’autres parties de l’éditeur, il a décidé que dans un premier temps on se limiterait à des salles de formes rectangulaires. Toutefois cet algorithme a été implémenté avant cette décision, il fonctionne donc aussi bien avec des polygones convexes que concaves.

    Le principe est le suivant. On possède la liste des sommets formant le polygone et les coordonnées du point que l’on désire tester. Pour savoir si ce point est ou non à l’intérieur du polygone, on suit les étapes suivantes :

  • Test si le point est un sommet du polygone, cela évite un cas litigieux (1)

  • Calcul du nombre d’intersection existant entre le contour et une demi droite ayant pour origine le point à tester.

  • Test du nombre d’intersections, si le nombre est impair le point est à l’intérieur, s’il est pair, il est à l’extérieur, s’il est supérieur au nombre de segment formant le contour du polygone, c’est un cas litigieux (2).

  • (1) Si le point testé est un sommet du polygone, le nombre d’intersection avec le contour sera de deux, une pour chaque segment partant du sommet . Pour palier ce problème, il est nécessaire de vérifier au préalable si le point testé et oui ou non un sommet du contour.

    (2) Un autre problème peut être rencontré, il s’agit du cas où le point testé se situe dans le prolongement d’un segment appartenant au contour. Le nombre d’intersection est alors infini. Pour éviter ce problème, une solution est de compter le nombre d’intersection, si celui dépasse un seuil, on considère qu’il est impossible de déterminer la position du point, on relance alors l’algorithme en modifiant le coefficient directeur de la demi-droite issue du point à tester. Le seuil du nombre d’intersection autorisé peut être fixé au nombre de côté du contour.



    Figure 20 - Exemple de l'algorithme testant l'appartenance à un polygone

    3.4.3. Problèmes recontrés

    Comme il l’a été évoqué auparavant, dans la première version de l’éditeur de carte il était possible de créer des contours de n’importe quelle forme sans aucune restriction. Cela posait quelques problèmes notamment, il était en fait difficile de dessiner un long trait horizontal ou vertical, le moindre mouvement de la souris le faisant dévier. Pour palier à ce problème, les orientations des contours et des murs ont été restreintes. Il n’est désormais possible que de créer des contours horizontaux, verticaux où ayant un angle de plus ou moins 45°. Il ne s’agit toutefois que d’une solution provisoire, car la forme d’un navire n’est pas limitée à ces angles, les coques des bateaux , par exemple, suivent des courbes.

    3.4.4. Limitations de l'éditeur

    Actuellement la principale limitation de l’éditeur est la restriction des salles à des formes rectangulaires. De plus un seul type d’objet à été ajouté, il s’agit de la chaise. Enfin l’unique sinistre disponible est l’incendie.

    3.4.5. Améliorations possibles

    La première amélioration à apporter consiste à automatiser la création des salles. Actuellement pour créer une salle, il est nécessaire de cliquer sur chacun des murs la formant. Automatiser cette tache lorsque les salles sont obligatoirement de forme rectangulaire ne devrait pas être difficile. Le problème vient qu’il faudra lever cette limitation, et créer un algorithme permettant de définir toutes les salles quelques soit leur forme, en évitant que certaines en englobent de plus petites.

    Une autre amélioration serait la possibilité de pré-visualiser le navire en 3 dimensions et ainsi pouvoir mieux évaluer l’aspect final.

    Il pourrait aussi être utile de modifier le format du fichier de sauvegarde, il s’agit actuellement d’un fichier texte, il pourrait être passé dans un format tel que le xml. Cela implique, bien entendu, de modifier le système de chargement dans le simulateur.

    Enfin, il serait utile de permettre le choix des textures pour chaque mur. Pour cela, il est nécessaire de rajouter un champ dans les propriétés des murs pour y stocker le nom de fichier que l’on désire appliquer comme texture.

    D’autres améliorations sont envisageables, mais elle concerne autant l’éditeur que le simulateur, elles seront donc abordées ultérieurement dans une partie commune.

    3.5. Le simulateur
    3.5.1. Principes

    Le simulateur permet de générer un niveau en 3 dimensions à partir du chargement d’une carte préalablement créée à partir de l’éditeur. L’utilisateur peut ensuite se déplacer à l’aide de la souris et du clavier à l’intérieur du pont et ainsi observer la progression de l’incendie. Diverses informations sont disponibles à l’écran, il s’agit de la température de la pièce où se trouve la caméra, ainsi que du volume d’oxygène encore présent. On trouve aussi un pourcentage de vie, et une réserve d’oxygène en bouteille.



    Figure 21 - Vue du simulateur sans sinistre apparent

    3.5.1.1. Génération de niveau

    La génération de niveau n’a pas été traitée dans la partie conception, car c’est Stéphane Laporte qui s’en est occupé. Il a créé le système de chargement de fichier où il récupère les données nécessaire à l’élaboration des différents éléments, ensuite il les fait parvenir à un monteur graphique dans lequel j’ai implémenté des méthodes de création pour chaque type d’élément.

    Pour chaque salle :

  • Création de deux polygones, l’un pour former le sol l’autre le plafond

  • Création des murs de la salle. Pour chacun on connaît le point d’origine et le point final, on génère alors 4 polygones pour former leur contour. Les faces du dessus et de dessous ne sont pas créées car elles ne sont en aucun cas visible.

  • Gestion des murs contenant des portes. Pour permettre leur création, ils sont découpés en plusieurs pans. En fait, chaque mur contient la liste de ses portes, et donc leurs coordonnées, cela permet de facilement percer les murs pour pouvoir ensuite y insérer les portes. Dans ce cas, il faut rajouter un polygone au pan de mur surplombant l’ouverture de la porte pour que l’intérieur ne soit pas visible.

  • Génération des portes. De même que pour les murs, elles sont composées de 4 polygones.

  • Génération des objets de la salle.

  • Il faut toutefois noter quelques différences entre la génération des différents objets. Pour les salles, les polygones formant le sol et le plafond sont stockés dans une liste d’affichage, il en est de même pour les murs. Mais ce n’est pas le cas pour les portes et les objets. Il s’agit de formes qui sont tout le temps identiques. Par conséquent, à la génération du niveau une liste d’affichage est créée pour une porte, et une autre pour chaque type d’objet (pour l’instant uniquement la chaise) Ensuite quand il est nécessaire d’afficher une porte ou un objet, on appelle toujours la même liste d’affichage en se contentant d’y appliquer la bonne translation et les bonnes rotations pour les positionner correctement.

    3.5.1.2. Gestion de la caméra

    Une des parties les plus importantes dans un moteur graphique concerne la gestion de la caméra. Elle représente le champ de vision de l’utilisateur dans le simulateur. A terme, il devrait s’agir d’un casque de réalité virtuelle immergeant totalement la personne dans le navire.

    La caméra a été créée de manière à pouvoir facilement être réutilisée dans une autre application. Elle dispose de diverses fonctionnalités :

  • Avance : permet de translater la caméra dans le sens négatif de l’axe Oz, cela correspond à marcher vers l’avant.

  • Recule : permet de translater la caméra dans le sens positif de l’axe Oz, cela correspond à marcher à reculons.

  • Rotation_x : permet d’effectuer une rotation suivant l’axe Ox, cela correspond à un hochement de tête de haut en bas.

  • Rotation_y : permet d’effectuer une rotation suivant l’axe Oy, cela correspond à regarder de gauche à droite.

  • Rotation_z : permet d’effectuer une rotation suivant l’axe Oz, cela correspond à pencher la tête sur le côté comme pour regarder au coin d’un mur.

  • Retournement : permet d’effectuer une rotation de 180°, cela correspond à une volte face.

  • Monte : permet de translater la caméra dans le sens positif de l’axe Oy.

  • Descend : permet de translater la caméra dans le sens négatif de l’axe Oy.

  • Strafe_droite : permet de translater la caméra dans le sens positif de l’axe Ox, ce la correspond à un pas latéral vers la droite.

  • Strafe_gauche : permet de translater la caméra dans le sens négatif de l’axe Ox, cela correspond à un pas latéral vers la gauche.

  • A l’exception de Rotation_z toutes ces fonctionnalités sont accessibles à l’utilisateur par l’intermédiaire du clavier et de la souris : les rotations s’effectuent à l’aide de la souris, alors que les déplacements se font au clavier.

    Comme le montre la description des fonctionnalités, tous les mouvements se font par rapport à des axes fixes, ce qui implique que la caméra effectue ses rotations dans un repère local avant d’être translater pour se positionner dans le repère global.

    Il faut également noter que la méthode avance est en partie indépendante de l’orientation. On pourrait penser que le mouvement s’effectue suivant la direction de la caméra, mais ça ne serait pas réaliste pour la simulation d’une personne, donc la méthode avance ne modifie pas la position de la caméra par rapport à l’axe Oy, il faut pour cela appeler la méthode monte ou la méthode descend.

    3.5.1.3. Interactions entre l'utilisateur et le simulateur

    Pour utiliser le simulateur, l’utilisateur peut se servir du clavier et de la souris. Ces événements sont capturés via les méthodes existantes de QT.

    Les mouvements de la souris permettent d’effectuer des rotations de la caméra, simulant ainsi les mouvements de la tête. Pour ce faire, l’interface stocke les coordonnées de la souris (elles sont initialisées au centre de l’écran au lancement), puis on effectue la différence entre les coordonnées obtenues à la fin de l’événement et celle stockée. Ces valeurs permettent de passer les angles de rotation aux routines de la caméra qui effectue le mouvement.

    Le clavier permet de déplacer la caméra suivant les 3 axes. L’amplitude du déplacement est modifiable à l’aide de la molette de la souris, ce qui permet de passer d’un mouvement de course rapide à celui d’une marche.

    Le clavier sert aussi pour deux autres interactions, il s’agit de l’ouverture et la fermeture des portes à l’aide de la touche espace, et de l’activation ou désactivation de la bouteille d’oxygène à l’aide de la touche ‘O’.

    3.5.1.4. Sinistres

    Le but principal de ce simulateur est de pouvoir entraîner des équipes à la lutte contre les sinistres à bord de navires. Pour l’instant seul les incendies sont représentés, et l’on ne peut pour l’instant qu’observer leur progression.

    Pour permettre le rendu du sinistre deux outils sont utilisés. Le premier est un moteur à particules qui permet de visualiser une représentation des flammes, le deuxième permet de modifier les textures des éléments suivant leur état.

    Chaque élément possède 3 états :

  • normal
  • en feu
  • consummé
  • Le premier est l’état de base dans lequel se trouve tout élément au lancement du simulateur. Il passe au deuxième lorsque le modèle de propagation a atteint tous les conditions nécessaires, le sinistre est alors déclaré. Enfin quand toute la capacité thermique de l’élément a été absorbée par le sinistre, on atteint le troisième état.

    Chaque texture existe donc sous trois formes. A chaque changement d’état, la texture adéquate est appliquée à l’élément.

    Comme pour les textures, le moteur à particule existe sous trois formes, chacune d’elle permet de représenter l’incendie sur des éléments différents. Il existe un type de moteur pour les murs, un pour le plafond des salles, et un dernier pour le sol. Ces moteurs sont détaillés dans la partie algorithme plus loin dans ce chapitre.

    Vous trouverez en figure 19 une représentation d’une salle lorsqu’elle est en feu et en figure 20, quand elle est consumée, la figure 18 au 3.5.1 donnait un aperçu à l’état normal.



    Figure 22 - Vue du simulateur lors d'un incendie



    Figure 23 - Vue du simulateur après le passage d'un incendie

    3.5.2. Algorithmes
    3.5.2.1 Utilisation des quaternions

    L’utilisation d’une caméra sensé simulé le champ de vision d’une personne implique de posséder un maximum de liberté de mouvement, dont notamment des combinaisons de rotations. Le moyen le plus adapté pour calculer ces combinaisons consiste à utiliser des quaternions.

    Un quaternion est une extension des nombres complexes, qui au lieu de n’avoir que i comme partie imaginaire, possède i, j et k, ce qui nous donne comme écriture, pour un quaternion q : q = w + xi + yj +zkw, x, y, z sont des nombres réels et i, j, k des vecteurs formant un trièdre orthonormé direct. Le produit vérifie les lois habituelles des nombres sauf la commutativité

    On peut imaginer un quaternion unitaire comme une rotation en 4 dimensions où x, y et z sont les composantes suivant les 3 axes arbitraires et w l’angle de rotation. L’ensemble des quaternions unitaires forment une sphère unitaire dans un espace à 4 dimensions. Il est important de noter que seul les quaternions unitaires peuvent représenter une orientation. Il est donc nécessaire de toujours normaliser un nouveau quaternion.

    Le problème posé par l’utilisation de quaternions est qu’il est impossible de convertir un événement clavier ou souris directement en quaternion. Il est nécessaire de passer par un système intermédiaire ce qui implique une conversion entre les deux systèmes.

    Donc on récupère les événements souris sous forme d’angle en degrés et on convertit ces valeurs pour obtenir le résultat sous la forme d’un quaternion. A partir de ce quaternion, on peut calculer l’axe et l’angle de rotation à appliquer à la caméra.

    Les formules de conversion et de calculs sont disponibles en Annexe 4.

    3.5.2.2. Détections des collisions

    La détection des collisions est basé sur le type d’élément Salle. Cet élément possède la liste de ses murs, de ses portes et de ses objets. De plus la caméra est obligatoirement dans une salle. Le calcul des collisions est alors très simple. On calcule la distance séparant la caméra de chaque mur et on garde la plus petite. On a ainsi le mur le plus proche de la caméra. Ensuite on calcule la distance qui séparera la caméra de ce mur si le déplacement est fait, si cette distance est trop petite le mouvement n’est pas autorisé.

    Le problème à ce niveau, c’est que les portes sont sur le même axe que les murs et que donc, même si elles sont ouvertes une collision sera trouvée avec le mur, et le franchissement impossible. Donc avant d’interdire un mouvement, on vérifie si le mur le plus proche possède des portes, si c’est le cas, on vérifie si certaines sont ouvertes et si oui on vérifie si le déplacement que l’on veut effectuer intersecte la porte ouverte la plus proche de la caméra, si c’est le cas le déplacement est autorisé, sinon il est impossible.

    Toutefois la gestion des collisions avec les objets n’est pas gérée par cette méthode.

    3.5.2.3. Elimination des faces cachées

    L’élimination des faces cachées se décomposent en deux parties : la première est l’utilisation des routines OpenGL dédiées à cette tache, le deuxième est l’implémentation d’un système propre au simulateur permettant de réduire le nombre de calculs.

    La première routine d’OpenGL qui est utilisée est glCullFace(), elle permet dans ce simulateur d’éliminer les faces arrières des polygones, ensuite, le test de profondeur du Z-buffer est activé, enfin l’utilisation de la routine gluPerspective()permet de définir un volume visualisé, OpenGL se chargeant d’éliminer tous les polygones ne se trouvant pas à l’intérieur.

    La première étape du système directement implémenté dans le simulateur consiste à n’afficher que la salle où se trouve la caméra. Cela évite tous les calculs nécessaires aux autres salles, notamment si celles-ci sont en feu, et contiennent plusieurs centaines de particules. Cette méthode est très efficace, car il n’y a plus que quelques dizaines de polygones à afficher, mais elle pose un problème. Si une porte est ouverte, la salle de l’autre côté n’est pas affichée, et l’on voit la couleur de fond.

    Pour pallier à ce problème plusieurs solutions ont été envisagées, la première consiste à afficher en plus toutes les salles adjacentes à celle contenant la caméra. Mais cela ne résout pas le problème, car il est tout à fait envisageable d’avoir une succession de salles avec des portes ouvertes alignées. Donc la salle se situant derrière la porte serait bien été affichée, mais pas les suivantes.

    Une deuxième solution consiste à prendre une « photo » de la salle se trouvant derrière la porte et de la stockée, si la porte est ouverte, on applique cette photo comme texture, on a donc l’impression de voir la salle adjacente. Cette solution posait encore plus de problème, du fait qu’une salle peut être normale, en feu ou consumée, il aurait donc fallut stocker plusieurs images, et cela ne résout pas le problème de la première solution.

    Illustration des problèmes

    La caméra se situe en salle 3, elle est représentée par la flèche bleue, les portes sont représentées en rouge si elles sont fermées, en vert si elles sont ouvertes.

    En affichant que la salle où se trouve la caméra, on afficherait que la salle 3 alors que la salle 2 est visible par la caméra, à la place on verrait du noir.

    Si on affichait toutes salles adjacentes, on afficherait les salles 2, 5 et 8, or seule la 2 est visible, ce qui impliquerait des calculs inutiles pour les deux autres salles. De plus par prolongement de la ligne de vue, la salle 1 est elle aussi visible à partir de la 3 mais elle n’est pas affichée.



    Figure 24 - Affichage des salles visibles

    Une autre solution a alors été envisagée, il s’agissait d’effectuer une recherche récursive des salles visibles par la caméra. On connaît la salle où se trouve la caméra et les portes ouvertes visibles par la caméra.

  • On commence par stocker dans une liste la porte par laquelle on voit une autre salle, on la nomme liste_porte_ouverte.

  • Ensuite on recherche la salle qui se trouve de l’autre côté de la porte.

  • On lance alors l’algorithme sur toutes les portes de la salle. Il recherche toutes les portes ouvertes. Pour chacune d’elle on teste si elle est visible par la caméra. Pour cela il faut que le segment reliant le centre de la porte et la caméra intersecte toutes les portes stockées dans liste_porte_ouverte, si c’est le cas, on crée une nouvelle liste de porte qui est une copie de liste_porte_ouverte et on y ajoute la porte.

  • On recherche la salle se trouvant de l’autre côté de la porte ajoutée.

  • On relance l’algorithme avec en paramètre cette nouvelle salle, et la nouvelle liste de porte.

  • Cet algorithme est récursif et ne s’arrête que quand il ne trouve plus de porte visible par la caméra. Grâce à ce système seul les salles visibles par la caméra sont affichées.

    3.5.2.4. Moteur à particules

    Pour permettre le rendu des incendies, un moteur à particules a été intégré au simulateur. Ce moteur a été décliné en trois versions, l’une pour donner un rendu sur un mur, une autre pour le donner sur un sol et la dernière pour le donner sur un plafond. Mais avant de créer un moteur à particules, il faut déjà créer les particules.

    3.5.2.4.1. Particules

    Il y a deux parties à détailler dans les particules, il s’agit de leur composition et de leur rendu. Une particule possède plusieurs attributs pour pouvoir avoir un comportement réaliste :

  • sa date de naissance qui permet de calculer son âge à chaque évolution et de le comparer à sa durée de vie

  • sa durée de vie qui indique quand elle sera supprimée

  • sa position d’origine

  • sa masse qui permet d’estimer l’application des forces quelle subit

  • sa position qui permet de calculer son évolution et de la restreindre à un espace

  • sa couleur qui évolue selon son âge

  • sa taille qui évolue aussi selon son âge

  • le cumul des forces qui lui sont appliquées qui permet de calculer son déplacement

  • Toutes ces données sont nécessaires pour espérer obtenir un comportement réaliste. De plus elles sont amenées à évoluer au cours du temps suivant le moteur auquel elle appartient.

    Le rendu d’une particule est quelque peu compliqué, étant donné son nom on pourrait penser qu’il s’agit d’une sphère, mais ce n’est pas le cas, cela demanderait trop de ressources quand on doit afficher plusieurs centaines de particules, voir plusieurs milliers. En fait une particule est un plan sur lequel est appliqué une texture (figure suivante)



    Figure 25 - Texture d'une particule

    On lui applique ensuite une couleur variant entre le rouge et le blanc en passant par l’orange et le jaune. Puis on modifie son canal alpha pour quelle soit plus ou moins transparentes ce qui joue sur son intensité. Il reste toutefois le problème qu’il s’agit d’un plan et que donc, elle ne devrait être visible que d’un seul côté. Pour cela on utilise la technique du billboarding qui permet de calculer un plan qui est toujours parallèle à celui au plan formé par la caméra, et qui est toujours à la même distance de celle-ci. Il suffit alors de redimensionner ce plan à la taille que l’on désire donner à la particule et à le placer à la position de celle-ci. De cette manière quelque soit l’endroit d’où on regarde on a l’impression de faire face à la particule.

    3.5.2.4.2. Moteur à particules

    Pour permette des évolutions différentes sans avoir à effectuer des tests dans la fonction de rendu du moteur, trois déclinaisons ont été créées, une pour les murs, une pour les sols et une pour les plafonds. Ils sont tous trois très similaires. Les différences se situent au niveau de la taille des particules, de leur nombre, de leur couleur et bien sur au niveau de leur évolution.

    Chaque moteur possède ses propres contraintes au niveau des particules, notamment sur leur espace de vie et leur évolution. Dans le cas d’un sol, les particules naissent à sa proximité, subissent une force principalement verticale mais sont limitées au contour de la pièce, si elles le dépassent, elles sont détruites puis régénérées à une position autorisée. De plus, à chaque calcul de position, leur hauteur est testée, et suivant un tirage aléatoire de plus en plus strict elles sont supprimées pour réapparaître au niveau du sol ce qui permet d’en réduire le nombre en fonction de l’axe y, de la même manière leur taille diminue, ainsi que leur couleur qui tend vers le blanc tout en augmentant leur transparence. Pour les murs, l’évolution est quasi identique à celles des sols, c’est seulement le volume dans lequel les particules peuvent évoluer qui est plus restreint. Le plus différent est le moteur du plafond, l’évolution des particules y est dirigée horizontalement et les particules sont restreintes à un très faible espace de mouvement, c’est le plus difficile à réaliser et le résultat n’est pas encore celui escompté.

    3.5.3. Problèmes rencontrés

    Le premier problème rencontré fut sur les moteurs à particule, il n’est pas facile d’obtenir un rendu réaliste. Il a fallu influer sur la taille, la couleur et les forces des particules pour obtenir un effet. Toutefois il est encore possible d’y apporter de nombreuses améliorations.

    Un autre problème concerne la communication avec le contrôleur qui permet de connaître l’état de chaque élément. De façon qui semble aléatoire, les valeurs du volume d’oxygène et la température ne sont plus mises à jour, donc l’état ne change pas, et l’on peut obtenir des incendies qui ne s’éteignent jamais.

    3.5.4. Limitations du simulateur

    Une limitation quelque peu gênante du simulateur concerne les événements claviers, il ne peut en capturer qu’un seul à la fois, ce qui empêche les combinaisons de touches. Cela rend impossible certains mouvements comme le fait d’avancer tout en effectuant un mouvement latéral.

    Une autre limitation voyante est le manque d’objets pour rendre le décor plus vraisemblable.

    Il y a aussi le fait que les collisions ne soit gérées qu’envers les murs et les portes, il est tout à fait possible de traverser les objets du décor.

    Enfin, il y a aussi le problème, que pour l’instant, il n’est pas possible de changer de pont. Ils sont bien affichés les uns sur les autres, les trous correspondant aux écoutilles apparaissent, mais les échelles ne sont pas gérées. Pour passer d’un niveau à un autre, il faut « voler ».

    3.5.5. Améliorations possibles

    Les améliorations possibles sont nombreuses. Tout d’abord il et nécessaire d’étendre la détection des collisions aux objets, pour cela il faut définir une boite englobante de chaque type d’objets et de tester sa proximité avec la caméra. Ensuite, toujours en ce qui concerne les objets, il serait intéressant d’intégrer un loader d’objets 3DS. Les objets ainsi créés avec un modeleur seront plus réalistes, et cette méthode est bien plus rapide que de devoir dessiner à l’aide des méthodes OpenGL chaque type d’objet. De plus de nombreux objets existent déjà et sont disponibles sur Internet. L’intégration de ce loader apporte donc une autre amélioration : la possibilité d’avoir de nombreux types d’objets disponibles pour rendre le simulateur plus réaliste.

    En ce qui concerne les textures, pour l’instant, chaque type d’élément en possède 3 qui correspondent à chaque état possible. Il serait plus réaliste d’intégrer un système permettant de les faire évoluer dynamiquement, par exemple quelles noircissent au fur et à mesure de la propagation de l’incendie. Pour cela, on pourrait utiliser du multi-texturing et permettre de modifier une partie de la texture. L’idée serait d’avoir la texture correspondant à l’état normal, et suivant le changement d’état de l’élément, de lui appliquer une deuxième texture spécifique à cet état. Par exemple, on aurait une texture de bois, une autre de métal, et si l’élément prend feu, on applique par dessus ces textures, une texture de flamme possédant un niveau de transparence.

    Pour les moteurs à particules, 3 améliorations seraient souhaitables. En premier lieu il faudrait améliorer l’évolution des particules pour obtenir un effet plus réaliste. On peut imaginer des flammes qui lèchent les murs ou le plafond. Dans le même ordre d’idée, c’est directement le rendu des particules qui seraient à améliorer pour obtenir des formes toujours plus conformes à la réalité. Enfin c’est la propagation du feu à l’intérieur même des salles qui seraient à améliorer. Pour l’instant une salle est en feu ou ne l’est pas. Il serait plus intéressant de déclencher le feu à un endroit précis de la pièce et qu’il s’étende au fil du temps. Toutefois cela implique aussi des modifications au niveau du modèle de propagation, notamment de connaître le point d’origine du sinistre dans une salle, ce qui n’est pour l’instant pas possible, et aussi de gérer le temps de vie de l’incendie d’en une pièce de façon à y connaître son ampleur.

    Une dernière amélioration pour les moteurs à particule serait d’intégrer la gestion d’événement comme les retours de flammes, mais cela nécessite une étude pour savoir quand cela peut se produire et comment.

    Il serait aussi plus réaliste d’intégrer un effet de fumée qui gênerait la vue de l’utilisateur mais aussi sur sa santé, puisque l’un des plus gros danger dans le feu d’un navire concerne les fumées toxiques.

    Toujours dans un soucis de réalisme, la gestion des effets sonores apporterait un grand plus. Quelques sons sont déjà présents comme un bruit de respiration lors de l’utilisation de la bouteille d’oxygène, ou un bruit de douleur lorsque l’utilisateur se situe dans un environnement hostile. Toutefois leur gestion n’est pas au point, c’est en partie du à QT qui ne permet, par exemple, pas de jouer plusieurs sons en même temps.

    Enfin, on pourrait ajouter de nouvelles possibilités de mouvements comme le saut par exemple, ou encore pouvoir se pencher sur le côté.

    La dernière amélioration à apporter est très certainement la plus importante, il s’agit de pouvoir éteindre un incendie à l’aide soit d’une lance que porterait l’utilisateur, soit d’un système automatique de lutte contre les incendies qui serait dans la salle.

    Sommaire       Travail réalisé       Bilan