\documentclass{scrartcl} \usepackage[utf8x]{inputenc} \usepackage[frenchb]{babel} \usepackage{amssymb} \usepackage{lmodern} \usepackage[T1]{fontenc} \usepackage{verbatim} \usepackage{ucs} \usepackage{graphicx} \usepackage{amsmath} \usepackage{multicol} \usepackage[hidelinks]{hyperref} \usepackage{cpp} \usepackage{tikz} \usepackage{pgfplots} \usepackage{subcaption} \lstset{language=matlab} \setlength{\hoffset}{-18pt} \setlength{\oddsidemargin}{0pt} % Marge gauche sur pages impaires \setlength{\evensidemargin}{9pt} % Marge gauche sur pages paires \setlength{\marginparwidth}{54pt} % Largeur de note dans la marge \setlength{\textwidth}{481pt} % Largeur de la zone de texte (17cm) \setlength{\voffset}{-18pt} % Bon pour DOS \setlength{\marginparsep}{7pt} % Séparation de la marge \setlength{\topmargin}{0pt} % Pas de marge en haut \setlength{\headheight}{13pt} % Haut de page \setlength{\headsep}{10pt} % Entre le haut de page et le texte \setlength{\footskip}{27pt} % Bas de page + séparation \setlength{\textheight}{708pt} % Hauteur de la zone de texte (25cm) \usepackage{titling} \usepackage{fancyhdr} \pagestyle{fancy} \renewcommand{\headrulewidth}{1pt} \renewcommand{\footrulewidth}{\headrulewidth} \usepackage{float} \newcommand{\hsp}{\hspace{20pt}} \newcommand{\HRule}{\rule{\linewidth}{0.5mm}} \fancyfoot[RO]{\thepage/\pageref*{end}} \fancyfoot[C]{Mars 2015 --- Septembre 2015} \fancyfoot[L]{\emph{Rapport de stage}} \lstset{columns=fixed,basewidth=.5em,} \newcommand{\hsc}[1]{{\Large\MakeUppercase{#1}}} \newcommand{\hscs}[1]{{\footnotesize\MakeUppercase{#1}}} \newcommand{\namedparagraph}[1]{\paragraph{#1}\mbox{}\\} \newcommand{\tikzvline}[2]{ \draw (#1,-6) -- (#1,-5.5); \draw (#1,-6) node[below]{#2}; } \begin{document} \begin{titlepage} \begin{sffamily} \begin{center} ~\\[2cm] \LARGE R\hsc{apport de Stage de 3A}\\[3cm] % Title \HRule \\[0.4cm] { \huge \bfseries Prédiction du comportement des utilisateurs d'une application interactive en 3D \\[0.4cm] } \HRule \\[3cm] \includegraphics[scale=0.5]{img/icons/n7.png}~\\[4cm] % Author and supervisor \begin{minipage}{0.4\textwidth} \begin{flushleft} \large Thomas F\hscs{orgione}\\ 3IN\\ \end{flushleft} \end{minipage} \begin{minipage}{0.4\textwidth} \begin{flushright} \large \emph{Tuteur :} M. Vincent C\hscs{harvillat} \end{flushright} \end{minipage} \vfill % Bottom of the page {\large 16 Mars 2015 --- 25 Septembre 2015} \end{center} \end{sffamily} \end{titlepage} \normalsize \newpage \tableofcontents \newpage \section*{Introduction} \section{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. \subsection{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 Three.js permettant une utilisation facile de WebGL. \subsection{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 Socket.io 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). \subsection{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. \subsection{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 rapide 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. \section{L'interface} \subsection{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} \subsection{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. \subsubsection{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). \subsubsection{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} \subsubsection{Les interactions} \namedparagraph{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} \namedparagraph{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. \subsection{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} \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} \section{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. \paragraph{} \section{Streaming de modèle 3D} \section*{Conclusion} \label{end}\end{document}