Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(OGC3DTilesLayer): handle multiple views #2435

Merged
merged 4 commits into from
Oct 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -152,9 +153,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 @@ -190,25 +188,28 @@ class OGC3DTilesLayer extends GeometryLayer {
this.pntsMaxAttenuatedSize = config.pntsMaxAttenuatedSize || 7;
}


/**
* 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 @@ -249,6 +250,12 @@ class OGC3DTilesLayer extends GeometryLayer {
});
view.notifyChange(this);
});


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


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