UNPKG

@loaders.gl/3d-tiles

Version:

3D Tiles, an open standard for streaming massive heterogeneous 3D geospatial datasets.

146 lines (118 loc) 5.22 kB
// loaders.gl // SPDX-License-Identifier: MIT AND Apache-2.0 // Copyright vis.gl contributors // This file is derived from the Cesium code base under Apache 2 license // See LICENSE.md and https://github.com/AnalyticalGraphicsInc/cesium/blob/master/LICENSE.md import {getStringFromArrayBuffer} from './parse-utils'; import {Tiles3DLoaderOptions} from '../../../tiles-3d-loader'; import {Tiles3DTileContent} from '../../../types'; const SIZEOF_UINT32 = 4; const DEPRECATION_WARNING = 'b3dm tile in legacy format.'; // eslint-disable-next-line max-statements export function parse3DTileTablesHeaderSync( tile: Tiles3DTileContent, arrayBuffer: ArrayBuffer, byteOffset: number ) { const view = new DataView(arrayBuffer); let batchLength; tile.header = tile.header || {}; let featureTableJsonByteLength = view.getUint32(byteOffset, true); byteOffset += SIZEOF_UINT32; let featureTableBinaryByteLength = view.getUint32(byteOffset, true); byteOffset += SIZEOF_UINT32; let batchTableJsonByteLength = view.getUint32(byteOffset, true); byteOffset += SIZEOF_UINT32; let batchTableBinaryByteLength = view.getUint32(byteOffset, true); byteOffset += SIZEOF_UINT32; // First legacy header format - [batchLength] [batchTableByteLength] ('batchTableJsonByteLength': JSON starts with a quotation mark or the glTF magic) // Second legacy format - [batchTableJsonByteLength] [batchTableBinaryByteLength] [batchLength] (Second legacy format is similar as first but here we check 'batchTableBinaryByteLength' instead) // Current header format - [featureTableJsonByteLength] [featureTableBinaryByteLength] [batchTableJsonByteLength] [batchTableBinaryByteLength] // First byte will be 0x22 or 0x67. The minimum uint32 expected is 0x22000000 = 570425344 = 570MB. if (batchTableJsonByteLength >= 570425344) { byteOffset -= SIZEOF_UINT32 * 2; batchLength = featureTableJsonByteLength; batchTableJsonByteLength = featureTableBinaryByteLength; batchTableBinaryByteLength = 0; featureTableJsonByteLength = 0; featureTableBinaryByteLength = 0; console.warn(DEPRECATION_WARNING); // eslint-disable-line } else if (batchTableBinaryByteLength >= 570425344) { byteOffset -= SIZEOF_UINT32; batchLength = batchTableJsonByteLength; batchTableJsonByteLength = featureTableJsonByteLength; batchTableBinaryByteLength = featureTableBinaryByteLength; featureTableJsonByteLength = 0; featureTableBinaryByteLength = 0; console.warn(DEPRECATION_WARNING); // eslint-disable-line } tile.header.featureTableJsonByteLength = featureTableJsonByteLength; tile.header.featureTableBinaryByteLength = featureTableBinaryByteLength; tile.header.batchTableJsonByteLength = batchTableJsonByteLength; tile.header.batchTableBinaryByteLength = batchTableBinaryByteLength; tile.header.batchLength = batchLength; return byteOffset; } export function parse3DTileTablesSync( tile: Tiles3DTileContent, arrayBuffer: ArrayBuffer, byteOffset: number, options?: Tiles3DLoaderOptions ) { byteOffset = parse3DTileFeatureTable(tile, arrayBuffer, byteOffset, options); byteOffset = parse3DTileBatchTable(tile, arrayBuffer, byteOffset, options); return byteOffset; } function parse3DTileFeatureTable( tile: Tiles3DTileContent, arrayBuffer: ArrayBuffer, byteOffset: number, options?: Tiles3DLoaderOptions ) { const {featureTableJsonByteLength, featureTableBinaryByteLength, batchLength} = tile.header || {}; tile.featureTableJson = { BATCH_LENGTH: batchLength || 0 }; if (featureTableJsonByteLength && featureTableJsonByteLength > 0) { const featureTableString = getStringFromArrayBuffer( arrayBuffer, byteOffset, featureTableJsonByteLength ); tile.featureTableJson = JSON.parse(featureTableString); } byteOffset += featureTableJsonByteLength || 0; tile.featureTableBinary = new Uint8Array(arrayBuffer, byteOffset, featureTableBinaryByteLength); byteOffset += featureTableBinaryByteLength || 0; /* const featureTable = parseFeatureTable(featureTableJson, featureTableBinary); const batchLength = featureTable.getGlobalProperty('BATCH_LENGTH'); featureTable.featuresLength = batchLength; */ return byteOffset; } function parse3DTileBatchTable( tile: Tiles3DTileContent, arrayBuffer: ArrayBuffer, byteOffset: number, options?: Tiles3DLoaderOptions ) { const {batchTableJsonByteLength, batchTableBinaryByteLength} = tile.header || {}; if (batchTableJsonByteLength && batchTableJsonByteLength > 0) { const batchTableString = getStringFromArrayBuffer( arrayBuffer, byteOffset, batchTableJsonByteLength ); tile.batchTableJson = JSON.parse(batchTableString); byteOffset += batchTableJsonByteLength; if (batchTableBinaryByteLength && batchTableBinaryByteLength > 0) { // Has a batch table binary tile.batchTableBinary = new Uint8Array(arrayBuffer, byteOffset, batchTableBinaryByteLength); // Copy the batchTableBinary section and let the underlying ArrayBuffer be freed tile.batchTableBinary = new Uint8Array(tile.batchTableBinary); byteOffset += batchTableBinaryByteLength; } } return byteOffset; }