Skip to content

Commit

Permalink
TilesRendererBase: Share tile set fetch call (#692)
Browse files Browse the repository at this point in the history
* Add preprocessTileSet function

* Simplify request logic, external tile set detection

* Remove fetchTileSet function

* Fix loading
  • Loading branch information
gkjohnson authored Aug 16, 2024
1 parent 6f100fe commit 67d59c1
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 134 deletions.
199 changes: 84 additions & 115 deletions src/base/TilesRendererBase.js
Original file line number Diff line number Diff line change
Expand Up @@ -442,60 +442,54 @@ export class TilesRendererBase {
}

// Private Functions
fetchTileSet( url, fetchOptions, parent = null ) {
preprocessTileSet( json, url, parent = null ) {

return fetch( url, fetchOptions )
.then( res => {

if ( res.ok ) {

return res.json();

} else {

throw new Error( `TilesRenderer: Failed to load tileset "${ url }" with status ${ res.status } : ${ res.statusText }` );

}

} )
.then( json => {
const version = json.asset.version;
const [ major, minor ] = version.split( '.' ).map( v => parseInt( v ) );
console.assert(
major <= 1,
'TilesRenderer: asset.version is expected to be a 1.x or a compatible version.',
);

const version = json.asset.version;
const [ major, minor ] = version.split( '.' ).map( v => parseInt( v ) );
console.assert(
major <= 1,
'TilesRenderer: asset.version is expected to be a 1.x or a compatible version.',
);
if ( major === 1 && minor > 0 ) {

if ( major === 1 && minor > 0 ) {
console.warn( 'TilesRenderer: tiles versions at 1.1 or higher have limited support. Some new extensions and features may not be supported.' );

console.warn( 'TilesRenderer: tiles versions at 1.1 or higher have limited support. Some new extensions and features may not be supported.' );

}

// remove trailing slash and last path-segment from the URL
let basePath = url.replace( /\/[^/]*\/?$/, '' );
basePath = new URL( basePath, window.location.href ).toString();
this.preprocessNode( json.root, basePath, parent );

return json;
}

} );
// remove trailing slash and last path-segment from the URL
let basePath = url.replace( /\/[^/]*\/?$/, '' );
basePath = new URL( basePath, window.location.href ).toString();
this.preprocessNode( json.root, basePath, parent );

}

loadRootTileSet( url ) {

// TODO: remove "tileSets" objects since it's not used anywhere else
const tileSets = this.tileSets;
if ( ! ( url in tileSets ) ) {

let processedUrl = url;
this.invokeAllPlugins( plugin => processedUrl = plugin.preprocessURL ? plugin.preprocessURL( processedUrl, null ) : processedUrl );

const pr = this
.fetchTileSet( processedUrl, this.fetchOptions )
const pr = fetch( processedUrl, this.fetchOptions )
.then( res => {

if ( res.ok ) {

return res.json();

} else {

throw new Error( `TilesRenderer: Failed to load tileset "${ processedUrl }" with status ${ res.status } : ${ res.statusText }` );

}

} )
.then( json => {

this.preprocessTileSet( json, processedUrl );
tileSets[ url ] = json;

} );
Expand Down Expand Up @@ -533,15 +527,15 @@ export class TilesRendererBase {

}

let isExternalTileSet = false;
let uri = new URL( tile.content.uri, tile.__basePath + '/' ).toString();
this.invokeAllPlugins( plugin => uri = plugin.preprocessURL ? plugin.preprocessURL( uri, tile ) : uri );

const stats = this.stats;
const lruCache = this.lruCache;
const downloadQueue = this.downloadQueue;
const parseQueue = this.parseQueue;
const uriExtension = getUrlExtension( uri );
const isExternalTileSet = Boolean( uriExtension && /json$/.test( uriExtension ) );
const extension = getUrlExtension( uri );
const addedSuccessfully = lruCache.add( tile, t => {

// Stop the load if it's started
Expand Down Expand Up @@ -639,127 +633,102 @@ export class TilesRendererBase {

};

if ( isExternalTileSet ) {

downloadQueue.add( tile, tileCb => {

// if it has been unloaded then the tile has been disposed
if ( tileCb.__loadIndex !== loadIndex ) {

return Promise.resolve();

}
// queue the download and parse
downloadQueue.add( tile, downloadTile => {

return this.fetchTileSet( uri, Object.assign( { signal }, this.fetchOptions ), tileCb );
if ( downloadTile.__loadIndex !== loadIndex ) {

} )
.then( json => {
return Promise.resolve();

// if it has been unloaded then the tile has been disposed
if ( tile.__loadIndex !== loadIndex ) {
}

return;
return fetch( uri, Object.assign( { signal }, this.fetchOptions ) );

}
} )
.then( res => {

stats.downloading --;
tile.__loadAbort = null;
tile.__loadingState = LOADED;
if ( tile.__loadIndex !== loadIndex ) {

tile.children.push( json.root );
return;

} )
.catch( errorCallback );
}

} else {
if ( res.ok ) {

downloadQueue.add( tile, downloadTile => {
return extension === 'json' ? res.json() : res.arrayBuffer();

if ( downloadTile.__loadIndex !== loadIndex ) {
} else {

return Promise.resolve();
throw new Error( `Failed to load model with error code ${res.status}` );

}

return fetch( uri, Object.assign( { signal }, this.fetchOptions ) );

} )
.then( res => {

if ( tile.__loadIndex !== loadIndex ) {

return;

}

if ( res.ok ) {
.then( content => {

return res.arrayBuffer();
// if it has been unloaded then the tile has been disposed
if ( tile.__loadIndex !== loadIndex ) {

} else {
return;

throw new Error( `Failed to load model with error code ${res.status}` );
}

}
stats.downloading --;
stats.parsing ++;
tile.__loadAbort = null;
tile.__loadingState = PARSING;

} )
.then( buffer => {
return parseQueue.add( tile, parseTile => {

// if it has been unloaded then the tile has been disposed
if ( tile.__loadIndex !== loadIndex ) {
if ( parseTile.__loadIndex !== loadIndex ) {

return;
return Promise.resolve();

}

stats.downloading --;
stats.parsing ++;
tile.__loadAbort = null;
tile.__loadingState = PARSING;

return parseQueue.add( tile, parseTile => {

// if it has been unloaded then the tile has been disposed
if ( parseTile.__loadIndex !== loadIndex ) {
if ( extension === 'json' && content.root ) {

return Promise.resolve();
this.preprocessTileSet( content, uri, tile );
tile.children.push( content.root );
isExternalTileSet = true;
return Promise.resolve();

}
} else {

const extension = getUrlExtension( uri );
return this.invokeOnePlugin( plugin => plugin.parseTile && plugin.parseTile( buffer, parseTile, extension, uri ) );
return this.invokeOnePlugin( plugin => plugin.parseTile && plugin.parseTile( content, parseTile, extension, uri ) );

} );
}

} )
.then( () => {
} );

// if it has been unloaded then the tile has been disposed
if ( tile.__loadIndex !== loadIndex ) {
} )
.then( () => {

return;
// if it has been unloaded then the tile has been disposed
if ( tile.__loadIndex !== loadIndex ) {

}
return;

stats.parsing --;
tile.__loadingState = LOADED;
}

if ( tile.__wasSetVisible ) {
stats.parsing --;
tile.__loadingState = LOADED;

this.setTileVisible( tile, true );
if ( tile.__wasSetVisible ) {

}
this.setTileVisible( tile, true );

if ( tile.__wasSetActive ) {
}

this.setTileActive( tile, true );
if ( tile.__wasSetActive ) {

}
this.setTileActive( tile, true );

} )
.catch( errorCallback );
}

}
} )
.catch( errorCallback );

}

Expand Down
26 changes: 7 additions & 19 deletions src/three/TilesRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -340,31 +340,19 @@ export class TilesRenderer extends TilesRendererBase {
}

/* Overriden */
fetchTileSet( url, ...rest ) {
preprocessTileSet( json, url ) {

const pr = super.fetchTileSet( url, ...rest );
pr.then( json => {
super.preprocessTileSet( json, url );

// Push this onto the end of the event stack to ensure this runs
// after the base renderer has placed the provided json where it
// needs to be placed and is ready for an update.
queueMicrotask( () => {

this.dispatchEvent( {
type: 'load-tile-set',
tileSet: json,
url,
} );
queueMicrotask( () => {

this.dispatchEvent( {
type: 'load-tile-set',
tileSet: json,
url,
} );


} ).catch( () => {

// error is logged internally

} );
return pr;

}

Expand Down

0 comments on commit 67d59c1

Please sign in to comment.