@jdultra/threedtiles 7.0.2 → 8.0.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/.babelrc +8 -0
- package/README.md +45 -20
- package/package.json +8 -7
- package/src/decoder/B3DMDecoder.js +82 -203
- package/src/index.js +71 -31
- package/src/tileset/OGC3DTile.js +30 -25
- package/src/tileset/TileLoader.js +44 -10
- package/src/tileset/instanced/InstancedTile.js +1 -1
- package/src/tileset/instanced/InstancedTileLoader.js +85 -51
- package/threedtiles.js +80023 -20211
- package/threedtiles.js.map +1 -1
- package/webpack.config.js +17 -16
package/src/tileset/OGC3DTile.js
CHANGED
|
@@ -4,12 +4,14 @@ import { TileLoader } from "./TileLoader";
|
|
|
4
4
|
import { v4 as uuidv4 } from "uuid";
|
|
5
5
|
import * as path from "path-browserify"
|
|
6
6
|
import { clamp } from "three/src/math/MathUtils";
|
|
7
|
+
//import { Octree } from 'three/addons/math/Octree.js';
|
|
8
|
+
//import { OctreeHelper } from 'three/addons/helpers/OctreeHelper.js';
|
|
7
9
|
|
|
8
10
|
const tempSphere = new THREE.Sphere(new THREE.Vector3(0, 0, 0), 1);
|
|
9
11
|
const tempVec1 = new THREE.Vector3(0, 0, 0);
|
|
10
12
|
const tempVec2 = new THREE.Vector3(0, 0, 0);
|
|
11
13
|
const upVector = new THREE.Vector3(0, 1, 0);
|
|
12
|
-
const rendererSize = new THREE.Vector2(1000,1000);
|
|
14
|
+
const rendererSize = new THREE.Vector2(1000, 1000);
|
|
13
15
|
const tempQuaternion = new THREE.Quaternion();
|
|
14
16
|
|
|
15
17
|
|
|
@@ -46,16 +48,16 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
46
48
|
if (!!properties.tileLoader) {
|
|
47
49
|
this.tileLoader = properties.tileLoader;
|
|
48
50
|
} else {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
51
|
+
const tileLoaderOptions = {};
|
|
52
|
+
tileLoaderOptions.meshCallback = !properties.meshCallback ? mesh => {
|
|
53
|
+
mesh.material.wireframe = false;
|
|
54
|
+
mesh.material.side = THREE.DoubleSide;
|
|
55
|
+
} : properties.meshCallback;
|
|
56
|
+
tileLoaderOptions.pointsCallback = !properties.pointsCallback ? points => {
|
|
57
|
+
points.material.size = 0.1;
|
|
58
|
+
points.material.sizeAttenuation = true;
|
|
59
|
+
} : properties.pointsCallback;
|
|
60
|
+
this.tileLoader = new TileLoader(tileLoaderOptions);
|
|
59
61
|
}
|
|
60
62
|
// set properties general to the entire tileset
|
|
61
63
|
this.geometricErrorMultiplier = !!properties.geometricErrorMultiplier ? properties.geometricErrorMultiplier : 1.0;
|
|
@@ -93,6 +95,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
93
95
|
this.centerModel = properties.centerModel;
|
|
94
96
|
this.abortController = new AbortController();
|
|
95
97
|
this.layers.disable(0);
|
|
98
|
+
//this.octree = new Octree();
|
|
96
99
|
|
|
97
100
|
if (!!properties.json) { // If this tile is created as a child of another tile, properties.json is not null
|
|
98
101
|
self.setup(properties);
|
|
@@ -123,11 +126,11 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
123
126
|
(this.json.boundingVolume.region[1] + this.json.boundingVolume.region[3]) * 0.5,
|
|
124
127
|
(this.json.boundingVolume.region[4] + this.json.boundingVolume.region[5]) * 0.5,
|
|
125
128
|
tempVec1);
|
|
126
|
-
|
|
129
|
+
|
|
127
130
|
tempQuaternion.setFromUnitVectors(tempVec1.normalize(), upVector.normalize());
|
|
128
131
|
self.applyQuaternion(tempQuaternion);
|
|
129
132
|
}
|
|
130
|
-
|
|
133
|
+
|
|
131
134
|
self.translateX(-tempSphere.center.x * self.scale.x);
|
|
132
135
|
self.translateY(-tempSphere.center.y * self.scale.y);
|
|
133
136
|
self.translateZ(-tempSphere.center.z * self.scale.z);
|
|
@@ -169,7 +172,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
169
172
|
mat.elements = this.json.transform;
|
|
170
173
|
this.applyMatrix4(mat);
|
|
171
174
|
}
|
|
172
|
-
|
|
175
|
+
|
|
173
176
|
// decode volume
|
|
174
177
|
if (!!this.json.boundingVolume) {
|
|
175
178
|
if (!!this.json.boundingVolume.box) {
|
|
@@ -190,7 +193,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
190
193
|
this.boundingVolume = properties.parentBoundingVolume;
|
|
191
194
|
}
|
|
192
195
|
|
|
193
|
-
|
|
196
|
+
|
|
194
197
|
|
|
195
198
|
if (!!this.json.content) { //if there is a content, json or otherwise, schedule it to be loaded
|
|
196
199
|
if (!!this.json.content.uri && this.json.content.uri.includes("json")) {
|
|
@@ -215,7 +218,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
215
218
|
|
|
216
219
|
return absoluteURL || absolutePath;
|
|
217
220
|
}
|
|
218
|
-
|
|
221
|
+
|
|
219
222
|
load() {
|
|
220
223
|
var self = this;
|
|
221
224
|
if (self.deleted) return;
|
|
@@ -238,12 +241,12 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
238
241
|
if (!!url) {
|
|
239
242
|
if (url.includes(".b3dm") || url.includes(".glb") || url.includes(".gltf")) {
|
|
240
243
|
self.contentURL = url;
|
|
241
|
-
|
|
244
|
+
|
|
242
245
|
self.tileLoader.get(self.abortController, this.uuid, url, mesh => {
|
|
243
246
|
if (!!self.deleted) return;
|
|
244
247
|
mesh.traverse((o) => {
|
|
245
248
|
if (o.isMesh) {
|
|
246
|
-
|
|
249
|
+
|
|
247
250
|
o.layers.disable(0);
|
|
248
251
|
if (self.occlusionCullingService) {
|
|
249
252
|
const position = o.geometry.attributes.position;
|
|
@@ -259,17 +262,19 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
259
262
|
//o.material.visible = false;
|
|
260
263
|
}
|
|
261
264
|
});
|
|
262
|
-
|
|
265
|
+
//let s = Date.now();
|
|
266
|
+
//self.octree.fromGraphNode( mesh );
|
|
267
|
+
//console.log(Date.now()-s);
|
|
263
268
|
self.add(mesh);
|
|
264
269
|
self.updateWorldMatrix(false, true);
|
|
265
270
|
// mesh.layers.disable(0);
|
|
266
271
|
self.meshContent = mesh;
|
|
267
272
|
}, !self.cameraOnLoad ? () => 0 : () => {
|
|
268
273
|
return self.calculateDistanceToCamera(self.cameraOnLoad);
|
|
269
|
-
}, () => self.getSiblings(),
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
274
|
+
}, () => self.getSiblings(),
|
|
275
|
+
self.level,
|
|
276
|
+
!!self.json.boundingVolume.region,
|
|
277
|
+
self.geometricError
|
|
273
278
|
);
|
|
274
279
|
} else if (url.includes(".json")) {
|
|
275
280
|
self.tileLoader.get(self.abortController, this.uuid, url, json => {
|
|
@@ -549,7 +554,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
549
554
|
return;
|
|
550
555
|
}
|
|
551
556
|
self.materialVisibility = visibility
|
|
552
|
-
|
|
557
|
+
|
|
553
558
|
self.meshDisplayed = true;
|
|
554
559
|
if (!!self.meshContent.traverse) {
|
|
555
560
|
self.meshContent.traverse(function (element) {
|
|
@@ -597,7 +602,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
597
602
|
return 0;
|
|
598
603
|
}
|
|
599
604
|
const scale = this.matrixWorld.getMaxScaleOnAxis();
|
|
600
|
-
if(!!this.renderer){
|
|
605
|
+
if (!!this.renderer) {
|
|
601
606
|
this.renderer.getDrawingBufferSize(rendererSize);
|
|
602
607
|
}
|
|
603
608
|
let s = rendererSize.y;
|
|
@@ -5,6 +5,7 @@ import { initial } from 'lodash';
|
|
|
5
5
|
import * as THREE from 'three';
|
|
6
6
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
7
7
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
8
|
+
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
|
|
8
9
|
|
|
9
10
|
let concurentDownloads = 0;
|
|
10
11
|
const zUpToYUpMatrix = new THREE.Matrix4();
|
|
@@ -12,17 +13,49 @@ zUpToYUpMatrix.set(1, 0, 0, 0,
|
|
|
12
13
|
0, 0, -1, 0,
|
|
13
14
|
0, 1, 0, 0,
|
|
14
15
|
0, 0, 0, 1);
|
|
15
|
-
const gltfLoader = new GLTFLoader();
|
|
16
|
-
const dracoLoader = new DRACOLoader();
|
|
17
|
-
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
|
|
18
|
-
gltfLoader.setDRACOLoader(dracoLoader);
|
|
19
16
|
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A Tile loader that manages caching and load order.
|
|
22
|
+
* The cache is an LRU cache and is defined by the number of items it can hold.
|
|
23
|
+
* The actual number of cached items might grow beyond max if all items are in use.
|
|
24
|
+
*
|
|
25
|
+
* The load order is designed for optimal perceived loading speed (nearby tiles are refined first).
|
|
26
|
+
*
|
|
27
|
+
* @param {Object} [options] - Optional configuration object.
|
|
28
|
+
* @param {number} [options.maxCachedItems=100] - the cache size.
|
|
29
|
+
* @param {function} [options.meshCallback] - A callback to call on newly decoded meshes.
|
|
30
|
+
* @param {function} [options.pointsCallback] - A callback to call on newly decoded points.
|
|
31
|
+
* @param {renderer} [options.renderer] - The renderer, this is required for KTX2 support.
|
|
32
|
+
*/
|
|
20
33
|
class TileLoader {
|
|
21
|
-
constructor(
|
|
22
|
-
this.
|
|
23
|
-
|
|
34
|
+
constructor(options) {
|
|
35
|
+
this.maxCachedItems = 100;
|
|
36
|
+
if (!!options) {
|
|
37
|
+
this.meshCallback = options.meshCallback;
|
|
38
|
+
this.pointsCallback = options.pointsCallback;
|
|
39
|
+
if (options.maxCachedItems) this.maxCachedItems = options.maxCachedItems;
|
|
40
|
+
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
this.gltfLoader = new GLTFLoader();
|
|
44
|
+
const dracoLoader = new DRACOLoader();
|
|
45
|
+
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
|
|
46
|
+
this.gltfLoader.setDRACOLoader(dracoLoader);
|
|
47
|
+
|
|
48
|
+
if(!!options && !!options.renderer){
|
|
49
|
+
const ktx2Loader = new KTX2Loader();
|
|
50
|
+
ktx2Loader.setTranscoderPath('https://storage.googleapis.com/ogc-3d-tiles/basis/').detectSupport(options.renderer);
|
|
51
|
+
this.gltfLoader.setKTX2Loader(ktx2Loader);
|
|
52
|
+
|
|
53
|
+
this.b3dmDecoder=new B3DMDecoder(options.renderer);
|
|
54
|
+
}else{
|
|
55
|
+
this.b3dmDecoder=new B3DMDecoder(null);
|
|
56
|
+
}
|
|
57
|
+
|
|
24
58
|
this.cache = new LinkedHashMap();
|
|
25
|
-
this.maxCachedItems = !!maxCachedItems ? maxCachedItems : 100;
|
|
26
59
|
this.register = {};
|
|
27
60
|
|
|
28
61
|
|
|
@@ -33,6 +66,7 @@ class TileLoader {
|
|
|
33
66
|
this.init();
|
|
34
67
|
}
|
|
35
68
|
|
|
69
|
+
|
|
36
70
|
init() {
|
|
37
71
|
|
|
38
72
|
const self = this;
|
|
@@ -195,7 +229,7 @@ class TileLoader {
|
|
|
195
229
|
|
|
196
230
|
})
|
|
197
231
|
.then(resultArrayBuffer => {
|
|
198
|
-
return
|
|
232
|
+
return this.b3dmDecoder.parseB3DM(resultArrayBuffer, self.meshCallback, geometricError, zUpToYUp);
|
|
199
233
|
})
|
|
200
234
|
.then(mesh => {
|
|
201
235
|
self.cache.put(key, mesh);
|
|
@@ -207,7 +241,7 @@ class TileLoader {
|
|
|
207
241
|
} else if (path.includes(".glb") || path.includes(".gltf")) {
|
|
208
242
|
downloadFunction = () => {
|
|
209
243
|
concurentDownloads++;
|
|
210
|
-
gltfLoader.load(path, gltf => {
|
|
244
|
+
this.gltfLoader.load(path, gltf => {
|
|
211
245
|
gltf.scene.traverse((o) => {
|
|
212
246
|
o.geometricError = geometricError;
|
|
213
247
|
if (o.isMesh) {
|
|
@@ -6,25 +6,58 @@ import { MeshTile } from './MeshTile';
|
|
|
6
6
|
import { JsonTile } from './JsonTile';
|
|
7
7
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
8
8
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
9
|
-
|
|
9
|
+
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
|
|
10
10
|
|
|
11
11
|
let concurentDownloads = 0;
|
|
12
|
-
|
|
13
|
-
const dracoLoader = new DRACOLoader();
|
|
14
|
-
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
|
|
15
|
-
gltfLoader.setDRACOLoader(dracoLoader);
|
|
12
|
+
|
|
16
13
|
const zUpToYUpMatrix = new THREE.Matrix4();
|
|
17
14
|
zUpToYUpMatrix.set(1, 0, 0, 0,
|
|
18
15
|
0, 0, -1, 0,
|
|
19
16
|
0, 1, 0, 0,
|
|
20
17
|
0, 0, 0, 1);
|
|
21
18
|
|
|
19
|
+
/**
|
|
20
|
+
* A Tile loader that manages caching and load order for instanced tiles.
|
|
21
|
+
* The cache is an LRU cache and is defined by the number of items it can hold.
|
|
22
|
+
* The actual number of cached items might grow beyond max if all items are in use.
|
|
23
|
+
*
|
|
24
|
+
* The load order is designed for optimal perceived loading speed (nearby tiles are refined first).
|
|
25
|
+
*
|
|
26
|
+
* @param {scene} [scene] - a threejs scene.
|
|
27
|
+
* @param {Object} [options] - Optional configuration object.
|
|
28
|
+
* @param {number} [options.maxCachedItems=100] - the cache size.
|
|
29
|
+
* @param {number} [options.maxInstances=1] - the cache size.
|
|
30
|
+
* @param {function} [options.meshCallback] - A callback to call on newly decoded meshes.
|
|
31
|
+
* @param {function} [options.pointsCallback] - A callback to call on newly decoded points.
|
|
32
|
+
* @param {renderer} [options.renderer] - The renderer, this is required for KTX2 support.
|
|
33
|
+
*/
|
|
22
34
|
class InstancedTileLoader {
|
|
23
|
-
constructor(scene,
|
|
24
|
-
this.
|
|
25
|
-
this.maxInstances =
|
|
35
|
+
constructor(scene, options) {
|
|
36
|
+
this.maxCachedItems = 100;
|
|
37
|
+
this.maxInstances = 1;
|
|
38
|
+
if (!!options) {
|
|
39
|
+
this.meshCallback = options.meshCallback;
|
|
40
|
+
this.pointsCallback = options.pointsCallback;
|
|
41
|
+
if (options.maxCachedItems) this.maxCachedItems = options.maxCachedItems;
|
|
42
|
+
if (options.maxInstances) this.maxInstances = options.maxInstances;
|
|
43
|
+
|
|
44
|
+
}
|
|
45
|
+
this.gltfLoader = new GLTFLoader();
|
|
46
|
+
const dracoLoader = new DRACOLoader();
|
|
47
|
+
dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
|
|
48
|
+
this.gltfLoader.setDRACOLoader(dracoLoader);
|
|
49
|
+
|
|
50
|
+
if(!!options && !!options.renderer){
|
|
51
|
+
const ktx2Loader = new KTX2Loader();
|
|
52
|
+
ktx2Loader.setTranscoderPath('https://storage.googleapis.com/ogc-3d-tiles/basis/').detectSupport(options.renderer);
|
|
53
|
+
this.gltfLoader.setKTX2Loader(ktx2Loader);
|
|
54
|
+
|
|
55
|
+
this.b3dmDecoder=new B3DMDecoder(options.renderer);
|
|
56
|
+
}else{
|
|
57
|
+
this.b3dmDecoder=new B3DMDecoder(null);
|
|
58
|
+
}
|
|
59
|
+
|
|
26
60
|
this.cache = new LinkedHashMap();
|
|
27
|
-
this.maxCachedItems = !!maxCachedItems ? maxCachedItems : 100;
|
|
28
61
|
this.scene = scene;
|
|
29
62
|
|
|
30
63
|
this.ready = [];
|
|
@@ -34,16 +67,17 @@ class InstancedTileLoader {
|
|
|
34
67
|
this.init();
|
|
35
68
|
}
|
|
36
69
|
|
|
37
|
-
|
|
70
|
+
|
|
71
|
+
update() {
|
|
38
72
|
const self = this;
|
|
39
|
-
|
|
40
|
-
self.cache._data.forEach(v=>{
|
|
73
|
+
|
|
74
|
+
self.cache._data.forEach(v => {
|
|
41
75
|
v.update();
|
|
42
76
|
})
|
|
43
|
-
|
|
77
|
+
|
|
44
78
|
}
|
|
45
|
-
init(){
|
|
46
|
-
|
|
79
|
+
init() {
|
|
80
|
+
|
|
47
81
|
const self = this;
|
|
48
82
|
setIntervalAsync(() => {
|
|
49
83
|
self.download();
|
|
@@ -54,7 +88,7 @@ class InstancedTileLoader {
|
|
|
54
88
|
do {
|
|
55
89
|
loaded = self.loadBatch();
|
|
56
90
|
} while (loaded > 0 && (Date.now() - start) <= 0)
|
|
57
|
-
|
|
91
|
+
|
|
58
92
|
}, 10);
|
|
59
93
|
}
|
|
60
94
|
|
|
@@ -69,8 +103,8 @@ class InstancedTileLoader {
|
|
|
69
103
|
if (!!nextDownload && nextDownload.shouldDoDownload()) {
|
|
70
104
|
//nextDownload.doDownload();
|
|
71
105
|
concurentDownloads++;
|
|
72
|
-
if(nextDownload.path.includes(".b3dm")){
|
|
73
|
-
fetch(nextDownload.path, {signal: nextDownload.abortController.signal}).then(result => {
|
|
106
|
+
if (nextDownload.path.includes(".b3dm")) {
|
|
107
|
+
fetch(nextDownload.path, { signal: nextDownload.abortController.signal }).then(result => {
|
|
74
108
|
concurentDownloads--;
|
|
75
109
|
if (!result.ok) {
|
|
76
110
|
console.error("could not load tile with path : " + path)
|
|
@@ -79,17 +113,17 @@ class InstancedTileLoader {
|
|
|
79
113
|
return result.arrayBuffer();
|
|
80
114
|
|
|
81
115
|
})
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}if(nextDownload.path.includes(".glb") || (nextDownload.path.includes(".gltf"))){
|
|
92
|
-
gltfLoader.load(nextDownload.path, gltf => {
|
|
116
|
+
.then(resultArrayBuffer => {
|
|
117
|
+
return this.b3dmDecoder.parseB3DMInstanced(resultArrayBuffer, self.meshCallback, self.maxInstances, nextDownload.zUpToYUp);
|
|
118
|
+
})
|
|
119
|
+
.then(mesh => {
|
|
120
|
+
nextDownload.tile.setObject(mesh);
|
|
121
|
+
self.ready.unshift(nextDownload);
|
|
122
|
+
|
|
123
|
+
})
|
|
124
|
+
.catch(e => console.error(e));
|
|
125
|
+
} if (nextDownload.path.includes(".glb") || (nextDownload.path.includes(".gltf"))) {
|
|
126
|
+
this.gltfLoader.load(nextDownload.path, gltf => {
|
|
93
127
|
gltf.scene.traverse((o) => {
|
|
94
128
|
o.geometricError = nextDownload.geometricError;
|
|
95
129
|
if (o.isMesh) {
|
|
@@ -112,34 +146,34 @@ class InstancedTileLoader {
|
|
|
112
146
|
instancedMesh = new THREE.InstancedMesh(child.geometry, child.material, self.maxInstances);
|
|
113
147
|
instancedMesh.baseMatrix = child.matrixWorld;
|
|
114
148
|
}
|
|
115
|
-
|
|
149
|
+
|
|
116
150
|
});
|
|
117
151
|
self.ready.unshift(nextDownload);
|
|
118
|
-
if(!instancedMesh){
|
|
119
|
-
gltf.scene.traverse(c=>{
|
|
120
|
-
if(c.dispose) c.dispose();
|
|
121
|
-
if(c.material) c.material.dispose();
|
|
152
|
+
if (!instancedMesh) {
|
|
153
|
+
gltf.scene.traverse(c => {
|
|
154
|
+
if (c.dispose) c.dispose();
|
|
155
|
+
if (c.material) c.material.dispose();
|
|
122
156
|
});
|
|
123
|
-
}else{
|
|
157
|
+
} else {
|
|
124
158
|
nextDownload.tile.setObject(instancedMesh);
|
|
125
159
|
}
|
|
126
160
|
});
|
|
127
|
-
|
|
128
|
-
}else if(nextDownload.path.includes(".json")){
|
|
161
|
+
|
|
162
|
+
} else if (nextDownload.path.includes(".json")) {
|
|
129
163
|
concurentDownloads++;
|
|
130
|
-
fetch(nextDownload.path, {signal: nextDownload.abortController.signal}).then(result => {
|
|
164
|
+
fetch(nextDownload.path, { signal: nextDownload.abortController.signal }).then(result => {
|
|
131
165
|
concurentDownloads--;
|
|
132
166
|
if (!result.ok) {
|
|
133
167
|
console.error("could not load tile with path : " + path)
|
|
134
168
|
throw new Error(`couldn't load "${path}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
135
169
|
}
|
|
136
170
|
return result.json();
|
|
137
|
-
|
|
171
|
+
|
|
138
172
|
}).then(json => {
|
|
139
173
|
nextDownload.tile.setObject(json, nextDownload.path);
|
|
140
174
|
self.ready.unshift(nextDownload);
|
|
141
175
|
})
|
|
142
|
-
|
|
176
|
+
.catch(e => console.error(e))
|
|
143
177
|
}
|
|
144
178
|
}
|
|
145
179
|
}
|
|
@@ -153,8 +187,8 @@ class InstancedTileLoader {
|
|
|
153
187
|
}
|
|
154
188
|
const download = this.nextReady.shift();
|
|
155
189
|
if (!download) return 0;
|
|
156
|
-
|
|
157
|
-
if(!!download.tile.addToScene)download.tile.addToScene();
|
|
190
|
+
|
|
191
|
+
if (!!download.tile.addToScene) download.tile.addToScene();
|
|
158
192
|
return 1;
|
|
159
193
|
}
|
|
160
194
|
|
|
@@ -162,7 +196,7 @@ class InstancedTileLoader {
|
|
|
162
196
|
let smallestDistance = Number.MAX_VALUE;
|
|
163
197
|
let closest = -1;
|
|
164
198
|
for (let i = this.ready.length - 1; i >= 0; i--) {
|
|
165
|
-
|
|
199
|
+
|
|
166
200
|
if (!this.ready[i].distanceFunction) {// if no distance function, must be a json, give absolute priority!
|
|
167
201
|
this.nextReady.push(this.ready.splice(i, 1)[0]);
|
|
168
202
|
}
|
|
@@ -205,7 +239,7 @@ class InstancedTileLoader {
|
|
|
205
239
|
if (path.includes(".b3dm") || path.includes(".glb") || path.includes(".gltf")) {
|
|
206
240
|
const tile = new MeshTile(self.scene);
|
|
207
241
|
tile.addInstance(instancedOGC3DTile);
|
|
208
|
-
|
|
242
|
+
|
|
209
243
|
self.cache.put(key, tile);
|
|
210
244
|
|
|
211
245
|
const realAbortController = new AbortController();
|
|
@@ -229,7 +263,7 @@ class InstancedTileLoader {
|
|
|
229
263
|
return true;
|
|
230
264
|
},
|
|
231
265
|
})
|
|
232
|
-
}else if(path.includes(".json")){
|
|
266
|
+
} else if (path.includes(".json")) {
|
|
233
267
|
const tile = new JsonTile();
|
|
234
268
|
tile.addInstance(instancedOGC3DTile);
|
|
235
269
|
self.cache.put(key, tile);
|
|
@@ -258,7 +292,7 @@ class InstancedTileLoader {
|
|
|
258
292
|
}
|
|
259
293
|
|
|
260
294
|
|
|
261
|
-
|
|
295
|
+
|
|
262
296
|
getNextDownloads() {
|
|
263
297
|
let smallestDistance = Number.MAX_VALUE;
|
|
264
298
|
let closest = -1;
|
|
@@ -267,7 +301,7 @@ class InstancedTileLoader {
|
|
|
267
301
|
if (!download.shouldDoDownload()) {
|
|
268
302
|
this.downloads.splice(i, 1);
|
|
269
303
|
continue;
|
|
270
|
-
}
|
|
304
|
+
}
|
|
271
305
|
if (!download.distanceFunction) { // if no distance function, must be a json, give absolute priority!
|
|
272
306
|
this.nextDownloads.push(this.downloads.splice(i, 1)[0]);
|
|
273
307
|
}
|
|
@@ -275,7 +309,7 @@ class InstancedTileLoader {
|
|
|
275
309
|
if (this.nextDownloads.length > 0) return;
|
|
276
310
|
for (let i = this.downloads.length - 1; i >= 0; i--) {
|
|
277
311
|
const download = this.downloads[i];
|
|
278
|
-
const dist = download.distanceFunction()*download.level;
|
|
312
|
+
const dist = download.distanceFunction() * download.level;
|
|
279
313
|
if (dist < smallestDistance) {
|
|
280
314
|
smallestDistance = dist;
|
|
281
315
|
closest = i;
|
|
@@ -301,12 +335,12 @@ class InstancedTileLoader {
|
|
|
301
335
|
while (self.cache.size() > self.maxCachedItems && i < self.cache.size()) {
|
|
302
336
|
i++;
|
|
303
337
|
const entry = self.cache.head();
|
|
304
|
-
if(entry.value.getCount()>0){
|
|
338
|
+
if (entry.value.getCount() > 0) {
|
|
305
339
|
self.cache.remove(entry.key);
|
|
306
340
|
self.cache.put(entry.key, entry.value);
|
|
307
|
-
}else{
|
|
341
|
+
} else {
|
|
308
342
|
self.cache.remove(entry.key);
|
|
309
|
-
if(entry.value.instancedMesh){
|
|
343
|
+
if (entry.value.instancedMesh) {
|
|
310
344
|
entry.value.instancedMesh.traverse((o) => {
|
|
311
345
|
if (o.material) {
|
|
312
346
|
// dispose materials
|