From 1da915d263ff4ac80b3fde83f3e2b0a04de1acde Mon Sep 17 00:00:00 2001 From: Thomas FORGIONE Date: Mon, 7 Sep 2015 17:10:40 +0200 Subject: [PATCH] Commit --- rapport/rapport.tex | 573 ++------------------------------------------ 1 file changed, 21 insertions(+), 552 deletions(-) diff --git a/rapport/rapport.tex b/rapport/rapport.tex index 5a80e28..5fbb1f8 100644 --- a/rapport/rapport.tex +++ b/rapport/rapport.tex @@ -1,5 +1,5 @@ \documentclass{scrartcl} -\usepackage[utf8x]{inputenc} +\usepackage{import} \usepackage[frenchb]{babel} \usepackage{amssymb} \usepackage{lmodern} @@ -9,7 +9,12 @@ \usepackage{graphicx} \usepackage{amsmath} \usepackage{multicol} -\usepackage[hidelinks]{hyperref} +% \usepackage[hidelinks]{hyperref} +\usepackage[colorlinks = true, + linkcolor = blue, + urlcolor = blue, + citecolor = blue, +anchorcolor = blue]{hyperref} \usepackage{cpp} \usepackage{tikz} \usepackage{pgfplots} @@ -45,8 +50,10 @@ \newcommand{\hsc}[1]{{\Large\MakeUppercase{#1}}} \newcommand{\hscs}[1]{{\footnotesize\MakeUppercase{#1}}} -\newcommand{\threejs}{\href{http://threejs.org/}{Three.js}} -\newcommand{\socketio}{\href{http://socket.io/}{Socket.IO}} +\newcommand{\threejs}{\href{http://threejs.org/}{Three.js }} +\newcommand{\socketio}{\href{http://socket.io/}{Socket.IO }} +\newcommand{\jsdoc}{\href{http://usejsdoc.org/}{JSDoc }} +\renewcommand{\include}[1]{\import{./}{#1.tex}} \newcommand{\namedparagraph}[1]{\paragraph{#1}\mbox{}\\} @@ -55,6 +62,10 @@ \draw (#1,-6) node[below]{#2}; } +\makeatletter +\@addtoreset{section}{part} +\makeatother + \begin{document} \begin{titlepage} @@ -102,563 +113,21 @@ \newpage -\part*{Introduction} +\include{intro} \newpage -\part{Choix des technologies et prise en main} -\paragraph{} -La première phase de stage était de choisir les technologies qui allaient être -utilisées par la suite. Nous cherchions des technologies permettant la -visualisation 3D sur un navigateur web afin de pouvoir faire une étude -utilisateur simplement. - -\section{Côté client} -\paragraph{} -Pour le côté client, il y avait plusieurs possibilités : -\begin{itemize} - \item WebGL, la spécification des fonctions permettant la 3D dans le - navigateur - \item Une librairie facilitant l'utilisation de WebGL - \item Du code C++ compilé en JavaScript grâce à Emscripten - \item N'importe quel moteur graphique qui puisse exporter vers JavaScript -\end{itemize} - -\paragraph{} -La plupart des moteurs graphiques exportant vers JavaScript sont putôt lourd à -prendre en main, et nous voulions garder des solutions simples, c'est pourquoi -nous avons utilisé une librairie libre nommée \threejs permettant une -utilisation facile de WebGL. - -\paragraph{} -Pour des raisons de simplicité, nous avons décidé de développer le code client -pour Google Chrome et Firefox, les autres navigateurs ne sont donc pas -(officiellement) supportés. - -\section{Côté serveur} -\paragraph{} -Dans un premier temps, seul le côté client était pris en compte. Les programmes -étaient écrits en JavaScript et ne nécessitaient pas de serveur. Quand les -problématiques de dynamicité sont arrivées, il a fallu choisir une technologie -pour le côté serveur, et là, tous les langages étaient possibles. - -\paragraph{} -Plusieurs langages et framework ont été téstés. Quand les problématiques -étaient encore simples (passage d'un paramètre dans une requête), on a commencé -par utiliser le php, puis on s'est tourné vers des scripts CGI en python. Quand -de plus nombreuses pages ont été nécessaires, on a commencé à chercher un vrai -framework, et on s'est penché sur Django (framework web pour Python) qui est -très pratique mais assez coûteux en mémoire vive (le serveur était alors -herbergé sur une petite machine de 512Mo de RAM). - -\paragraph{} -Quand les problématiques de streaming ont commencé à apparaître, nous avons -choisi la simplicité en utilisant Node.js pour le côté serveur (un serveur -écrit en JavaScript) à cause de la présence d'une librairie nommée \socketio -qui s'avère très pratique pour la communication entre le client et le serveur. -Pour des raisons pratiques, le serveur a été herbergé sur un cloud gratuit -(OpenShift). - -\section{Base de données} -\paragraph{} -Pour le système de gestion de base de données, nous avons choisi Postgres (qui -est libre et qui a largement fait ses preuves). OpenShift propose d'héberger -lui-même la base de données, mais la version gratuite ne proposant qu'1 Go -d'espace de stockage, nous avons préféré l'héberger nous-même. - - -\section{Développement, debug et déploiement} -\paragraph{} -Pour éviter d'avoir des fichiers trop longs, nous avons choisi de séparer les -sources dans de nombreux fichiers de taille plus petite, et de les fusionner -automatiquement. Pour le développement, ils seront simplement concaténés grâce -à un script développé spécialement pour cela, qui mime les paramètres de -Closure Compiler qui sera utilisé pour la fusion au moment du le déploiement -(ce dernier permet non seulement la fusion des fichiers mais aussi la -minification\footnote{la minification sert notamment à réduire la taille du -script : n'oublions pas que nous parlons de serveur web, et il est donc -intéressant de réduire la taille des programmes de sorte à les charger plus -rapidement} (effacement des commentaires et des retours à la ligne, -simplifications des noms de variables et plus \footnote{en JavaScript, il est -plus court d'écrire \texttt{!0} pour \texttt{true} par exemple.}). Pour le -développement, on a utilisé \href{https://github.com/remy/nodemon}{nodemon} et -inotify, qui permettent de relancer le serveur local lorsqu'une modification -est détectée (la fusion des fichiers est donc réeffectuée). - -\paragraph{} -En ce qui concerne le versionnage des fichiers, nous avons utilisé Git avec -deux \emph{repositories} : -\begin{itemize} - \item le premier, hébergé sur - \href{https://github.com/tforgione/3dinterface}{Github}, sert au - développement, et contient les fichiers fractionnés ainsi que les - outils permettant la génération des fichiers fusionnés. - \item le deuxième, hebergé chez OpenShift, qui contient la version finale - du programme, permet de déployer le code du serveur quand les - \emph{commits} sont \emph{pushés}. -\end{itemize} - -\paragraph{} -Pour nous aider au debug, nous avons utilisé \href{http://jshint.com/}{JSHint} -qui nous aide à détecter les erreurs potentielles liées aux subtilités du -langage. - +\include{techno} \newpage -\part{L'interface} -\section{Interactions élémentaires} -\paragraph{} -La première interface a été pensée pour être la plus simple possible. -L'utilisateur contrôle une caméra qui se déplace librement dans un modèle 3D. - -\paragraph{} -La translation de la caméra est contrôlée par le clavier : les touches Z, Q, S, -et D servent respectivement à avancer, aller à gauche, reculer et aller à -droite (de même que les touches fléchées). - -\paragraph{} -On peut pivoter la caméra de plusieurs manières : -\begin{itemize} - \item via le pavé numérique (2, 4, 6, et 8 pour tourner respectivement vers - le bas, vers la gauche, vers la droite et vers le haut) - \item via la souris, comme \emph{drag-n-drop}, en cliquant un point de la - scène et en le déplaçant - \item via la souris, en mode \emph{pointer-lock}, comme dans un jeu video - de tir -\end{itemize} - - -\section{Les recommandations} -\paragraph{} -Les recommandations sont là pour suggérer des points de vue à l'utilisateur. -Elles permettent d'aider la navigation. Elles sont affichées sous forme -d'objets 3D ajoutés à la scène. Deux affichages ont été testés. - - -\subsection{Les \emph{viewports}} -\paragraph{} -Les \emph{viewports} sont les affichages les plus simples : ils représentent -une caméra, avec son centre optique et son plan image. -\begin{figure}[H] - \centering - \includegraphics[scale=0.275]{img/new/01.png} - \caption{Une recommandation \emph{viewport}} -\end{figure} -Cette façon d'afficher une recommandation a l'avantage d'être simple, de ne pas -beaucoup masquer le reste des modèles et suggère assez bien l'idée d'un -\emph{point de vue recommandé}, mais elle a l'inconvéniant d'être ambigüe à -cause de la perspective (dans cette image, il peut être difficile de savoir si -le point de vue et vers le modèle ou vers nous). - - -\subsection{Les flèches} -\paragraph{} -Les flèches sont supposées être plus intuitives pour un utilisateur qui n'a pas -l'habitude des \emph{viewports} précédemment utilisés. Plutôt que de suggérer -un point de vue, elles suggèrent le mouvemement qui va mener à ce point de vue. -\begin{figure}[H] - \centering - \includegraphics[scale=0.275]{img/new/02.png} - \caption{Des recommandations flèches} -\end{figure} - -\subsection{Les interactions} -\subsubsection{Au survol} -\indent Cette fonctionnalité est inspirée des récents lecteurs video sur le -web. Lorsque l'on regarde une video, on a la barre de \emph{seeking} en bas et -passer le curseur sur cette barre affiche l'image de la vidéo à l'instant visé. -Nous avons simplement adapté cette techniques à nos recommandations : lorsque -le curseur survole une recommandation, une prévisualisation est affichée dans -une petite boite au voisinage du curseur. - -\begin{figure}[H] \centering - \includegraphics[scale=0.275]{img/new/03.png} - \caption{Une prévisualisation} -\end{figure} - -\subsubsection{Au clic} -\indent Lors d'un clic sur une recommandation, la caméra suit un mouvement -fluide jusqu'au point de vue recommandé. La trajectoire est définié par un -polynôme interpolant tel que : -\begin{itemize} - \item la position initiale est la position de la caméra - \item la position finale est la position de la recommandation - \item la dérivée de la trajectoire à l'instant final est la direction de la - recommandation -\end{itemize} - -\paragraph{} -Ce mouvement fluide est là pour ne pas perturber l'utilisateur qui pourrait -\emph{se perde} si jamais il était téléporté - -\paragraph{} -De plus, les recommandations se comportent comme des liens hypertextes : elles -sont bleues si elles n'ont jamais été clicées, et deviennent violettes si -l'utilisateur les a déjà consommées. Ceci est fait pour qu'un utilisateur -puisse savoir par où il est passé, et ce qui lui reste encore à visiter. - - -\section{Autres éléments de navigation} -\paragraph{} -Pour faciliter la navigation, quelques autres éléments de navigation sont -présents. - -\begin{figure}[H] - \centering - \begin{tikzpicture}[] - \node (myfirstpic) at (0,0) {\includegraphics[scale=0.35]{img/new/buttons.png}}; - \tikzvline{-7}{1} - \tikzvline{-5.8}{2} - \tikzvline{-5.2}{3} - \tikzvline{-4}{4} - \tikzvline{-1.5}{5} - - \draw (8,5) -- (7,5); - \draw (8,5) node[right]{6}; - - \draw (-8,5) -- (-7,5); - \draw (-8,5) node[left]{7}; - \end{tikzpicture} - \caption{Les différents éléments de l'interface} -\end{figure} +\include{interface} \newpage -\paragraph{} -\begin{enumerate} - - \item \emph{Reset camera} : pour chaque scène, une position initiale est - définie. Cliquer sur ce bouton ramène la caméra à sa position initiale. - - \item \emph{Previous} : à chaque clic sur une recommandation, les positions - intiales et finales sont sauvegardées. Cliquer sur ce bouton ramène à - la position précédente. - - \item \emph{Next} : cliquer sur ce bouton ramène à la position suivante. - - \item \emph{Pointer lock} : permet de passer du mode \emph{pointer-lock} au - mode \emph{drag-n-drop} et vice-versa. - - \item \emph{Music} : un lecteur qui contrôle une petite musique qui permet - de se mettre dans l'ambiance de la scène. - - \item \emph{Coin gauge} : une jauge qui représente l'avancement de la - récupération des pièces. - - \item \emph{FPS counter} : indique la période de rafraîchissement du rendu. - -\end{enumerate} - +\include{userstudy} \newpage -\part{L'étude utilisateur} -\paragraph{} -Pour tester le comportement des utilisateurs face aux recommandations, nous -avons dissimulé des pièces rouges à travers ces modèles, et nous avons demandé -à des utilisateurs de les trouver. -\begin{figure}[H] - \centering - \includegraphics[scale=0.275]{img/new/04.png} - \caption{Une pièce rouge} -\end{figure} - -\paragraph{} -Pour éviter la dépendance entre les recomendations et les pièces rouges (si les -recommandations visent les pièces rouges, il est évident qu'il sera très facile -de les trouver avec les recommandations), un système de tirage aléatoire de -pièces rouges a été fait. - -\section{Déroulement de l'expérience} -\subsection{Première page} -La première page présente rapidement l'expérience. Elle vérifie aussi le -navigateur : si le client est sur Google Chrome ou Firefox, un lien apparaîtra -pour passer à la suite, sinon, un message d'erreur s'affichera. - -\subsection{Identification} -Cette page nous permet d'en savoir un peu plus sur l'utilisateur : nous allons -demander l'age, le sexe et les habitudes en terme de jeux video de -l'utilisateur (nous avons considéré que la capacité des utilisateurs à manier -notre interface allait dépendre fortement de leur habitude aux jeux video). -Nous leur demandons notamment de noter leurs capacités en terme de jeux videos -(entre 1 et 5 étoiles). - -\subsection{Tutoriel} -Ensuite, nous demandons à l'utilisateur de suivre un tutoriel : c'est une sorte -de réelle expérience mais guidée. Des messages indiquant les interactions à -faire aideront l'utilisateur à s'habituer à cette interface. On y présente les -moyens de déplacer la caméra, puis les recommandations et les différents -boutons de l'interface. - - -\subsection{Les trois vraies expériences} -C'est ensuite que la \emph{vraie} partie de l'étude utilisateur commence : à 3 -reprises, l'utilisateur va se retrouver dans une scène avec certaines pièces -rouges à trouver, et un certain style de recommandations\footnote{aucune -recommandation sera considéré comme un style de recommandation, de sorte à -comparer la présence à l'absence de recommandation pour la navigation} pour -l'aider. Nous expliquerons dans la sous-section \ref{selection} comment le -choix de la scène et du style de recommandation sera fait. - -\paragraph{} -Dans chacune des expériences, l'utilisateur devra chercher des pièces rouges, -en s'aidant (ou pas) des recommandations. L'expérience se terminera soit quand -l'utilisateur aura trouvé les huit pièces rouges, soit une minute après avoir -trouvé la 6\up{ème} pièce rouge. Pour éviter que l'utilisateur soit -\emph{frustré} de ne pas avoir trouvé toutes les pièces, nous n'indiquons pas -clairement le nombre de pièces qu'il a, ou qu'il lui reste à trouver. -Simplement, une \emph{vague} idée de sa progression. - -\subsection{Le \emph{feedback}} -Après avoir fini ces expériences, l'utilisateur se retrouvera sur un formulaire -lui demandant son avis quand à la difficulté de l'interface, et l'utilité des -recommandations pour se déplacer dans la scène. - -\section{Choix de la scène et du style de recommandations\label{selection}} -\paragraph{} -Il y a trois scènes disponibles, et sur chaque scène, nous avons placé des -pièces dans de nombreuses positions. Lorsqu'un utilisateur commence une -expérience, l'algorithme de selection fonctionne de façon à faire des -expériences sur les mêmes scènes avec les mêmes dispositions de pièces mais des -styles de recommandations différents pour des utilisateurs de même niveau de -sorte à pouvoir comparer l'efficacité des recommandations. - -\paragraph{} -Nous cherchons en fait des expériences qui permettraient de compléter les trio -d'expériences avec des pièces identiques sur des scènes identiques mais avec -des styles de recomendations différents. Si une telle expérience n'existe pas -(les trios sont déjà complets, ou bien il n'existe pas d'expérience pour un -niveau d'utilisateur donné), la scène, ainsi que les pièces à trouver et le -style de recommandations seront choisi aléatoirement : on choisira une scène et -un style de recommandations que l'utilisateur n'a pas encore effectué, et on -choisira 8 pièces aléatoirement parmi les positions possibles que nous avons -fixées au préalable. - -\section{Positions possibles des pièces} -Pour choisir les positions possibles des pièces dans chaque scène, un petit -outil à été développé permettant de se déplacer dans une scène et des créer des -pièces en cliquant. Cliquer sur une paroie de la scène crée une pièce devant -cette paroie, et cliquer sur une pièce la supprime. Un bouton permet d'envoyer -la liste des pièces par mail, lorsque l'on a fini de créer des pièces. - +\include{streaming} \newpage -\part{Streaming de modèle 3D} -Le but ultime de ce projet est de biaiser l'utilisateur avec les -recommandations de sorte à être capable de prévoir ses déplacements futurs, et -ainsi précharger les parties du modèle qui vont être vues. Cette section -présente le travail qui a été réalisé dans le domaine du chargement de modèle. -\paragraph{} -Évidemment, cette partie est celle qui comment après la fin de la première -partie : il faut nous seulement connaître l'influence des recommandations sur -l'utilisateur, ensuite être capable de prévoir le comportement de -l'utilisateur, et enfin s'en servir pour précharger les bonnes parties du -modèles. Tout ceci n'étant pas encore possible, le travail qui a été fait est -nettement plus simpliste : il n'y aura aucune prévision du comportement ici. - -\section*{Introduction} -Notre problématique ici est de transférer des modèles 3D sur le réseau. Les -modèles sont stockés sur le serveur au format \texttt{.obj} et sont constitués -: -\begin{itemize} - \item des materiaux (\texttt{usemtl}) : cela définit le matériau utilisé - pour les faces qui vont suivre - \item de sommets (\emph{vertices}) : des points 3D - \item de coordonnées de textures : des points en 2D qui référence un point - d'une image - \item de normales : des vecteurs en 3D - \item de faces : une liste de 3 ou 4 sommets (représentés par leurs - indices), avec éventuellement leurs coordonnées de textures et/ou - normales -\end{itemize} - -\paragraph{} -La seule contrainte d'ordre des éléments est qu'une face qui contient des -sommets, coordonnées de textures ou normales n'arrive pas avant ses sommets, -coordonnées de textures ou normales dans le fichier : si l'on parcourt les -lignes du fichier, on doit déjà avoir toutes les informations sur la face. - -\paragraph{} -Généralement, le fichier \texttt{.obj} vient souvent avec un fichier -\texttt{.mtl} qui contient la définition des matériaux (leurs noms, leurs -textures, leurs constantes...). - -\newpage -\section{Streaming linéaire} -La première étape de cette fonctionnalité a été de faire un système -client-serveur permettant le streaming de modèle 3D. En effet, les -\emph{loaders} de modèles présents dans la libraire \threejs ne permettent pas -le chargement progressif : ils se content d'envoyer une requête vers le fichier -contenant le modèle et à créer un modèle une fois que le fichier est chargé -complètement. - -\paragraph{} -Pour commencer, nous avons donc utilisé \socketio, une librairie permettant de -gérer les sockets facilement avec JavaScript et Nodejs, pour faire une première -version simpliste du streaming : on travaillait sur un modèle ne contenant que -des sommets et des faces (donc pas de textures ni de normales) et le protocole -fonctionnait ainsi : - -\begin{figure}[H] - \centering - \begin{tikzpicture}[] - \draw (0,0) node[above]{Client}; - \draw (0,0) -- (0,-6); - \draw (5,0) node[above]{Serveur}; - \draw (5,0) -- (5,-6); - - \draw (2.5,-1.3) node[rotate=-12] {Path jusqu'au modèle}; - \draw[->] (0,-1) -- (5, -2); - - \draw (2.5,-2.3) node[rotate=12] {Des éléments}; - \draw[<-] (0,-3) -- (5, -2); - - \draw (2.5,-3.3) node[rotate=-12] {ACK}; - \draw[->] (0,-3) -- (5, -4); - - \draw (2.5,-4.3) node[rotate=12] {D'autres éléments}; - \draw[<-] (0,-5) -- (5, -4); - - \draw (2.5,-6) node{$\vdots$}; - \end{tikzpicture} - \caption{Transmission élémentaire\label{transmission1}} -\end{figure} - -\paragraph{} -Le serveur envoyait alors les éléments dans l'ordre dans lequel ils étaient -présents dans le fichier du modèle 3D. Le gros inconvéniant de cette méthode -est que souvent, les sommets sont présents au début du fichier, et les faces -vers la fin : nous recevons donc des informations de sommets au début qui ne -nous permettent rien d'afficher, puis toutes les faces d'un coup, ce qui fait -que le streaming n'est pas aussi progressif que l'on souhaiterais. - -\paragraph{} -Dans le cas d'un modèle sans coordonnées de textures et sans normales, la seule -condition pour pouvoir afficher une face est d'avoir envoyé les sommets qui la -composent. On peut donc améliorer la fluidité en réarrangeant le fichier -\texttt{.obj} : il suffit de faire apparaître les faces dès que les sommets -sont disponibles. - -\paragraph{} -Dans le cas où l'on souhaite gérer les textures et les normales, utiliser cette -technique est beaucoup plus compliqué puisqu'il faut aussi décider de l'ordre -relatif entre les sommets, coordonnées de textures et normales : en effet, pour -envoyer une face le plus tôt possible, il faut que toutes ces composantes -soient envoyés, et il est donc nécessaire de mélanger les sommets, coordonnées -de texture et normales. - -\newpage -\section{Streaming linéaire amélioré} -La remarque précédente conduit directement à cette méthode. Le principe reste -le même que celui précédent (figure \ref{transmission1}), mais les éléments -seront envoyés différemment : on va en fait parcourir les faces directement. - -\paragraph{} -Le serveur va garder en mémoire ce qui a déjà été envoyé et ce qui ne l'a pas -été, et envoyer les faces dans l'ordre : si certains éléments des faces n'ont -pas encore été envoyé, on les enverra juste avant d'envoyer la face en -question. - -\paragraph{} -On peut de cette façon à la fois gérer les coordonnées de texture et les -normales, tout en envoyant les faces le plus tôt possible (on peut aussi noter -que si certains sommets / coordonnées de textures / normales sont inutilisés -dans les faces, ils ne seront pas envoyés et on s'évite donc de transférer des -données inutiles). - -\paragraph{} -C'est dans cette version que nous avons commencé à nous intéresser à la façon -de gérer les matériaux. Dans \threejs, un objet 3D est lié à un materiau, et -nous sommes donc obligés de créer autant d'objets que de materiaux. Pour cela, -nous avons légèrement modifié notre protocole : - -\begin{figure}[H] - \centering - \begin{tikzpicture}[] - \draw (0,0) node[above]{Client}; - \draw (0,0) -- (0,-8); - \draw (5,0) node[above]{Serveur}; - \draw (5,0) -- (5,-8); - - \draw (2.5,-1.3) node[rotate=-12] {Path jusqu'au modèle}; - \draw[->] (0,-1) -- (5, -2); - - \draw (2.5,-2.3) node[rotate=12] {Liste des matériaux}; - \draw[<-] (0,-3) -- (5, -2); - - \draw[dashed, ->] (-0.1,-3) -- (-0.1,-4); - - \draw (2.5,-3.3) node[rotate=-12] {ACK}; - \draw[->] (0,-3) -- (5, -4); - - \draw (2.5,-4.3) node[rotate=12] {Des éléments}; - \draw[<-] (0,-5) -- (5, -4); - - \draw (2.5,-5.3) node[rotate=-12] {ACK}; - \draw[->] (0,-5) -- (5, -6); - - \draw (2.5,-6.3) node[rotate=12] {D'autres éléments}; - \draw[<-] (0,-7) -- (5, -6); - - \draw (2.5,-8) node{$\vdots$}; - \end{tikzpicture} - \caption{Transmission avec gestion des matériaux} -\end{figure} - -\paragraph{} -Les directives de matériau à utiliser (\texttt{usemtl}) seront ignorées, et les -faces seront envoyées avec l'indice de l'objet auquel elles appartiennent, ce -qui permettra au client de savoir dans quel objet (et donc avec quel matériau) -elles doivent être ajoutées. - -\newpage -\section{Streaming intelligent} -C'est la dernière version du streaming qui a été faite sur ce projet. À chaque -transfert, le client envoie sa position au serveur (ainsi que les plans -définissant son \emph{frustum}\footnote{les bords du champ de vision de la -caméra}) et le serveur va parcourir les faces du modèle en cherchant celles qui -apparaissent dans le \emph{frustum}\footnote{dans cette version, on considère -qu'une face apparaît dans le \emph{frsutum} si un de ces sommets y appartient. -Évidemment, une face très grande pourrait appraître dans le \emph{frustum} -sans qu'aucun de ses sommets n'y soit, mais nous n'avons pas traité ce cas -particulier ici.}. On évite ainsi d'envoyer les faces du modèle qui sont -derrière la caméra et que l'utilisateur ne voit pas. - -\paragraph{} -Bien sûr, si il n'y a plus de faces dans le \emph{frustum} de la caméra, on va -envoyer les faces en suivant la méthode de la section précédente. - -\begin{figure}[H] - \centering - \begin{tikzpicture}[] - \draw (0,0) node[above]{Client}; - \draw (0,0) -- (0,-8); - \draw (5,0) node[above]{Serveur}; - \draw (5,0) -- (5,-8); - - \draw (2.5,-1.3) node[rotate=-12] {Path jusqu'au modèle}; - \draw[->] (0,-1) -- (5, -2); - - \draw (2.5,-2.3) node[rotate=12] {Liste des matériaux}; - \draw[<-] (0,-3) -- (5, -2); - - \draw[dashed, ->] (-0.1,-3) -- (-0.1,-4); - - \draw (2.5,-3.3) node[rotate=-12] {Caméra / \emph{frustum}}; - \draw[->] (0,-3) -- (5, -4); - - \draw (2.5,-4.3) node[rotate=12] {Des éléments}; - \draw[<-] (0,-5) -- (5, -4); - - \draw (2.5,-5.3) node[rotate=-12] {Caméra / \emph{frustum}}; - \draw[->] (0,-5) -- (5, -6); - - \draw (2.5,-6.3) node[rotate=12] {D'autres éléments}; - \draw[<-] (0,-7) -- (5, -6); - - \draw (2.5,-8) node{$\vdots$}; - \end{tikzpicture} - \caption{Version finale} -\end{figure} - -\newpage -\part*{Conclusion} +\include{conclusion} \label{end}\end{document}