Skip to content

Commit 103af91

Browse files
AnthonyGltjailln
authored andcommitted
fix(OGC3DTilesLayer): handle multiple views (iTowns#2435)
fix(OGC3DTilesLayer): handle multiple views cache
1 parent 669a84a commit 103af91

2 files changed

Lines changed: 41 additions & 28 deletions

File tree

src/Core/View.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export const VIEW_EVENTS = {
3232
INITIALIZED: 'initialized',
3333
COLOR_LAYERS_ORDER_CHANGED,
3434
CAMERA_MOVED: 'camera-moved',
35+
DISPOSED: 'disposed',
3536
};
3637

3738
/**
@@ -119,8 +120,11 @@ const viewers = [];
119120
// Size of the camera frustrum, in meters
120121
let screenMeters;
121122

123+
let id = 0;
124+
122125
/**
123-
* @property {HTMLElement} domElement - Thhe domElement holding the canvas where the view is displayed
126+
* @property {number} id - The id of the view. It's incremented at each new view instance, starting at 0.
127+
* @property {HTMLElement} domElement - The domElement holding the canvas where the view is displayed
124128
* @property {String} referenceCrs - The coordinate reference system of the view
125129
* @property {MainLoop} mainLoop - itowns mainloop scheduling the operations
126130
* @property {THREE.Scene} scene - threejs scene of the view
@@ -145,10 +149,10 @@ class View extends THREE.EventDispatcher {
145149
* var view = itowns.View('EPSG:4326', viewerDiv, { camera: { type: itowns.CAMERA_TYPE.ORTHOGRAPHIC } });
146150
* var customControls = itowns.THREE.OrbitControls(view.camera3D, viewerDiv);
147151
*
148-
* @param {string} crs - The default CRS of Three.js coordinates. Should be a cartesian CRS.
152+
* @param {String} crs - The default CRS of Three.js coordinates. Should be a cartesian CRS.
149153
* @param {HTMLElement} viewerDiv - Where to instanciate the Three.js scene in the DOM
150154
* @param {Object} [options] - Optional properties.
151-
* @param {object} [options.camera] - Options for the camera associated to the view. See {@link Camera} options.
155+
* @param {Object} [options.camera] - Options for the camera associated to the view. See {@link Camera} options.
152156
* @param {MainLoop} [options.mainLoop] - {@link MainLoop} instance to use, otherwise a default one will be constructed
153157
* @param {WebGLRenderer|Object} [options.renderer] - {@link WebGLRenderer} instance to use, otherwise
154158
* a default one will be constructed. In this case, if options.renderer is an object, it will be used to
@@ -169,6 +173,7 @@ class View extends THREE.EventDispatcher {
169173
super();
170174

171175
this.domElement = viewerDiv;
176+
this.id = id++;
172177

173178
this.referenceCrs = crs;
174179

@@ -303,8 +308,6 @@ class View extends THREE.EventDispatcher {
303308
}
304309
// remove alls frameRequester
305310
this.removeAllFrameRequesters();
306-
// remove alls events
307-
this.removeAllEvents();
308311
// remove all layers
309312
const layers = this.getLayers(l => !l.isTiledGeometryLayer && !l.isAtmosphere);
310313
for (const layer of layers) {
@@ -321,6 +324,9 @@ class View extends THREE.EventDispatcher {
321324
viewers.splice(id, 1);
322325
// Remove remaining objects in the scene (e.g. helpers, debug, etc.)
323326
this.scene.traverse(ObjectRemovalHelper.cleanup);
327+
this.dispatchEvent({ type: VIEW_EVENTS.DISPOSED });
328+
// remove alls events
329+
this.removeAllEvents();
324330
}
325331

326332
/**

src/Layer/OGC3DTilesLayer.js

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,22 @@ import PointsMaterial, {
2020
PNTS_SIZE_MODE,
2121
ClassificationScheme,
2222
} from 'Renderer/PointsMaterial';
23+
import { VIEW_EVENTS } from 'Core/View';
2324

2425
const _raycaster = new THREE.Raycaster();
2526

27+
// Stores lruCache, downloadQueue and parseQueue for each id of view {@link View}
28+
// every time a tileset has been added
29+
// https://github.com/iTowns/itowns/issues/2426
30+
const viewers = {};
31+
2632
// Internal instance of GLTFLoader, passed to 3d-tiles-renderer-js to support GLTF 1.0 and 2.0
2733
// Temporary exported to be used in deprecated B3dmParser
2834
export const itownsGLTFLoader = new iGLTFLoader();
2935
itownsGLTFLoader.register(() => new GLTFMeshFeaturesExtension());
3036
itownsGLTFLoader.register(() => new GLTFStructuralMetadataExtension());
3137
itownsGLTFLoader.register(() => new GLTFCesiumRTCExtension());
3238

33-
// Instantiated by the first tileset. Used to share cache and download and parse queues between tilesets
34-
let lruCache = null;
35-
let downloadQueue = null;
36-
let parseQueue = null;
37-
3839
export const OGC3DTILES_LAYER_EVENTS = {
3940
/**
4041
* Fired when a new root or child tile set is loaded
@@ -171,9 +172,6 @@ class OGC3DTilesLayer extends GeometryLayer {
171172

172173
this.tilesRenderer.manager.addHandler(/\.gltf$/, itownsGLTFLoader);
173174

174-
this._setupCacheAndQueues();
175-
this._setupEvents();
176-
177175
this.object3d.add(this.tilesRenderer.group);
178176

179177
// Add an initialization step that is resolved when the root tileset is loaded (see this._setup below), meaning
@@ -209,25 +207,28 @@ class OGC3DTilesLayer extends GeometryLayer {
209207
this.pntsMaxAttenuatedSize = config.pntsMaxAttenuatedSize || 10;
210208
}
211209

210+
212211
/**
213-
* Sets the lruCache and download and parse queues so they are shared amongst all tilesets.
212+
* Sets the lruCache and download and parse queues so they are shared amongst
213+
* all tilesets from a same {@link View} view.
214+
* @param {View} view - view associated to this layer.
214215
* @private
215216
*/
216-
_setupCacheAndQueues() {
217-
if (lruCache === null) {
218-
lruCache = this.tilesRenderer.lruCache;
219-
} else {
220-
this.tilesRenderer.lruCache = lruCache;
221-
}
222-
if (downloadQueue === null) {
223-
downloadQueue = this.tilesRenderer.downloadQueue;
217+
_setupCacheAndQueues(view) {
218+
const id = view.id;
219+
if (viewers[id]) {
220+
this.tilesRenderer.lruCache = viewers[id].lruCache;
221+
this.tilesRenderer.downloadQueue = viewers[id].downloadQueue;
222+
this.tilesRenderer.parseQueue = viewers[id].parseQueue;
224223
} else {
225-
this.tilesRenderer.downloadQueue = downloadQueue;
226-
}
227-
if (parseQueue === null) {
228-
parseQueue = this.tilesRenderer.parseQueue;
229-
} else {
230-
this.tilesRenderer.parseQueue = parseQueue;
224+
viewers[id] = {
225+
lruCache: this.tilesRenderer.lruCache,
226+
downloadQueue: this.tilesRenderer.downloadQueue,
227+
parseQueue: this.tilesRenderer.parseQueue,
228+
};
229+
view.addEventListener(VIEW_EVENTS.DISPOSED, (evt) => {
230+
delete viewers[evt.target.id];
231+
});
231232
}
232233
}
233234

@@ -268,6 +269,12 @@ class OGC3DTilesLayer extends GeometryLayer {
268269
});
269270
view.notifyChange(this);
270271
});
272+
273+
274+
this._setupCacheAndQueues(view);
275+
this._setupEvents();
276+
277+
271278
// Start loading tileset and tiles
272279
this.tilesRenderer.update();
273280
}

0 commit comments

Comments
 (0)