itowns 2.34.0 → 2.36.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CONTRIBUTORS.md +1 -0
  2. package/changelog.md +150 -0
  3. package/dist/debug.js +2 -16
  4. package/dist/debug.js.LICENSE.txt +6 -0
  5. package/dist/debug.js.map +1 -1
  6. package/dist/itowns.js +2 -19
  7. package/dist/itowns.js.LICENSE.txt +28 -0
  8. package/dist/itowns.js.map +1 -1
  9. package/examples/3dtiles_basic.html +2 -2
  10. package/examples/config.json +2 -1
  11. package/examples/js/plugins/CSVnVRTParser.js +0 -1
  12. package/examples/layers/JSONLayers/Administrative.json +1 -1
  13. package/examples/layers/JSONLayers/Cada.json +1 -1
  14. package/examples/layers/JSONLayers/EtatMajor.json +1 -1
  15. package/examples/layers/JSONLayers/IGN_MNT.json +1 -1
  16. package/examples/layers/JSONLayers/IGN_MNT_HIGHRES.json +1 -1
  17. package/examples/layers/JSONLayers/Ortho.json +1 -1
  18. package/examples/layers/JSONLayers/WORLD_DTM.json +1 -1
  19. package/examples/misc_camera_traveling.html +148 -0
  20. package/examples/misc_custom_label.html +0 -2
  21. package/examples/plugins_vrt.html +0 -1
  22. package/examples/source_file_geojson_raster.html +0 -3
  23. package/examples/source_file_shapefile.html +0 -1
  24. package/examples/source_stream_wfs_25d.html +8 -16
  25. package/examples/vector_tile_raster_2d.html +2 -2
  26. package/examples/vector_tile_raster_3d.html +2 -2
  27. package/examples/view_25d_map.html +28 -0
  28. package/examples/view_multi_25d.html +1 -1
  29. package/lib/Controls/FirstPersonControls.js +12 -14
  30. package/lib/Controls/FlyControls.js +2 -10
  31. package/lib/Controls/GlobeControls.js +231 -303
  32. package/lib/Controls/PlanarControls.js +5 -16
  33. package/lib/Controls/StateControl.js +362 -96
  34. package/lib/Converter/Feature2Mesh.js +20 -5
  35. package/lib/Converter/Feature2Texture.js +2 -2
  36. package/lib/Converter/convertToTile.js +1 -1
  37. package/lib/Core/AnimationPlayer.js +15 -0
  38. package/lib/Core/Feature.js +39 -38
  39. package/lib/Core/Geographic/Coordinates.js +56 -0
  40. package/lib/Core/Geographic/Crs.js +15 -0
  41. package/lib/Core/Geographic/Extent.js +99 -11
  42. package/lib/Core/Label.js +1 -1
  43. package/lib/Core/Math/Ellipsoid.js +26 -8
  44. package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +1 -1
  45. package/lib/Core/Prefab/PlanarView.js +1 -1
  46. package/lib/Core/Style.js +1 -0
  47. package/lib/Core/TileMesh.js +3 -2
  48. package/lib/Core/View.js +3 -3
  49. package/lib/Layer/ElevationLayer.js +9 -16
  50. package/lib/Layer/LabelLayer.js +7 -1
  51. package/lib/Main.js +1 -1
  52. package/lib/Parser/ShapefileParser.js +1 -2
  53. package/lib/Parser/VectorTileParser.js +1 -1
  54. package/lib/Process/3dTilesProcessing.js +8 -8
  55. package/lib/Process/FeatureProcessing.js +1 -2
  56. package/lib/Process/ObjectRemovalHelper.js +5 -2
  57. package/lib/Renderer/Label2DRenderer.js +15 -11
  58. package/lib/Renderer/LayeredMaterial.js +2 -1
  59. package/lib/Renderer/OBB.js +2 -2
  60. package/lib/Renderer/RasterTile.js +22 -4
  61. package/lib/Renderer/Shader/ShaderChunk.js +3 -3
  62. package/lib/Renderer/c3DEngine.js +14 -2
  63. package/lib/Source/FileSource.js +2 -7
  64. package/lib/Source/VectorTilesSource.js +19 -0
  65. package/lib/ThreeExtended/loaders/GLTFLoader.js +320 -76
  66. package/lib/Utils/CameraUtils.js +8 -8
  67. package/lib/Utils/DEMUtils.js +2 -2
  68. package/package.json +29 -29
