This repository was archived by the owner on Oct 12, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvues-360-en-webgl.html
More file actions
236 lines (189 loc) · 14.4 KB
/
Copy pathvues-360-en-webgl.html
File metadata and controls
236 lines (189 loc) · 14.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
<!DOCTYPE html>
<html lang="en">
<head>
<title>Vues 360 en WebGL</title>
<meta charset="utf-8" />
<link href="https://techblog.mappy.com/feeds/rss.xml" type="application/atom+xml" rel="alternate" title="Mappy Labs Full Atom Feed" />
<link href="https://techblog.mappy.com/feeds/web/rss.xml" type="application/atom+xml" rel="alternate" title="Mappy Labs Categories Atom Feed" />
<!-- Mobile viewport optimized: j.mp/bplateviewport -->
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1">
<link rel="stylesheet" type="text/css" href="./theme/gumby.css" />
<link rel="stylesheet" type="text/css" href="./theme/style.css" />
<link rel="stylesheet" type="text/css" href="./theme/pygment.css" />
<link rel="icon" type="image/png" href="images/favicon-96x96.png" sizes="96x96">
<link rel="icon" type="image/png" href="images/favicon-16x16.png" sizes="16x16">
<link rel="icon" type="image/png" href="images/favicon-32x32.png" sizes="32x32">
</head>
<body id="index" class="home">
<div class="container">
<header id="banner" class="body">
<h1><a href="/"><img src="/images/logo.png" /> Labs</a></h1>
<div id="navigation" class="navbar row">
<a href="#" gumby-trigger="#navigation > ul" class="toggle"><i class="icon-menu"></i></a>
</div>
</header><!-- /#banner -->
<div class="row">
<section id="content" class="body">
<div class="row">
<div class="ten columns">
<header>
<h2 class="entry-title">
<a href="./vues-360-en-webgl.html" rel="bookmark"
title="Permalink to Vues 360 en WebGL">Vues 360 en WebGL</a></h2>
</header>
<footer class="post-info">
<abbr class="published" title="2015-11-05T00:00:00+01:00">
Thu 05 November 2015
</abbr>
<address class="vcard author">
By <a class="url fn" href="./author/gregory-paul.html">Grégory Paul</a>
</address>
</footer><!-- /.post-info -->
<div class="entry-content">
<p>Le site <a href="http://fr.mappy.com">Mappy</a> offre depuis 2011 des <a href="http://fr.mappy.com/#/436/M1/TSearch/Sparis/N1090.14493,12.34393,2.34821,48.85369/Z7/">vues 360°</a> des <a href="http://widgets.mappy.com/360view/documentation/#coverage">320 villes</a> plus grandes villes de France :</p>
<iframe src="http://widgets.mappy.com/360view?key=techblog&lat=48.85369&lng=2.34821" width="100%" height="400" scrolling="no"></iframe>
<h2>MappyCar</h2>
<p>En effet, 2 voitures surnommées "MappyCar" (<a href="https://twitter.com/earthmine02">@earthmine02</a>, <a href="https://twitter.com/earthmine07">@earthmine07</a>) parcourent les rues des villes de France pour prendre des photos sous plusieurs angles.</p>
<p><img alt="Mappy Car" src="images/webgl/mappy-car.jpg"></p>
<h2>Historiquement...</h2>
<p>Historiquement, le composant chargé d’afficher les vues sur le site <a href="http://fr.mappy.com">fr.mappy.com</a> fût développé en Flash.</p>
<p>Il était grand temps de mettre ce composant à jour en adoptant des technologies modernes pour afficher de la 3d au sein du navigateur, j’ai nommé <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API">WebGL</a>.</p>
<p>Mais avant de nous plonger dans WebGL, une présentation des vues 360 s’impose.</p>
<h2>Explications des prises de vue 360</h2>
<p>Les véhicules Mappy sont équipés de 8 appareils photos orientés de chaque côté de la voiture et prennent des photos régulièrement de façon synchronisée pendant le déplacement.
Ils enregistrent également différents paramètres tels que les coordonnées GPS, l’altitude, le tangage (pitch), l’orientation (yaw) et le roulis (roll).</p>
<p>Les photos sont ensuites assemblées afin d'obtenir 6 images.
Ces 6 images seront projetées à l’intérieur d’un cube. Ce cube est alors appelé "skybox".</p>
<p><img alt="Bitmap tile faces layout on a cube" src="images/panoramic_cube_01.png"></p>
<h2>Scène 3d</h2>
<p>L’astuce est alors de créer une scène 3d composée de ce cube et d’une caméra au centre.</p>
<p><img alt="Cube faces layout" src="images/panoramic_cube_02.png"></p>
<p>La caméra peut bouger à l’intérieur du cube sur 2 axes afin de pivoter horizontalement et verticalement, donnant l’effet de regarder autour de soi.</p>
<h2>Déplacement</h2>
<p>Il y a plusieurs façons de se déplacer d'une vue à l'autre :</p>
<ul>
<li>En utilisant les flèches, on peut se déplacer vers la vue la plus proche dans la direction souhaitée.</li>
<li>En cliquant sur le sol, on va chercher s'il existe une vue proche à ce point et l'afficher.</li>
</ul>
<p>Le déplacement d'une vue à l'autre consiste simplement à charger les images formant la nouvelle "skybox" (le cube dans lequel se trouve la caméra) et à effacer les précédentes.</p>
<p>Il est également possible de zoomer dans la vue. Pour cela, nous avons joué sur l'angle de vision (on l’appelle <a href="https://en.wikipedia.org/wiki/Field_of_view">field of view</a> en anglais).</p>
<h2>Chargement progressif</h2>
<p>Afin d'avoir un rendu le plus rapide possible et pour éviter à l'utilisateur de bloquer sur un fond noir lorsque sa connexion est lente, la vue charge d'abord un cube avec des images de basse qualité, donc très légères.
Lorsque cette première "skybox" est affichée, la vue va charger des images de meilleure qualité. En fonction de la taille d’écran ou de la résolution, chaque face du cube sera composée d'une ou de plusieurs images (1, 4 ou 16 images par face) afin d’avoir un rendu net sur tous les supports.</p>
<p><img alt="différentes résolutions" src="images/panoramic_cube_03.png"></p>
<h2>Three.js</h2>
<p>Plutôt que de réinventer la roue, nous nous sommes rapidement orientés vers <a href="http://threejs.org/">three.js</a>, une excellente librairie 3d.
Three.js permet, en quelques lignes de code, d’afficher une vue 3d sans avoir à manipuler l’API WebGL de plus bas niveau.</p>
<p>Voici un exemple de "skybox" basique où la caméra tourne sur elle-même :</p>
<iframe width="100%" height="700" src="//jsfiddle.net/053ng6gm/2/embedded/" allowfullscreen="allowfullscreen" frameborder="0"></iframe>
<h2>Interaction avec les objets</h2>
<p>Savoir sur quel élément a cliqué l’utilisateur dans un moteur 3d est plus compliqué que simplement ajouter un "listener" sur un élément HTML.
En effet, lors d’un clic dans la scène 3d, nous récupèrons simplement un point (x,y) et il convient alors de trouver quel objet il croise (c’est le principe du <a href="https://fr.wikipedia.org/wiki/Raycasting">raycasting</a>).</p>
<p>Pour cela, nous allons d’abord trouver le vecteur 3d entre ce point et la position de la caméra.
Ensuite, Three.js nous propose le <a href="https://github.com/mrdoob/three.js/blob/master/src/core/Raycaster.js">Raycaster</a> qui permet ensuite de détecter une intersection avec un objet 3d.</p>
<div class="highlight"><pre><span></span>var vector = getVectorFromEvent(event);
var raycaster = new THREE.Raycaster(this.camera.position, vector);
var intersectedObjects = raycaster.intersectObjects(objectsIn3dScene);
</pre></div>
<h2>Support navigateurs</h2>
<p>WebGL est supporté dans tous les <a href="http://caniuse.com/#search=webgl">navigateurs modernes</a>, y compris IE11.
Cependant, nous nous sommes rapidement rendus compte que certaines tablettes ou téléphones Android, bien que récents, ne supportent pas WebGL.
Par ailleurs, WebGL peut être désactivé en fonction des <a href="https://www.khronos.org/webgl/wiki/BlacklistsAndWhitelists">pilotes installés (ou non) sur la machine</a>.</p>
<p>Par conséquent, nous avons également utilisé un système de rendu alternatif proposé par Three.js, le <a href="https://github.com/mrdoob/three.js/blob/master/examples/js/renderers/CSS3DRenderer.js">CSS3DRenderer.js</a>.</p>
<p>Ce dernier utilise les <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform">transformations CSS 3d</a> qui sont elles <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/transform">supportées de façon un peu plus large</a>.
CSS3DRenderer est en pratique moins performant que WebGL mais permet d’offrir un support minimal sur ces périphèriques ainsi que sur IE 10.</p>
<h2>Réalité augmentée et cardBoard</h2>
<p>Les téléphones et tablettes modernes possèdent des capteurs d’orientations.
Ils sont accessibles en JavaScript via <a href="https://developer.mozilla.org/en-US/docs/Web/API/Detecting_device_orientation">API DeviceOrientations</a>.
Nous n’avons pas pu résister à l'envie de <a href="http://cdn.rawgit.com/Mappy/mappy.github.io-source/7545ef6cc29d998935e3cc8b5697bf533b4d7349/content/resources/webgl/deviceorientation.html">connecter cette API à la vue pour la piloter avec son téléphone</a>.</p>
<p>Enfin, si vous disposez d’un <a href="https://www.google.com/get/cardboard/">cardboard</a> (boîte en carton où l’on peut insérer son téléphone), vous pouvez chausser vos lunettes et <a href="http://cdn.rawgit.com/Mappy/mappy.github.io-source/7545ef6cc29d998935e3cc8b5697bf533b4d7349/content/resources/webgl/cardboard.html">visualiser les vues 360 en réalité augmentée</a>.</p>
<p><img alt="virtual reality" src="images/webgl/virtual-reality.png"></p>
<p>Three.js implémente cette fonctionnalité via <a href="https://github.com/mrdoob/three.js/blob/master/examples/js/effects/StereoEffect.js">StereoEffect</a> et <a href="https://github.com/mrdoob/three.js/blob/master/examples/js/controls/DeviceOrientationControls.js">DeviceOrientationControls</a>. Je vous invite à lire ce <a href="http://www.sitepoint.com/bringing-vr-to-web-google-cardboard-three-js/">très bon article</a> si le sujet vous intéresse.</p>
<h2>Un dernier mot sur l’intégration des vues sur votre site</h2>
<p><a href="http://fr.mappy.com">Mappy</a> propose plusieurs <a href="http://corporate.mappy.com/faq/integrez-mappy/">modes d’intégration</a> pour ses cartes ou sa vue 360.
L’un des modes se présente sous la forme d’un widget (tel que l’exemple en haut de cette page).
N’hésitez pas à nous contacter (contact[AT]mappy.com) si une intégration sur votre site ou vos applications mobiles vous intéresse.</p>
</div><!-- /.entry-content -->
</div><!-- /.eleven.columns -->
<div class="four columns" id="sidebar">
<h4>Pages</h4>
<ul>
</ul>
<h4>Categories</h4>
<ul>
<li><a href="./category/agile.html">Agile</a></li>
<li><a href="./category/android.html">Android</a></li>
<li><a href="./category/gis.html">GIS</a></li>
<li><a href="./category/mapping.html">Mapping</a></li>
<li><a href="./category/solr.html">Solr</a></li>
<li><a href="./category/web.html">Web</a></li>
</ul>
<h4>Tags</h4>
<ul>
<li class="tag-4"><a href="./tag/panorama.html">panorama</a></li>
<li class="tag-4"><a href="./tag/responsive.html">responsive</a></li>
<li class="tag-4"><a href="./tag/osm.html">osm</a></li>
<li class="tag-1"><a href="./tag/javascript.html">javascript</a></li>
<li class="tag-4"><a href="./tag/retrospective.html">rétrospective</a></li>
<li class="tag-4"><a href="./tag/gis.html">GIS</a></li>
<li class="tag-4"><a href="./tag/sotm.html">sotm</a></li>
<li class="tag-4"><a href="./tag/android.html">android</a></li>
<li class="tag-4"><a href="./tag/agilite.html">agilité</a></li>
<li class="tag-4"><a href="./tag/webgl.html">webgl</a></li>
<li class="tag-4"><a href="./tag/openlr.html">openlr</a></li>
<li class="tag-3"><a href="./tag/postgis.html">postGIS</a></li>
<li class="tag-3"><a href="./tag/mapnik.html">mapnik</a></li>
<li class="tag-4"><a href="./tag/abtest.html">abtest</a></li>
<li class="tag-3"><a href="./tag/leaflet.html">leaflet</a></li>
<li class="tag-4"><a href="./tag/python.html">python</a></li>
<li class="tag-3"><a href="./tag/backbone.html">backbone</a></li>
<li class="tag-1"><a href="./tag/opensource.html">opensource</a></li>
<li class="tag-1"><a href="./tag/francais.html">français</a></li>
<li class="tag-4"><a href="./tag/watch.html">watch</a></li>
<li class="tag-4"><a href="./tag/meetup.html">meetup</a></li>
<li class="tag-4"><a href="./tag/browserify.html">browserify</a></li>
<li class="tag-4"><a href="./tag/opengl.html">opengl</a></li>
<li class="tag-4"><a href="./tag/docker.html">docker</a></li>
<li class="tag-3"><a href="./tag/solr.html">solr</a></li>
<li class="tag-2"><a href="./tag/nodejs.html">node.js</a></li>
<li class="tag-2"><a href="./tag/webperfs.html">webperfs</a></li>
<li class="tag-2"><a href="./tag/english.html">english</a></li>
<li class="tag-4"><a href="./tag/livereload.html">livereload</a></li>
</ul>
<nav class="widget">
<h4>Links</h4>
<ul>
<li><a href="https://www.mappy.com/">Mappy</a></li>
<li><a href="https://play.google.com/store/apps/details?id=com.mappy.app">Appli Android</a></li>
<li><a href="https://itunes.apple.com/fr/app/mappy-itineraire-et-recherche/id313834655?mt=8">Appli iOS</a></li>
<li><a href="http://corporate.mappy.com">Blog Mappy</a></li>
<li><a href="http://corporate.mappy.com/faq/integrez-mappy/">API Mappy</a></li>
</ul>
</nav>
</div> </div><!-- /.row -->
</section>
</div><!-- /.row -->
</div><!-- /.container -->
<div class="container.nopad bg">
<footer id="credits" class="row">
<div class="seven columns left-center">
<address id="about" class="vcard body">
Proudly powered by <a href="http://getpelican.com/">Pelican</a>,
which takes great advantage of <a href="http://python.org">Python</a>.
<br />
Based on the <a target="_blank" href="http://gumbyframework.com">Gumby Framework</a>
</address>
</div>
<div class="seven columns">
<div class="row">
<ul class="socbtns">
<li><div class="btn primary"><a href="https://github.com/Mappy" target="_blank">Github</a></div></li>
<li><div class="btn twitter"><a href="https://twitter.com/Mappy" target="_blank">Twitter</a></div></li>
<li><div class="btn facebook"><a href="https://www.facebook.com/MappyOnline" target="_blank">Facebook</a></div></li>
</ul>
</div>
</div>
</footer>
</div>
</body>
</html>