itowns 2.44.3-next.0 → 2.44.3-next.10
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.
- package/CODING.md +1 -1
- package/dist/455.js +1 -1
- package/dist/455.js.map +1 -1
- package/dist/debug.js +1 -1
- package/dist/debug.js.LICENSE.txt +1 -1
- package/dist/debug.js.map +1 -1
- package/dist/itowns.js +1 -1
- package/dist/itowns.js.map +1 -1
- package/dist/itowns_lasworker.js +1 -1
- package/dist/itowns_lasworker.js.map +1 -1
- package/dist/itowns_widgets.js +1 -1
- package/dist/itowns_widgets.js.map +1 -1
- package/examples/3dtiles_loader.html +104 -43
- package/examples/config.json +2 -10
- package/lib/Controls/GlobeControls.js +41 -22
- package/lib/Controls/StateControl.js +4 -1
- package/lib/Controls/StreetControls.js +5 -2
- package/lib/Converter/Feature2Mesh.js +11 -4
- package/lib/Converter/textureConverter.js +3 -3
- package/lib/Core/Feature.js +2 -2
- package/lib/Core/Geographic/Extent.js +74 -266
- package/lib/Core/Prefab/Globe/GlobeLayer.js +1 -4
- package/lib/Core/Prefab/Planar/PlanarLayer.js +1 -4
- package/lib/Core/Style.js +2 -2
- package/lib/Core/Tile/Tile.js +219 -0
- package/lib/Core/Tile/TileGrid.js +46 -0
- package/lib/Core/TileMesh.js +3 -2
- package/lib/Core/View.js +1 -1
- package/lib/Layer/C3DTilesLayer.js +15 -14
- package/lib/Layer/CopcLayer.js +1 -1
- package/lib/Layer/LabelLayer.js +9 -5
- package/lib/Layer/OGC3DTilesLayer.js +36 -9
- package/lib/Layer/TiledGeometryLayer.js +3 -16
- package/lib/Parser/GeoJsonParser.js +1 -1
- package/lib/Parser/LASParser.js +1 -1
- package/lib/Parser/Potree2BinParser.js +1 -1
- package/lib/Parser/VectorTileParser.js +1 -1
- package/lib/Parser/XbilParser.js +15 -4
- package/lib/Provider/URLBuilder.js +22 -11
- package/lib/Renderer/Camera.js +1 -1
- package/lib/Renderer/LayeredMaterial.js +1 -1
- package/lib/Renderer/PointsMaterial.js +1 -1
- package/lib/Source/CopcSource.js +1 -1
- package/lib/Source/TMSSource.js +9 -7
- package/lib/Source/VectorTilesSource.js +2 -2
- package/lib/Source/WFSSource.js +4 -1
- package/lib/Source/WMSSource.js +4 -1
- package/lib/ThreeExtended/capabilities/WebGL.js +16 -11
- package/lib/ThreeExtended/loaders/GLTFLoader.js +10 -6
- package/lib/ThreeExtended/loaders/KTX2Loader.js +14 -7
- package/lib/Utils/CameraUtils.js +5 -4
- package/lib/Utils/gui/C3DTilesStyle.js +2 -3
- package/package.json +33 -28
- package/examples/3dtiles_25d.html +0 -120
- package/examples/3dtiles_basic.html +0 -94
- package/examples/3dtiles_batch_table.html +0 -86
- package/examples/3dtiles_ion.html +0 -126
- package/examples/3dtiles_pointcloud.html +0 -95
|
@@ -11,7 +11,15 @@
|
|
|
11
11
|
<style type="text/css">
|
|
12
12
|
#description {
|
|
13
13
|
z-index: 2;
|
|
14
|
-
|
|
14
|
+
left: 10px;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
#featureInfoText {
|
|
18
|
+
font-size: small;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#description .marg {
|
|
22
|
+
margin: 10px;
|
|
15
23
|
}
|
|
16
24
|
</style>
|
|
17
25
|
|
|
@@ -21,12 +29,17 @@
|
|
|
21
29
|
<div id="viewerDiv"></div>
|
|
22
30
|
<div id="description">Specify the URL of a tileset to load:
|
|
23
31
|
<input type="text" id="url" />
|
|
24
|
-
<button onclick="
|
|
25
|
-
|
|
26
|
-
|
|
32
|
+
<button onclick="readURL()">Load</button>
|
|
33
|
+
<div class="marg">
|
|
34
|
+
<button onClick="loadLyon()">Load Lyon 1 (Mesh)</button>
|
|
35
|
+
<button onClick="loadSete()">Load Sete (Point Cloud)</button>
|
|
36
|
+
<button onClick="loadLille()">Load Lille (Mesh)</button>
|
|
37
|
+
<div id="share"></div>
|
|
38
|
+
</div>
|
|
27
39
|
<hr />
|
|
40
|
+
<p id="featureInfoText" class="marg"><em>Display feature information by clicking on it</em></p>
|
|
28
41
|
<p><b>Feature Information:</b></p>
|
|
29
|
-
<div id="featureInfo"></div>
|
|
42
|
+
<div id="featureInfo" class="marg"></div>
|
|
30
43
|
</div>
|
|
31
44
|
|
|
32
45
|
<script src="js/GUI/GuiTools.js"></script>
|
|
@@ -52,28 +65,17 @@
|
|
|
52
65
|
|
|
53
66
|
const {
|
|
54
67
|
TMSSource, WMTSSource, OGC3DTilesSource,
|
|
55
|
-
ColorLayer, ElevationLayer, OGC3DTilesLayer,
|
|
68
|
+
ColorLayer, ElevationLayer, OGC3DTilesLayer, PNTS_SIZE_MODE,
|
|
56
69
|
GlobeView, Coordinates, Fetcher,
|
|
57
70
|
} = itowns;
|
|
58
71
|
|
|
59
|
-
|
|
60
|
-
const state = {
|
|
61
|
-
// URL to tileset JSON
|
|
62
|
-
tileset: uri.searchParams.get('tileset'),
|
|
63
|
-
// Cesium ION /
|
|
64
|
-
assetId: uri.searchParams.get('assetId'),
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
function setURL(url) {
|
|
68
|
-
if (!url) return;
|
|
72
|
+
window.layer = null; // 3D Tiles layer
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
history.pushState(null, '', `?${uri.searchParams.toString()}`);
|
|
74
|
+
const uri = new URL(location);
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
}
|
|
76
|
+
window.gui = new dat.GUI();
|
|
75
77
|
|
|
76
|
-
// ----
|
|
78
|
+
// ---- Create a GlobeView ----
|
|
77
79
|
|
|
78
80
|
// Define camera initial position
|
|
79
81
|
const placement = {
|
|
@@ -85,7 +87,17 @@
|
|
|
85
87
|
const viewerDiv = document.getElementById('viewerDiv');
|
|
86
88
|
|
|
87
89
|
// Create a GlobeView
|
|
88
|
-
const view = new GlobeView(viewerDiv, placement, {
|
|
90
|
+
const view = new GlobeView(viewerDiv, placement, {
|
|
91
|
+
controls: {
|
|
92
|
+
minDistance: 100,
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Enable various compression support for 3D Tiles tileset:
|
|
97
|
+
// - `KHR_draco_mesh_compression` mesh compression extension
|
|
98
|
+
// - `KHR_texture_basisu` texture compresion extension
|
|
99
|
+
itowns.enableDracoLoader('./libs/draco/');
|
|
100
|
+
itowns.enableKtx2Loader('./lib/basis/', view.renderer);
|
|
89
101
|
|
|
90
102
|
// Add ambient light to globally illuminates all objects
|
|
91
103
|
const light = new AmbientLight(0x404040, 15);
|
|
@@ -94,36 +106,68 @@
|
|
|
94
106
|
// Setup loading screen
|
|
95
107
|
setupLoadingScreen(viewerDiv, view);
|
|
96
108
|
|
|
97
|
-
//
|
|
98
|
-
const menuGlobe = new GuiTools('menuDiv', view, 300);
|
|
99
|
-
debug.createTileDebugUI(menuGlobe.gui, view, view.tileLayer);
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
// ---- ADD A BASEMAP ----
|
|
109
|
+
// ---- Add a basemap ----
|
|
103
110
|
|
|
104
111
|
// Add one imagery layer to the scene. This layer's properties are
|
|
105
112
|
// defined in a json file, but it cou ld be defined as a plain js
|
|
106
113
|
// object. See `Layer` documentation for more info.
|
|
107
114
|
Fetcher.json('./layers/JSONLayers/OPENSM.json').then((config) => {
|
|
108
|
-
const
|
|
115
|
+
const colorLayer = new ColorLayer('Ortho', {
|
|
109
116
|
...config,
|
|
110
117
|
source: new TMSSource(config.source),
|
|
111
118
|
});
|
|
112
|
-
view.addLayer(
|
|
119
|
+
view.addLayer(colorLayer);
|
|
113
120
|
});
|
|
114
121
|
|
|
115
|
-
// ----
|
|
122
|
+
// ---- Add 3D terrain ----
|
|
116
123
|
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
// Add two elevation layers: world terrain and a more precise terrain for france
|
|
125
|
+
// These will deform iTowns globe geometry to represent terrain elevation.
|
|
126
|
+
function addElevationLayerFromConfig(config) {
|
|
127
|
+
config.source = new itowns.WMTSSource(config.source);
|
|
128
|
+
var elevationLayer = new itowns.ElevationLayer(config.id, config);
|
|
129
|
+
view.addLayer(elevationLayer);
|
|
130
|
+
}
|
|
131
|
+
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
|
|
132
|
+
itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
|
|
133
|
+
|
|
134
|
+
// ---------- 3D Tiles loading
|
|
135
|
+
|
|
136
|
+
function readURL() {
|
|
137
|
+
const url = document.getElementById('url').value;
|
|
138
|
+
|
|
139
|
+
if (url) {
|
|
140
|
+
setUrl(url);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function setUrl(url) {
|
|
145
|
+
if (!url) return;
|
|
146
|
+
|
|
147
|
+
const input_url = document.getElementById('url');
|
|
148
|
+
if (!input_url) return;
|
|
149
|
+
|
|
150
|
+
uri.searchParams.set('copc', url);
|
|
151
|
+
history.replaceState(null, null, `?${uri.searchParams.toString()}`);
|
|
152
|
+
|
|
153
|
+
input_url.value = url;
|
|
154
|
+
load(url);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
function load(url) {
|
|
159
|
+
const source = new OGC3DTilesSource({ url });
|
|
122
160
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
161
|
+
if (window.layer) {
|
|
162
|
+
gui.removeFolder('Layer 3DTiles');
|
|
163
|
+
view.removeLayer('3DTiles');
|
|
164
|
+
view.notifyChange();
|
|
165
|
+
window.layer.delete();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
window.layer = new OGC3DTilesLayer('3DTiles', {
|
|
126
169
|
source,
|
|
170
|
+
pntsSizeMode: PNTS_SIZE_MODE.ATTENUATED,
|
|
127
171
|
});
|
|
128
172
|
|
|
129
173
|
// Add an event for picking the 3D Tiles layer and displaying
|
|
@@ -131,20 +175,37 @@
|
|
|
131
175
|
const pickingArgs = {
|
|
132
176
|
htmlDiv: document.getElementById('featureInfo'),
|
|
133
177
|
view,
|
|
134
|
-
layer,
|
|
178
|
+
layer: window.layer,
|
|
135
179
|
};
|
|
136
180
|
|
|
137
181
|
// Add the layer to our view
|
|
138
|
-
view.addLayer(layer).then((layer) => {
|
|
182
|
+
view.addLayer(window.layer).then((layer) => {
|
|
139
183
|
zoomToLayer(view, layer);
|
|
140
184
|
window.addEventListener('click',
|
|
141
185
|
(event) => fillHTMLWithPickingInfo(event, pickingArgs), false);
|
|
142
186
|
});
|
|
143
187
|
|
|
144
|
-
|
|
188
|
+
window.layer.whenReady
|
|
189
|
+
.then(() => debug.createOGC3DTilesDebugUI(gui, view, window.layer));
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function loadLyon() {
|
|
193
|
+
setUrl("https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/refs/heads/master/3DTiles/lyon1-4978/tileset.json");
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
function loadSete() {
|
|
197
|
+
setUrl("https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/pnts-sete-2021-0756_6256/tileset.json");
|
|
145
198
|
}
|
|
146
199
|
|
|
147
|
-
|
|
200
|
+
function loadLille() {
|
|
201
|
+
setUrl("https://webimaging.lillemetropole.fr/externe/maillage/2020_mel_5cm/tileset.json");
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
window.readURL = readURL;
|
|
205
|
+
window.loadLyon = loadLyon;
|
|
206
|
+
window.loadSete = loadSete;
|
|
207
|
+
window.loadLille = loadLille;
|
|
208
|
+
|
|
148
209
|
</script>
|
|
149
210
|
</body>
|
|
150
211
|
</html>
|
package/examples/config.json
CHANGED
|
@@ -14,16 +14,8 @@
|
|
|
14
14
|
"geoid_geoidLayer": "Display geoid heights"
|
|
15
15
|
},
|
|
16
16
|
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"3dtiles_25d": "On 2.5D map",
|
|
20
|
-
"3dtiles_batch_table": "Batch table Hierarchy extension",
|
|
21
|
-
"3dtiles_ion": "From Cesium ion",
|
|
22
|
-
"3dtiles_pointcloud": "Pointcloud classification"
|
|
23
|
-
},
|
|
24
|
-
|
|
25
|
-
"3D Tiles (new)": {
|
|
26
|
-
"3dtiles_loader": "3D Tiles tileset loader"
|
|
17
|
+
"3D Tiles": {
|
|
18
|
+
"3dtiles_loader": "3D Tiles loader"
|
|
27
19
|
},
|
|
28
20
|
|
|
29
21
|
"Pointcloud": {
|
|
@@ -149,7 +149,7 @@ let previous;
|
|
|
149
149
|
* @param {object} [options] An object with one or more configuration properties. Any property of GlobeControls
|
|
150
150
|
* can be passed in this object.
|
|
151
151
|
* @property {number} zoomFactor The factor the scale is multiplied by when dollying (zooming) in or
|
|
152
|
-
* divided by when dollying out. Default is
|
|
152
|
+
* divided by when dollying out. Default is 1.1.
|
|
153
153
|
* @property {number} rotateSpeed Speed camera rotation in orbit and panoramic mode. Default is 0.25.
|
|
154
154
|
* @property {number} minDistance Minimum distance between ground and camera in meters (Perspective Camera only).
|
|
155
155
|
* Default is 250.
|
|
@@ -170,6 +170,8 @@ let previous;
|
|
|
170
170
|
* @property {boolean} enableDamping Enable damping or not (simulates the lag that a real camera
|
|
171
171
|
* operator introduces while operating a heavy physical camera). Default is true.
|
|
172
172
|
* @property {boolean} dampingMoveFactor the damping move factor. Default is 0.25.
|
|
173
|
+
* @property {StateControl~State} stateControl redefining which controls state is triggered by the keyboard/mouse
|
|
174
|
+
* event (For example, rewrite the PAN movement to be triggered with the 'left' mouseButton instead of 'right').
|
|
173
175
|
*/
|
|
174
176
|
class GlobeControls extends THREE.EventDispatcher {
|
|
175
177
|
constructor(view, placement) {
|
|
@@ -180,7 +182,7 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
180
182
|
this.camera = view.camera3D;
|
|
181
183
|
|
|
182
184
|
// State control
|
|
183
|
-
this.states = new StateControl(this.view);
|
|
185
|
+
this.states = new StateControl(this.view, options.stateControl);
|
|
184
186
|
|
|
185
187
|
// this.enabled property has moved to StateControl
|
|
186
188
|
Object.defineProperty(this, 'enabled', {
|
|
@@ -197,7 +199,7 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
197
199
|
console.warn('Controls zoomSpeed parameter is deprecated. Use zoomFactor instead.');
|
|
198
200
|
options.zoomFactor = options.zoomFactor || options.zoomSpeed;
|
|
199
201
|
}
|
|
200
|
-
this.zoomFactor = options.zoomFactor || 1.
|
|
202
|
+
this.zoomFactor = options.zoomFactor || 1.1;
|
|
201
203
|
|
|
202
204
|
// Limits to how far you can dolly in and out ( PerspectiveCamera only )
|
|
203
205
|
this.minDistance = options.minDistance || 250;
|
|
@@ -291,10 +293,10 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
291
293
|
this.lookAtCoordinate(placement, false);
|
|
292
294
|
coordCameraTarget.crs = this.view.referenceCrs;
|
|
293
295
|
}
|
|
294
|
-
get
|
|
296
|
+
get zoomInScale() {
|
|
295
297
|
return this.zoomFactor;
|
|
296
298
|
}
|
|
297
|
-
get
|
|
299
|
+
get zoomOutScale() {
|
|
298
300
|
return 1 / this.zoomFactor;
|
|
299
301
|
}
|
|
300
302
|
get isPaused() {
|
|
@@ -353,11 +355,13 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
353
355
|
this.panUp(deltaY * (this.camera.top - this.camera.bottom) / gfx.height);
|
|
354
356
|
}
|
|
355
357
|
}
|
|
358
|
+
|
|
359
|
+
// For Mobile
|
|
356
360
|
dolly(delta) {
|
|
357
361
|
if (delta === 0) {
|
|
358
362
|
return;
|
|
359
363
|
}
|
|
360
|
-
dollyScale = delta > 0 ? this.
|
|
364
|
+
dollyScale = delta > 0 ? this.zoomInScale : this.zoomOutScale;
|
|
361
365
|
if (this.camera.isPerspectiveCamera) {
|
|
362
366
|
orbitScale /= dollyScale;
|
|
363
367
|
} else if (this.camera.isOrthographicCamera) {
|
|
@@ -554,6 +558,7 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
554
558
|
|
|
555
559
|
// Initialize dolly movement.
|
|
556
560
|
dollyStart.copy(event.viewCoords);
|
|
561
|
+
this.view.getPickingPositionFromDepth(event.viewCoords, pickedPosition); // mouse position
|
|
557
562
|
|
|
558
563
|
// Initialize pan movement.
|
|
559
564
|
panStart.copy(event.viewCoords);
|
|
@@ -585,9 +590,11 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
585
590
|
handleDolly(event) {
|
|
586
591
|
dollyEnd.copy(event.viewCoords);
|
|
587
592
|
dollyDelta.subVectors(dollyEnd, dollyStart);
|
|
588
|
-
this.dolly(-dollyDelta.y);
|
|
589
593
|
dollyStart.copy(dollyEnd);
|
|
590
|
-
|
|
594
|
+
event.delta = dollyDelta.y;
|
|
595
|
+
if (event.delta != 0) {
|
|
596
|
+
this.handleZoom(event);
|
|
597
|
+
}
|
|
591
598
|
}
|
|
592
599
|
handlePan(event) {
|
|
593
600
|
if (event.viewCoords) {
|
|
@@ -712,21 +719,33 @@ class GlobeControls extends THREE.EventDispatcher {
|
|
|
712
719
|
handleZoom(event) {
|
|
713
720
|
this.player.stop();
|
|
714
721
|
CameraUtils.stop(this.view, this.camera);
|
|
715
|
-
this.
|
|
716
|
-
|
|
717
|
-
this.
|
|
718
|
-
|
|
719
|
-
this.
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
722
|
+
const zoomScale = event.delta > 0 ? this.zoomInScale : this.zoomOutScale;
|
|
723
|
+
let point = event.type === 'dolly' ? pickedPosition : this.view.getPickingPositionFromDepth(event.viewCoords); // get cursor position
|
|
724
|
+
let range = this.getRange();
|
|
725
|
+
range *= zoomScale;
|
|
726
|
+
if (point && range > this.minDistance && range < this.maxDistance) {
|
|
727
|
+
// check if the zoom is in the allowed interval
|
|
728
|
+
const camPos = xyz.setFromVector3(cameraTarget.position).as('EPSG:4326', c).toVector3();
|
|
729
|
+
point = xyz.setFromVector3(point).as('EPSG:4326', c).toVector3();
|
|
730
|
+
if (camPos.x * point.x < 0) {
|
|
731
|
+
// Correct rotation at 180th meridian by using 0 <= longitude <=360 for interpolation purpose
|
|
732
|
+
if (camPos.x - point.x > 180) {
|
|
733
|
+
point.x += 360;
|
|
734
|
+
} else if (point.x - camPos.x > 180) {
|
|
735
|
+
camPos.x += 360;
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
point.lerp(
|
|
739
|
+
// point interpol between mouse cursor and cam pos
|
|
740
|
+
camPos, zoomScale // interpol factor
|
|
741
|
+
);
|
|
742
|
+
point = c.setFromVector3(point).as('EPSG:4978', xyz);
|
|
743
|
+
return this.lookAtCoordinate({
|
|
744
|
+
// update view to the interpolate point
|
|
745
|
+
coord: point,
|
|
746
|
+
range
|
|
747
|
+
}, false);
|
|
727
748
|
}
|
|
728
|
-
this.dispatchEvent(this.startEvent);
|
|
729
|
-
this.dispatchEvent(this.endEvent);
|
|
730
749
|
}
|
|
731
750
|
onTouchStart(event) {
|
|
732
751
|
// CameraUtils.stop(view);
|
|
@@ -376,9 +376,12 @@ class StateControl extends THREE.EventDispatcher {
|
|
|
376
376
|
onMouseWheel(event) {
|
|
377
377
|
event.preventDefault();
|
|
378
378
|
if (this.enabled && this.ZOOM.enable) {
|
|
379
|
+
viewCoords.copy(this._view.eventToViewCoords(event));
|
|
380
|
+
this.currentState = this.NONE;
|
|
379
381
|
this.dispatchEvent({
|
|
380
382
|
type: this.ZOOM._event,
|
|
381
|
-
delta: event.deltaY
|
|
383
|
+
delta: event.deltaY,
|
|
384
|
+
viewCoords
|
|
382
385
|
});
|
|
383
386
|
}
|
|
384
387
|
}
|
|
@@ -290,7 +290,7 @@ class StreetControls extends FirstPersonControls {
|
|
|
290
290
|
this.end.lookAt(position);
|
|
291
291
|
this.tween = new TWEEN.Tween({
|
|
292
292
|
t: 0
|
|
293
|
-
}
|
|
293
|
+
}).to({
|
|
294
294
|
t: 1
|
|
295
295
|
}, time).easing(TWEEN.Easing.Quadratic.Out).onComplete(() => {
|
|
296
296
|
this.stopAnimations();
|
|
@@ -298,6 +298,7 @@ class StreetControls extends FirstPersonControls {
|
|
|
298
298
|
// 'manually' slerp the Quaternion to avoid rotation issues
|
|
299
299
|
this.camera.quaternion.slerpQuaternions(startQuaternion, this.end.quaternion, d.t);
|
|
300
300
|
}).start();
|
|
301
|
+
this.tweenGroup.add(this.tween);
|
|
301
302
|
this.animationFrameRequester = () => {
|
|
302
303
|
this.tweenGroup.update();
|
|
303
304
|
// call reset from super class FirsPersonControls to make mouse rotation managed by FirstPersonControl still aligned
|
|
@@ -325,12 +326,13 @@ class StreetControls extends FirstPersonControls {
|
|
|
325
326
|
resolve = r;
|
|
326
327
|
});
|
|
327
328
|
this.stopAnimations();
|
|
328
|
-
this.tween = new TWEEN.Tween(this.camera.position
|
|
329
|
+
this.tween = new TWEEN.Tween(this.camera.position) // Create a new tween that modifies camera position
|
|
329
330
|
.to(position.clone(), time).easing(TWEEN.Easing.Quadratic.Out) // Use an easing function to make the animation smooth.
|
|
330
331
|
.onComplete(() => {
|
|
331
332
|
this.stopAnimations();
|
|
332
333
|
resolve();
|
|
333
334
|
}).start();
|
|
335
|
+
this.tweenGroup.add(this.tween);
|
|
334
336
|
this.animationFrameRequester = () => {
|
|
335
337
|
this.tweenGroup.update();
|
|
336
338
|
this.view.notifyChange(this.camera);
|
|
@@ -343,6 +345,7 @@ class StreetControls extends FirstPersonControls {
|
|
|
343
345
|
if (this.tween) {
|
|
344
346
|
this.tween.stop();
|
|
345
347
|
this.tween = undefined;
|
|
348
|
+
this.tweenGroup.removeAll();
|
|
346
349
|
}
|
|
347
350
|
if (this.animationFrameRequester) {
|
|
348
351
|
this.view.removeFrameRequester(MAIN_LOOP_EVENTS.BEFORE_RENDER, this.animationFrameRequester);
|
|
@@ -27,8 +27,8 @@ const crsWGS84 = 'EPSG:4326';
|
|
|
27
27
|
class FeatureMesh extends THREE.Group {
|
|
28
28
|
#currentCrs;
|
|
29
29
|
#originalCrs;
|
|
30
|
-
#collection = new THREE.Group();
|
|
31
|
-
#place = new THREE.Group();
|
|
30
|
+
#collection = (() => new THREE.Group())();
|
|
31
|
+
#place = (() => new THREE.Group())();
|
|
32
32
|
constructor(meshes, collection) {
|
|
33
33
|
super();
|
|
34
34
|
this.meshes = new THREE.Group().add(...meshes);
|
|
@@ -55,8 +55,15 @@ class FeatureMesh extends THREE.Group {
|
|
|
55
55
|
// calculate the scale transformation to transform the feature.extent
|
|
56
56
|
// to feature.extent.as(crs)
|
|
57
57
|
coord.crs = Crs.formatToEPSG(this.#originalCrs);
|
|
58
|
-
extent
|
|
59
|
-
extent
|
|
58
|
+
// TODO: An extent here could be either a geographic extent (for
|
|
59
|
+
// features from WFS) or a tiled extent (for features from MVT).
|
|
60
|
+
// Unify both behavior.
|
|
61
|
+
if (this.extent.isExtent) {
|
|
62
|
+
extent.copy(this.extent).applyMatrix4(this.#collection.matrix);
|
|
63
|
+
extent.as(coord.crs, extent);
|
|
64
|
+
} else {
|
|
65
|
+
this.extent.toExtent(coord.crs, extent);
|
|
66
|
+
}
|
|
60
67
|
extent.spatialEuclideanDimensions(dim_ref);
|
|
61
68
|
extent.planarDimensions(dim);
|
|
62
69
|
if (dim.x && dim.y) {
|
|
@@ -15,15 +15,15 @@ function textureColorLayer(texture, layer) {
|
|
|
15
15
|
return textureLayer(texture, layer);
|
|
16
16
|
}
|
|
17
17
|
export default {
|
|
18
|
-
convert(data,
|
|
18
|
+
convert(data, destinationTile, layer) {
|
|
19
19
|
let texture;
|
|
20
20
|
if (data.isFeatureCollection) {
|
|
21
21
|
const backgroundLayer = layer.source.backgroundLayer;
|
|
22
22
|
const backgroundColor = backgroundLayer && backgroundLayer.paint ? new THREE.Color(backgroundLayer.paint['background-color']) : undefined;
|
|
23
|
-
|
|
23
|
+
destinationTile.toExtent(CRS.formatToEPSG(layer.crs), extentTexture);
|
|
24
24
|
texture = Feature2Texture.createTextureFromFeature(data, extentTexture, layer.subdivisionThreshold, layer.style, backgroundColor);
|
|
25
25
|
texture.features = data;
|
|
26
|
-
texture.extent =
|
|
26
|
+
texture.extent = destinationTile;
|
|
27
27
|
} else if (data.isTexture) {
|
|
28
28
|
texture = data;
|
|
29
29
|
} else {
|
package/lib/Core/Feature.js
CHANGED
|
@@ -332,8 +332,8 @@ const alignYtoEast = new THREE.Quaternion();
|
|
|
332
332
|
*/
|
|
333
333
|
|
|
334
334
|
export class FeatureCollection extends THREE.Object3D {
|
|
335
|
-
#transformToLocalSystem = transformToLocalSystem2D;
|
|
336
|
-
#setLocalSystem = doNothing;
|
|
335
|
+
#transformToLocalSystem = (() => transformToLocalSystem2D)();
|
|
336
|
+
#setLocalSystem = (() => doNothing)();
|
|
337
337
|
/**
|
|
338
338
|
* @param {FeatureBuildingOptions|Layer} options The building options .
|
|
339
339
|
*/
|