diff --git a/src/core/renderer/tiles/optimizedTraverseFunctions.js b/src/core/renderer/tiles/optimizedTraverseFunctions.js index 1725e8830..aa11830d2 100644 --- a/src/core/renderer/tiles/optimizedTraverseFunctions.js +++ b/src/core/renderer/tiles/optimizedTraverseFunctions.js @@ -434,7 +434,7 @@ function toggleTiles( tile, renderer ) { } - } else { + } else if ( tile.internal.hasContent ) { tile.traversal.active = false; @@ -449,7 +449,7 @@ function toggleTiles( tile, renderer ) { } // if the tile is loaded and in frustum we can mark it as visible - tile.traversal.visible = tile.internal.hasRenderableContent && tile.traversal.active && tile.traversal.inFrustum && tile.internal.loadingState === LOADED; + tile.traversal.visible = tile.traversal.active && tile.traversal.inFrustum && ( tile.internal.hasRenderableContent && tile.internal.loadingState === LOADED || ! tile.internal.hasContent ); renderer.stats.used ++; if ( tile.traversal.inFrustum ) { @@ -488,7 +488,8 @@ function toggleTiles( tile, renderer ) { } // If the active or visible state changed then call the functions. - if ( tile.internal.hasRenderableContent && tile.internal.loadingState === LOADED ) { + // Fire for tiles with loaded renderable content, or for empty tiles (no content at all). + if ( ( tile.internal.hasRenderableContent && tile.internal.loadingState === LOADED ) || ! tile.internal.hasContent ) { if ( tile.traversal.wasSetActive !== setActive ) { diff --git a/src/core/renderer/tiles/traverseFunctions.js b/src/core/renderer/tiles/traverseFunctions.js index 8283d815b..38107090d 100644 --- a/src/core/renderer/tiles/traverseFunctions.js +++ b/src/core/renderer/tiles/traverseFunctions.js @@ -327,7 +327,7 @@ function markVisibleTiles( tile, renderer ) { // Request the tile contents or mark it as visible if we've found a leaf. if ( tile.traversal.isLeaf ) { - if ( tile.internal.loadingState === LOADED ) { + if ( tile.internal.loadingState === LOADED || ! tile.internal.hasContent ) { if ( tile.traversal.inFrustum ) { @@ -449,7 +449,8 @@ function toggleTiles( tile, renderer ) { } // If the active or visible state changed then call the functions. - if ( tile.internal.hasRenderableContent && tile.internal.loadingState === LOADED ) { + // Fire for tiles with loaded renderable content, or for empty tiles (no content at all). + if ( ( tile.internal.hasRenderableContent && tile.internal.loadingState === LOADED ) || ! tile.internal.hasContent ) { if ( tile.traversal.wasSetActive !== setActive ) { diff --git a/src/three/plugins/DebugTilesPlugin.js b/src/three/plugins/DebugTilesPlugin.js index 66e9c9915..84b0d914d 100644 --- a/src/three/plugins/DebugTilesPlugin.js +++ b/src/three/plugins/DebugTilesPlugin.js @@ -324,7 +324,7 @@ export class DebugTilesPlugin { }; - this._onTileVisibilityChangeCB = ( { scene, tile, visible } ) => { + this._onTileVisibilityChangeCB = ( { tile, visible } ) => { this._onTileVisibilityChange( tile, visible ); @@ -367,7 +367,7 @@ export class DebugTilesPlugin { if ( result ) { - return true; + return; } @@ -647,7 +647,12 @@ export class DebugTilesPlugin { // update tile materials visibleTiles.forEach( tile => { - const scene = tile.engineData.scene; + const { scene } = tile.engineData; + if ( ! scene ) { + + return; + + } // create a random color per-tile let h, s, l; diff --git a/src/three/plugins/TileFlatteningPlugin.js b/src/three/plugins/TileFlatteningPlugin.js index 396da98f4..570284de5 100644 --- a/src/three/plugins/TileFlatteningPlugin.js +++ b/src/three/plugins/TileFlatteningPlugin.js @@ -97,9 +97,15 @@ export class TileFlatteningPlugin { _updateTile( tile ) { const { positionsUpdated, positionsMap, shapes, tiles } = this; + const { scene } = tile.engineData; positionsUpdated.add( tile ); - const scene = tile.engineData.scene; + if ( ! scene ) { + + return; + + } + if ( ! positionsMap.has( tile ) ) { // save the geometry positions for resetting after @@ -222,7 +228,6 @@ export class TileFlatteningPlugin { } ); - this.tiles.dispatchEvent( { type: 'needs-render' } ); } diff --git a/src/three/plugins/batched/BatchedTilesPlugin.js b/src/three/plugins/batched/BatchedTilesPlugin.js index 7591a75f4..c5ef02a90 100644 --- a/src/three/plugins/batched/BatchedTilesPlugin.js +++ b/src/three/plugins/batched/BatchedTilesPlugin.js @@ -169,6 +169,12 @@ export class BatchedTilesPlugin { setTileVisible( tile, visible ) { const scene = tile.engineData.scene; + if ( ! scene ) { + + return false; + + } + if ( visible ) { // Add tileset to the batched mesh if it hasn't been added already diff --git a/src/three/plugins/fade/TilesFadePlugin.js b/src/three/plugins/fade/TilesFadePlugin.js index 09889bbd5..7ae904cbc 100644 --- a/src/three/plugins/fade/TilesFadePlugin.js +++ b/src/three/plugins/fade/TilesFadePlugin.js @@ -399,6 +399,12 @@ export class TilesFadePlugin { // callback for fading to prevent tiles from being removed until the fade effect has completed setTileVisible( tile, visible ) { + if ( ! tile.engineData.scene ) { + + return false; + + } + const fadeManager = this._fadeManager; // track the fade state diff --git a/src/three/renderer/tiles/raycastTraverse.js b/src/three/renderer/tiles/raycastTraverse.js index ef49cd5a4..2e2003360 100644 --- a/src/three/renderer/tiles/raycastTraverse.js +++ b/src/three/renderer/tiles/raycastTraverse.js @@ -14,6 +14,12 @@ function distanceSort( a, b ) { function intersectTileScene( tile, raycaster, renderer, intersects ) { const { scene } = tile.engineData; + if ( ! scene ) { + + return; + + } + const didRaycast = renderer.invokeOnePlugin( plugin => plugin.raycastTile && plugin.raycastTile( tile, scene, raycaster, intersects ) ); if ( ! didRaycast ) {