\part{Architecture du programme} Comme dit précédemment, le programme se décompose en un côté serveur et un côté client. Le cas du \emph{streaming} sera traité à part (dans la partie \ref{streaming}, puisqu'il est à cheval sur le client et le serveur) et nous ne parlerons ici que du serveur, puis du code client. \paragraph{} Voici une simplification de l'arborescence de la version de développement : \begin{figure}[H] \centering \begin{subfigure}[b]{0.3\textwidth} \centering \tikzstyle{every node}=[draw=black,thick,anchor=west] \tikzstyle{folder}=[draw=blue, fill=blue!30] \begin{tikzpicture}[% grow via three points={one child at (0.5,-0.7) and two children at (0.5,-0.7) and (0.5,-1.4)}, edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] \node [folder] {root} child { node [folder] {js} child {node [folder] {l3d} child {node [folder] {src}} child {node [folder] {apps}} } child [missing] {} child [missing] {} child {node [folder] {Autres libraries}} child {node {Makefile}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node [folder] {lib} child {node {NodeLog.js}} child {node {controllers.js}} child {node {posts.js}} child {node {mail.js}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node [folder] {controllers}} child { node [folder] {posts}} child { node [folder] {geo} child {node {Geo.js}} child {node {Mesh.js}} child {node {MeshContainer.js}} child {node {MeshStreamer.js}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node {private.js }} child { node {package.json }} child { node {npm-shrinkwrap.json }} child { node {server.js }}; \end{tikzpicture} \caption{Vue globale} \end{subfigure} ~ \begin{subfigure}[b]{0.3\textwidth} \centering \tikzstyle{every node}=[draw=black,thick,anchor=west] \tikzstyle{folder}=[draw=blue, fill=blue!30] \begin{tikzpicture}[% grow via three points={one child at (0.5,-0.7) and two children at (0.5,-0.7) and (0.5,-1.4)}, edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] \node [folder] {src} child { node [folder] {cameras} child { node {FixedCamera.js}} child { node {PointerCamera.js}} child { node {ReplayCamera.js}} } child [missing] {} child [missing] {} child [missing] {} child { node [folder] {canvases} child { node { MousePointer.js}} child { node { Previewer.js}} child { node { StartCanvas.js}} } child [missing] {} child [missing] {} child [missing] {} child { node [folder] {loaders} child { node { ProgressiveLoader.js }} } child [missing] {} child { node [folder] {math} child { node { Hermite.js }} } child [missing] {} child { node [folder] {recommendations} child { node { Arrow.js}} child { node { Viewport.js}} } child [missing] {} child [missing] {} child { node [folder] {scenes}} child { node [folder] {utils} child { node [folder] {closure-compiler}} child { node [folder] {simple-compiler}} child { node { build\_all.sh}} child { node { demon.sh}} } child [missing] {} child [missing] {} child [missing] {} child [missing] {} child { node {l3d.js}} ; \end{tikzpicture} \caption{Détail des sources de L3D} \end{subfigure} ~ \begin{subfigure}[b]{0.3\textwidth} \centering \tikzstyle{every node}=[draw=black,thick,anchor=west] \tikzstyle{folder}=[draw=blue, fill=blue!30] \begin{tikzpicture}[% grow via three points={one child at (0.5,-0.7) and two children at (0.5,-0.7) and (0.5,-1.4)}, edge from parent path={(\tikzparentnode.south) |- (\tikzchildnode.west)}] \node [folder] {apps} child {node [folder] {bouncing-cube} child { node {BouncingCube.js}} child { node {main.js}} } child [missing] {} child [missing] {} child {node [folder] {multi-sphere} child {node {main.js}} } child [missing] {} child {node [folder] {stream-demo} child {node {main.js}} } child [missing] {} child {node [folder] {prototype} child {node [folder] {interactive} child {node {main.js}} } child [missing] {} child {node [folder] {replay} child {node {main.js}} } child [missing] {} child {node [folder] {tutorial} child {node {main.js}} } child [missing] {} child {node [folder] {coin-creator} child {node {main.js}} } child [missing] {} child {node [folder] {coin-viewer} child {node {main.js}} } child [missing] {} child {node [folder] {coin-checker} child {node {main.js}} } child [missing] {} child {node {ButtonManager.js}} child {node {Coin.js}} child {node {GlobalFunctions.js}} } ; \end{tikzpicture} \caption{Détail des applications} \end{subfigure} \caption{Arborescence} \end{figure} \tikzstyle{every node}=[] \section{Code serveur} Le code serveur est situé à la racine du projet : le fichier \texttt{server.js} est en fait le programme principal du serveur. \subsection{Dépendances} Le programme principal utilise de nombreuses libraires : les dépendances de notre serveur sont définies dans le fichier \texttt{package.json}. L'inconviéniant d'avoir de nombreuses librairies en même temps est la compatibilité des versions : en effet, une des dépendances nécessite une version particulière d'une autre librairie, et c'est pourquoi nous avons utilisé \texttt{npm-shrinkwrap.json} pour préciser les versions de chacune des dépendances de manière récursive. \paragraph{} Les \emph{packages} que nous utilisons sont les suivants : \begin{itemize} \item \emph{express} : un framework web pour NodeJs \item \emph{jade} : un moteur de template pour simplifier la génération des pages HTML \item \emph{pg} : une librairie permettant la connexion à la base de données \item \emph{body-parser} : une librairie permettant de traiter simplement les paramètres passés aux requêtes \item \emph{cookie-parser} et \emph{cookie-session} : une librairie gérant les sessions sous forme de cookies \item \emph{socket.io} : une librairie permettant d'utiliser facilement les sockets (côté serveur et client) \item \emph{serve-favicon} : une librairie pour choisir facilement l'icône du site \item \emph{emailjs} : une librairie permettant de se connecter à une adresse e-mail \end{itemize} \subsection{Modèle, vue, contrôleur} Pour ce projet, nous avons adopté une version simplifiée du design-pattern \emph{modèle-vue-controleur} : en JavaScript, nos modèles seront des objets simples, et le modèle sera limité à l'exécution des requêtes SQL. \paragraph{} Les contrôleurs sont chargés au démarrage par le fichier \texttt{controllers.js}, qui parcourt les dossiers qui sont contenus dans le dossier \texttt{controllers}. Dans chacun de ces dossiers, deux fichiers et un dossier sont présents : \begin{itemize} \item \texttt{index.js} qui contient des fonctions (contrôleurs) qui répondent à des requêtes \item \texttt{urls.js} qui contient les urls existantes et les fonctions auxquelles elles vont être associées \item \texttt{views}, dossier qui contient les vues qui vont être utilisées par les contrôleurs définis dans \texttt{index.js} \end{itemize} \paragraph{} La même technique à été appliquée pour le dossier \texttt{posts} et le fichier \texttt{posts.js}, à la différence près que les requêtes traitées sont des requêtes POST et non pas des requêtes GET : elles servent principalement à stocker des informations dans la base de donneés. \section{Code client} Le code client est séparé en trois parties : \begin{itemize} \item une partie dans le répertoire \texttt{src} contenant de nombreuses fonctions et classes \item une partie dans le répertoire \texttt{apps} contenant des applications que nous avons développées \item des autres librairies développées par des tiers, dans le répertoire \texttt{js} \end{itemize} Le \texttt{Makefile} présent dans le dossier \texttt{js} est celui qui concatènera nos sources, les minifieras et génèrera les scripts que nous utiliserons par la suite. \paragraph{} Dans la suite, nous allons seulement parler de L3D, puisque c'est le code que nous avons développé. \subsection{Les sources} L3D est composée de plusieurs classes : \begin{itemize} \item les caméras, permettant de choisir des caméras avec des mouvements particuliers \item les canvas, qui permettent d'afficher des informations supplémentaires à l'écran \item les loaders, qui permettent de charger des modèles de manière différente de celles proposées par \threejs{} \item les classes mathématiques, comme les polynômes de Hermite \item les recommandations, notamment les flèches et les \emph{viewports} \end{itemize} \paragraph{} Elle contient aussi quelques fonctions qui permettent de créer les scènes que nous avons utilisées, et notamment leurs recommandations et leurs pièces rouges. \paragraph{} Dans le répertoire \texttt{utils}, il y a plusieurs outils pratiques pour le développement et le déploiement : c'est là qu'est rangé le \emph{minifier} de Google, \closurecompiler{}, et une version simplifiée, le Simple-Compiler, qui utilise les mêmes paramètres mais se contente de concaténer le code. \paragraph{} Pour L3D, le premier fichier qui sera dans la version finale est \texttt{l3d.js}. Il contient simplement l'initialisation du \emph{namespace} \texttt{L3D}, auquel toutes les classes et fonctions appartiendront. \subsection{Les applications} Les applications sont principalement composées de programmes principaux, qui utilisent les classes de L3D, ainsi, elles ne sont pas fusionnées avec L3D, et laissées dans le namespace global. \paragraph{} Ces premières applications sont des applications de test pour se familiariser avec les technologies. \subsubsection{Bouncing Cube} Ceci est une première application de test de la libraire graphique. C'est une des premières applications qui été faite, et elle m'a surtout servi à m'initier avec la technologie, et notamment avec les clics sur les objets. C'est un simple cube, qui rebondit sur le sol et finit par s'arrêter. En cliquant sur le cube, il saute à nouveau. \subsubsection{Multisphere} Ceci est une des premières applications faites : elle m'a permi de tester l'affichage et le masquage des objets dans la librairie graphique. L'objectif était de raffiner le maillage au fur et à mesure en utilisant des modèles diffférents (plusieurs modèles sont chargés et on passe de l'un à l'autre en cliquant sur l'interface). \subsubsection{Stream-demo} Ceci est la première application que j'ai développée et qui utilise les sockets : c'est une version simplifiée du \texttt{ProgressiveLoader} que l'on détaillera dans la section \ref{streaming}. \newpage \paragraph{} Les prochaines sous-sections détaillent les applications qui ont été développées pour le projet. \subsubsection{Interactive} Ceci est l'interface principale, où l'utilisateur doit rechercher les pièces. Nous en parlerons plus dans la section \ref{interface}. \subsubsection{Replay} C'est l'interface qui crée une \texttt{ReplayCamera} et permet de visionner une expérience qui a été faite dans le passé. \subsubsection{Tutorial} C'est le tutoriel de l'application : il possède notamment une classe qui copie la caméra principale tout en permettant de vérifier que les interactions sont faites comme il faut. \subsubsection{Coin-creator} C'est une interface qui permet de créer des pièces : en cliquant sur une paroi, une pièce apparaît, et en cliquant sur une pièce, elle disparaît. Cette interface possède un bouton qui permet d'envoyer un mail contenant les données des pièces créées au format JSON. \subsubsection{Coin-editor} Cette interface permet d'éditer les pièces : elle est similaire à la précédente, mais expose une variable globale lors du clic sur une pièce qui permet de déplacer celle-ci. Elle sert à corriger les bugs potentiels introduits par l'interface précédente, notamment lorsqu'une pièce traverse une paroi. \subsubsection{Coin-checker} Elle permet de chercher toutes les pièces d'une scène, au cas où certaines se soient glissées à l'intérieur du modèle. Elle contient notamment un affichage du nombre de pièces présentes sur la scène, et cliquer sur une pièce la supprime.