3d-interface-rapport/rapport/techno.tex

197 lines
9.9 KiB
TeX

\mypart{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 Du code C++ compilé en JavaScript grâce à Emscripten
\item N'importe quel moteur graphique qui puisse exporter vers JavaScript
\item Une librairie JavaScript facilitant l'utilisation de WebGL
\end{itemize}
\subsection{WebGL}
WebGL est basé sur OpenGL ES (\emph{Open Graphic Library for Embedded Device}).
Cela signifie que de nombreuses fonctions présentes dans OpenGL rendant son
utilisation plus simple ne sont pas disponibles dans OpenGL ES pour des raisons
de performance. L'utilisation de WebGL devient donc assez complexe, et le
simple dessin d'un cube tournant avec une lumière et une caméra devient très
complexe. La contrepartie de WebGL est que toutes les fonctions élémentaires
sont disponibles, et donc, il n'y a pas de limite imposée par un
\emph{framework} : tout devient possible, mais il faut le faire soi-même.
\subsection{C++ vers JavaScript}
Le code compilé de C++ et transformé en JavaScript avec Emscripten à ses
inconvénients : comme WebGL ne supporte que OpenGL ES, il faut rédiger le code
en utilisant OpenGL ES en C++\footnote{En fait, certaines fonctions de OpenGL
fonctionnent avec Emscripten : ce sont elles qui sont équivalentes en OpenGL et
en WebGL}, et les contraintes de la sous-section précédentes sont toujours
présentes.
\paragraph{}
Cette technique permet de bénéficier des performances (à l'exécution) du C++,
et est très utile notamment dans le cas de portage de programmes déjà
existants.
\paragraph{}
Un des inconvénients de passer par du C++ est que le binaire produit à la
sortie sera relativement lourd (l'objectif du C++ est de faire le plus de
calcul possible à la compilation, et les résultats de ces calculs seront donc
inscrits dans le binaire) et le temps de chargement par le navigateur sera
long.
\subsection{Moteur graphique}
Pour les moteurs graphiques, il y a de nombreux choix possibles. J'ai plutôt
cherché des moteurs libres, et Vincent \textsc{Charvillat} m'a parlé de \minko{}.
C'est un moteur graphique qui utilise Emscripten pour exporter vers JavaScript.
\paragraph{}
Le principal avantage d'utiliser un moteur graphique est qu'il permet d'avoir
de très bons rendus assez facilement : toute la partie complexe du rendu est
déjà implémentée.
\paragraph{}
Son inconvénient est qu'il est assez lourd, long à prendre en main, et le
programme JavaScript sera lui aussi lourd puisqu'il contiendra à la fois notre
code et la librairie \minko{} compilée vers JavaScript. Les temps de chargement
étant trop grand, nous nous sommes tournés vers la dernière option.
\subsection{Three.js}
\threejs{} est une librairie écrite en JavaScript qui utilise les fonctions de
WebGL dans des classes qui permettent une utilisation plus simple de WebGL,
tout en gardant sa puissance. Nous avons opté pour cette librairie pour
développer notre interface.
\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é\footnote{On oppose les sites dynamiques (par
exemple les réseaux sociaux) aux sites statiques (par exemple les blogs) : dans
un site statique, l'utilisateur ne peut pas interagir avec le site. Le site se
contente de délivrer une information.} sont arrivées, il a fallu choisir une
technologie pour le côté serveur, et là, de nombreux langages étaient utilisables.
\paragraph{}
Plusieurs langages et framework ont été testée :
\begin{itemize}
\item le PHP : pratique pour des applications très petites, mais le langage
est peu confortable dès que la taille du serveur grandit.
\item les scripts CGI\footnote{Un script CGI est un programme dont
l'exécution imprime une page web (ou autre) sur la sortie standard.
Ils sont très simples à utiliser, puisqu'un simple \emph{Hello world}
en C peut devenir un script CGI} (en python) : assez pratique pour des
petites applications. Au final, cela ressemble un peu à du PHP mais
dans un langage un peu plus confortable.
\item Django (framework web en python) : très pratique, notamment pour des
grosses applications, mais il a l'inconvénient d'être assez coûteux en
mémoire vive (à ce moment, le serveur était hébergé sur une machine qui
n'avait que 512 Mo de mémoire vive, et les temps de génération des
réponses était de l'ordre de la dizaine de secondes).
\item \nodejs{} : permet d'écrire le code serveur en JavaScript. Il est un
peu moins pratique que Django (même si avec un peu de travail, on
arrive à obtenir une architecture y ressemblant), mais il a l'avantage
d'être très utilisé, et il existe donc de nombreuses librairies qu'on
peut y ajouter.
\end{itemize}
\paragraph{}
J'ai fini par choisir \nodejs{}, notamment pour l'existance d'une librairie
nommée \socketio{}, qui permet l'utilisation facile des sockets (côté serveur,
et côté client, c'est-à-dire les WebSockets du navigateur web). 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.
\newpage
\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 s'utilise de la même façon
que 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 dépôts :
\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
modifications sont propagées jusqu'à celui-ci.
\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{Documentation}
En plus des rapports, deux documentations sont présentes.
\subsection{\href{https://github.com/tforgione/3dinterface/wiki}{\emph{Github Wiki}}}
Github permet la création de Wiki pour chaque \emph{dépôt} et nous nous en
sommes servi pour de la documentation de haut niveau : il ne présente que des
aspects théoriques de ce qui a été réalisé pendant ce projet.
\subsection{\href{http://l3d.no-ip.org/}{L3D}}
Pour de la documentation de plus bas niveau (comment chaque classe ou méthode
fonctionne) nous avons utilisé \jsdoc{} (équivalent de javadoc mais pour
JavaScript) et nous générons automatiquement des pages html pour avoir une
documentation lisible et à jour sans avoir à parcourir le code.
\newpage
\section{Familiarisation}
Pour me familiariser avec les technologies et librairies, j'ai développé
quelques applications simples.
\subsection{Bouncing Cube}
Ceci est une première application de test de la librairie graphique. C'est une
des premières applications qui a été faite, et elle m'a surtout servi à
me familiariser 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.
\subsection{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).
\subsection{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}.