Quellcode durchsuchen

Moved ion code out from core

Petter vor 4 Jahren
Ursprung
Commit
eda6e9ccca
4 geänderte Dateien mit 65 neuen und 152 gelöschten Zeilen
  1. 42 43
      example/ionExample.js
  2. 5 1
      src/base/TilesRendererBase.d.ts
  3. 7 101
      src/base/TilesRendererBase.js
  4. 11 7
      src/three/TilesRenderer.js

+ 42 - 43
example/ionExample.js

@@ -46,6 +46,8 @@ let raycaster, mouse, rayIntersect, lastHoveredElement;
 let offsetParent;
 let statsContainer, stats;
 
+const defaultIonToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwY2Q2MzQ1OS1kNjI4LTRiZDEtOWVkZC1kMWI4YzAyODU3OGMiLCJpZCI6MjU5LCJpYXQiOjE2MDY4NzMyMTh9.8EwC6vilVHM2yizt8nG6VmbNu66QiCrk3O-1lEDPI9I';
+
 let params = {
 
 	'enableUpdate': true,
@@ -55,7 +57,7 @@ let params = {
 	'orthographic': false,
 
 	'ionAssetId': '40866',
-	'ionAccessToken': 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiIwY2Q2MzQ1OS1kNjI4LTRiZDEtOWVkZC1kMWI4YzAyODU3OGMiLCJpZCI6MjU5LCJpYXQiOjE2MDY4NzMyMTh9.8EwC6vilVHM2yizt8nG6VmbNu66QiCrk3O-1lEDPI9I',
+	'ionAccessToken': defaultIonToken,
 	'preFetchToken': false,
 	'errorTarget': 6,
 	'errorThreshold': 60,
@@ -77,35 +79,6 @@ let params = {
 init();
 animate();
 
-function loadIonJson( assetId, accessToken ) {
-
-	const ionEndpointUrl = new URL(
-		`https://api.cesium.com/v1/assets/${assetId}/endpoint`
-	);
-	ionEndpointUrl.searchParams.append( "access_token", accessToken );
-
-	return fetch( ionEndpointUrl, { mode: 'cors' } )
-		.then( ( res ) => {
-
-			if ( res.ok ) {
-
-				return res.json();
-
-			} else {
-
-				return Promise.reject( `${res.status} : ${res.statusText}` );
-
-			}
-
-		} )
-		.then( ( json ) => {
-
-			return [ json.url, json.accessToken ];
-
-		} );
-
-}
-
 function setupTiles() {
 
 	tiles.fetchOptions.mode = 'cors';
@@ -156,28 +129,49 @@ function reinstantiateTiles() {
 
 	if ( params.ionAssetId ) {
 
-		if ( params.preFetchToken ) {
 
-			// If you don't want to share your ion access token on the client you can pre-fetch a temporary 1h bearer token on the server like so
-			loadIonJson( params.ionAssetId, params.ionAccessToken )
-				.then( ( [ ionUrl, token ] ) => {
+		url = new URL( `https://api.cesium.com/v1/assets/${params.ionAssetId}/endpoint` );
+		url.searchParams.append( 'access_token', params.ionAccessToken );
 
-					tiles = new TilesRenderer( ionUrl, token );
+		fetch( url, { mode: 'cors' } )
+			.then( ( res ) => {
 
-					setupTiles();
+				if ( res.ok ) {
 
-				} );
+					return res.json();
 
+				} else {
 
-		} else {
+					return Promise.reject( `${res.status} : ${res.statusText}` );
 
-			// If no access token is given, the default ion token will be used.
-			tiles = new TilesRenderer( params.ionAssetId, params.ionAccessToken );
+				}
 
-			setupTiles();
+			} )
+			.then( ( json ) => {
 
-		}
+				url = new URL( json.url );
+				const version = url.searchParams.get( 'v' );
+
+				tiles = new TilesRenderer( url );
+				tiles.fetchOptions.headers = {};
+				tiles.fetchOptions.headers.Authorization = `Bearer ${json.accessToken}`;
+
+				tiles.onPreprocessURL = uri => {
+
+					uri = new URL( uri );
+					uri.searchParams.append( 'v', version );
+					return uri;
 
+				};
+
+				setupTiles();
+
+			} )
+			.catch( err => {
+
+				console.error( 'Unable to get ion tileset:', err );
+
+			} );
 
 	} else {
 
@@ -291,7 +285,12 @@ function init() {
 	scene.add( rayIntersect );
 	rayIntersect.visible = false;
 
-	reinstantiateTiles();
+	new Promise( r => setTimeout( r, 1 ) )
+		.then( () => {
+
+			reinstantiateTiles();
+
+		} );
 
 	onWindowResize();
 	window.addEventListener( 'resize', onWindowResize, false );

+ 5 - 1
src/base/TilesRendererBase.d.ts

@@ -14,12 +14,16 @@ export class TilesRendererBase {
 	stopAtEmptyTiles : Boolean;
 
 	fetchOptions : Object;
+	/** function to preprocess the url for each individual tile */
+	onPreprocessURL : (uri: string | URL) => URL | string | null;
+	/** Does the tileset exist on the surface of an ellipsoid. If undefined, tries determine by distance from origin */
+	isGeoReferenced: boolean | undefined;
 
 	lruCache : LRUCache;
 	parseQueue : PriorityQueue;
 	downloadQueue : PriorityQueue;
 
-	constructor( url : String, ionAccessToken? : String );
+	constructor( url : String );
 	update() : void;
 	traverse(
 		beforeCb : ( ( tile : Object, parent : Object, depth : Number ) => Boolean ) | null,

+ 7 - 101
src/base/TilesRendererBase.js

@@ -8,8 +8,6 @@ import { UNLOADED, LOADING, PARSING, LOADED, FAILED } from './constants.js';
 // Function for sorting the evicted LRU items. We should evict the shallowest depth first.
 const priorityCallback = tile => 1 / ( tile.__depthFromRenderedParent + 1 );
 
-const defaultIonToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiJlNzMyOGZjZC1jMWUzLTQxNDctOGQxYi03YTYyZDQ1OTIxMjkiLCJpZCI6MjU5LCJpYXQiOjE2MDE1Njk1NDN9.X1a0DCM6F539g9MDSs_ldZ0gwgruxLAZiBl60JwG1ck';
-
 export class TilesRendererBase {
 
 	get rootTileSet() {
@@ -34,17 +32,16 @@ export class TilesRendererBase {
 
 	}
 
-	//The url can be:
-	//A plain url to the tileset json file
-	//A Cesium Ion asset number with access token
-	//A url to the Cesium Ion json file with bearer token as the ionAccessToken. This needs to be fetched from the Ion endpoint separately
-	constructor( url, ionAccessToken = defaultIonToken ) {
+	constructor( url ) {
 
 		// state
 		this.tileSets = {};
+		this.rootURL = url;
 		this.fetchOptions = {};
 
-		this.setupUrlTokens( url, ionAccessToken );
+		this.isGeoReferenced = undefined;
+
+		this.onPreprocessURL = null;
 
 		const lruCache = new LRUCache();
 		lruCache.unloadPriorityCallback = priorityCallback;
@@ -81,73 +78,6 @@ export class TilesRendererBase {
 
 	}
 
-	setupUrlTokens( url, ionToken ) {
-
-		this.ionAssetId = this.isInt( url ) ? url : null;
-		this.ionAccessToken = ionToken;
-		this.fetchOptions.headers = {};
-
-		if ( ! this.ionAssetId ) {
-
-			this.rootURL = url;
-			if ( this.isIonJsonUrl( url ) ) {
-
-				this.ionAssetId = url.split( "/" )[ 3 ];
-				this.ionJsonUrl = new URL( url );
-				this.ionVersion = this.ionJsonUrl.searchParams.get( 'v' );
-				this.fetchOptions.headers.Authorization = `Bearer ${ionToken}`;
-				this.rootURL = this.ionJsonUrl;
-
-			}
-			return;
-
-		} else {
-
-			this.ionEndpointUrl = new URL( `https://api.cesium.com/v1/assets/${this.ionAssetId}/endpoint` );
-			this.ionEndpointUrl.searchParams.append( 'access_token', ionToken );
-
-		}
-
-	}
-
-	isInt( input ) {
-
-		return ( typeof input === 'string' ) ? ! isNaN( input ) && ! isNaN( parseFloat( input, 10 ) ) && Number.isInteger( parseFloat( input, 10 ) ) : Number.isInteger( input );
-
-	}
-	isIonJsonUrl( input ) {
-
-		return input.includes( '://assets.cesium.com/' ) && input.includes( '/tileset.json' );
-
-	}
-
-	getIonAssetJson( url ) {
-
-		return fetch( url, this.fetchOptions )
-			.then( res => {
-
-				if ( res.ok ) {
-
-					return res.json();
-
-				} else {
-
-					return Promise.reject( `${res.status} : ${res.statusText}` );
-
-				}
-
-			} )
-			.then( json => {
-
-				this.ionJsonUrl = new URL( json.url );
-				this.ionVersion = this.ionJsonUrl.searchParams.get( 'v' );
-				this.fetchOptions.headers.Authorization = `Bearer ${json.accessToken}`;
-				this.rootURL = this.ionJsonUrl;
-
-			} );
-
-	}
-
 	traverse( beforecb, aftercb ) {
 
 		const tileSets = this.tileSets;
@@ -167,18 +97,6 @@ export class TilesRendererBase {
 		const rootTileSet = tileSets[ this.rootURL ];
 		if ( ! ( this.rootURL in tileSets ) ) {
 
-			if ( this.ionAssetId && ! this.ionJsonUrl ) {
-
-				if ( this.ionJsonUrl == undefined ) {
-
-					this.ionJsonUrl = false; // Can't use promise to block update loop, hence this hack
-					this.getIonAssetJson( this.ionEndpointUrl ).catch( err => console.error( `TilesRenderer: Failed to load ION endpoint "${this.ionEndpointUrl}" with error: ${err}` ) );
-
-				}
-				return;
-
-			}
-
 			this.loadRootTileSet( this.rootURL );
 			return;
 
@@ -513,13 +431,7 @@ export class TilesRendererBase {
 
 				}
 
-				let uri = tile.content.uri;
-				if ( this.ionAssetId ) {
-
-					uri = new URL( tile.content.uri );
-					uri.searchParams.append( 'v', this.ionVersion );
-
-				}
+				const uri = this.onPreprocessURL ? this.onPreprocessURL( tile.content.uri ) : tile.content.uri;
 				return this.fetchTileSet( uri, Object.assign( { signal }, this.fetchOptions ), tile );
 
 			} )
@@ -550,14 +462,8 @@ export class TilesRendererBase {
 					return Promise.resolve();
 
 				}
-				let uri = tile.content.uri;
-				if ( this.ionAssetId ) {
-
-					uri = new URL( tile.content.uri );
-					uri.searchParams.append( 'v', this.ionVersion );
-
-				}
 
+				const uri = this.onPreprocessURL ? this.onPreprocessURL( tile.content.uri ) : tile.content.uri;
 				return fetch( uri, Object.assign( { signal }, this.fetchOptions ) );
 
 			} )

+ 11 - 7
src/three/TilesRenderer.js

@@ -264,22 +264,26 @@ export class TilesRenderer extends TilesRendererBase {
 			}
 			Promise.resolve().then( () => {
 
-				if ( this.ionAssetId ) {
+				if ( this.isGeoReferenced === undefined ) {
 
-					const transform = this.root.cached.boxTransform;
-					let position = new Vector3().setFromMatrixPosition( transform );
-					let distanceToEarthCenter = position.length();
+					this.isGeoReferenced = new Vector3().setFromMatrixPosition( this.root.cached.boxTransform ).length() > 6360000; // approximate Earth radius
 
-					const surfaceDir = position.normalize();
+				}
+
+				if ( this.isGeoReferenced ) {
 
-					const rotationToNorthPole = this.rotationBetweenDirections( surfaceDir, new Vector3( 0, 1, 0 ) );
+					const position = new Vector3().setFromMatrixPosition( this.root.cached.boxTransform );
+					const distanceToEarthCenter = position.length();
+
+					const surfaceDir = position.normalize();
+					const rotationToNorthPole = this.rotationBetweenDirections( surfaceDir, Y_AXIS );
 
 					this.group.quaternion.x = rotationToNorthPole.x;
 					this.group.quaternion.y = rotationToNorthPole.y;
 					this.group.quaternion.z = rotationToNorthPole.z;
 					this.group.quaternion.w = rotationToNorthPole.w;
 
-					this.group.position.y = -distanceToEarthCenter;
+					this.group.position.y = - distanceToEarthCenter;
 
 				}