@@ -49,7 +49,7 @@
49
49
  name: 'DiscreteLOD',
50
50
  sseThreshold: 0.05,
51
51
  source: new itowns.C3DTilesSource({
52
- url: 'https://raw.githubusercontent.com/AnalyticalGraphicsInc/3d-tiles-samples/master/tilesets/TilesetWithDiscreteLOD/tileset.json',
52
+ url: 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/master/1.0/TilesetWithDiscreteLOD/tileset.json',
53
53
  }),
54
54
  }, view);
55
55
 
@@ -61,7 +61,7 @@
61
61
  var $3dTilesLayerRequestVolume = new itowns.C3DTilesLayer('3d-tiles-request-volume', {
62
62
  name: 'RequestVolume',
63
63
  source: new itowns.C3DTilesSource({
64
- url: 'https://raw.githubusercontent.com/AnalyticalGraphicsInc/3d-tiles-samples/master/tilesets/TilesetWithRequestVolume/tileset.json',
64
+ url: 'https://raw.githubusercontent.com/CesiumGS/3d-tiles-samples/master/1.0/TilesetWithRequestVolume/tileset.json',
65
65
  }),
66
66
  sseThreshold: 1,
67
67
  }, view);
@@ -60,7 +60,8 @@
60
60
  "misc_georeferenced_images": "Georeferenced image",
61
61
  "misc_orthographic_camera": "Orthographic camera",
62
62
  "misc_custom_controls": "Define custom controls",
63
- "misc_custom_label": "Custom label popup"
63
+ "misc_custom_label": "Custom label popup",
64
+ "misc_camera_traveling": "Camera traveling"
64
65
  },
65
66
 
