Skip to content

Commit

Permalink
fix(OGC3DTilesLayer): handle multiple views (#2435)
Browse files Browse the repository at this point in the history
fix(OGC3DTilesLayer): handle multiple views cache
  • Loading branch information
AnthonyGlt authored Oct 18, 2024
1 parent f8021b4 commit b991878
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 28 deletions.
16 changes: 11 additions & 5 deletions src/Core/View.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const VIEW_EVENTS = {
INITIALIZED: 'initialized',
COLOR_LAYERS_ORDER_CHANGED,
CAMERA_MOVED: 'camera-moved',
DISPOSED: 'disposed',
};

/**
Expand Down Expand Up @@ -119,8 +120,11 @@ const viewers = [];
// Size of the camera frustrum, in meters
let screenMeters;

let id = 0;

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

this.domElement = viewerDiv;
this.id = id++;

this.referenceCrs = crs;

Expand Down Expand Up @@ -303,8 +308,6 @@ class View extends THREE.EventDispatcher {
}
// remove alls frameRequester
this.removeAllFrameRequesters();
// remove alls events
this.removeAllEvents();
// remove all layers
const layers = this.getLayers(l => !l.isTiledGeometryLayer && !l.isAtmosphere);
for (const layer of layers) {
Expand All @@ -321,6 +324,9 @@ class View extends THREE.EventDispatcher {
viewers.splice(id, 1);
// Remove remaining objects in the scene (e.g. helpers, debug, etc.)
this.scene.traverse(ObjectRemovalHelper.cleanup);
this.dispatchEvent({ type: VIEW_EVENTS.DISPOSED });
// remove alls events
this.removeAllEvents();
}

/**
Expand Down
53 changes: 30 additions & 23 deletions src/Layer/OGC3DTilesLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,22 @@ import PointsMaterial, {
PNTS_SIZE_MODE,
ClassificationScheme,
} from 'Renderer/PointsMaterial';
import { VIEW_EVENTS } from 'Core/View';

const _raycaster = new THREE.Raycaster();

// Stores lruCache, downloadQueue and parseQueue for each id of view {@link View}
// every time a tileset has been added
// https://github.com/iTowns/itowns/issues/2426
const viewers = {};

// Internal instance of GLTFLoader, passed to 3d-tiles-renderer-js to support GLTF 1.0 and 2.0
// Temporary exported to be used in deprecated B3dmParser
export const itownsGLTFLoader = new iGLTFLoader();
itownsGLTFLoader.register(() => new GLTFMeshFeaturesExtension());
itownsGLTFLoader.register(() => new GLTFStructuralMetadataExtension());
itownsGLTFLoader.register(() => new GLTFCesiumRTCExtension());

// Instantiated by the first tileset. Used to share cache and download and parse queues between tilesets
let lruCache = null;
let downloadQueue = null;
let parseQueue = null;

export const OGC3DTILES_LAYER_EVENTS = {
/**
* Fired when a new root or child tile set is loaded
Expand Down Expand Up @@ -171,9 +172,6 @@ class OGC3DTilesLayer extends GeometryLayer {

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

this._setupCacheAndQueues();
this._setupEvents();

this.object3d.add(this.tilesRenderer.group);

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


/**
* Sets the lruCache and download and parse queues so they are shared amongst all tilesets.
* Sets the lruCache and download and parse queues so they are shared amongst
* all tilesets from a same {@link View} view.
* @param {View} view - view associated to this layer.
* @private
*/
_setupCacheAndQueues() {
if (lruCache === null) {
lruCache = this.tilesRenderer.lruCache;
} else {
this.tilesRenderer.lruCache = lruCache;
}
if (downloadQueue === null) {
downloadQueue = this.tilesRenderer.downloadQueue;
_setupCacheAndQueues(view) {
const id = view.id;
if (viewers[id]) {
this.tilesRenderer.lruCache = viewers[id].lruCache;
this.tilesRenderer.downloadQueue = viewers[id].downloadQueue;
this.tilesRenderer.parseQueue = viewers[id].parseQueue;
} else {
this.tilesRenderer.downloadQueue = downloadQueue;
}
if (parseQueue === null) {
parseQueue = this.tilesRenderer.parseQueue;
} else {
this.tilesRenderer.parseQueue = parseQueue;
viewers[id] = {
lruCache: this.tilesRenderer.lruCache,
downloadQueue: this.tilesRenderer.downloadQueue,
parseQueue: this.tilesRenderer.parseQueue,
};
view.addEventListener(VIEW_EVENTS.DISPOSED, (evt) => {
delete viewers[evt.target.id];
});
}
}

Expand Down Expand Up @@ -268,6 +269,12 @@ class OGC3DTilesLayer extends GeometryLayer {
});
view.notifyChange(this);
});


this._setupCacheAndQueues(view);
this._setupEvents();


// Start loading tileset and tiles
this.tilesRenderer.update();
}
Expand Down

0 comments on commit b991878

Please sign in to comment.