diff --git a/src/core/plugins/GoogleCloudAuthPlugin.js b/src/core/plugins/GoogleCloudAuthPlugin.js index 4feba5213..7ec2935f2 100644 --- a/src/core/plugins/GoogleCloudAuthPlugin.js +++ b/src/core/plugins/GoogleCloudAuthPlugin.js @@ -67,7 +67,7 @@ export class GoogleCloudAuthPlugin { this._visibilityChangeCallback = ( { tile, visible } ) => { - const copyright = tile.cached.metadata?.asset?.copyright || ''; + const copyright = tile.engineData.metadata?.asset?.copyright || ''; if ( visible ) { this._attributionsManager.addAttributions( copyright ); diff --git a/src/core/renderer/tiles/TilesRendererBase.js b/src/core/renderer/tiles/TilesRendererBase.js index 3fcb866fb..9efebe25d 100644 --- a/src/core/renderer/tiles/TilesRendererBase.js +++ b/src/core/renderer/tiles/TilesRendererBase.js @@ -649,6 +649,24 @@ export class TilesRendererBase { tile.__lastFrameVisited = - 1; + // Initialize engineData data structure with engine-agnostic fields + tile.engineData = { + scene: null, + metadata: null, + boundingVolume: null, + }; + + // Backwards compatibility: cached is an alias for engineData + Object.defineProperty( tile, 'cached', { + get() { + + return this.engineData; + + }, + enumerable: false, + configurable: true, + } ); + this.invokeAllPlugins( plugin => { plugin !== this && plugin.preprocessNode && plugin.preprocessNode( tile, tilesetDir, parentTile ); @@ -775,7 +793,7 @@ export class TilesRendererBase { if ( plugin.calculateBytesUsed ) { - bytes += plugin.calculateBytesUsed( tile, tile.cached.scene ) || 0; + bytes += plugin.calculateBytesUsed( tile, tile.engineData.scene ) || 0; } @@ -1121,11 +1139,11 @@ export class TilesRendererBase { } - if ( tile.cached.scene ) { + if ( tile.engineData.scene ) { this.dispatchEvent( { type: 'load-model', - scene: tile.cached.scene, + scene: tile.engineData.scene, tile, url: uri, } ); diff --git a/src/three/plugins/DebugTilesPlugin.js b/src/three/plugins/DebugTilesPlugin.js index 7d5c16188..235b67f5b 100644 --- a/src/three/plugins/DebugTilesPlugin.js +++ b/src/three/plugins/DebugTilesPlugin.js @@ -282,9 +282,9 @@ export class DebugTilesPlugin { // initialize an already-loaded tiles tiles.traverse( tile => { - if ( tile.cached.scene ) { + if ( tile.engineData.scene ) { - this._onLoadModel( tile.cached.scene, tile ); + this._onLoadModel( tile.engineData.scene, tile ); } @@ -312,7 +312,7 @@ export class DebugTilesPlugin { } - const scene = tile.cached.scene; + const scene = tile.engineData.scene; if ( scene ) { scene.traverse( c => { @@ -451,7 +451,7 @@ export class DebugTilesPlugin { // update plugins visibleTiles.forEach( tile => { - const scene = tile.cached.scene; + const scene = tile.engineData.scene; // create a random color per-tile let h, s, l; @@ -656,7 +656,7 @@ export class DebugTilesPlugin { _createBoundHelper( tile ) { const tiles = this.tiles; - const cached = tile.cached; + const cached = tile.engineData; const { sphere, obb, region } = cached.boundingVolume; if ( obb ) { @@ -750,7 +750,7 @@ export class DebugTilesPlugin { _updateBoundHelper( tile, visible ) { - const cached = tile.cached; + const cached = tile.engineData; if ( ! cached ) { @@ -910,7 +910,7 @@ export class DebugTilesPlugin { _onDisposeModel( tile ) { - const cached = tile.cached; + const cached = tile.engineData; if ( cached.boxHelperGroup ) { cached.boxHelperGroup.children[ 0 ].geometry.dispose(); diff --git a/src/three/plugins/LoadRegionPlugin.js b/src/three/plugins/LoadRegionPlugin.js index 9d5f07907..448c0913e 100644 --- a/src/three/plugins/LoadRegionPlugin.js +++ b/src/three/plugins/LoadRegionPlugin.js @@ -54,7 +54,7 @@ export class LoadRegionPlugin { // tiles are only loaded if they are within those shapes. calculateTileViewError( tile, target ) { - const boundingVolume = tile.cached.boundingVolume; + const boundingVolume = tile.engineData.boundingVolume; const { regions, tiles } = this; let inShape = false; diff --git a/src/three/plugins/QuantizedMeshPlugin.js b/src/three/plugins/QuantizedMeshPlugin.js index 56bc561c2..dcdba719d 100644 --- a/src/three/plugins/QuantizedMeshPlugin.js +++ b/src/three/plugins/QuantizedMeshPlugin.js @@ -253,7 +253,7 @@ export class QuantizedMeshPlugin { clipper.minLon = west; clipper.maxLon = east; - result = clipper.clipToQuadrant( tile.parent.cached.scene, left, bottom ); + result = clipper.clipToQuadrant( tile.parent.engineData.scene, left, bottom ); } else if ( extension === 'terrain' ) { @@ -284,7 +284,7 @@ export class QuantizedMeshPlugin { const { minHeight, maxHeight, metadata } = result.userData; tile.boundingVolume.region[ 4 ] = minHeight; tile.boundingVolume.region[ 5 ] = maxHeight; - tile.cached.boundingVolume.setRegionData( ellipsoid, ...tile.boundingVolume.region ); + tile.engineData.boundingVolume.setRegionData( ellipsoid, ...tile.boundingVolume.region ); // use the geometric error value if it's present if ( metadata ) { diff --git a/src/three/plugins/TileFlatteningPlugin.js b/src/three/plugins/TileFlatteningPlugin.js index 216d66da8..6656a7f7d 100644 --- a/src/three/plugins/TileFlatteningPlugin.js +++ b/src/three/plugins/TileFlatteningPlugin.js @@ -94,7 +94,7 @@ export class TileFlatteningPlugin { const { positionsUpdated, positionsMap, shapes, tiles } = this; positionsUpdated.add( tile ); - const scene = tile.cached.scene; + const scene = tile.engineData.scene; if ( ! positionsMap.has( tile ) ) { // save the geometry positions for resetting after diff --git a/src/three/plugins/UnloadTilesPlugin.js b/src/three/plugins/UnloadTilesPlugin.js index d3bd0e943..c28eb243c 100644 --- a/src/three/plugins/UnloadTilesPlugin.js +++ b/src/three/plugins/UnloadTilesPlugin.js @@ -68,7 +68,7 @@ export class UnloadTilesPlugin { const unloadCallback = tile => { - const scene = tile.cached.scene; + const scene = tile.engineData.scene; const visible = tiles.visibleTiles.has( tile ); if ( ! visible ) { diff --git a/src/three/plugins/batched/BatchedTilesPlugin.js b/src/three/plugins/batched/BatchedTilesPlugin.js index b2fb77880..25c6158f5 100644 --- a/src/three/plugins/batched/BatchedTilesPlugin.js +++ b/src/three/plugins/batched/BatchedTilesPlugin.js @@ -145,7 +145,7 @@ export class BatchedTilesPlugin { setTileVisible( tile, visible ) { - const scene = tile.cached.scene; + const scene = tile.engineData.scene; if ( visible ) { // Add tileset to the batched mesh if it hasn't been added already @@ -374,7 +374,7 @@ export class BatchedTilesPlugin { // TODO: this would be best done in a more general way if ( this.discardOriginalContent ) { - tile.cached.textures.forEach( tex => { + tile.engineData.textures.forEach( tex => { if ( tex.image instanceof ImageBitmap ) { @@ -384,10 +384,10 @@ export class BatchedTilesPlugin { } ); - tile.cached.scene = null; - tile.cached.materials = []; - tile.cached.geometries = []; - tile.cached.textures = []; + tile.engineData.scene = null; + tile.engineData.materials = []; + tile.engineData.geometries = []; + tile.engineData.textures = []; } diff --git a/src/three/plugins/fade/TilesFadePlugin.js b/src/three/plugins/fade/TilesFadePlugin.js index aef03a672..ca693f16e 100644 --- a/src/three/plugins/fade/TilesFadePlugin.js +++ b/src/three/plugins/fade/TilesFadePlugin.js @@ -59,7 +59,7 @@ function onUpdateAfter() { // if a tile is fading out then it may not be traversed and thus will not have // the frustum flag set correctly. - const scene = t.cached.scene; + const scene = t.engineData.scene; if ( scene ) { scene.visible = t.__inFrustum; @@ -124,7 +124,7 @@ function onUpdateAfter() { fadeManager.forEachObject( ( tile, { fadeIn, fadeOut } ) => { // prevent faded tiles from being unloaded - const scene = tile.cached.scene; + const scene = tile.engineData.scene; const isFadingOut = fadeManager.isFadingOut( tile ); tiles.markTileUsed( tile ); if ( scene ) { @@ -252,7 +252,7 @@ export class TilesFadePlugin { // this function gets fired _after_ all set visible callbacks including the batched meshes // revert the scene and fade to the initial state when toggling - const scene = tile.cached.scene; + const scene = tile.engineData.scene; if ( scene ) { scene.visible = true; @@ -308,7 +308,7 @@ export class TilesFadePlugin { fadeManager.onFadeComplete = ( tile, visible ) => { // mark the fade as finished and reset the fade parameters - this._fadeMaterialManager.setFade( tile.cached.scene, 0, 0 ); + this._fadeMaterialManager.setFade( tile.engineData.scene, 0, 0 ); this.forEachBatchIds( tile, ( id, batchedMesh, plugin ) => { diff --git a/src/three/plugins/images/EllipsoidProjectionTilesPlugin.js b/src/three/plugins/images/EllipsoidProjectionTilesPlugin.js index e2bf037aa..6624521bc 100644 --- a/src/three/plugins/images/EllipsoidProjectionTilesPlugin.js +++ b/src/three/plugins/images/EllipsoidProjectionTilesPlugin.js @@ -63,7 +63,7 @@ export class EllipsoidProjectionTilesPlugin extends ImageFormatPlugin { // adjust the geometry to position it at the region const { position, normal, uv } = geometry.attributes; const vertCount = position.count; - tile.cached.boundingVolume.getSphere( _sphere ); + tile.engineData.boundingVolume.getSphere( _sphere ); for ( let i = 0; i < vertCount; i ++ ) { // retrieve attributes diff --git a/src/three/plugins/images/ImageOverlayPlugin.js b/src/three/plugins/images/ImageOverlayPlugin.js index 3f6e9847c..0c64af73e 100644 --- a/src/three/plugins/images/ImageOverlayPlugin.js +++ b/src/three/plugins/images/ImageOverlayPlugin.js @@ -426,7 +426,7 @@ export class ImageOverlayPlugin { } - const clone = parent.cached.scene.clone(); + const clone = parent.engineData.scene.clone(); clone.updateMatrixWorld(); if ( fullDispose || parent[ SPLIT_HASH ] !== this._getSplitVectors( clone, parent ).hash ) { @@ -613,7 +613,7 @@ export class ImageOverlayPlugin { // remove the parent transform because it will be multiplied back in after the fact result.matrix - .premultiply( tile.cached.transformInverse ) + .premultiply( tile.engineData.transformInverse ) .decompose( result.position, result.quaternion, result.scale ); // collect the meshes diff --git a/src/three/renderer/tiles/TilesRenderer.js b/src/three/renderer/tiles/TilesRenderer.js index 093764206..bee4c785d 100644 --- a/src/three/renderer/tiles/TilesRenderer.js +++ b/src/three/renderer/tiles/TilesRenderer.js @@ -173,7 +173,7 @@ export class TilesRenderer extends TilesRendererBase { } - const boundingVolume = this.root.cached.boundingVolume; + const boundingVolume = this.root.engineData.boundingVolume; if ( boundingVolume ) { boundingVolume.getAABB( target ); @@ -195,7 +195,7 @@ export class TilesRenderer extends TilesRendererBase { } - const boundingVolume = this.root.cached.boundingVolume; + const boundingVolume = this.root.engineData.boundingVolume; if ( boundingVolume ) { boundingVolume.getOBB( targetBox, targetMatrix ); @@ -217,7 +217,7 @@ export class TilesRenderer extends TilesRendererBase { } - const boundingVolume = this.root.cached.boundingVolume; + const boundingVolume = this.root.engineData.boundingVolume; if ( boundingVolume ) { boundingVolume.getSphere( target ); @@ -235,7 +235,7 @@ export class TilesRenderer extends TilesRendererBase { this.traverse( tile => { - const scene = tile.cached && tile.cached.scene; + const scene = tile.engineData && tile.engineData.scene; if ( scene ) { callback( scene, tile ); @@ -548,7 +548,7 @@ export class TilesRenderer extends TilesRendererBase { if ( parentTile ) { - transform.premultiply( parentTile.cached.transform ); + transform.premultiply( parentTile.engineData.transform ); } @@ -572,35 +572,27 @@ export class TilesRenderer extends TilesRendererBase { } - tile.cached = { - - transform, - transformInverse, - - active: false, - - boundingVolume, - - metadata: null, - scene: null, - geometry: null, - materials: null, - textures: null, - - }; + // Extend the base engineData structure with Three.js-specific fields + // Base class initializes: scene, metadata, boundingVolume + tile.engineData.transform = transform; + tile.engineData.transformInverse = transformInverse; + tile.engineData.boundingVolume = boundingVolume; + tile.engineData.geometry = null; + tile.engineData.materials = null; + tile.engineData.textures = null; } async parseTile( buffer, tile, extension, uri, abortSignal ) { - const cached = tile.cached; + const engineData = tile.engineData; const workingPath = LoaderUtils.getWorkingPath( uri ); const fetchOptions = this.fetchOptions; const manager = this.manager; let promise = null; - const cachedTransform = cached.transform; + const tileTransform = engineData.transform; const upRotationMatrix = this._upRotationMatrix; const fileType = ( LoaderUtils.readMagicBytes( buffer ) || extension ).toLowerCase(); switch ( fileType ) { @@ -737,7 +729,7 @@ export class TilesRenderer extends TilesRendererBase { // ensure the matrix is up to date in case the scene has a transform applied scene.updateMatrix(); - scene.matrix.premultiply( cachedTransform ); + scene.matrix.premultiply( tileTransform ); scene.matrix.decompose( scene.position, scene.quaternion, scene.scale ); // wait for extra processing by plugins if needed @@ -811,11 +803,11 @@ export class TilesRenderer extends TilesRendererBase { } - cached.materials = materials; - cached.geometry = geometry; - cached.textures = textures; - cached.scene = scene; - cached.metadata = metadata; + engineData.materials = materials; + engineData.geometry = geometry; + engineData.textures = textures; + engineData.scene = scene; + engineData.metadata = metadata; } @@ -824,18 +816,18 @@ export class TilesRenderer extends TilesRendererBase { super.disposeTile( tile ); // This could get called before the tile has finished downloading - const cached = tile.cached; - if ( cached.scene ) { + const engineData = tile.engineData; + if ( engineData.scene ) { - const materials = cached.materials; - const geometry = cached.geometry; - const textures = cached.textures; - const parent = cached.scene.parent; + const materials = engineData.materials; + const geometry = engineData.geometry; + const textures = engineData.textures; + const parent = engineData.scene.parent; // dispose of any textures required by the mesh features extension // TODO: these are being discarded here to remove the image bitmaps - // can this be handled in another way? Or more generically? - cached.scene.traverse( child => { + engineData.scene.traverse( child => { if ( child.userData.meshFeatures ) { @@ -879,21 +871,21 @@ export class TilesRenderer extends TilesRendererBase { if ( parent ) { - parent.remove( cached.scene ); + parent.remove( engineData.scene ); } this.dispatchEvent( { type: 'dispose-model', - scene: cached.scene, + scene: engineData.scene, tile, } ); - cached.scene = null; - cached.materials = null; - cached.textures = null; - cached.geometry = null; - cached.metadata = null; + engineData.scene = null; + engineData.materials = null; + engineData.textures = null; + engineData.geometry = null; + engineData.metadata = null; } @@ -901,7 +893,7 @@ export class TilesRenderer extends TilesRendererBase { setTileVisible( tile, visible ) { - const scene = tile.cached.scene; + const scene = tile.engineData.scene; const group = this.group; if ( visible ) { @@ -949,10 +941,10 @@ export class TilesRenderer extends TilesRendererBase { calculateTileViewError( tile, target ) { - const cached = tile.cached; + const engineData = tile.engineData; const cameras = this.cameras; const cameraInfo = this.cameraInfo; - const boundingVolume = cached.boundingVolume; + const boundingVolume = engineData.boundingVolume; let inView = false; let inViewError = - Infinity; diff --git a/src/three/renderer/tiles/raycastTraverse.js b/src/three/renderer/tiles/raycastTraverse.js index 2697cb96b..5db063181 100644 --- a/src/three/renderer/tiles/raycastTraverse.js +++ b/src/three/renderer/tiles/raycastTraverse.js @@ -13,7 +13,7 @@ function distanceSort( a, b ) { function intersectTileScene( tile, raycaster, renderer, intersects ) { - const { scene } = tile.cached; + const { scene } = tile.engineData; const didRaycast = renderer.invokeOnePlugin( plugin => plugin.raycastTile && plugin.raycastTile( tile, scene, raycaster, intersects ) ); if ( ! didRaycast ) { @@ -66,7 +66,7 @@ export function raycastTraverseFirstHit( renderer, tile, raycaster, localRay = n } // track the tile and hit distance for sorting - const boundingVolume = child.cached.boundingVolume; + const boundingVolume = child.engineData.boundingVolume; if ( boundingVolume.intersectRay( localRay, _vec ) !== null ) { _vec.applyMatrix4( group.matrixWorld ); @@ -140,7 +140,7 @@ export function raycastTraverse( renderer, tile, raycaster, intersects, localRay } const { group, activeTiles } = renderer; - const { boundingVolume } = tile.cached; + const { boundingVolume } = tile.engineData; // get the ray in the local group frame if ( localRay === null ) {