66
67
  "Plugins": {
@@ -18,7 +18,6 @@
18
18
  * }).then(function _(res) {
19
19
  * res.csv = Papa.parse(res.csv.trim()).data;
20
20
  * return CSVnVRTParser.parse(res, { out: {
21
- * buildExtent: true,
22
21
  * crs: 'EPSG:4326'
23
22
  * }
24
23
  * });
@@ -6,7 +6,7 @@
6
6
  "transparent": true,
7
7
  "source": {
8
8
  "crs": "EPSG:3857",
9
- "url": "https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wmts",
9
+ "url": "https://wxs.ign.fr/administratif/geoportail/wmts",
10
10
  "format": "image/png",
11
11
  "name": "LIMITES_ADMINISTRATIVES_EXPRESS.LATEST",
12
12
  "style": "normal",
@@ -5,7 +5,7 @@
5
5
  "opacity": 1,
6
6
  "transparent": true,
7
7
  "source": {
8
- "url": "https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wmts",
8
+ "url": "https://wxs.ign.fr/parcellaire/geoportail/wmts",
9
9
  "crs": "EPSG:3857",
10
10
  "networkOptions": {
11
11
  "crossOrigin": "omit"
@@ -4,7 +4,7 @@
4
4
  "transparent": true,
5
5
  "source": {
6
6
  "crs": "EPSG:3857",
7
- "url": "http://wxs.ign.fr/va5orxd0pgzvq3jxutqfuy0b/geoportail/wmts",
7
+ "url": "http://wxs.ign.fr/cartes/geoportail/wmts",
8
8
  "networkOptions": {
9
9
  "crossOrigin": "anonymous"
10
10
  },
@@ -8,7 +8,7 @@
8
8
  }
9
9
  },
10
10
  "source": {
11
- "url": "https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wmts",
11
+ "url": "https://wxs.ign.fr/altimetrie/geoportail/wmts",
12
12
  "crs": "EPSG:4326",
13
13
  "format": "image/x-bil;bits=32",
14
14
  "attribution" : {
@@ -8,7 +8,7 @@
8
8
  }
9
9
  },
10
10
  "source": {
11
- "url": "https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wmts",
11
+ "url": "https://wxs.ign.fr/altimetrie/geoportail/wmts",
12
12
  "crs": "EPSG:4326",
13
13
  "format": "image/x-bil;bits=32",
14
14
  "attribution" : {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "id": "Ortho",
3
3
  "source": {
4
- "url": "https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wmts",
4
+ "url": "https://wxs.ign.fr/decouverte/geoportail/wmts",
5
5
  "crs": "EPSG:3857",
6
6
  "networkOptions": {
7
7
  "crossOrigin": "anonymous"
@@ -11,7 +11,7 @@
11
11
  "source": {
12
12
  "format": "image/x-bil;bits=32",
13
13
  "crs": "EPSG:4326",
14
- "url": "https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wmts",
14
+ "url": "https://wxs.ign.fr/altimetrie/geoportail/wmts",
15
15
  "name": "ELEVATION.ELEVATIONGRIDCOVERAGE.SRTM3",
16
16
  "tileMatrixSet": "WGS84G",
17
17
  "tileMatrixSetLimits": {
@@ -0,0 +1,148 @@
1
+ <html lang="en">
2
+ <head>
3
+ <title>Itowns - Pick positions</title>
4
+
5
+ <meta charset="UTF-8">
6
+ <link rel="stylesheet" type="text/css" href="css/example.css">
7
+ <link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
8
+
9
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
11
+ </head>
12
+ <body>
13
+ <div id="description">
14
+ Controls
15
+ <ul>
16
+ <li>Left-Click: camera translation (drag)</li>
17
+ <li>Right-Click: camera translation (pan)</li>
18
+ <li>Ctrl + Left-Click: camera rotation (orbit)</li>
19
+ <li>Mouse Wheel: zoom in/out</li>
20
+ </ul>
21
+ Recording
22
+ <ul>
23
+ <li>P: save current camera position</li>
24
+ <li>T: travel through each saved camera positions</li>
25
+ <li>T while traveling: interrupt travel</li>
26
+ <li>C: clear all saved camera positions</li>
27
+ </ul>
28
+ </div>
29
+ <div id="viewerDiv"></div>
30
+
31
+ <script src="js/GUI/GuiTools.js"></script>
32
+ <script src="../dist/itowns.js"></script>
33
+ <script src="js/GUI/LoadingScreen.js"></script>
34
+ <script src="../dist/debug.js"></script>
35
+ <script type="text/javascript">
36
+ /* global itowns */
37
+
38
+ // ---------- Display a GlobeView with ortho-images and digital elevation model : ----------
39
+
40
+ // `viewerDiv` will contain iTowns rendering area (`<canvas>`) :
41
+ let viewerDiv = document.getElementById('viewerDiv');
42
+
43
+ // Define initial camera position :
44
+ let initialPlacement = {
45
+ coord: new itowns.Coordinates('EPSG:4326', 2.351323, 48.856712),
46
+ range: 50000
47
+ };
48
+
49
+ // Instantiate iTowns GlobeView :
50
+ let view = new itowns.GlobeView(viewerDiv, initialPlacement);
51
+
52
+ // Sets a loading screen :
53
+ setupLoadingScreen(viewerDiv, view);
54
+
55
+ // Add one imagery layer to the scene and the miniView.
56
+ // This layer is defined in a json file but it could be defined as a plain js
57
+ // object. See Layer for more info.
58
+ itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
59
+ config.source = new itowns.WMTSSource(config.source);
60
+ const orthoLayer = new itowns.ColorLayer('Ortho', config);
61
+ view.addLayer(orthoLayer);
62
+ });
63
+
64
+ // Add two elevation layers.
65
+ // These will deform iTowns globe geometry to represent terrain elevation.
66
+ function addElevationLayerFromConfig(config) {
67
+ config.source = new itowns.WMTSSource(config.source);
68
+ let layer = new itowns.ElevationLayer(config.id, config);
69
+ view.addLayer(layer);
70
+ }
71
+ itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
72
+ itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
73
+
74
+
75
+ // ---------- Select camera positions and travel through these positions : ----------
76
+
77
+ // THREE.Group which stores picked camera positions markers.
78
+ let cameraHelpers = new itowns.THREE.Group();
79
+ cameraHelpers.visible = false;
80
+ view.scene.add(cameraHelpers);
81
+
82
+ // Array which stores successive camera transform options (headings, tilts, ranges...
83
+ // see CameraTransformOptions doc at http://www.itowns-project.org/itowns/docs/#api/Controls/CameraUtils)
84
+ let travelSteps = [];
85
+ // Boolean which states if the camera is performing a travel animation or not
86
+ let travelOn = false;
87
+
88
+ function saveCurrentCameraTransformOptions() {
89
+ // Retrieve current camera transform options
90
+ const cameraTransformOptions = itowns.CameraUtils.getTransformCameraLookingAtTarget(
91
+ view,
92
+ view.camera.camera3D,
93
+ );
94
+ // Change default easing parameter for animation speed
95
+ // (see https://sole.github.io/tween.js/examples/03_graphs.html)
96
+ cameraTransformOptions.easing = itowns.CameraUtils.Easing.Quadratic.InOut;
97
+
98
+ // Add the camera transform options to the travel step array
99
+ travelSteps.push(cameraTransformOptions);
100
+
101
+ // Create a CameraHelper (https://threejs.org/docs/index.html?q=Camera#api/en/helpers/CameraHelper) at
102
+ // the current position of the camera. The camera is copied, and the copy's `far` is lowered. This
103
+ // renders shorter axes on the displayed CameraHelper.
104
+ const copyCamera = view.camera.camera3D.clone();
105
+ copyCamera.far = 50;
106
+ const helper = new itowns.THREE.CameraHelper(copyCamera);
107
+ helper.updateWorldMatrix(true, false);
108
+ cameraHelpers.add(helper);
109
+ view.notifyChange();
110
+ }
111
+
112
+ function animateCamera() {
113
+ if (!travelOn) { // If travel is off, begin travel
114
+ travelOn = true;
115
+ return itowns.CameraUtils.sequenceAnimationsToLookAtTarget(
116
+ view,
117
+ view.camera.camera3D,
118
+ travelSteps,
119
+ ).then(() => { travelOn = false; });
120
+ }
121
+
122
+ itowns.CameraUtils.stop(view, view.camera.camera3D); // If travel is on, interrupt it
123
+ }
124
+
125
+ // Listens for user input :
126
+ window.addEventListener('keypress', async function (event) {
127
+ // If user presses `p` (for 'pick:'), saves the current camera position, heading, tilt...
128
+ if (event.key === 'p') { saveCurrentCameraTransformOptions(); }
129
+ // If user presses `t` (for 'travel'), switches travelling mode on or off.
130
+ else if (event.key === 't') { animateCamera(); }
131
+ // If user presses `c` (for 'clear'), removes all the picked position from lists.
132
+ else if (event.key ==='c') {
133
+ travelSteps = [];
134
+ cameraHelpers.clear();
135
+ view.notifyChange();
136
+ }
137
+ })
138
+
139
+ // Add a menu with an option to display CameraHelpers or not :
140
+ let menuGlobe = new GuiTools('menuDiv', view);
141
+ menuGlobe.addGUI('Picked positions', false, function (v) {
142
+ cameraHelpers.visible = !!v;
143
+ view.notifyChange();
144
+ })
145
+
146
+ </script>
147
+ </body>
148
+ </html>
@@ -124,8 +124,6 @@
124
124
  // create new featureCollection
125
125
  const collection = new itowns.FeatureCollection({
126
126
  crs: view.tileLayer.extent.crs,
127
- buildExtent: true,
128
- structure: '2d',
129
127
  });
130
128
 
131
129
  // create new feature
@@ -50,7 +50,6 @@
50
50
  }).then(function _(res) {
51
51
  res.csv = Papa.parse(res.csv.trim()).data;
52
52
  return CSVnVRTParser.parse(res, { out: {
53
- buildExtent: true,
54
53
  crs: view.tileLayer.extent.crs,
55
54
  }});
56
55
  }).then(function _(features) {
@@ -109,9 +109,6 @@
109
109
  // Here, we pass a FeatureBuildingOptions (http://www.itowns-project.org/itowns/docs/#api/Base/FeatureBuildingOptions)
110
110
  out: {
111
111
  crs: view.tileLayer.extent.crs,
112
- buildExtent: true,
113
- mergeFeatures: true,
114
- structure: '2d',
115
112
  },
116
113
  });
117
114
  }).then(function _(features) {
@@ -50,7 +50,6 @@
50
50
  return itowns.ShapefileParser.parse(res, {
51
51
  out: {
52
52
  crs: view.tileLayer.extent.crs,
53
- buildExtent: true,
54
53
  }
55
54
  });
56
55
  }).then(function _(features) {
@@ -242,40 +242,32 @@
242
242
  view.addLayer(wfsBuildingLayer);
243
243
 
244
244
  var wfsCartoSource = new itowns.WFSSource({
245
- url: 'https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wfs?',
245
+ url: 'https://wxs.ign.fr/cartovecto/geoportail/wfs?',
246
246
  version: '2.0.0',
247
- typeName: 'BDCARTO_BDD_WLD_WGS84G:zone_habitat',
248
- crs: 'EPSG:4326',
247
+ typeName: 'BDCARTO_BDD_WLD_WGS84G:zone_habitat_mairie',
248
+ crs: 'EPSG:3946',
249
249
  ipr: 'IGN',
250
250
  format: 'application/json',
251
- extent: {
252
- west: 4.568,
253
- east: 5.18,
254
- south: 45.437,
255
- north: 46.03,
256
- },
257
251
  });
258
252
 
259
253
  var wfsCartoStyle = new itowns.Style({
260
254
  zoom: { min: 0, max: 20 },
261
255
  text: {
262
256
  field: '{toponyme}',
257
+ color: 'white',
263
258
  transform: 'uppercase',
264
- size: 20,
265
- haloColor: 'white',
266
- haloWidth: 1,
259
+ size: 15,
260
+ haloColor: 'rgba(20,20,20, 0.8)',
261
+ haloWidth: 3,
267
262
  },
268
263
  });
269
264
 
270
265
  var wfsCartoLayer = new itowns.LabelLayer('wfsCarto', {
271
- crs: 'EPSG:3946',
272
266
  source: wfsCartoSource,
273
267
  style: wfsCartoStyle,
274
268
  });
275
269
 
276
- // TODO: enable this again when the stream became available
277
- // Search for "zone_habitat" in this page https://wxs.ign.fr/3ht7xcw6f7nciopo16etuqp2/geoportail/wfs?SERVICE=WFS&REQUEST=GetCapabilities
278
- // view.addLayer(wfsCartoLayer);
270
+ view.addLayer(wfsCartoLayer);
279
271
 
280
272
  function picking(event) {
281
273
  var htmlInfo = document.getElementById('info');
@@ -48,9 +48,9 @@
48
48
 
49
49
  // Defines a VectorTilesSource to load Vector Tiles data from the geoportail
50
50
  var mvtSource = new itowns.VectorTilesSource({
51
- style: 'https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/standard.json',
51
+ style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/standard.json',
52
52
  // We don't display mountains related data to ease visualisation
53
- filter: (layer) => !layer['source-layer'].includes('oro_'),
53
+ filter: (layer) => !layer['source-layer'].includes('oro_') && !layer['source-layer'].includes('parcellaire'),
54
54
  });
55
55
 
56
56
  var mvtLayer = new itowns.ColorLayer('MVT', {
@@ -54,9 +54,9 @@
54
54
 
55
55
  // Define a VectorTilesSource to load Vector Tiles data from the geoportail
56
56
  var mvtSource = new itowns.VectorTilesSource({
57
- style: 'https://wxs.ign.fr/static/vectorTiles/styles/PLAN.IGN/standard.json',
57
+ style: 'https://wxs.ign.fr/essentiels/static/vectorTiles/styles/PLAN.IGN/standard.json',
58
58
  // We don't display mountains related data to ease visualisation
59
- filter: (layer) => !layer['source-layer'].includes('oro_'),
59
+ filter: (layer) => !layer['source-layer'].includes('oro_') && !layer['source-layer'].includes('parcellaire'),
60
60
  });
61
61
 
62
62
  var mvtLayer = new itowns.ColorLayer('MVT', {
@@ -97,6 +97,34 @@
97
97
 
98
98
  view.addLayer(wmsElevationLayer);
99
99
 
100
+ var wfsCartoSource = new itowns.WFSSource({
101
+ url: 'https://wxs.ign.fr/cartovecto/geoportail/wfs?',
102
+ version: '2.0.0',
103
+ typeName: 'BDCARTO_BDD_WLD_WGS84G:zone_habitat_mairie',
104
+ crs: 'EPSG:3946',
105
+ ipr: 'IGN',
106
+ format: 'application/json',
107
+ });
108
+
109
+ var wfsCartoStyle = new itowns.Style({
110
+ zoom: { min: 0, max: 20 },
111
+ text: {
112
+ field: '{toponyme}',
113
+ color: 'white',
114
+ transform: 'uppercase',
115
+ size: 15,
116
+ haloColor: 'rgba(20,20,20, 0.8)',
117
+ haloWidth: 3,
118
+ },
119
+ });
120
+
121
+ var wfsCartoLayer = new itowns.LabelLayer('wfsCarto', {
122
+ source: wfsCartoSource,
123
+ style: wfsCartoStyle,
124
+ });
125
+
126
+ view.addLayer(wfsCartoLayer);
127
+
100
128
  // Initialize scale :
101
129
  const initialScaleSize = 200; // in pixel
102
130
  const divScaleWidget = document.getElementById('divScaleWidget');
@@ -81,7 +81,7 @@
81
81
 
82
82
  itowns.THREE.Object3D.DefaultUp.set(0, 0, 1);
83
83
 
84
- scale = new itowns.THREE.Vector3(1, 1, 1).divideScalar(extent.dimensions().x);
84
+ scale = new itowns.THREE.Vector3(1, 1, 1).divideScalar(extent.planarDimensions().x);
85
85
 
86
86
  // Instanciate View
87
87
  view = new itowns.View(extent.crs, viewerDiv);
@@ -170,15 +170,16 @@ var FirstPersonControls = /*#__PURE__*/function (_THREE$EventDispatche) {
170
170
  _this._onMouseWheel = _this.onMouseWheel.bind((0, _assertThisInitialized2["default"])(_this));
171
171
  _this._onKeyUp = _this.onKeyUp.bind((0, _assertThisInitialized2["default"])(_this));
172
172
  _this._onKeyDown = _this.onKeyDown.bind((0, _assertThisInitialized2["default"])(_this));
173
+ _this._onContextMenu = _this.onContextMenu.bind((0, _assertThisInitialized2["default"])(_this));
173
174
  view.domElement.addEventListener('mousedown', _this._onMouseDown, false);
174
175
  view.domElement.addEventListener('touchstart', _this._onMouseDown, false);
175
176
  view.domElement.addEventListener('mousemove', _this._onMouseMove, false);
176
177
  view.domElement.addEventListener('touchmove', _this._onMouseMove, false);
177
178
  view.domElement.addEventListener('mouseup', _this._onMouseUp, false);
178
179
  view.domElement.addEventListener('touchend', _this._onMouseUp, false);
179
- view.domElement.addEventListener('mousewheel', _this._onMouseWheel, false);
180
- view.domElement.addEventListener('DOMMouseScroll', _this._onMouseWheel, false); // firefox
181
- // TODO: Why windows
180
+ view.domElement.addEventListener('wheel', _this._onMouseWheel, false); // Disable context menu when right clicking.
181
+
182
+ view.domElement.addEventListener('contextmenu', _this._onContextMenu, false); // TODO: Why windows
182
183
 
183
184
  document.addEventListener('keydown', _this._onKeyDown, false);
184
185
  document.addEventListener('keyup', _this._onKeyUp, false);
@@ -345,14 +346,7 @@ var FirstPersonControls = /*#__PURE__*/function (_THREE$EventDispatche) {
345
346
  return;
346
347
  }
347
348
 
348
- var delta = 0;
349
-
350
- if (event.wheelDelta !== undefined) {
351
- delta = -event.wheelDelta; // Firefox
352
- } else if (event.detail !== undefined) {
353
- delta = event.detail;
354
- }
355
-
349
+ var delta = event.deltaY;
356
350
  this.camera.fov = THREE.MathUtils.clamp(this.camera.fov + Math.sign(delta), 10, Math.min(100, this.options.verticalFOV));
357
351
  this.camera.updateProjectionMatrix();
358
352
  this._state.rotateX = limitRotation(this.camera, this._state.rotateX, this.options.verticalFOV);
@@ -389,6 +383,11 @@ var FirstPersonControls = /*#__PURE__*/function (_THREE$EventDispatche) {
389
383
  e.preventDefault();
390
384
  }
391
385
  }
386
+ }, {
387
+ key: "onContextMenu",
388
+ value: function onContextMenu(event) {
389
+ event.preventDefault();
390
+ }
392
391
  }, {
393
392
  key: "dispose",
394
393
  value: function dispose() {
@@ -399,9 +398,8 @@ var FirstPersonControls = /*#__PURE__*/function (_THREE$EventDispatche) {
399
398
  this.view.domElement.removeEventListener('touchmove', this._onMouseMove, false);
400
399
  this.view.domElement.removeEventListener('mouseup', this._onMouseUp, false);
401
400
  this.view.domElement.removeEventListener('touchend', this._onMouseUp, false);
402
- this.view.domElement.removeEventListener('mousewheel', this._onMouseWheel, false);
403
- this.view.domElement.removeEventListener('DOMMouseScroll', this._onMouseWheel, false); // firefox
404
-
401
+ this.view.domElement.removeEventListener('wheel', this._onMouseWheel, false);
402
+ this.view.domElement.removeEventListener('contextmenu', this._onContextMenu, false);
405
403
  document.removeEventListener('keydown', this._onKeyDown, false);
406
404
  document.removeEventListener('keyup', this._onKeyUp, false);
407
405
  }
@@ -143,13 +143,7 @@ function onKeyDown(e) {
143
143
  }
144
144
 
145
145
  function onDocumentMouseWheel(event) {
146
- var delta = 0;
147
-
148
- if (event.wheelDelta !== undefined) {
149
- delta = event.wheelDelta; // Firefox
150
- } else if (event.detail !== undefined) {
151
- delta = -event.detail;
152
- }
146
+ var delta = -event.deltaY;
153
147
 
154
148
  if (delta < 0) {
155
149
  this.moves.add(MOVEMENTS.wheelup);
@@ -204,9 +198,7 @@ var FlyControls = /*#__PURE__*/function (_THREE$EventDispatche) {
204
198
  view.domElement.addEventListener('touchmove', bindedPM, false);
205
199
  view.domElement.addEventListener('mouseup', onDocumentMouseUp.bind((0, _assertThisInitialized2["default"])(_this)), false);
206
200
  view.domElement.addEventListener('touchend', onDocumentMouseUp.bind((0, _assertThisInitialized2["default"])(_this)), false);
207
- view.domElement.addEventListener('mousewheel', onDocumentMouseWheel.bind((0, _assertThisInitialized2["default"])(_this)), false);
208
- view.domElement.addEventListener('DOMMouseScroll', onDocumentMouseWheel.bind((0, _assertThisInitialized2["default"])(_this)), false); // firefox
209
-
201
+ view.domElement.addEventListener('wheel', onDocumentMouseWheel.bind((0, _assertThisInitialized2["default"])(_this)), false);
210
202
  view.domElement.addEventListener('keyup', onKeyUp.bind((0, _assertThisInitialized2["default"])(_this)), true);
211
203
  view.domElement.addEventListener('keydown', onKeyDown.bind((0, _assertThisInitialized2["default"])(_this)), true);
212
204