Kaynağa Gözat

Merge pull request #271 from NASA-AMMOS/magic-bytes

Use magic bytes to determine file type when parsing
Garrett Johnson 3 yıl önce
ebeveyn
işleme
0eeafc5591

+ 2 - 5
src/base/B3DMLoaderBase.js

@@ -3,6 +3,7 @@
 
 import { FeatureTable, BatchTable } from '../utilities/FeatureTable.js';
 import { LoaderBase } from './LoaderBase.js';
+import { readMagicBytes } from '../utilities/readMagicBytes.js';
 
 export class B3DMLoaderBase extends LoaderBase {
 
@@ -14,11 +15,7 @@ export class B3DMLoaderBase extends LoaderBase {
 		// 28-byte header
 
 		// 4 bytes
-		const magic =
-			String.fromCharCode( dataView.getUint8( 0 ) ) +
-			String.fromCharCode( dataView.getUint8( 1 ) ) +
-			String.fromCharCode( dataView.getUint8( 2 ) ) +
-			String.fromCharCode( dataView.getUint8( 3 ) );
+		const magic = readMagicBytes( dataView );
 
 		console.assert( magic === 'b3dm' );
 

+ 3 - 10
src/base/CMPTLoaderBase.js

@@ -1,6 +1,7 @@
 // CMPT File Format
 // https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/Composite/README.md
 import { LoaderBase } from './LoaderBase.js';
+import { readMagicBytes } from '../utilities/readMagicBytes.js';
 
 export class CMPTLoaderBase extends LoaderBase {
 
@@ -11,11 +12,7 @@ export class CMPTLoaderBase extends LoaderBase {
 		// 16-byte header
 
 		// 4 bytes
-		const magic =
-			String.fromCharCode( dataView.getUint8( 0 ) ) +
-			String.fromCharCode( dataView.getUint8( 1 ) ) +
-			String.fromCharCode( dataView.getUint8( 2 ) ) +
-			String.fromCharCode( dataView.getUint8( 3 ) );
+		const magic = readMagicBytes( dataView );
 
 		console.assert( magic === 'cmpt', 'CMPTLoader: The magic bytes equal "cmpt".' );
 
@@ -37,11 +34,7 @@ export class CMPTLoaderBase extends LoaderBase {
 		for ( let i = 0; i < tilesLength; i ++ ) {
 
 			const tileView = new DataView( buffer, offset, 12 );
-			const tileMagic =
-				String.fromCharCode( tileView.getUint8( 0 ) ) +
-				String.fromCharCode( tileView.getUint8( 1 ) ) +
-				String.fromCharCode( tileView.getUint8( 2 ) ) +
-				String.fromCharCode( tileView.getUint8( 3 ) );
+			const tileMagic = readMagicBytes( tileView );
 			const tileVersion = tileView.getUint32( 4, true );
 			const byteLength = tileView.getUint32( 8, true );
 

+ 2 - 5
src/base/I3DMLoaderBase.js

@@ -4,6 +4,7 @@
 import { FeatureTable, BatchTable } from '../utilities/FeatureTable.js';
 import { arrayToString } from '../utilities/arrayToString.js';
 import { LoaderBase } from './LoaderBase.js';
+import { readMagicBytes } from '../utilities/readMagicBytes.js';
 
 export class I3DMLoaderBase extends LoaderBase {
 
@@ -14,11 +15,7 @@ export class I3DMLoaderBase extends LoaderBase {
 		// 32-byte header
 
 		// 4 bytes
-		const magic =
-			String.fromCharCode( dataView.getUint8( 0 ) ) +
-			String.fromCharCode( dataView.getUint8( 1 ) ) +
-			String.fromCharCode( dataView.getUint8( 2 ) ) +
-			String.fromCharCode( dataView.getUint8( 3 ) );
+		const magic = readMagicBytes( dataView );
 
 		console.assert( magic === 'i3dm' );
 

+ 2 - 5
src/base/PNTSLoaderBase.js

@@ -2,6 +2,7 @@
 // https://github.com/CesiumGS/3d-tiles/blob/master/specification/TileFormats/PointCloud/README.md
 
 import { FeatureTable, BatchTable } from '../utilities/FeatureTable.js';
+import { readMagicBytes } from '../utilities/readMagicBytes.js';
 import { LoaderBase } from './LoaderBase.js';
 
 export class PNTSLoaderBase extends LoaderBase {
@@ -13,11 +14,7 @@ export class PNTSLoaderBase extends LoaderBase {
 		// 28-byte header
 
 		// 4 bytes
-		const magic =
-			String.fromCharCode( dataView.getUint8( 0 ) ) +
-			String.fromCharCode( dataView.getUint8( 1 ) ) +
-			String.fromCharCode( dataView.getUint8( 2 ) ) +
-			String.fromCharCode( dataView.getUint8( 3 ) );
+		const magic = readMagicBytes( dataView );
 
 		console.assert( magic === 'pnts' );
 

+ 5 - 3
src/three/TilesRenderer.js

@@ -15,6 +15,7 @@ import {
 	LoadingManager
 } from 'three';
 import { raycastTraverse, raycastTraverseFirstHit } from './raycastTraverse.js';
+import { readMagicBytes } from '../utilities/readMagicBytes.js';
 
 const INITIAL_FRUSTUM_CULLED = Symbol( 'INITIAL_FRUSTUM_CULLED' );
 const tempMat = new Matrix4();
@@ -600,7 +601,8 @@ export class TilesRenderer extends TilesRendererBase {
 
 		}
 
-		switch ( extension ) {
+		const fileType = readMagicBytes( buffer ) || extension;
+		switch ( fileType ) {
 
 			case 'b3dm': {
 
@@ -671,7 +673,7 @@ export class TilesRenderer extends TilesRendererBase {
 				break;
 
 			default:
-				console.warn( `TilesRenderer: Content type "${ extension }" not supported.` );
+				console.warn( `TilesRenderer: Content type "${ fileType }" not supported.` );
 				promise = Promise.resolve( null );
 				break;
 
@@ -692,7 +694,7 @@ export class TilesRenderer extends TilesRendererBase {
 			// any transformations applied to it can be assumed to be applied after load
 			// (such as applying RTC_CENTER) meaning they should happen _after_ the z-up
 			// rotation fix which is why "multiply" happens here.
-			if ( extension === 'glb' || extension === 'gltf' ) {
+			if ( fileType === 'glb' || fileType === 'gltf' ) {
 
 				scene.matrix.multiply( tempMat );
 

+ 29 - 0
src/utilities/readMagicBytes.js

@@ -0,0 +1,29 @@
+export function readMagicBytes( bufferOrDataView ) {
+
+	let view;
+	if ( bufferOrDataView instanceof DataView ) {
+
+		view = bufferOrDataView;
+
+	} else {
+
+		view = new DataView( bufferOrDataView );
+
+	}
+
+	if ( String.fromCharCode( view.getUint8( 0 ) ) === '{' ) {
+
+		return null;
+
+	}
+
+	let magicBytes = '';
+	for ( let i = 0; i < 4; i ++ ) {
+
+		magicBytes += String.fromCharCode( view.getUint8( i ) );
+
+	}
+
+	return magicBytes;
+
+}