@loaders.gl/3d-tiles 4.0.0-alpha.8 → 4.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/3d-tiles-archive/3d-tiles-archive-archive.d.ts +30 -0
- package/dist/3d-tiles-archive/3d-tiles-archive-archive.d.ts.map +1 -0
- package/dist/3d-tiles-archive/3d-tiles-archive-parser.d.ts +10 -0
- package/dist/3d-tiles-archive/3d-tiles-archive-parser.d.ts.map +1 -0
- package/dist/3d-tiles-archive-loader.d.ts +13 -0
- package/dist/3d-tiles-archive-loader.d.ts.map +1 -0
- package/dist/cesium-ion-loader.d.ts +2 -2
- package/dist/cesium-ion-loader.d.ts.map +1 -1
- package/dist/dist.min.js +10981 -4462
- package/dist/es5/3d-tiles-archive/3d-tiles-archive-archive.js +126 -0
- package/dist/es5/3d-tiles-archive/3d-tiles-archive-archive.js.map +1 -0
- package/dist/es5/3d-tiles-archive/3d-tiles-archive-parser.js +69 -0
- package/dist/es5/3d-tiles-archive/3d-tiles-archive-parser.js.map +1 -0
- package/dist/es5/3d-tiles-archive-loader.js +50 -0
- package/dist/es5/3d-tiles-archive-loader.js.map +1 -0
- package/dist/es5/cesium-ion-loader.js.map +1 -1
- package/dist/es5/index.js +14 -0
- package/dist/es5/index.js.map +1 -1
- package/dist/es5/lib/filesystems/tiles-3d-archive-file-system.js +151 -0
- package/dist/es5/lib/filesystems/tiles-3d-archive-file-system.js.map +1 -0
- package/dist/es5/lib/ion/ion.js +3 -9
- package/dist/es5/lib/ion/ion.js.map +1 -1
- package/dist/es5/lib/parsers/helpers/parse-3d-implicit-tiles.js +63 -38
- package/dist/es5/lib/parsers/helpers/parse-3d-implicit-tiles.js.map +1 -1
- package/dist/es5/lib/parsers/helpers/parse-3d-tile-gltf-view.js +3 -3
- package/dist/es5/lib/parsers/helpers/parse-3d-tile-gltf-view.js.map +1 -1
- package/dist/es5/lib/parsers/helpers/parse-3d-tile-subtree.js +70 -55
- package/dist/es5/lib/parsers/helpers/parse-3d-tile-subtree.js.map +1 -1
- package/dist/es5/lib/parsers/parse-3d-tile-composite.js +3 -1
- package/dist/es5/lib/parsers/parse-3d-tile-composite.js.map +1 -1
- package/dist/es5/lib/parsers/parse-3d-tile-gltf.js +14 -12
- package/dist/es5/lib/parsers/parse-3d-tile-gltf.js.map +1 -1
- package/dist/es5/lib/parsers/parse-3d-tile-header.js +14 -12
- package/dist/es5/lib/parsers/parse-3d-tile-header.js.map +1 -1
- package/dist/es5/lib/parsers/parse-3d-tile-point-cloud.js +6 -6
- package/dist/es5/lib/parsers/parse-3d-tile-point-cloud.js.map +1 -1
- package/dist/es5/lib/parsers/parse-3d-tile.js +3 -1
- package/dist/es5/lib/parsers/parse-3d-tile.js.map +1 -1
- package/dist/es5/lib/utils/version.js +1 -1
- package/dist/es5/lib/utils/version.js.map +1 -1
- package/dist/es5/tile-3d-subtree-loader.js.map +1 -1
- package/dist/es5/tile-3d-writer.js.map +1 -1
- package/dist/es5/tiles-3d-loader.js +2 -0
- package/dist/es5/tiles-3d-loader.js.map +1 -1
- package/dist/es5/types.js.map +1 -1
- package/dist/esm/3d-tiles-archive/3d-tiles-archive-archive.js +46 -0
- package/dist/esm/3d-tiles-archive/3d-tiles-archive-archive.js.map +1 -0
- package/dist/esm/3d-tiles-archive/3d-tiles-archive-parser.js +23 -0
- package/dist/esm/3d-tiles-archive/3d-tiles-archive-parser.js.map +1 -0
- package/dist/esm/3d-tiles-archive-loader.js +20 -0
- package/dist/esm/3d-tiles-archive-loader.js.map +1 -0
- package/dist/esm/cesium-ion-loader.js.map +1 -1
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/filesystems/tiles-3d-archive-file-system.js +49 -0
- package/dist/esm/lib/filesystems/tiles-3d-archive-file-system.js.map +1 -0
- package/dist/esm/lib/ion/ion.js +3 -9
- package/dist/esm/lib/ion/ion.js.map +1 -1
- package/dist/esm/lib/parsers/helpers/parse-3d-implicit-tiles.js +45 -23
- package/dist/esm/lib/parsers/helpers/parse-3d-implicit-tiles.js.map +1 -1
- package/dist/esm/lib/parsers/helpers/parse-3d-tile-gltf-view.js +5 -6
- package/dist/esm/lib/parsers/helpers/parse-3d-tile-gltf-view.js.map +1 -1
- package/dist/esm/lib/parsers/helpers/parse-3d-tile-subtree.js +18 -24
- package/dist/esm/lib/parsers/helpers/parse-3d-tile-subtree.js.map +1 -1
- package/dist/esm/lib/parsers/parse-3d-tile-composite.js +3 -1
- package/dist/esm/lib/parsers/parse-3d-tile-composite.js.map +1 -1
- package/dist/esm/lib/parsers/parse-3d-tile-gltf.js +7 -8
- package/dist/esm/lib/parsers/parse-3d-tile-gltf.js.map +1 -1
- package/dist/esm/lib/parsers/parse-3d-tile-header.js +8 -5
- package/dist/esm/lib/parsers/parse-3d-tile-header.js.map +1 -1
- package/dist/esm/lib/parsers/parse-3d-tile-point-cloud.js +2 -4
- package/dist/esm/lib/parsers/parse-3d-tile-point-cloud.js.map +1 -1
- package/dist/esm/lib/parsers/parse-3d-tile.js +3 -1
- package/dist/esm/lib/parsers/parse-3d-tile.js.map +1 -1
- package/dist/esm/lib/utils/version.js +1 -1
- package/dist/esm/lib/utils/version.js.map +1 -1
- package/dist/esm/tile-3d-subtree-loader.js.map +1 -1
- package/dist/esm/tile-3d-writer.js.map +1 -1
- package/dist/esm/tiles-3d-loader.js +2 -0
- package/dist/esm/tiles-3d-loader.js.map +1 -1
- package/dist/esm/types.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/filesystems/tiles-3d-archive-file-system.d.ts +32 -0
- package/dist/lib/filesystems/tiles-3d-archive-file-system.d.ts.map +1 -0
- package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.d.ts +4 -1
- package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.d.ts.map +1 -1
- package/dist/lib/parsers/helpers/parse-3d-tile-gltf-view.d.ts.map +1 -1
- package/dist/lib/parsers/helpers/parse-3d-tile-subtree.d.ts.map +1 -1
- package/dist/lib/parsers/parse-3d-tile-gltf.d.ts +2 -2
- package/dist/lib/parsers/parse-3d-tile-gltf.d.ts.map +1 -1
- package/dist/lib/parsers/parse-3d-tile-header.d.ts +30 -2
- package/dist/lib/parsers/parse-3d-tile-header.d.ts.map +1 -1
- package/dist/lib/parsers/parse-3d-tile-point-cloud.d.ts +1 -1
- package/dist/lib/parsers/parse-3d-tile-point-cloud.d.ts.map +1 -1
- package/dist/lib/parsers/parse-3d-tile.d.ts +1 -1
- package/dist/lib/parsers/parse-3d-tile.d.ts.map +1 -1
- package/dist/tile-3d-subtree-loader.d.ts +3 -3
- package/dist/tile-3d-subtree-loader.d.ts.map +1 -1
- package/dist/tile-3d-writer.d.ts +2 -2
- package/dist/tile-3d-writer.d.ts.map +1 -1
- package/dist/tiles-3d-loader.d.ts +2 -1
- package/dist/tiles-3d-loader.d.ts.map +1 -1
- package/dist/types.d.ts +49 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -8
- package/src/3d-tiles-archive/3d-tiles-archive-archive.ts +85 -0
- package/src/3d-tiles-archive/3d-tiles-archive-parser.ts +52 -0
- package/src/3d-tiles-archive-loader.ts +47 -0
- package/src/cesium-ion-loader.ts +2 -3
- package/src/index.ts +3 -0
- package/src/lib/filesystems/tiles-3d-archive-file-system.ts +97 -0
- package/src/lib/ion/ion.ts +3 -3
- package/src/lib/parsers/helpers/parse-3d-implicit-tiles.ts +76 -32
- package/src/lib/parsers/helpers/parse-3d-tile-gltf-view.ts +8 -3
- package/src/lib/parsers/helpers/parse-3d-tile-subtree.ts +44 -62
- package/src/lib/parsers/parse-3d-tile-composite.ts +1 -1
- package/src/lib/parsers/parse-3d-tile-gltf.ts +11 -10
- package/src/lib/parsers/parse-3d-tile-header.ts +39 -6
- package/src/lib/parsers/parse-3d-tile-point-cloud.ts +10 -3
- package/src/lib/parsers/parse-3d-tile.ts +2 -2
- package/src/tile-3d-subtree-loader.ts +3 -3
- package/src/tile-3d-writer.ts +2 -2
- package/src/tiles-3d-loader.ts +16 -4
- package/src/types.ts +52 -9
- package/dist/bundle.js +0 -5
- package/dist/cesium-ion-loader.js +0 -41
- package/dist/index.js +0 -26
- package/dist/lib/classes/helpers/tile-3d-accessor-utils.js +0 -113
- package/dist/lib/classes/tile-3d-batch-table-hierarchy.js +0 -197
- package/dist/lib/classes/tile-3d-batch-table.js +0 -245
- package/dist/lib/classes/tile-3d-feature-table.js +0 -72
- package/dist/lib/constants.js +0 -26
- package/dist/lib/encoders/encode-3d-tile-batched-model.js +0 -46
- package/dist/lib/encoders/encode-3d-tile-composite.js +0 -24
- package/dist/lib/encoders/encode-3d-tile-instanced-model.js +0 -38
- package/dist/lib/encoders/encode-3d-tile-point-cloud.js +0 -39
- package/dist/lib/encoders/encode-3d-tile.js +0 -33
- package/dist/lib/encoders/helpers/encode-3d-tile-header.js +0 -30
- package/dist/lib/ion/ion.js +0 -68
- package/dist/lib/parsers/helpers/normalize-3d-tile-colors.js +0 -65
- package/dist/lib/parsers/helpers/normalize-3d-tile-normals.js +0 -30
- package/dist/lib/parsers/helpers/normalize-3d-tile-positions.js +0 -42
- package/dist/lib/parsers/helpers/parse-3d-implicit-tiles.js +0 -266
- package/dist/lib/parsers/helpers/parse-3d-tile-gltf-view.js +0 -96
- package/dist/lib/parsers/helpers/parse-3d-tile-header.js +0 -28
- package/dist/lib/parsers/helpers/parse-3d-tile-subtree.js +0 -104
- package/dist/lib/parsers/helpers/parse-3d-tile-tables.js +0 -93
- package/dist/lib/parsers/helpers/parse-utils.js +0 -32
- package/dist/lib/parsers/parse-3d-tile-batched-model.js +0 -33
- package/dist/lib/parsers/parse-3d-tile-composite.js +0 -24
- package/dist/lib/parsers/parse-3d-tile-gltf.js +0 -28
- package/dist/lib/parsers/parse-3d-tile-header.js +0 -192
- package/dist/lib/parsers/parse-3d-tile-instanced-model.js +0 -172
- package/dist/lib/parsers/parse-3d-tile-point-cloud.js +0 -433
- package/dist/lib/parsers/parse-3d-tile.js +0 -33
- package/dist/lib/utils/obb/s2-corners-to-obb.js +0 -37
- package/dist/lib/utils/s2/converters/s2-to-boundary.js +0 -61
- package/dist/lib/utils/s2/converters/s2-to-obb-points.js +0 -36
- package/dist/lib/utils/s2/converters/s2-to-region.js +0 -59
- package/dist/lib/utils/s2/index.js +0 -23
- package/dist/lib/utils/s2/s2-geometry-functions.js +0 -29
- package/dist/lib/utils/s2/s2-token-functions.js +0 -68
- package/dist/lib/utils/s2/s2geometry/s2-cell-utils.js +0 -32
- package/dist/lib/utils/s2/s2geometry/s2-geometry.js +0 -260
- package/dist/lib/utils/version.js +0 -7
- package/dist/tile-3d-subtree-loader.js +0 -23
- package/dist/tile-3d-writer.js +0 -27
- package/dist/tiles-3d-loader.js +0 -76
- package/dist/types.js +0 -2
package/src/cesium-ion-loader.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
1
|
+
import type {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
|
|
2
2
|
import {Tiles3DLoader} from './tiles-3d-loader';
|
|
3
3
|
import {getIonTilesetMetadata} from './lib/ion/ion';
|
|
4
4
|
|
|
@@ -18,7 +18,7 @@ async function preload(url, options = {}) {
|
|
|
18
18
|
/**
|
|
19
19
|
* Loader for 3D tiles from Cesium ION
|
|
20
20
|
*/
|
|
21
|
-
export const CesiumIonLoader: LoaderWithParser = {
|
|
21
|
+
export const CesiumIonLoader: LoaderWithParser<unknown, never, LoaderOptions> = {
|
|
22
22
|
...Tiles3DLoader,
|
|
23
23
|
id: 'cesium-ion',
|
|
24
24
|
name: 'Cesium Ion',
|
|
@@ -33,7 +33,6 @@ export const CesiumIonLoader: LoaderWithParser = {
|
|
|
33
33
|
},
|
|
34
34
|
options: {
|
|
35
35
|
'cesium-ion': {
|
|
36
|
-
// @ts-expect-error
|
|
37
36
|
...Tiles3DLoader.options['3d-tiles'],
|
|
38
37
|
accessToken: null
|
|
39
38
|
}
|
package/src/index.ts
CHANGED
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
export {Tiles3DLoader} from './tiles-3d-loader';
|
|
3
3
|
export {CesiumIonLoader} from './cesium-ion-loader';
|
|
4
4
|
export {Tile3DSubtreeLoader} from './tile-3d-subtree-loader';
|
|
5
|
+
export type {Tiles3DArchiveFileLoaderOptions} from './3d-tiles-archive-loader';
|
|
6
|
+
export {Tiles3DArchiveFileLoader} from './3d-tiles-archive-loader';
|
|
7
|
+
export {Tiles3DArchiveFileSystem} from './lib/filesystems/tiles-3d-archive-file-system';
|
|
5
8
|
|
|
6
9
|
// WRITERS
|
|
7
10
|
export {Tile3DWriter} from './tile-3d-writer';
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import {FileProvider} from '@loaders.gl/loader-utils';
|
|
2
|
+
import {
|
|
3
|
+
ZipFileSystem,
|
|
4
|
+
cdSignature as cdHeaderSignature,
|
|
5
|
+
searchFromTheEnd,
|
|
6
|
+
parseZipCDFileHeader,
|
|
7
|
+
HashElement,
|
|
8
|
+
parseHashFile,
|
|
9
|
+
parseZipLocalFileHeader
|
|
10
|
+
} from '@loaders.gl/zip';
|
|
11
|
+
import {Tiles3DArchive} from '../../3d-tiles-archive/3d-tiles-archive-archive';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* FileSystem adapter for a 3tz (3D tiles archive format) file
|
|
15
|
+
* Holds FileProvider object that provides random access to archived files.
|
|
16
|
+
* The difference from ZipFileSystem is usage of `@3dtilesIndex1@` index file that increases
|
|
17
|
+
* access speed to archived files
|
|
18
|
+
* @see https://github.com/erikdahlstrom/3tz-specification/blob/master/Specification.md
|
|
19
|
+
*/
|
|
20
|
+
export class Tiles3DArchiveFileSystem extends ZipFileSystem {
|
|
21
|
+
hashData?: HashElement[] | null;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Constructor
|
|
25
|
+
* @param file - instance of FileProvider or file path string
|
|
26
|
+
*/
|
|
27
|
+
constructor(file: FileProvider | string) {
|
|
28
|
+
super(file);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Implementation of fetch against this file system.
|
|
33
|
+
* It tries to take `@3dtilesIndex1@` file from the archive and use it
|
|
34
|
+
* for faster access to archived files
|
|
35
|
+
* @param filename - name of a file
|
|
36
|
+
* @returns - Response with file data
|
|
37
|
+
*/
|
|
38
|
+
async fetch(filename: string): Promise<Response> {
|
|
39
|
+
const fileProvider = await this.fileProvider;
|
|
40
|
+
if (!fileProvider) {
|
|
41
|
+
throw new Error('No data detected in the zip archive');
|
|
42
|
+
}
|
|
43
|
+
await this.parseHashFile();
|
|
44
|
+
if (this.hashData) {
|
|
45
|
+
const archive = new Tiles3DArchive(fileProvider, this.hashData);
|
|
46
|
+
|
|
47
|
+
const fileData = await archive.getFile(filename);
|
|
48
|
+
const response = new Response(fileData);
|
|
49
|
+
Object.defineProperty(response, 'url', {value: `${this.fileName || ''}/${filename}`});
|
|
50
|
+
return response;
|
|
51
|
+
}
|
|
52
|
+
return super.fetch(filename);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Try to get and parse '@3dtilesIndex1@' file, that allows to get direct access
|
|
57
|
+
* to files inside the archive
|
|
58
|
+
* @returns void
|
|
59
|
+
*/
|
|
60
|
+
private async parseHashFile(): Promise<void> {
|
|
61
|
+
if (this.hashData !== undefined) {
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const fileProvider = await this.fileProvider;
|
|
66
|
+
if (!fileProvider) {
|
|
67
|
+
throw new Error('No data detected in the zip archive');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const hashCDOffset = await searchFromTheEnd(fileProvider, cdHeaderSignature);
|
|
71
|
+
|
|
72
|
+
const cdFileHeader = await parseZipCDFileHeader(hashCDOffset, fileProvider);
|
|
73
|
+
|
|
74
|
+
// '@3dtilesIndex1@' is index file that must be the last in the archive. It allows
|
|
75
|
+
// to improve load and read performance when the archive contains a very large number
|
|
76
|
+
// of files.
|
|
77
|
+
if (cdFileHeader?.fileName === '@3dtilesIndex1@') {
|
|
78
|
+
const localFileHeader = await parseZipLocalFileHeader(
|
|
79
|
+
cdFileHeader.localHeaderOffset,
|
|
80
|
+
fileProvider
|
|
81
|
+
);
|
|
82
|
+
if (!localFileHeader) {
|
|
83
|
+
throw new Error('corrupted 3tz');
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const fileDataOffset = localFileHeader.fileDataOffset;
|
|
87
|
+
const hashFile = await fileProvider.slice(
|
|
88
|
+
fileDataOffset,
|
|
89
|
+
fileDataOffset + localFileHeader.compressedSize
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
this.hashData = parseHashFile(hashFile);
|
|
93
|
+
} else {
|
|
94
|
+
this.hashData = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
package/src/lib/ion/ion.ts
CHANGED
|
@@ -34,7 +34,7 @@ export async function getIonAssets(accessToken) {
|
|
|
34
34
|
assert(accessToken);
|
|
35
35
|
const url = CESIUM_ION_URL;
|
|
36
36
|
const headers = {Authorization: `Bearer ${accessToken}`};
|
|
37
|
-
const response = await fetchFile(url, {
|
|
37
|
+
const response = await fetchFile(url, {headers});
|
|
38
38
|
if (!response.ok) {
|
|
39
39
|
throw new Error(response.statusText);
|
|
40
40
|
}
|
|
@@ -49,7 +49,7 @@ export async function getIonAssetMetadata(accessToken, assetId) {
|
|
|
49
49
|
const url = `${CESIUM_ION_URL}/${assetId}`;
|
|
50
50
|
// https://cesium.com/docs/rest-api/#operation/getAsset
|
|
51
51
|
// Retrieves metadata information about a specific asset.
|
|
52
|
-
let response = await fetchFile(`${url}`, {
|
|
52
|
+
let response = await fetchFile(`${url}`, {headers});
|
|
53
53
|
if (!response.ok) {
|
|
54
54
|
throw new Error(response.statusText);
|
|
55
55
|
}
|
|
@@ -57,7 +57,7 @@ export async function getIonAssetMetadata(accessToken, assetId) {
|
|
|
57
57
|
|
|
58
58
|
// https://cesium.com/docs/rest-api/#operation/getAssetEndpoint
|
|
59
59
|
// Retrieves information and credentials that allow you to access the tiled asset data for visualization and analysis.
|
|
60
|
-
response = await fetchFile(`${url}/endpoint`, {
|
|
60
|
+
response = await fetchFile(`${url}/endpoint`, {headers});
|
|
61
61
|
if (!response.ok) {
|
|
62
62
|
throw new Error(response.statusText);
|
|
63
63
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type {Availability, Tile3DBoundingVolume, Subtree} from '../../../types';
|
|
2
2
|
import {Tile3DSubtreeLoader} from '../../../tile-3d-subtree-loader';
|
|
3
3
|
import {load} from '@loaders.gl/core';
|
|
4
|
+
import {default as log} from '@probe.gl/log';
|
|
4
5
|
|
|
5
6
|
import {getS2CellIdFromToken, getS2ChildCellId, getS2TokenFromCellId} from '../../utils/s2/index';
|
|
6
7
|
import type {S2VolumeInfo} from '../../utils/obb/s2-corners-to-obb';
|
|
7
8
|
import {convertS2BoundingVolumetoOBB} from '../../utils/obb/s2-corners-to-obb';
|
|
8
9
|
import Long from 'long';
|
|
10
|
+
import {Tiles3DLoaderOptions} from '../../../tiles-3d-loader';
|
|
11
|
+
import {ImplicitOptions} from '../parse-3d-tile-header';
|
|
9
12
|
|
|
10
13
|
const QUADTREE_DEVISION_COUNT = 4;
|
|
11
14
|
const OCTREE_DEVISION_COUNT = 8;
|
|
@@ -83,15 +86,16 @@ function getChildS2VolumeBox(
|
|
|
83
86
|
// eslint-disable-next-line max-statements
|
|
84
87
|
export async function parseImplicitTiles(params: {
|
|
85
88
|
subtree: Subtree;
|
|
86
|
-
|
|
89
|
+
implicitOptions: ImplicitOptions;
|
|
87
90
|
parentData?: {mortonIndex: number; x: number; y: number; z: number};
|
|
88
91
|
childIndex?: number;
|
|
89
92
|
level?: number;
|
|
90
93
|
globalData?: {level: number; mortonIndex: number; x: number; y: number; z: number};
|
|
91
94
|
s2VolumeBox?: S2VolumeBox;
|
|
95
|
+
loaderOptions: Tiles3DLoaderOptions;
|
|
92
96
|
}) {
|
|
93
97
|
const {
|
|
94
|
-
|
|
98
|
+
implicitOptions,
|
|
95
99
|
parentData = {
|
|
96
100
|
mortonIndex: 0,
|
|
97
101
|
x: 0,
|
|
@@ -106,7 +110,8 @@ export async function parseImplicitTiles(params: {
|
|
|
106
110
|
y: 0,
|
|
107
111
|
z: 0
|
|
108
112
|
},
|
|
109
|
-
s2VolumeBox
|
|
113
|
+
s2VolumeBox,
|
|
114
|
+
loaderOptions
|
|
110
115
|
} = params;
|
|
111
116
|
let {subtree, level = 0} = params;
|
|
112
117
|
const {
|
|
@@ -116,43 +121,56 @@ export async function parseImplicitTiles(params: {
|
|
|
116
121
|
contentUrlTemplate,
|
|
117
122
|
subtreesUriTemplate,
|
|
118
123
|
basePath
|
|
119
|
-
} =
|
|
120
|
-
|
|
124
|
+
} = implicitOptions;
|
|
121
125
|
const tile = {children: [], lodMetricValue: 0, contentUrl: ''};
|
|
122
126
|
|
|
127
|
+
if (!maximumLevel) {
|
|
128
|
+
// eslint-disable-next-line no-console
|
|
129
|
+
log.once(
|
|
130
|
+
`Missing 'maximumLevel' or 'availableLevels' property. The subtree ${contentUrlTemplate} won't be loaded...`
|
|
131
|
+
);
|
|
132
|
+
return tile;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const lev = level + globalData.level;
|
|
136
|
+
if (lev > maximumLevel) {
|
|
137
|
+
return tile;
|
|
138
|
+
}
|
|
139
|
+
|
|
123
140
|
const childrenPerTile = SUBDIVISION_COUNT_MAP[subdivisionScheme];
|
|
141
|
+
const bitsPerTile = Math.log2(childrenPerTile);
|
|
124
142
|
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
const
|
|
143
|
+
// childIndex is in range [0,4] for quadtrees and [0, 7] for octrees
|
|
144
|
+
const childX = childIndex & 0b01; // Get first bit for X
|
|
145
|
+
const childY = (childIndex >> 1) & 0b01; // Get second bit for Y
|
|
146
|
+
const childZ = (childIndex >> 2) & 0b01; // Get third bit for Z
|
|
128
147
|
|
|
129
148
|
const levelOffset = (childrenPerTile ** level - 1) / (childrenPerTile - 1);
|
|
130
|
-
let childTileMortonIndex = concatBits(parentData.mortonIndex, childIndex);
|
|
149
|
+
let childTileMortonIndex = concatBits(parentData.mortonIndex, childIndex, bitsPerTile);
|
|
131
150
|
let tileAvailabilityIndex = levelOffset + childTileMortonIndex;
|
|
132
151
|
|
|
133
152
|
// Local tile coordinates
|
|
134
|
-
let childTileX = concatBits(parentData.x, childX);
|
|
135
|
-
let childTileY = concatBits(parentData.y, childY);
|
|
136
|
-
let childTileZ = concatBits(parentData.z, childZ);
|
|
153
|
+
let childTileX = concatBits(parentData.x, childX, 1);
|
|
154
|
+
let childTileY = concatBits(parentData.y, childY, 1);
|
|
155
|
+
let childTileZ = concatBits(parentData.z, childZ, 1);
|
|
137
156
|
|
|
138
157
|
let isChildSubtreeAvailable = false;
|
|
139
158
|
|
|
140
|
-
if (level
|
|
159
|
+
if (level >= subtreeLevels) {
|
|
141
160
|
isChildSubtreeAvailable = getAvailabilityResult(
|
|
142
161
|
subtree.childSubtreeAvailability,
|
|
143
162
|
childTileMortonIndex
|
|
144
163
|
);
|
|
145
164
|
}
|
|
146
165
|
|
|
147
|
-
const x = concatBits(globalData.x, childTileX);
|
|
148
|
-
const y = concatBits(globalData.y, childTileY);
|
|
149
|
-
const z = concatBits(globalData.z, childTileZ);
|
|
150
|
-
const lev = level + globalData.level;
|
|
166
|
+
const x = concatBits(globalData.x, childTileX, level * bitsPerTile);
|
|
167
|
+
const y = concatBits(globalData.y, childTileY, level * bitsPerTile);
|
|
168
|
+
const z = concatBits(globalData.z, childTileZ, level * bitsPerTile);
|
|
151
169
|
|
|
152
170
|
if (isChildSubtreeAvailable) {
|
|
153
171
|
const subtreePath = `${basePath}/${subtreesUriTemplate}`;
|
|
154
172
|
const childSubtreeUrl = replaceContentUrlTemplate(subtreePath, lev, x, y, z);
|
|
155
|
-
const childSubtree = await load(childSubtreeUrl, Tile3DSubtreeLoader);
|
|
173
|
+
const childSubtree = await load(childSubtreeUrl, Tile3DSubtreeLoader, loaderOptions);
|
|
156
174
|
|
|
157
175
|
subtree = childSubtree;
|
|
158
176
|
|
|
@@ -172,7 +190,7 @@ export async function parseImplicitTiles(params: {
|
|
|
172
190
|
|
|
173
191
|
const isTileAvailable = getAvailabilityResult(subtree.tileAvailability, tileAvailabilityIndex);
|
|
174
192
|
|
|
175
|
-
if (!isTileAvailable
|
|
193
|
+
if (!isTileAvailable) {
|
|
176
194
|
return tile;
|
|
177
195
|
}
|
|
178
196
|
|
|
@@ -198,11 +216,12 @@ export async function parseImplicitTiles(params: {
|
|
|
198
216
|
// Recursive calling...
|
|
199
217
|
const childTileParsed = await parseImplicitTiles({
|
|
200
218
|
subtree,
|
|
201
|
-
|
|
219
|
+
implicitOptions,
|
|
220
|
+
loaderOptions,
|
|
202
221
|
parentData: pData,
|
|
203
222
|
childIndex: index,
|
|
204
223
|
level: childTileLevel,
|
|
205
|
-
globalData,
|
|
224
|
+
globalData: {...globalData},
|
|
206
225
|
s2VolumeBox: childS2VolumeBox
|
|
207
226
|
});
|
|
208
227
|
|
|
@@ -213,7 +232,7 @@ export async function parseImplicitTiles(params: {
|
|
|
213
232
|
childTileParsed,
|
|
214
233
|
globalLevel,
|
|
215
234
|
childCoordinates,
|
|
216
|
-
|
|
235
|
+
implicitOptions,
|
|
217
236
|
s2VolumeBox
|
|
218
237
|
);
|
|
219
238
|
// @ts-ignore
|
|
@@ -224,13 +243,37 @@ export async function parseImplicitTiles(params: {
|
|
|
224
243
|
return tile;
|
|
225
244
|
}
|
|
226
245
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Check tile availability in the bitstream array
|
|
248
|
+
* @param availabilityData - tileAvailability / contentAvailability / childSubtreeAvailability object
|
|
249
|
+
* @param index - index in the bitstream array
|
|
250
|
+
* @returns
|
|
251
|
+
*/
|
|
252
|
+
function getAvailabilityResult(
|
|
253
|
+
availabilityData: Availability | Availability[],
|
|
254
|
+
index: number
|
|
255
|
+
): boolean {
|
|
256
|
+
let availabilityObject: Availability;
|
|
257
|
+
if (Array.isArray(availabilityData)) {
|
|
258
|
+
/** TODO: we don't support `3DTILES_multiple_contents` extension at the moment.
|
|
259
|
+
* https://github.com/CesiumGS/3d-tiles/blob/main/extensions/3DTILES_implicit_tiling/README.md#multiple-contents
|
|
260
|
+
* Take first item in the array
|
|
261
|
+
*/
|
|
262
|
+
availabilityObject = availabilityData[0];
|
|
263
|
+
if (availabilityData.length > 1) {
|
|
264
|
+
// eslint-disable-next-line no-console
|
|
265
|
+
log.once('Not supported extension "3DTILES_multiple_contents" has been detected');
|
|
266
|
+
}
|
|
267
|
+
} else {
|
|
268
|
+
availabilityObject = availabilityData;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if ('constant' in availabilityObject) {
|
|
272
|
+
return Boolean(availabilityObject.constant);
|
|
230
273
|
}
|
|
231
274
|
|
|
232
|
-
if (
|
|
233
|
-
return getBooleanValueFromBitstream(index,
|
|
275
|
+
if (availabilityObject.explicitBitstream) {
|
|
276
|
+
return getBooleanValueFromBitstream(index, availabilityObject.explicitBitstream);
|
|
234
277
|
}
|
|
235
278
|
|
|
236
279
|
return false;
|
|
@@ -248,7 +291,7 @@ function formatTileData(
|
|
|
248
291
|
tile,
|
|
249
292
|
level: number,
|
|
250
293
|
childCoordinates: {childTileX: number; childTileY: number; childTileZ: number},
|
|
251
|
-
options:
|
|
294
|
+
options: ImplicitOptions,
|
|
252
295
|
s2VolumeBox?: S2VolumeBox
|
|
253
296
|
) {
|
|
254
297
|
const {
|
|
@@ -337,11 +380,12 @@ function calculateBoundingVolumeForChildTile(
|
|
|
337
380
|
|
|
338
381
|
/**
|
|
339
382
|
* Do binary concatenation
|
|
340
|
-
* @param
|
|
341
|
-
* @param
|
|
383
|
+
* @param higher - number to put to higher part of result
|
|
384
|
+
* @param lower - number to put to lower part of result
|
|
385
|
+
* @param shift - number of bits to shift lower number
|
|
342
386
|
*/
|
|
343
|
-
function concatBits(
|
|
344
|
-
return
|
|
387
|
+
function concatBits(higher: number, lower: number, shift: number): number {
|
|
388
|
+
return (higher << shift) + lower;
|
|
345
389
|
}
|
|
346
390
|
|
|
347
391
|
/**
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
// - Also, should we have hard dependency on gltf module or use injection or auto-discovery for gltf parser?
|
|
9
9
|
|
|
10
10
|
import {GLTFLoader, postProcessGLTF, _getMemoryUsageGLTF} from '@loaders.gl/gltf';
|
|
11
|
-
import {LoaderContext, sliceArrayBuffer} from '@loaders.gl/loader-utils';
|
|
11
|
+
import {LoaderContext, sliceArrayBuffer, parseFromContext} from '@loaders.gl/loader-utils';
|
|
12
12
|
import {Tiles3DTileContent} from '../../../types';
|
|
13
13
|
import {Tiles3DLoaderOptions} from '../../../tiles-3d-loader';
|
|
14
14
|
|
|
@@ -74,15 +74,20 @@ export async function extractGLTF(
|
|
|
74
74
|
if (!context) {
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
|
-
const {parse, fetch} = context;
|
|
78
77
|
if (tile.gltfUrl) {
|
|
78
|
+
const {fetch} = context;
|
|
79
79
|
const response = await fetch(tile.gltfUrl, options);
|
|
80
80
|
tile.gltfArrayBuffer = await response.arrayBuffer();
|
|
81
81
|
tile.gltfByteOffset = 0;
|
|
82
82
|
}
|
|
83
83
|
if (tile.gltfArrayBuffer) {
|
|
84
84
|
// TODO - Should handle byteOffset... However, not used now...
|
|
85
|
-
const gltfWithBuffers = await
|
|
85
|
+
const gltfWithBuffers = await parseFromContext(
|
|
86
|
+
tile.gltfArrayBuffer,
|
|
87
|
+
GLTFLoader,
|
|
88
|
+
options,
|
|
89
|
+
context
|
|
90
|
+
);
|
|
86
91
|
tile.gltf = postProcessGLTF(gltfWithBuffers);
|
|
87
92
|
tile.gpuMemoryUsageInBytes = _getMemoryUsageGLTF(tile.gltf);
|
|
88
93
|
delete tile.gltfArrayBuffer;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {Subtree,
|
|
1
|
+
import type {Subtree, Availability} from '../../../types';
|
|
2
2
|
import type {LoaderContext, LoaderOptions} from '@loaders.gl/loader-utils';
|
|
3
3
|
|
|
4
4
|
const SUBTREE_FILE_MAGIC = 0x74627573;
|
|
@@ -42,79 +42,54 @@ export default async function parse3DTilesSubtree(
|
|
|
42
42
|
internalBinaryBuffer = data.slice(24 + jsonByteLength);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
45
|
+
await loadExplicitBitstream(subtree, subtree.tileAvailability, internalBinaryBuffer, context);
|
|
46
|
+
if (Array.isArray(subtree.contentAvailability)) {
|
|
47
|
+
for (const contentAvailability of subtree.contentAvailability) {
|
|
48
|
+
await loadExplicitBitstream(subtree, contentAvailability, internalBinaryBuffer, context);
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
await loadExplicitBitstream(
|
|
47
52
|
subtree,
|
|
48
|
-
|
|
49
|
-
internalBinaryBuffer,
|
|
50
|
-
context
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if ('bufferView' in subtree.contentAvailability) {
|
|
55
|
-
subtree.contentAvailability.explicitBitstream = await getExplicitBitstream(
|
|
56
|
-
subtree,
|
|
57
|
-
'contentAvailability',
|
|
58
|
-
internalBinaryBuffer,
|
|
59
|
-
context
|
|
60
|
-
);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if ('bufferView' in subtree.childSubtreeAvailability) {
|
|
64
|
-
subtree.childSubtreeAvailability.explicitBitstream = await getExplicitBitstream(
|
|
65
|
-
subtree,
|
|
66
|
-
'childSubtreeAvailability',
|
|
53
|
+
subtree.contentAvailability,
|
|
67
54
|
internalBinaryBuffer,
|
|
68
55
|
context
|
|
69
56
|
);
|
|
70
57
|
}
|
|
58
|
+
await loadExplicitBitstream(
|
|
59
|
+
subtree,
|
|
60
|
+
subtree.childSubtreeAvailability,
|
|
61
|
+
internalBinaryBuffer,
|
|
62
|
+
context
|
|
63
|
+
);
|
|
71
64
|
|
|
72
65
|
return subtree;
|
|
73
66
|
}
|
|
74
67
|
|
|
75
68
|
/**
|
|
76
|
-
*
|
|
77
|
-
* @param
|
|
78
|
-
* @param
|
|
79
|
-
* @
|
|
80
|
-
|
|
81
|
-
function resolveBufferUri(bitstreamRelativeUri: string, basePath: string): string {
|
|
82
|
-
const hasProtocol = basePath.startsWith('http');
|
|
83
|
-
|
|
84
|
-
if (hasProtocol) {
|
|
85
|
-
const resolvedUri = new URL(bitstreamRelativeUri, basePath);
|
|
86
|
-
return decodeURI(resolvedUri.toString());
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Adding http protocol only for new URL constructor usage.
|
|
91
|
-
* It allows to resolve relative paths like ../../example with basePath.
|
|
92
|
-
*/
|
|
93
|
-
const basePathWithProtocol = `http://${basePath}`;
|
|
94
|
-
const resolvedUri = new URL(bitstreamRelativeUri, basePathWithProtocol);
|
|
95
|
-
/**
|
|
96
|
-
* Drop protocol and use just relative path.
|
|
97
|
-
*/
|
|
98
|
-
return `/${resolvedUri.host}${resolvedUri.pathname}`;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Get explicit bitstream for subtree availability data.
|
|
103
|
-
* @param subtree
|
|
104
|
-
* @param name
|
|
105
|
-
* @param internalBinaryBuffer
|
|
69
|
+
* Load explicit bitstream for subtree availability data.
|
|
70
|
+
* @param subtree - subtree data
|
|
71
|
+
* @param availabilityObject - tileAvailability / contentAvailability / childSubtreeAvailability object
|
|
72
|
+
* @param internalBinaryBuffer - subtree binary buffer
|
|
73
|
+
* @param context - loaders.gl context
|
|
106
74
|
*/
|
|
107
|
-
async function
|
|
75
|
+
async function loadExplicitBitstream(
|
|
108
76
|
subtree: Subtree,
|
|
109
|
-
|
|
77
|
+
availabilityObject: Availability,
|
|
110
78
|
internalBinaryBuffer: ArrayBuffer,
|
|
111
79
|
context: LoaderContext | undefined
|
|
112
|
-
): Promise<
|
|
113
|
-
const bufferViewIndex =
|
|
80
|
+
): Promise<void> {
|
|
81
|
+
const bufferViewIndex = Number.isFinite(availabilityObject.bitstream)
|
|
82
|
+
? availabilityObject.bitstream
|
|
83
|
+
: availabilityObject.bufferView;
|
|
84
|
+
|
|
85
|
+
if (typeof bufferViewIndex !== 'number') {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
114
89
|
const bufferView = subtree.bufferViews[bufferViewIndex];
|
|
115
90
|
const buffer = subtree.buffers[bufferView.buffer];
|
|
116
91
|
|
|
117
|
-
if (!context?.
|
|
92
|
+
if (!context?.baseUrl) {
|
|
118
93
|
throw new Error('Url is not provided');
|
|
119
94
|
}
|
|
120
95
|
|
|
@@ -124,14 +99,21 @@ async function getExplicitBitstream(
|
|
|
124
99
|
|
|
125
100
|
// External bitstream loading
|
|
126
101
|
if (buffer.uri) {
|
|
127
|
-
const bufferUri =
|
|
102
|
+
const bufferUri = `${context?.baseUrl || ''}/${buffer.uri}`;
|
|
128
103
|
const response = await context.fetch(bufferUri);
|
|
129
104
|
const data = await response.arrayBuffer();
|
|
130
|
-
|
|
131
|
-
|
|
105
|
+
availabilityObject.explicitBitstream = new Uint8Array(
|
|
106
|
+
data,
|
|
107
|
+
bufferView.byteOffset,
|
|
108
|
+
bufferView.byteLength
|
|
109
|
+
);
|
|
110
|
+
return;
|
|
132
111
|
}
|
|
133
|
-
|
|
134
|
-
|
|
112
|
+
availabilityObject.explicitBitstream = new Uint8Array(
|
|
113
|
+
internalBinaryBuffer,
|
|
114
|
+
bufferView.byteOffset,
|
|
115
|
+
bufferView.byteLength
|
|
116
|
+
);
|
|
135
117
|
}
|
|
136
118
|
|
|
137
119
|
/**
|
|
@@ -38,7 +38,7 @@ export async function parseComposite3DTile(
|
|
|
38
38
|
// extract each tile from the byte stream
|
|
39
39
|
tile.tiles = [];
|
|
40
40
|
while (tile.tiles.length < tile.tilesLength && (tile.byteLength || 0) - byteOffset > 12) {
|
|
41
|
-
const subtile = {};
|
|
41
|
+
const subtile: Tiles3DTileContent = {shape: 'tile3d'};
|
|
42
42
|
tile.tiles.push(subtile);
|
|
43
43
|
byteOffset = await parse3DTile(arrayBuffer, byteOffset, options, context, subtile);
|
|
44
44
|
// TODO - do we need to add any padding in between tiles?
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
// loaders.gl, MIT license
|
|
2
|
+
|
|
3
|
+
import {parseFromContext, LoaderContext} from '@loaders.gl/loader-utils';
|
|
3
4
|
import {_getMemoryUsageGLTF, GLTFLoader, postProcessGLTF} from '@loaders.gl/gltf';
|
|
5
|
+
import type {Tiles3DLoaderOptions} from '../../tiles-3d-loader';
|
|
4
6
|
import {Tiles3DTileContent} from '../../types';
|
|
5
7
|
|
|
6
8
|
export async function parseGltf3DTile(
|
|
@@ -8,26 +10,25 @@ export async function parseGltf3DTile(
|
|
|
8
10
|
arrayBuffer: ArrayBuffer,
|
|
9
11
|
options?: Tiles3DLoaderOptions,
|
|
10
12
|
context?: LoaderContext
|
|
11
|
-
): Promise<
|
|
13
|
+
): Promise<number> {
|
|
12
14
|
// Set flags
|
|
13
15
|
// glTF models need to be rotated from Y to Z up
|
|
14
16
|
// https://github.com/AnalyticalGraphicsInc/3d-tiles/tree/master/specification#y-up-to-z-up
|
|
15
17
|
tile.rotateYtoZ = true;
|
|
16
18
|
// Save gltf up axis
|
|
17
|
-
tile.gltfUpAxis =
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
: 'Y';
|
|
19
|
+
tile.gltfUpAxis = options?.['3d-tiles']?.assetGltfUpAxis
|
|
20
|
+
? options['3d-tiles'].assetGltfUpAxis
|
|
21
|
+
: 'Y';
|
|
21
22
|
|
|
22
23
|
if (options?.['3d-tiles']?.loadGLTF) {
|
|
23
24
|
if (!context) {
|
|
24
|
-
return;
|
|
25
|
+
return arrayBuffer.byteLength;
|
|
25
26
|
}
|
|
26
|
-
const
|
|
27
|
-
const gltfWithBuffers = await parse(arrayBuffer, GLTFLoader, options, context);
|
|
27
|
+
const gltfWithBuffers = await parseFromContext(arrayBuffer, GLTFLoader, options, context);
|
|
28
28
|
tile.gltf = postProcessGLTF(gltfWithBuffers);
|
|
29
29
|
tile.gpuMemoryUsageInBytes = _getMemoryUsageGLTF(tile.gltf);
|
|
30
30
|
} else {
|
|
31
31
|
tile.gltfArrayBuffer = arrayBuffer;
|
|
32
32
|
}
|
|
33
|
+
return arrayBuffer.byteLength;
|
|
33
34
|
}
|