t3d-3dtiles 0.1.0
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/LICENSE +28 -0
- package/README.md +41 -0
- package/build/t3d.3dtiles.js +5418 -0
- package/build/t3d.3dtiles.min.js +2 -0
- package/build/t3d.3dtiles.module.js +6183 -0
- package/examples/jsm/CesiumIon.js +30 -0
- package/examples/jsm/Tiles3DDebugger.js +219 -0
- package/examples/jsm/Tiles3DUtils.js +32 -0
- package/examples/jsm/helpers/LineSegmentHelper.js +74 -0
- package/examples/jsm/helpers/OBBHelper.js +48 -0
- package/examples/jsm/helpers/Tiles3DHelper.js +135 -0
- package/examples/jsm/math/Intersects.js +100 -0
- package/examples/jsm/math/LineSegment.js +234 -0
- package/package.json +57 -0
- package/src/Tiles3D.js +402 -0
- package/src/libs/ImageBitmapLoader.js +56 -0
- package/src/libs/glTF/Constants.js +85 -0
- package/src/libs/glTF/GLTFLoader.js +169 -0
- package/src/libs/glTF/GLTFResource.js +28 -0
- package/src/libs/glTF/GLTFUtils.js +131 -0
- package/src/libs/glTF/extensions/EXT_meshopt_compression.js +35 -0
- package/src/libs/glTF/extensions/KHR_draco_mesh_compression.js +54 -0
- package/src/libs/glTF/extensions/KHR_lights_punctual.js +53 -0
- package/src/libs/glTF/extensions/KHR_materials_clearcoat.js +42 -0
- package/src/libs/glTF/extensions/KHR_materials_pbrSpecularGlossiness.js +53 -0
- package/src/libs/glTF/extensions/KHR_materials_unlit.js +13 -0
- package/src/libs/glTF/extensions/KHR_texture_basisu.js +14 -0
- package/src/libs/glTF/extensions/KHR_texture_transform.js +31 -0
- package/src/libs/glTF/parsers/AccessorParser.js +99 -0
- package/src/libs/glTF/parsers/AnimationParser.js +118 -0
- package/src/libs/glTF/parsers/BufferParser.js +35 -0
- package/src/libs/glTF/parsers/BufferViewParser.js +27 -0
- package/src/libs/glTF/parsers/ImageParser.js +97 -0
- package/src/libs/glTF/parsers/IndexParser.js +22 -0
- package/src/libs/glTF/parsers/MaterialParser.js +146 -0
- package/src/libs/glTF/parsers/NodeParser.js +145 -0
- package/src/libs/glTF/parsers/PrimitiveParser.js +289 -0
- package/src/libs/glTF/parsers/ReferenceParser.js +67 -0
- package/src/libs/glTF/parsers/SceneParser.js +41 -0
- package/src/libs/glTF/parsers/SkinParser.js +53 -0
- package/src/libs/glTF/parsers/TextureParser.js +71 -0
- package/src/libs/glTF/parsers/Validator.js +16 -0
- package/src/loaders/B3DMLoader.js +49 -0
- package/src/loaders/CMPTLoader.js +48 -0
- package/src/loaders/I3DMLoader.js +49 -0
- package/src/loaders/PNTSLoader.js +20 -0
- package/src/loaders/TileGLTFLoader.js +17 -0
- package/src/loaders/parsers/HeaderParser.js +104 -0
- package/src/loaders/parsers/LoadParser.js +22 -0
- package/src/loaders/parsers/TableParser.js +66 -0
- package/src/loaders/parsers/b3dm/B3DMParser.js +18 -0
- package/src/loaders/parsers/b3dm/B3DMRootParser.js +22 -0
- package/src/loaders/parsers/b3dm/MaterialParser.js +156 -0
- package/src/loaders/parsers/cmpt/CMPTParser.js +37 -0
- package/src/loaders/parsers/cmpt/CMPTRootParser.js +44 -0
- package/src/loaders/parsers/gltf/IndexParser.js +24 -0
- package/src/loaders/parsers/i3dm/I3DMParser.js +28 -0
- package/src/loaders/parsers/i3dm/I3DMRootParser.js +123 -0
- package/src/loaders/parsers/i3dm/MaterialParser.js +152 -0
- package/src/loaders/parsers/i3dm/PrimitiveParser.js +291 -0
- package/src/loaders/parsers/pnts/PNTSRootParser.js +69 -0
- package/src/main.js +14 -0
- package/src/materials/InstancedBasicMaterial.js +32 -0
- package/src/materials/InstancedPBRMaterial.js +32 -0
- package/src/materials/InstancedShaderChunks.js +23 -0
- package/src/math/Ellipsoid.js +41 -0
- package/src/math/EllipsoidRegion.js +160 -0
- package/src/math/FastFrustum.js +49 -0
- package/src/math/GeoUtils.js +31 -0
- package/src/math/OBB.js +395 -0
- package/src/math/TileBoundingVolume.js +172 -0
- package/src/math/TileOBB.js +103 -0
- package/src/utils/BatchTable.js +14 -0
- package/src/utils/CameraList.js +131 -0
- package/src/utils/FeatureTable.js +107 -0
- package/src/utils/IntersectionUtils.js +136 -0
- package/src/utils/LRUCache.js +159 -0
- package/src/utils/ModelLoader.js +150 -0
- package/src/utils/PriorityQueue.js +102 -0
- package/src/utils/RequestState.js +17 -0
- package/src/utils/TilesLoader.js +386 -0
- package/src/utils/TilesScheduler.js +375 -0
- package/src/utils/Utils.js +43 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GLTFLoader } from '../libs/glTF/GLTFLoader.js';
|
|
2
|
+
|
|
3
|
+
import { ReferenceParser } from '../libs/glTF/parsers/ReferenceParser.js';
|
|
4
|
+
import { Validator } from '../libs/glTF/parsers/Validator.js';
|
|
5
|
+
import { BufferParser } from '../libs/glTF/parsers/BufferParser.js';
|
|
6
|
+
import { BufferViewParser } from '../libs/glTF/parsers/BufferViewParser.js';
|
|
7
|
+
import { ImageParser } from '../libs/glTF/parsers/ImageParser.js';
|
|
8
|
+
import { TextureParser } from '../libs/glTF/parsers/TextureParser.js';
|
|
9
|
+
import { AccessorParser } from '../libs/glTF/parsers/AccessorParser.js';
|
|
10
|
+
import { PrimitiveParser } from '../libs/glTF/parsers/PrimitiveParser.js';
|
|
11
|
+
import { NodeParser } from '../libs/glTF/parsers/NodeParser.js';
|
|
12
|
+
import { SkinParser } from '../libs/glTF/parsers/SkinParser.js';
|
|
13
|
+
import { SceneParser } from '../libs/glTF/parsers/SceneParser.js';
|
|
14
|
+
import { AnimationParser } from '../libs/glTF/parsers/AnimationParser.js';
|
|
15
|
+
|
|
16
|
+
import { HeaderParser } from './parsers/HeaderParser.js';
|
|
17
|
+
import { TableParser } from './parsers/TableParser.js';
|
|
18
|
+
import { B3DMParser } from './parsers/b3dm/B3DMParser.js';
|
|
19
|
+
import { MaterialParser } from './parsers/b3dm/MaterialParser.js';
|
|
20
|
+
import { B3DMRootParser } from './parsers/b3dm/B3DMRootParser.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* B3DMLoader is a loader for the B3DM format.
|
|
24
|
+
*/
|
|
25
|
+
export class B3DMLoader extends GLTFLoader {
|
|
26
|
+
|
|
27
|
+
constructor(manager) {
|
|
28
|
+
super(manager, [
|
|
29
|
+
HeaderParser, // insert HeaderParser
|
|
30
|
+
TableParser, // insert TableParser
|
|
31
|
+
B3DMParser, // insert B3DMParser
|
|
32
|
+
ReferenceParser,
|
|
33
|
+
Validator,
|
|
34
|
+
BufferParser,
|
|
35
|
+
BufferViewParser,
|
|
36
|
+
ImageParser,
|
|
37
|
+
TextureParser,
|
|
38
|
+
MaterialParser, // replace MaterialParser
|
|
39
|
+
AccessorParser,
|
|
40
|
+
PrimitiveParser,
|
|
41
|
+
NodeParser,
|
|
42
|
+
SkinParser,
|
|
43
|
+
SceneParser,
|
|
44
|
+
AnimationParser,
|
|
45
|
+
B3DMRootParser // insert B3DMRootParser
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { GLTFLoader } from '../libs/glTF/GLTFLoader.js';
|
|
2
|
+
|
|
3
|
+
import { HeaderParser } from './parsers/HeaderParser.js';
|
|
4
|
+
import { CMPTParser } from './parsers/cmpt/CMPTParser.js';
|
|
5
|
+
import { CMPTRootParser } from './parsers/cmpt/CMPTRootParser.js';
|
|
6
|
+
|
|
7
|
+
import { B3DMLoader } from './B3DMLoader.js';
|
|
8
|
+
import { I3DMLoader } from './I3DMLoader.js';
|
|
9
|
+
import { PNTSLoader } from './PNTSLoader.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* CMPTLoader is a loader for the CMPT format.
|
|
13
|
+
*/
|
|
14
|
+
export class CMPTLoader extends GLTFLoader {
|
|
15
|
+
|
|
16
|
+
constructor(manager) {
|
|
17
|
+
super(manager, [
|
|
18
|
+
HeaderParser,
|
|
19
|
+
CMPTParser,
|
|
20
|
+
CMPTRootParser
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
const b3dmLoader = new B3DMLoader(manager);
|
|
24
|
+
const i3dmLoader = new I3DMLoader(manager);
|
|
25
|
+
const pntsLoader = new PNTSLoader(manager);
|
|
26
|
+
|
|
27
|
+
this._loaders = new Map([
|
|
28
|
+
['b3dm', b3dmLoader],
|
|
29
|
+
['i3dm', i3dmLoader],
|
|
30
|
+
['pnts', pntsLoader]
|
|
31
|
+
]);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
setDRACOLoader(dracoLoader) {
|
|
35
|
+
for (const loader of this._loaders.values()) {
|
|
36
|
+
loader.setDRACOLoader(dracoLoader);
|
|
37
|
+
}
|
|
38
|
+
return super.setDRACOLoader(dracoLoader);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
setKTX2Loader(ktx2Loader) {
|
|
42
|
+
for (const loader of this._loaders.values()) {
|
|
43
|
+
loader.setKTX2Loader(ktx2Loader);
|
|
44
|
+
}
|
|
45
|
+
return super.setKTX2Loader(ktx2Loader);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { GLTFLoader } from '../libs/glTF/GLTFLoader.js';
|
|
2
|
+
|
|
3
|
+
import { ReferenceParser } from '../libs/glTF/parsers/ReferenceParser.js';
|
|
4
|
+
import { Validator } from '../libs/glTF/parsers/Validator.js';
|
|
5
|
+
import { BufferParser } from '../libs/glTF/parsers/BufferParser.js';
|
|
6
|
+
import { BufferViewParser } from '../libs/glTF/parsers/BufferViewParser.js';
|
|
7
|
+
import { ImageParser } from '../libs/glTF/parsers/ImageParser.js';
|
|
8
|
+
import { TextureParser } from '../libs/glTF/parsers/TextureParser.js';
|
|
9
|
+
import { AccessorParser } from '../libs/glTF/parsers/AccessorParser.js';
|
|
10
|
+
import { NodeParser } from '../libs/glTF/parsers/NodeParser.js';
|
|
11
|
+
import { SkinParser } from '../libs/glTF/parsers/SkinParser.js';
|
|
12
|
+
import { SceneParser } from '../libs/glTF/parsers/SceneParser.js';
|
|
13
|
+
import { AnimationParser } from '../libs/glTF/parsers/AnimationParser.js';
|
|
14
|
+
|
|
15
|
+
import { HeaderParser } from './parsers/HeaderParser.js';
|
|
16
|
+
import { TableParser } from './parsers/TableParser.js';
|
|
17
|
+
import { I3DMParser } from './parsers/i3dm/I3DMParser.js';
|
|
18
|
+
import { MaterialParser } from './parsers/i3dm/MaterialParser.js';
|
|
19
|
+
import { PrimitiveParser } from './parsers/i3dm/PrimitiveParser.js';
|
|
20
|
+
import { I3DMRootParser } from './parsers/i3dm/I3DMRootParser.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* I3DMLoader is a loader for the I3DM format.
|
|
24
|
+
*/
|
|
25
|
+
export class I3DMLoader extends GLTFLoader {
|
|
26
|
+
|
|
27
|
+
constructor(manager) {
|
|
28
|
+
super(manager, [
|
|
29
|
+
HeaderParser, // insert HeaderParser
|
|
30
|
+
TableParser, // insert TableParser
|
|
31
|
+
I3DMParser, // insert I3DMParser
|
|
32
|
+
ReferenceParser,
|
|
33
|
+
Validator,
|
|
34
|
+
BufferParser,
|
|
35
|
+
BufferViewParser,
|
|
36
|
+
ImageParser,
|
|
37
|
+
TextureParser,
|
|
38
|
+
MaterialParser, // replace MaterialParser
|
|
39
|
+
AccessorParser,
|
|
40
|
+
PrimitiveParser, // replace PrimitiveParser
|
|
41
|
+
NodeParser,
|
|
42
|
+
SkinParser,
|
|
43
|
+
SceneParser,
|
|
44
|
+
AnimationParser,
|
|
45
|
+
I3DMRootParser // insert I3DMSetupParser
|
|
46
|
+
]);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { GLTFLoader } from '../libs/glTF/GLTFLoader.js';
|
|
2
|
+
|
|
3
|
+
import { HeaderParser } from './parsers/HeaderParser.js';
|
|
4
|
+
import { TableParser } from './parsers/TableParser.js';
|
|
5
|
+
import { PNTSRootParser } from './parsers/pnts/PNTSRootParser.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* PNTSLoader is a loader for the PNTS format.
|
|
9
|
+
*/
|
|
10
|
+
export class PNTSLoader extends GLTFLoader {
|
|
11
|
+
|
|
12
|
+
constructor(manager) {
|
|
13
|
+
super(manager, [
|
|
14
|
+
HeaderParser,
|
|
15
|
+
TableParser,
|
|
16
|
+
PNTSRootParser
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { GLTFLoader } from '../libs/glTF/GLTFLoader.js';
|
|
2
|
+
|
|
3
|
+
import { IndexParser } from './parsers/gltf/IndexParser.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* TileGLTFLoader is a gltf loader
|
|
7
|
+
* that extends the default gltf loader with additional parsers
|
|
8
|
+
* to support the tile gltf format.
|
|
9
|
+
*/
|
|
10
|
+
export class TileGLTFLoader extends GLTFLoader {
|
|
11
|
+
|
|
12
|
+
constructor(manager) {
|
|
13
|
+
super(manager);
|
|
14
|
+
this.replaceParser(IndexParser, 0);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { getUrlExtension } from '../../utils/Utils.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* This parser is used to parse the header of a 3D Tiles resource.
|
|
5
|
+
* For 'b3dm', 'i3dm', 'pnts' and 'cmpt' formats.
|
|
6
|
+
*/
|
|
7
|
+
export class HeaderParser {
|
|
8
|
+
|
|
9
|
+
static parse(context, loader) {
|
|
10
|
+
const buffer = context.options.buffer;
|
|
11
|
+
|
|
12
|
+
// TODO: this should be able to take a uint8array with an offset and length
|
|
13
|
+
const dataView = new DataView(buffer);
|
|
14
|
+
|
|
15
|
+
// 32-byte header for i3dm and 28-byte header for the others.
|
|
16
|
+
|
|
17
|
+
// 4 bytes for the magic, can be 'b3dm', 'i3dm', 'pnts', 'cmpt' for now.
|
|
18
|
+
// 'vctr' is not supported yet.
|
|
19
|
+
|
|
20
|
+
const magic =
|
|
21
|
+
String.fromCharCode(dataView.getUint8(0)) +
|
|
22
|
+
String.fromCharCode(dataView.getUint8(1)) +
|
|
23
|
+
String.fromCharCode(dataView.getUint8(2)) +
|
|
24
|
+
String.fromCharCode(dataView.getUint8(3));
|
|
25
|
+
|
|
26
|
+
const urlExtension = getUrlExtension(context.url);
|
|
27
|
+
|
|
28
|
+
if (magic !== urlExtension) {
|
|
29
|
+
throw `Not a ${urlExtension} type resource, with url ${context.url}!`;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 4 bytes for the version number.
|
|
33
|
+
|
|
34
|
+
const version = dataView.getUint32(4, true);
|
|
35
|
+
|
|
36
|
+
if (version !== 1) {
|
|
37
|
+
throw `${urlExtension} version must be 1, with url ${context.url}!`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// 4 bytes for the byte length of the entire tile content.
|
|
41
|
+
|
|
42
|
+
const byteLength = dataView.getUint32(8, true);
|
|
43
|
+
|
|
44
|
+
if (byteLength !== buffer.byteLength) {
|
|
45
|
+
throw `${urlExtension} data byte length check failed, with url ${context.url}!`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// output the header information to the context and return
|
|
49
|
+
// if the tile content is cmpt.
|
|
50
|
+
|
|
51
|
+
if (urlExtension === 'cmpt') {
|
|
52
|
+
// 4 bytes for the tiles length
|
|
53
|
+
const tilesLength = dataView.getUint32(12, true);
|
|
54
|
+
|
|
55
|
+
context.header = {
|
|
56
|
+
magic,
|
|
57
|
+
version,
|
|
58
|
+
byteLength,
|
|
59
|
+
tilesLength
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// 4 bytes for the byte length of the feature table JSON.
|
|
66
|
+
|
|
67
|
+
const featureTableJSONByteLength = dataView.getUint32(12, true);
|
|
68
|
+
|
|
69
|
+
// 4 bytes for the byte length of the feature table binary.
|
|
70
|
+
|
|
71
|
+
const featureTableBinaryByteLength = dataView.getUint32(16, true);
|
|
72
|
+
|
|
73
|
+
// 4 bytes for the byte length of the batch table JSON.
|
|
74
|
+
|
|
75
|
+
const batchTableJSONByteLength = dataView.getUint32(20, true);
|
|
76
|
+
|
|
77
|
+
// 4 bytes for the byte length of the batch table binary.
|
|
78
|
+
|
|
79
|
+
const batchTableBinaryByteLength = dataView.getUint32(24, true);
|
|
80
|
+
|
|
81
|
+
// 4 bytes for the gltf format if the tile content format is i3dm.
|
|
82
|
+
|
|
83
|
+
let gltfFormat = null;
|
|
84
|
+
if (urlExtension === 'i3dm') {
|
|
85
|
+
gltfFormat = dataView.getUint32(28, true);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// output the header information to the context.
|
|
89
|
+
|
|
90
|
+
context.header = {
|
|
91
|
+
magic,
|
|
92
|
+
version,
|
|
93
|
+
byteLength,
|
|
94
|
+
featureTableJSONByteLength,
|
|
95
|
+
featureTableBinaryByteLength,
|
|
96
|
+
batchTableJSONByteLength,
|
|
97
|
+
batchTableBinaryByteLength,
|
|
98
|
+
gltfFormat
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { getUrlExtension } from '../../utils/Utils.js';
|
|
2
|
+
|
|
3
|
+
export class LoadParser {
|
|
4
|
+
|
|
5
|
+
static parse(context, loader) {
|
|
6
|
+
const extension = getUrlExtension(context.url);
|
|
7
|
+
let pr = null;
|
|
8
|
+
if (extension === 'gltf') {
|
|
9
|
+
pr = loader.loadFile(context.url)
|
|
10
|
+
.then(buffer => {
|
|
11
|
+
context.options.buffer = buffer;
|
|
12
|
+
});
|
|
13
|
+
} else {
|
|
14
|
+
pr = loader.loadFile(context.url, 'arraybuffer')
|
|
15
|
+
.then(buffer => {
|
|
16
|
+
context.options.buffer = buffer;
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
return pr;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { BatchTable } from '../../utils/BatchTable.js';
|
|
2
|
+
import { FeatureTable } from '../../utils/FeatureTable.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This parser is used to parse the feature table and batch table of a 3D Tiles resource.
|
|
6
|
+
* For 'b3dm', 'i3dm' and 'pnts' formats.
|
|
7
|
+
*/
|
|
8
|
+
export class TableParser {
|
|
9
|
+
|
|
10
|
+
static parse(context, loader) {
|
|
11
|
+
const { header, options } = context;
|
|
12
|
+
const buffer = options.buffer;
|
|
13
|
+
|
|
14
|
+
const featureTableStart = header.magic === 'i3dm' ? 32 : 28;
|
|
15
|
+
const featureTableEnd = featureTableStart + header.featureTableJSONByteLength + header.featureTableBinaryByteLength;
|
|
16
|
+
const batchTableStart = featureTableEnd;
|
|
17
|
+
const batchTableEnd = batchTableStart + header.batchTableJSONByteLength + header.batchTableBinaryByteLength;
|
|
18
|
+
|
|
19
|
+
// parse the feature table
|
|
20
|
+
|
|
21
|
+
const featureTableBuffer = buffer.slice(
|
|
22
|
+
featureTableStart,
|
|
23
|
+
featureTableEnd
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
const featureTable = new FeatureTable(
|
|
27
|
+
featureTableBuffer,
|
|
28
|
+
0,
|
|
29
|
+
header.featureTableJSONByteLength,
|
|
30
|
+
header.featureTableBinaryByteLength
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
// parse the batch table
|
|
34
|
+
|
|
35
|
+
let batchSize;
|
|
36
|
+
if (header.magic === 'b3dm') {
|
|
37
|
+
batchSize = featureTable.getData('BATCH_LENGTH');
|
|
38
|
+
} else if (header.magic === 'i3dm') {
|
|
39
|
+
batchSize = featureTable.getData('INSTANCES_LENGTH');
|
|
40
|
+
} else if (header.magic === 'pnts') {
|
|
41
|
+
batchSize = featureTable.getData('BATCH_LENGTH') || featureTable.getData('POINTS_LENGTH');
|
|
42
|
+
} else {
|
|
43
|
+
throw `Unrecognized magic: ${header.magic}!`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const batchTableBuffer = buffer.slice(
|
|
47
|
+
batchTableStart,
|
|
48
|
+
batchTableEnd
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
const batchTable = new BatchTable(
|
|
52
|
+
batchTableBuffer,
|
|
53
|
+
batchSize,
|
|
54
|
+
0,
|
|
55
|
+
header.batchTableJSONByteLength,
|
|
56
|
+
header.batchTableBinaryByteLength
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// output the tables to the context
|
|
60
|
+
|
|
61
|
+
context.featureTable = featureTable;
|
|
62
|
+
context.batchTable = batchTable;
|
|
63
|
+
context.batchTableEnd = batchTableEnd;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { GLTFUtils } from '../../../libs/glTF/GLTFUtils.js';
|
|
2
|
+
|
|
3
|
+
export class B3DMParser {
|
|
4
|
+
|
|
5
|
+
static parse(context, loader) {
|
|
6
|
+
const glbBytes = new Uint8Array(
|
|
7
|
+
context.options.buffer,
|
|
8
|
+
context.batchTableEnd,
|
|
9
|
+
context.header.byteLength - context.batchTableEnd
|
|
10
|
+
);
|
|
11
|
+
|
|
12
|
+
const glbData = GLTFUtils.parseGLB(glbBytes.slice().buffer);
|
|
13
|
+
|
|
14
|
+
context.gltf = glbData.gltf;
|
|
15
|
+
context.buffers = glbData.buffers;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export class B3DMRootParser {
|
|
2
|
+
|
|
3
|
+
static parse(context, loader) {
|
|
4
|
+
const { root, featureTable, options } = context;
|
|
5
|
+
|
|
6
|
+
// fix rtc center
|
|
7
|
+
|
|
8
|
+
const rtcCenter = featureTable.getData('RTC_CENTER');
|
|
9
|
+
if (rtcCenter) {
|
|
10
|
+
root.position.x += rtcCenter[0];
|
|
11
|
+
root.position.y += rtcCenter[1];
|
|
12
|
+
root.position.z += rtcCenter[2];
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (options.adjustmentTransform) {
|
|
16
|
+
root.matrix.transform(root.position, root.scale, root.quaternion);
|
|
17
|
+
root.matrix.multiply(options.adjustmentTransform);
|
|
18
|
+
root.matrix.decompose(root.position, root.quaternion, root.scale);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PBRMaterial,
|
|
3
|
+
DRAW_SIDE,
|
|
4
|
+
TEXEL_ENCODING_TYPE
|
|
5
|
+
} from 't3d';
|
|
6
|
+
import { KHR_materials_unlit as _KHR_materials_unlit } from '../../../libs/glTF/extensions/KHR_materials_unlit.js';
|
|
7
|
+
import { KHR_materials_pbrSpecularGlossiness as _KHR_materials_pbrSpecularGlossiness } from '../../../libs/glTF/extensions/KHR_materials_pbrSpecularGlossiness.js';
|
|
8
|
+
import { KHR_materials_clearcoat as _KHR_materials_clearcoat } from '../../../libs/glTF/extensions/KHR_materials_clearcoat.js';
|
|
9
|
+
import { KHR_texture_transform } from '../../../libs/glTF/extensions/KHR_texture_transform.js';
|
|
10
|
+
import { ALPHA_MODES } from '../../../libs/glTF/Constants.js';
|
|
11
|
+
|
|
12
|
+
export class MaterialParser {
|
|
13
|
+
|
|
14
|
+
static parse(context) {
|
|
15
|
+
const { gltf, textures } = context;
|
|
16
|
+
|
|
17
|
+
if (!gltf.materials) return;
|
|
18
|
+
|
|
19
|
+
const materials = [];
|
|
20
|
+
for (let i = 0; i < gltf.materials.length; i++) {
|
|
21
|
+
const {
|
|
22
|
+
extensions = {},
|
|
23
|
+
pbrMetallicRoughness,
|
|
24
|
+
normalTexture,
|
|
25
|
+
occlusionTexture,
|
|
26
|
+
emissiveTexture,
|
|
27
|
+
emissiveFactor,
|
|
28
|
+
alphaMode,
|
|
29
|
+
alphaCutoff,
|
|
30
|
+
doubleSided,
|
|
31
|
+
name = ''
|
|
32
|
+
} = gltf.materials[i];
|
|
33
|
+
|
|
34
|
+
const { KHR_materials_unlit, KHR_materials_pbrSpecularGlossiness, KHR_materials_clearcoat, KHR_techniques_webgl } = extensions;
|
|
35
|
+
|
|
36
|
+
let material = null;
|
|
37
|
+
if (KHR_materials_unlit) {
|
|
38
|
+
material = _KHR_materials_unlit.getMaterial();
|
|
39
|
+
} else if (KHR_materials_pbrSpecularGlossiness) {
|
|
40
|
+
material = _KHR_materials_pbrSpecularGlossiness.getMaterial();
|
|
41
|
+
_KHR_materials_pbrSpecularGlossiness.parseParams(material, KHR_materials_pbrSpecularGlossiness, textures);
|
|
42
|
+
} else if (KHR_materials_clearcoat) {
|
|
43
|
+
material = _KHR_materials_clearcoat.getMaterial();
|
|
44
|
+
_KHR_materials_clearcoat.parseParams(material, KHR_materials_clearcoat, textures);
|
|
45
|
+
} else if (KHR_techniques_webgl) { // @parser-modification - add KHR_techniques_webgl
|
|
46
|
+
material = new PBRMaterial();
|
|
47
|
+
|
|
48
|
+
const { values } = KHR_techniques_webgl;
|
|
49
|
+
const { u_diffuse } = values;
|
|
50
|
+
|
|
51
|
+
if (u_diffuse) {
|
|
52
|
+
material.diffuseMap = textures[u_diffuse.index];
|
|
53
|
+
material.diffuseMapCoord = u_diffuse.texCoord || 0;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
material = new PBRMaterial();
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
material.name = name;
|
|
60
|
+
|
|
61
|
+
if (pbrMetallicRoughness) {
|
|
62
|
+
const { baseColorFactor, baseColorTexture, metallicFactor, roughnessFactor, metallicRoughnessTexture } = pbrMetallicRoughness;
|
|
63
|
+
|
|
64
|
+
if (Array.isArray(baseColorFactor)) {
|
|
65
|
+
material.diffuse.fromArray(baseColorFactor);
|
|
66
|
+
material.opacity = (baseColorFactor[3] !== undefined) ? baseColorFactor[3] : 1;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (baseColorTexture) {
|
|
70
|
+
material.diffuseMap = textures[baseColorTexture.index];
|
|
71
|
+
material.diffuseMapCoord = baseColorTexture.texCoord || 0;
|
|
72
|
+
if (material.diffuseMap) {
|
|
73
|
+
material.diffuseMap.encoding = TEXEL_ENCODING_TYPE.SRGB;
|
|
74
|
+
parseTextureTransform(material, 'diffuseMap', baseColorTexture.extensions);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!KHR_materials_unlit && !KHR_materials_pbrSpecularGlossiness) {
|
|
79
|
+
material.metalness = metallicFactor !== undefined ? metallicFactor : 1;
|
|
80
|
+
material.roughness = roughnessFactor !== undefined ? roughnessFactor : 1;
|
|
81
|
+
if (metallicRoughnessTexture) {
|
|
82
|
+
material.metalnessMap = textures[metallicRoughnessTexture.index];
|
|
83
|
+
material.roughnessMap = textures[metallicRoughnessTexture.index];
|
|
84
|
+
// parseTextureTransform(material, 'metalnessMap', metallicRoughnessTexture.extensions);
|
|
85
|
+
// parseTextureTransform(material, 'roughnessMap', metallicRoughnessTexture.extensions);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (emissiveFactor) {
|
|
91
|
+
material.emissive.fromArray(emissiveFactor);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
if (emissiveTexture) {
|
|
95
|
+
material.emissiveMap = textures[emissiveTexture.index];
|
|
96
|
+
material.emissiveMapCoord = emissiveTexture.texCoord || 0;
|
|
97
|
+
if (material.emissiveMap) {
|
|
98
|
+
material.emissiveMap.encoding = TEXEL_ENCODING_TYPE.SRGB;
|
|
99
|
+
parseTextureTransform(material, 'emissiveMap', emissiveTexture.extensions);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (occlusionTexture) {
|
|
104
|
+
material.aoMap = textures[occlusionTexture.index];
|
|
105
|
+
material.aoMapCoord = occlusionTexture.texCoord || 0;
|
|
106
|
+
if (occlusionTexture.strength !== undefined) {
|
|
107
|
+
material.aoMapIntensity = occlusionTexture.strength;
|
|
108
|
+
}
|
|
109
|
+
if (material.aoMap) {
|
|
110
|
+
parseTextureTransform(material, 'aoMap', occlusionTexture.extensions);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!KHR_materials_unlit) {
|
|
115
|
+
if (normalTexture) {
|
|
116
|
+
material.normalMap = textures[normalTexture.index];
|
|
117
|
+
|
|
118
|
+
material.normalScale.set(1, -1);
|
|
119
|
+
if (normalTexture.scale !== undefined) {
|
|
120
|
+
// fix flip y for normal map
|
|
121
|
+
// https://github.com/mrdoob/three.js/issues/11438#issuecomment-507003995
|
|
122
|
+
material.normalScale.set(normalTexture.scale, -normalTexture.scale);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (material.normalMap) {
|
|
126
|
+
// parseTextureTransform(material, 'normalMap', normalTexture.extensions);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
material.side = doubleSided === true ? DRAW_SIDE.DOUBLE : DRAW_SIDE.FRONT;
|
|
132
|
+
|
|
133
|
+
if (alphaMode === ALPHA_MODES.BLEND) {
|
|
134
|
+
material.transparent = true;
|
|
135
|
+
} else {
|
|
136
|
+
material.transparent = false;
|
|
137
|
+
|
|
138
|
+
if (alphaMode === ALPHA_MODES.MASK) {
|
|
139
|
+
material.alphaTest = alphaCutoff !== undefined ? alphaCutoff : 0.5;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
materials[i] = material;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
context.materials = materials;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function parseTextureTransform(material, key, extensions = {}) {
|
|
152
|
+
const extension = extensions.KHR_texture_transform;
|
|
153
|
+
if (extension) {
|
|
154
|
+
KHR_texture_transform.transform(material[key + 'Transform'], extension);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export class CMPTParser {
|
|
2
|
+
|
|
3
|
+
static parse(context, loader) {
|
|
4
|
+
const buffer = context.options.buffer;
|
|
5
|
+
const tilesLength = context.header.tilesLength;
|
|
6
|
+
|
|
7
|
+
const tiles = [];
|
|
8
|
+
let offset = 16;
|
|
9
|
+
|
|
10
|
+
for (let i = 0; i < tilesLength; i++) {
|
|
11
|
+
const tileView = new DataView(buffer, offset, 12);
|
|
12
|
+
|
|
13
|
+
const tileMagic =
|
|
14
|
+
String.fromCharCode(tileView.getUint8(0)) +
|
|
15
|
+
String.fromCharCode(tileView.getUint8(1)) +
|
|
16
|
+
String.fromCharCode(tileView.getUint8(2)) +
|
|
17
|
+
String.fromCharCode(tileView.getUint8(3));
|
|
18
|
+
|
|
19
|
+
const tileVersion = tileView.getUint32(4, true);
|
|
20
|
+
|
|
21
|
+
const byteLength = tileView.getUint32(8, true);
|
|
22
|
+
|
|
23
|
+
const tileBuffer = new Uint8Array(buffer, offset, byteLength);
|
|
24
|
+
|
|
25
|
+
tiles.push({
|
|
26
|
+
type: tileMagic,
|
|
27
|
+
buffer: tileBuffer,
|
|
28
|
+
version: tileVersion
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
offset += byteLength;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
context.tiles = tiles;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Object3D } from 't3d';
|
|
2
|
+
|
|
3
|
+
export class CMPTRootParser {
|
|
4
|
+
|
|
5
|
+
static parse(context, loader) {
|
|
6
|
+
const { tiles, options, path } = context;
|
|
7
|
+
|
|
8
|
+
const adjustmentTransform = options.adjustmentTransform;
|
|
9
|
+
|
|
10
|
+
const promises = [];
|
|
11
|
+
|
|
12
|
+
for (const i in tiles) {
|
|
13
|
+
const { type, buffer } = tiles[i];
|
|
14
|
+
|
|
15
|
+
const config = {
|
|
16
|
+
fetchOptions: options.fetchOptions,
|
|
17
|
+
path,
|
|
18
|
+
buffer: buffer.slice().buffer
|
|
19
|
+
};
|
|
20
|
+
if (type === 'b3dm' || type === 'i3dm') {
|
|
21
|
+
config.adjustmentTransform = adjustmentTransform;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const _loader = loader._loaders.get(type);
|
|
25
|
+
if (_loader) {
|
|
26
|
+
promises.push(_loader.load(`${path}/temp.${type}`, config));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return Promise.all(promises).then(results => {
|
|
31
|
+
const group = new Object3D();
|
|
32
|
+
|
|
33
|
+
results.forEach(result => {
|
|
34
|
+
group.add(result.root);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
return {
|
|
38
|
+
tiles: results,
|
|
39
|
+
root: group
|
|
40
|
+
};
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GLTFUtils } from '../../../libs/glTF/GLTFUtils.js';
|
|
2
|
+
|
|
3
|
+
export class IndexParser {
|
|
4
|
+
|
|
5
|
+
static parse(context, loader) {
|
|
6
|
+
const { url, options } = context;
|
|
7
|
+
const buffer = options.buffer;
|
|
8
|
+
|
|
9
|
+
const _isGLB = isGLB(url);
|
|
10
|
+
|
|
11
|
+
if (_isGLB) {
|
|
12
|
+
const glbData = GLTFUtils.parseGLB(buffer);
|
|
13
|
+
context.gltf = glbData.gltf;
|
|
14
|
+
context.buffers = glbData.buffers;
|
|
15
|
+
} else {
|
|
16
|
+
context.gltf = buffer;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const isGLB = url => {
|
|
23
|
+
return url.substring(url.lastIndexOf('.') + 1) === 'glb';
|
|
24
|
+
};
|