Some mdofic
This commit is contained in:
parent
50b2c6af07
commit
f72fbd85b0
|
@ -45,6 +45,9 @@
|
||||||
\newcommand{\hsc}[1]{{\Large\MakeUppercase{#1}}}
|
\newcommand{\hsc}[1]{{\Large\MakeUppercase{#1}}}
|
||||||
\newcommand{\hscs}[1]{{\footnotesize\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{\namedparagraph}[1]{\paragraph{#1}\mbox{}\\}
|
\newcommand{\namedparagraph}[1]{\paragraph{#1}\mbox{}\\}
|
||||||
|
|
||||||
\newcommand{\tikzvline}[2]{
|
\newcommand{\tikzvline}[2]{
|
||||||
|
@ -94,20 +97,22 @@
|
||||||
\end{titlepage}
|
\end{titlepage}
|
||||||
|
|
||||||
\normalsize
|
\normalsize
|
||||||
\newpage
|
|
||||||
\tableofcontents
|
\tableofcontents
|
||||||
\newpage
|
\newpage
|
||||||
|
|
||||||
\section*{Introduction}
|
|
||||||
|
|
||||||
\section{Choix des technologies et prise en main}
|
\part*{Introduction}
|
||||||
|
\newpage
|
||||||
|
|
||||||
|
\part{Choix des technologies et prise en main}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
La première phase de stage était de choisir les technologies qui allaient être
|
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
|
utilisées par la suite. Nous cherchions des technologies permettant la
|
||||||
visualisation 3D sur un navigateur web afin de pouvoir faire une étude
|
visualisation 3D sur un navigateur web afin de pouvoir faire une étude
|
||||||
utilisateur simplement.
|
utilisateur simplement.
|
||||||
|
|
||||||
\subsection{Côté client}
|
\section{Côté client}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Pour le côté client, il y avait plusieurs possibilités :
|
Pour le côté client, il y avait plusieurs possibilités :
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
|
@ -121,10 +126,15 @@ Pour le côté client, il y avait plusieurs possibilités :
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
La plupart des moteurs graphiques exportant vers JavaScript sont putôt lourd à
|
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
|
prendre en main, et nous voulions garder des solutions simples, c'est pourquoi
|
||||||
nous avons utilisé une librairie libre nommée Three.js permettant une
|
nous avons utilisé une librairie libre nommée \threejs permettant une
|
||||||
utilisation facile de WebGL.
|
utilisation facile de WebGL.
|
||||||
|
|
||||||
\subsection{Côté serveur}
|
\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{}
|
\paragraph{}
|
||||||
Dans un premier temps, seul le côté client était pris en compte. Les programmes
|
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
|
étaient écrits en JavaScript et ne nécessitaient pas de serveur. Quand les
|
||||||
|
@ -143,12 +153,12 @@ herbergé sur une petite machine de 512Mo de RAM).
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Quand les problématiques de streaming ont commencé à apparaître, nous avons
|
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
|
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 Socket.io
|
é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.
|
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
|
Pour des raisons pratiques, le serveur a été herbergé sur un cloud gratuit
|
||||||
(OpenShift).
|
(OpenShift).
|
||||||
|
|
||||||
\subsection{Base de données}
|
\section{Base de données}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Pour le système de gestion de base de données, nous avons choisi Postgres (qui
|
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
|
est libre et qui a largement fait ses preuves). OpenShift propose d'héberger
|
||||||
|
@ -156,7 +166,7 @@ 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.
|
d'espace de stockage, nous avons préféré l'héberger nous-même.
|
||||||
|
|
||||||
|
|
||||||
\subsection{Développement, debug et déploiement}
|
\section{Développement, debug et déploiement}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Pour éviter d'avoir des fichiers trop longs, nous avons choisi de séparer les
|
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
|
sources dans de nombreux fichiers de taille plus petite, et de les fusionner
|
||||||
|
@ -169,7 +179,7 @@ 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
|
intéressant de réduire la taille des programmes de sorte à les charger plus
|
||||||
rapidement} (effacement des commentaires et des retours à la ligne,
|
rapidement} (effacement des commentaires et des retours à la ligne,
|
||||||
simplifications des noms de variables et plus \footnote{en JavaScript, il est
|
simplifications des noms de variables et plus \footnote{en JavaScript, il est
|
||||||
plus rapide d'écrire \texttt{!0} pour \texttt{true} par exemple.}). Pour le
|
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
|
développement, on a utilisé \href{https://github.com/remy/nodemon}{nodemon} et
|
||||||
inotify, qui permettent de relancer le serveur local lorsqu'une modification
|
inotify, qui permettent de relancer le serveur local lorsqu'une modification
|
||||||
est détectée (la fusion des fichiers est donc réeffectuée).
|
est détectée (la fusion des fichiers est donc réeffectuée).
|
||||||
|
@ -192,8 +202,9 @@ 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
|
qui nous aide à détecter les erreurs potentielles liées aux subtilités du
|
||||||
langage.
|
langage.
|
||||||
|
|
||||||
\section{L'interface}
|
\newpage
|
||||||
\subsection{Interactions élémentaires}
|
\part{L'interface}
|
||||||
|
\section{Interactions élémentaires}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
La première interface a été pensée pour être la plus simple possible.
|
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.
|
L'utilisateur contrôle une caméra qui se déplace librement dans un modèle 3D.
|
||||||
|
@ -215,13 +226,14 @@ On peut pivoter la caméra de plusieurs manières :
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
|
||||||
\subsection{Les recommandations}
|
\section{Les recommandations}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Les recommandations sont là pour suggérer des points de vue à l'utilisateur.
|
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
|
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.
|
d'objets 3D ajoutés à la scène. Deux affichages ont été testés.
|
||||||
|
|
||||||
\subsubsection{Les \emph{viewports}}
|
|
||||||
|
\subsection{Les \emph{viewports}}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Les \emph{viewports} sont les affichages les plus simples : ils représentent
|
Les \emph{viewports} sont les affichages les plus simples : ils représentent
|
||||||
une caméra, avec son centre optique et son plan image.
|
une caméra, avec son centre optique et son plan image.
|
||||||
|
@ -237,7 +249,7 @@ 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).
|
le point de vue et vers le modèle ou vers nous).
|
||||||
|
|
||||||
|
|
||||||
\subsubsection{Les flèches}
|
\subsection{Les flèches}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Les flèches sont supposées être plus intuitives pour un utilisateur qui n'a pas
|
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
|
l'habitude des \emph{viewports} précédemment utilisés. Plutôt que de suggérer
|
||||||
|
@ -248,8 +260,8 @@ un point de vue, elles suggèrent le mouvemement qui va mener à ce point de vue
|
||||||
\caption{Des recommandations flèches}
|
\caption{Des recommandations flèches}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
\subsubsection{Les interactions}
|
\subsection{Les interactions}
|
||||||
\namedparagraph{Au survol}
|
\subsubsection{Au survol}
|
||||||
\indent Cette fonctionnalité est inspirée des récents lecteurs video sur le
|
\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
|
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é.
|
passer le curseur sur cette barre affiche l'image de la vidéo à l'instant visé.
|
||||||
|
@ -262,7 +274,7 @@ une petite boite au voisinage du curseur.
|
||||||
\caption{Une prévisualisation}
|
\caption{Une prévisualisation}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
\namedparagraph{Au clic}
|
\subsubsection{Au clic}
|
||||||
\indent Lors d'un clic sur une recommandation, la caméra suit un mouvement
|
\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
|
fluide jusqu'au point de vue recommandé. La trajectoire est définié par un
|
||||||
polynôme interpolant tel que :
|
polynôme interpolant tel que :
|
||||||
|
@ -283,7 +295,8 @@ 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
|
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.
|
puisse savoir par où il est passé, et ce qui lui reste encore à visiter.
|
||||||
|
|
||||||
\subsection{Autres éléments de navigation}
|
|
||||||
|
\section{Autres éléments de navigation}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Pour faciliter la navigation, quelques autres éléments de navigation sont
|
Pour faciliter la navigation, quelques autres éléments de navigation sont
|
||||||
présents.
|
présents.
|
||||||
|
@ -307,7 +320,7 @@ présents.
|
||||||
\caption{Les différents éléments de l'interface}
|
\caption{Les différents éléments de l'interface}
|
||||||
\end{figure}
|
\end{figure}
|
||||||
|
|
||||||
|
\newpage
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
\begin{enumerate}
|
\begin{enumerate}
|
||||||
|
|
||||||
|
@ -334,7 +347,8 @@ présents.
|
||||||
\end{enumerate}
|
\end{enumerate}
|
||||||
|
|
||||||
|
|
||||||
\section{L'étude utilisateur}
|
\newpage
|
||||||
|
\part{L'étude utilisateur}
|
||||||
\paragraph{}
|
\paragraph{}
|
||||||
Pour tester le comportement des utilisateurs face aux recommandations, nous
|
Pour tester le comportement des utilisateurs face aux recommandations, nous
|
||||||
avons dissimulé des pièces rouges à travers ces modèles, et nous avons demandé
|
avons dissimulé des pièces rouges à travers ces modèles, et nous avons demandé
|
||||||
|
@ -351,12 +365,300 @@ recommandations visent les pièces rouges, il est évident qu'il sera très faci
|
||||||
de les trouver avec les recommandations), un système de tirage aléatoire de
|
de les trouver avec les recommandations), un système de tirage aléatoire de
|
||||||
pièces rouges a été fait.
|
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{}
|
\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.
|
||||||
|
|
||||||
|
|
||||||
\section{Streaming de modèle 3D}
|
\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*{Conclusion}
|
\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}
|
||||||
|
|
||||||
\label{end}\end{document}
|
\label{end}\end{document}
|
||||||
|
|
Loading…
Reference in New Issue