@jdultra/threedtiles 3.1.4 → 3.2.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/README.md +12 -3
- package/index.html +43 -1
- package/package.json +2 -2
- package/src/decoder/B3DMDecoder.js +5 -4
- package/src/index.js +39 -20
- package/src/tileset/OGC3DTile.js +13 -29
- package/src/tileset/TileLoader.js +37 -26
- package/manifest.json +0 -4
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
#
|
|
1
|
+
# threedtiles
|
|
2
2
|
|
|
3
3
|
3DTiles viewer for three.js
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Photogrametry : https://ebeaufay.github.io/ThreedTilesViewer.github.io/
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
IFC : https://storage.googleapis.com/jdultra.com/ifc/index.html
|
|
8
|
+
|
|
9
|
+
Occlusion culling : https://storage.googleapis.com/jdultra.com/occlusionCulling/index.html
|
|
8
10
|
|
|
9
11
|
Adding a tileset to a scene is as easy as :
|
|
10
12
|
|
|
@@ -27,6 +29,8 @@ setInterval(function () {
|
|
|
27
29
|
}, 200);
|
|
28
30
|
```
|
|
29
31
|
|
|
32
|
+
Currently, the library is limmited to B3DM files.
|
|
33
|
+
|
|
30
34
|
## Features
|
|
31
35
|
|
|
32
36
|
- Handles nested tileset.json files which are loaded on the fly (a tileset.json may point to another tileset.json file as its child).
|
|
@@ -114,6 +118,11 @@ ogc3DTile.rotateOnAxis(new THREE.Vector3(1,0,0), -Math.PI*0.5);
|
|
|
114
118
|
...
|
|
115
119
|
```
|
|
116
120
|
|
|
121
|
+
### Occlusion culling
|
|
122
|
+
Occlusion culling is curently only available as a demo.
|
|
123
|
+
The reason is that it requires a specific render pass hence the setup is a little more complex.
|
|
124
|
+
I can expose this feature upon request.
|
|
125
|
+
|
|
117
126
|
# Displaying meshes on a globe
|
|
118
127
|
I'm working on this project in parallel https://github.com/ebeaufay/UltraGlobe which allows displaying a globe with multi resolution imagery, elevation and 3DTiles.
|
|
119
128
|
|
package/index.html
CHANGED
|
@@ -4,11 +4,53 @@
|
|
|
4
4
|
<head>
|
|
5
5
|
<meta charset="utf-8" />
|
|
6
6
|
<title>Three 3DTiles viewer sample</title>
|
|
7
|
-
<
|
|
7
|
+
<style>
|
|
8
|
+
.slidecontainer {
|
|
9
|
+
width: 100%;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.slider {
|
|
13
|
+
-webkit-appearance: none;
|
|
14
|
+
width: 100%;
|
|
15
|
+
height: 15px;
|
|
16
|
+
border-radius: 5px;
|
|
17
|
+
background: #d3d3d3;
|
|
18
|
+
outline: none;
|
|
19
|
+
opacity: 0.7;
|
|
20
|
+
-webkit-transition: .2s;
|
|
21
|
+
transition: opacity .2s;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.slider:hover {
|
|
25
|
+
opacity: 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.slider::-webkit-slider-thumb {
|
|
29
|
+
-webkit-appearance: none;
|
|
30
|
+
appearance: none;
|
|
31
|
+
width: 25px;
|
|
32
|
+
height: 25px;
|
|
33
|
+
border-radius: 50%;
|
|
34
|
+
background: #0439aa;
|
|
35
|
+
cursor: pointer;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.slider::-moz-range-thumb {
|
|
39
|
+
width: 25px;
|
|
40
|
+
height: 25px;
|
|
41
|
+
border-radius: 50%;
|
|
42
|
+
background: #04AA6D;
|
|
43
|
+
cursor: pointer;
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
8
46
|
</head>
|
|
9
47
|
|
|
10
48
|
<body>
|
|
11
49
|
<div id="screen"></div>
|
|
50
|
+
<div style="position: absolute; top: 1%; z-index: 100; right:1%; ">
|
|
51
|
+
<input type="range" min="0.1" max="2" value="1.0", step="0.001" class="slider" id="lodMultiplier" >
|
|
52
|
+
<p style="color: #0439aa;">LOD multiplier: <span id="multiplierValue"></span></p>
|
|
53
|
+
</div>
|
|
12
54
|
<div style="position: absolute; bottom: 1%; z-index: 100;">
|
|
13
55
|
<a href="https://openheritage3d.org/project.php?id=taz6-n215">ORIGINAL MODEL</a>
|
|
14
56
|
</div>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jdultra/threedtiles",
|
|
3
|
-
"version": "3.1
|
|
3
|
+
"version": "3.2.1",
|
|
4
4
|
"description": "An OGC 3DTiles viewer for Three.js",
|
|
5
5
|
"main": "tileset.js",
|
|
6
6
|
"scripts": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"path-browserify": "^1.0.1",
|
|
32
32
|
"regenerator-runtime": ">=0.13.7",
|
|
33
33
|
"set-interval-async": "^2.0.3",
|
|
34
|
-
"three": "0.
|
|
34
|
+
"three": "0.140.2",
|
|
35
35
|
"uuid": "^8.3.2"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
|
|
2
2
|
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
3
|
-
import { LegacyGLTFLoader } from './LegacyGLTFLoader.js';
|
|
3
|
+
//import { LegacyGLTFLoader } from './LegacyGLTFLoader.js';
|
|
4
4
|
|
|
5
5
|
const gltfLoader = new GLTFLoader();
|
|
6
6
|
const dracoLoader = new DRACOLoader();
|
|
7
7
|
dracoLoader.setDecoderPath( 'https://www.gstatic.com/draco/versioned/decoders/1.4.3/' );
|
|
8
8
|
gltfLoader.setDRACOLoader( dracoLoader );
|
|
9
|
-
const legacyGLTFLoader = new LegacyGLTFLoader();
|
|
9
|
+
//const legacyGLTFLoader = new LegacyGLTFLoader();
|
|
10
10
|
const B3DMDecoder = {
|
|
11
11
|
parseB3DM: (arrayBuffer, meshCallback) => {
|
|
12
12
|
const dataView = new DataView(arrayBuffer);
|
|
@@ -64,7 +64,8 @@ const B3DMDecoder = {
|
|
|
64
64
|
});
|
|
65
65
|
resolve(model.scene);
|
|
66
66
|
}, error=>{
|
|
67
|
-
|
|
67
|
+
console.error(error);
|
|
68
|
+
/* legacyGLTFLoader.parse(gltfBuffer, model => {
|
|
68
69
|
|
|
69
70
|
////TODO
|
|
70
71
|
//model.batchTable = b3dm.batchTable;
|
|
@@ -83,7 +84,7 @@ const B3DMDecoder = {
|
|
|
83
84
|
}
|
|
84
85
|
});
|
|
85
86
|
resolve(model.scene);
|
|
86
|
-
}, null);
|
|
87
|
+
}, null); */
|
|
87
88
|
});
|
|
88
89
|
});
|
|
89
90
|
}
|
package/src/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const scene = initScene();
|
|
|
11
11
|
const domContainer = initDomContainer("screen");
|
|
12
12
|
const camera = initCamera();
|
|
13
13
|
const ogc3DTiles = initTileset(scene);
|
|
14
|
+
initLODMultiplierSlider(ogc3DTiles)
|
|
14
15
|
const controller = initController(camera, domContainer);
|
|
15
16
|
|
|
16
17
|
const stats = initStats(domContainer);
|
|
@@ -20,8 +21,12 @@ animate();
|
|
|
20
21
|
|
|
21
22
|
function initScene() {
|
|
22
23
|
const scene = new THREE.Scene();
|
|
23
|
-
scene.background = new THREE.Color(
|
|
24
|
-
scene.add(new THREE.AmbientLight(0xFFFFFF,
|
|
24
|
+
scene.background = new THREE.Color(0xaaffcc);
|
|
25
|
+
scene.add(new THREE.AmbientLight(0xFFFFFF, 0.2));
|
|
26
|
+
const directionalLight = new THREE.DirectionalLight( 0xffffff, 0.8 );
|
|
27
|
+
directionalLight.position.set(100,100,100)
|
|
28
|
+
directionalLight.lookAt(-1,-1,-1)
|
|
29
|
+
scene.add( directionalLight );
|
|
25
30
|
return scene;
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -68,8 +73,8 @@ function initStats(dom) {
|
|
|
68
73
|
|
|
69
74
|
|
|
70
75
|
function initCamera() {
|
|
71
|
-
const camera = new THREE.PerspectiveCamera(70, window.offsetWidth / window.offsetHeight, 1,
|
|
72
|
-
camera.position.set(10,
|
|
76
|
+
const camera = new THREE.PerspectiveCamera(70, window.offsetWidth / window.offsetHeight, 0.1, 1000);
|
|
77
|
+
camera.position.set(-10, 5, 20);
|
|
73
78
|
|
|
74
79
|
return camera;
|
|
75
80
|
}
|
|
@@ -77,42 +82,45 @@ function initCamera() {
|
|
|
77
82
|
function initTileset(scene) {
|
|
78
83
|
|
|
79
84
|
const ogc3DTile = new OGC3DTile({
|
|
80
|
-
url: "https://storage.googleapis.com/ogc-3d-tiles/
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
url: "https://storage.googleapis.com/ogc-3d-tiles/house3/tileset.json",
|
|
86
|
+
//url: "http://localhost:8080/tileset.json",
|
|
87
|
+
geometricErrorMultiplier: 1,
|
|
88
|
+
loadOutsideView: false,
|
|
83
89
|
tileLoader: new TileLoader(mesh => {
|
|
84
90
|
//// Insert code to be called on every newly decoded mesh e.g.:
|
|
85
91
|
mesh.material.wireframe = false;
|
|
92
|
+
//mesh.material = new THREE.MeshBasicMaterial({color:new THREE.Color("rgb("+Math.floor(Math.random()*256)+", "+Math.floor(Math.random()*256)+", "+Math.floor(Math.random()*256)+")")})
|
|
86
93
|
mesh.material.side = THREE.DoubleSide;
|
|
87
94
|
}, 1000)
|
|
88
95
|
});
|
|
89
|
-
|
|
90
96
|
|
|
97
|
+
|
|
98
|
+
|
|
91
99
|
//// The OGC3DTile object is a threejs Object3D so you may do all the usual opperations like transformations e.g.:
|
|
92
|
-
//ogc3DTile.translateOnAxis(new THREE.Vector3(
|
|
93
|
-
//ogc3DTile.translateOnAxis(new THREE.Vector3(1,0
|
|
94
|
-
//ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1),
|
|
95
|
-
//ogc3DTile.scale.set(0.
|
|
96
|
-
|
|
100
|
+
// ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -2177749.59059337)
|
|
101
|
+
// ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), 4388730.67973434)
|
|
102
|
+
// ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), 4070064.60934734)
|
|
103
|
+
//ogc3DTile.scale.set(0.001,0.001,0.001);
|
|
104
|
+
ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5) // Z-UP to Y-UP
|
|
97
105
|
// ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -16.5)
|
|
98
106
|
// ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), 0)
|
|
99
107
|
// ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), -9.5)
|
|
100
108
|
//// It's up to the user to call updates on the tileset. You might call them whenever the camera moves or at regular time intervals like here
|
|
101
109
|
|
|
102
|
-
|
|
103
110
|
|
|
104
|
-
|
|
111
|
+
|
|
112
|
+
var interval;
|
|
105
113
|
document.addEventListener('keyup', (e) => {
|
|
106
114
|
console.log(camera.position)
|
|
107
|
-
if(!e.key || e.key !== "p") return;
|
|
108
|
-
if(!!interval){
|
|
115
|
+
if (!e.key || e.key !== "p") return;
|
|
116
|
+
if (!!interval) {
|
|
109
117
|
clearInterval(interval);
|
|
110
118
|
interval = null;
|
|
111
|
-
}else{
|
|
119
|
+
} else {
|
|
112
120
|
startInterval();
|
|
113
121
|
}
|
|
114
122
|
});
|
|
115
|
-
function startInterval(){
|
|
123
|
+
function startInterval() {
|
|
116
124
|
interval = setIntervalAsync(function () {
|
|
117
125
|
ogc3DTile.update(camera);
|
|
118
126
|
}, 20);
|
|
@@ -123,10 +131,21 @@ function initTileset(scene) {
|
|
|
123
131
|
return ogc3DTile;
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
function initLODMultiplierSlider(tileset) {
|
|
135
|
+
var slider = document.getElementById("lodMultiplier");
|
|
136
|
+
var output = document.getElementById("multiplierValue");
|
|
137
|
+
output.innerHTML = slider.value;
|
|
138
|
+
|
|
139
|
+
slider.oninput = () => {
|
|
140
|
+
tileset.setGeometricErrorMultiplier(slider.value)
|
|
141
|
+
output.innerHTML = slider.value;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
126
145
|
function initController(camera, dom) {
|
|
127
146
|
const controller = new OrbitControls(camera, dom);
|
|
128
147
|
|
|
129
|
-
controller.target.set(
|
|
148
|
+
controller.target.set(0, 0, 0);
|
|
130
149
|
controller.minDistance = 1;
|
|
131
150
|
controller.maxDistance = 5000;
|
|
132
151
|
controller.update();
|
package/src/tileset/OGC3DTile.js
CHANGED
|
@@ -2,9 +2,7 @@ import * as THREE from 'three';
|
|
|
2
2
|
import { OBB } from "../geometry/obb";
|
|
3
3
|
import { TileLoader } from "./TileLoader";
|
|
4
4
|
import { v4 as uuidv4 } from "uuid";
|
|
5
|
-
import
|
|
6
|
-
// import { clearIntervalAsync } from 'set-interval-async';
|
|
7
|
-
const path = require('path');
|
|
5
|
+
import * as path from "path-browserify"
|
|
8
6
|
|
|
9
7
|
const tempSphere = new THREE.Sphere(new THREE.Vector3(0, 0, 0, 1));
|
|
10
8
|
|
|
@@ -25,7 +23,8 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
25
23
|
* tileLoader : TileLoader,
|
|
26
24
|
* meshCallback: function,
|
|
27
25
|
* cameraOnLoad: camera,
|
|
28
|
-
* parentTile: OGC3DTile
|
|
26
|
+
* parentTile: OGC3DTile,
|
|
27
|
+
* onLoadCallback: function
|
|
29
28
|
* } properties
|
|
30
29
|
*/
|
|
31
30
|
constructor(properties) {
|
|
@@ -66,13 +65,17 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
66
65
|
|
|
67
66
|
if (!!properties.json) { // If this tile is created as a child of another tile, properties.json is not null
|
|
68
67
|
self.setup(properties);
|
|
68
|
+
if (properties.onLoadCallback) properties.onLoadCallback(self);
|
|
69
69
|
} else if (properties.url) { // If only the url to the tileset.json is provided
|
|
70
70
|
self.controller = new AbortController();
|
|
71
71
|
fetch(properties.url, { signal: self.controller.signal }).then(result => {
|
|
72
72
|
if (!result.ok) {
|
|
73
73
|
throw new Error(`couldn't load "${properties.url}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
74
74
|
}
|
|
75
|
-
result.json().then(json =>
|
|
75
|
+
result.json().then(json => {
|
|
76
|
+
self.setup({ rootPath: path.dirname(properties.url), json: json });
|
|
77
|
+
if (properties.onLoadCallback) properties.onLoadCallback(self);
|
|
78
|
+
});
|
|
76
79
|
});
|
|
77
80
|
}
|
|
78
81
|
}
|
|
@@ -169,7 +172,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
169
172
|
self.meshContent = mesh;
|
|
170
173
|
}, !self.cameraOnLoad ? () => 0 : () => {
|
|
171
174
|
return self.calculateDistanceToCamera(self.cameraOnLoad);
|
|
172
|
-
}, () => self.getSiblings(), self.level
|
|
175
|
+
}, () => self.getSiblings(), self.level);
|
|
173
176
|
} else if (url.includes(".json")) {
|
|
174
177
|
self.tileLoader.get(this.uuid, url, json => {
|
|
175
178
|
if (!!self.deleted) return;
|
|
@@ -180,24 +183,6 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
180
183
|
self.hasUnloadedJSONContent = false;
|
|
181
184
|
});
|
|
182
185
|
|
|
183
|
-
/* self.controller = new AbortController();
|
|
184
|
-
setTimeout(() => {
|
|
185
|
-
fetch(url, { signal: self.controller.signal }).then(result => {
|
|
186
|
-
if (!result.ok) {
|
|
187
|
-
throw new Error(`couldn't load "${properties.url}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
188
|
-
}
|
|
189
|
-
result.json().then(json => {
|
|
190
|
-
// when json content is downloaded, it is inserted into this tile's original JSON as a child
|
|
191
|
-
// and the content object is deleted from the original JSON
|
|
192
|
-
if (!self.json.children) self.json.children = [];
|
|
193
|
-
json.rootPath = path.dirname(url);
|
|
194
|
-
self.json.children.push(json);
|
|
195
|
-
delete self.json.content;
|
|
196
|
-
self.hasUnloadedJSONContent = false;
|
|
197
|
-
}).catch(error => { });
|
|
198
|
-
}).catch(error => { });
|
|
199
|
-
}, 0); */
|
|
200
|
-
|
|
201
186
|
}
|
|
202
187
|
|
|
203
188
|
}
|
|
@@ -316,10 +301,9 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
316
301
|
return;
|
|
317
302
|
}
|
|
318
303
|
if (metric >= self.geometricError) {
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
}
|
|
304
|
+
self.disposeChildren();
|
|
305
|
+
updateNodeVisibility();
|
|
306
|
+
return;
|
|
323
307
|
}
|
|
324
308
|
|
|
325
309
|
}
|
|
@@ -453,7 +437,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
453
437
|
return 0;
|
|
454
438
|
}
|
|
455
439
|
const scale = this.matrixWorld.getMaxScaleOnAxis();
|
|
456
|
-
return ((distance / 100) / this.geometricErrorMultiplier)
|
|
440
|
+
return ((distance / 100) / this.geometricErrorMultiplier) * scale;
|
|
457
441
|
} else if (this.boundingVolume instanceof THREE.Box3) {
|
|
458
442
|
// Region
|
|
459
443
|
// Region not supported
|
|
@@ -6,6 +6,7 @@ const ready = [];
|
|
|
6
6
|
const downloads = [];
|
|
7
7
|
const nextReady = [];
|
|
8
8
|
const nextDownloads = [];
|
|
9
|
+
let concurentDownloads = 0;
|
|
9
10
|
|
|
10
11
|
function scheduleDownload(f) {
|
|
11
12
|
downloads.unshift(f);
|
|
@@ -13,13 +14,18 @@ function scheduleDownload(f) {
|
|
|
13
14
|
function download() {
|
|
14
15
|
if (nextDownloads.length == 0) {
|
|
15
16
|
getNextDownloads();
|
|
16
|
-
if (nextDownloads.length == 0) return
|
|
17
|
+
if (nextDownloads.length == 0) return;
|
|
17
18
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
nextDownload.
|
|
19
|
+
while (nextDownloads.length > 0 && concurentDownloads < 500) {
|
|
20
|
+
const nextDownload = nextDownloads.shift();
|
|
21
|
+
if (!!nextDownload && nextDownload.shouldDoDownload()) {
|
|
22
|
+
nextDownload.doDownload();
|
|
23
|
+
}
|
|
21
24
|
}
|
|
22
|
-
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
return;
|
|
23
29
|
}
|
|
24
30
|
function meshReceived(cache, register, key, distanceFunction, getSiblings, level, uuid) {
|
|
25
31
|
ready.unshift([cache, register, key, distanceFunction, getSiblings, level, uuid]);
|
|
@@ -56,11 +62,11 @@ function getNextDownloads() {
|
|
|
56
62
|
downloads.splice(i, 1);
|
|
57
63
|
continue;
|
|
58
64
|
}
|
|
59
|
-
if(!downloads[i].distanceFunction){ // if no distance function, must be a json, give absolute priority!
|
|
65
|
+
if (!downloads[i].distanceFunction) { // if no distance function, must be a json, give absolute priority!
|
|
60
66
|
nextDownloads.push(downloads.splice(i, 1)[0]);
|
|
61
67
|
}
|
|
62
68
|
}
|
|
63
|
-
if(nextDownloads.length>0) return;
|
|
69
|
+
if (nextDownloads.length > 0) return;
|
|
64
70
|
for (let i = downloads.length - 1; i >= 0; i--) {
|
|
65
71
|
const dist = downloads[i].distanceFunction();
|
|
66
72
|
if (dist < smallestDistance) {
|
|
@@ -88,12 +94,12 @@ function getNextReady() {
|
|
|
88
94
|
let smallestDistance = Number.MAX_VALUE;
|
|
89
95
|
let closest = -1;
|
|
90
96
|
for (let i = ready.length - 1; i >= 0; i--) {
|
|
91
|
-
|
|
92
|
-
if(!ready[i][3]){// if no distance function, must be a json, give absolute priority!
|
|
93
|
-
nextReady.push(ready.splice(i,1)[0]);
|
|
97
|
+
|
|
98
|
+
if (!ready[i][3]) {// if no distance function, must be a json, give absolute priority!
|
|
99
|
+
nextReady.push(ready.splice(i, 1)[0]);
|
|
94
100
|
}
|
|
95
101
|
}
|
|
96
|
-
if(nextReady.length>0) return;
|
|
102
|
+
if (nextReady.length > 0) return;
|
|
97
103
|
for (let i = ready.length - 1; i >= 0; i--) {
|
|
98
104
|
const dist = ready[i][3]();
|
|
99
105
|
if (dist < smallestDistance) {
|
|
@@ -116,22 +122,23 @@ function getNextReady() {
|
|
|
116
122
|
}
|
|
117
123
|
}
|
|
118
124
|
}
|
|
119
|
-
setIntervalAsync(()=>{
|
|
120
|
-
|
|
125
|
+
setIntervalAsync(() => {
|
|
126
|
+
download();
|
|
127
|
+
/* const start = Date.now();
|
|
121
128
|
let uploaded = 0;
|
|
122
129
|
do{
|
|
123
130
|
uploaded = download();
|
|
124
|
-
}while(uploaded > 0 && (Date.now() - start)<= 2 )
|
|
125
|
-
|
|
126
|
-
},10);
|
|
127
|
-
setIntervalAsync(()=>{
|
|
131
|
+
}while(uploaded > 0 && (Date.now() - start)<= 2 ) */
|
|
132
|
+
|
|
133
|
+
}, 10);
|
|
134
|
+
setIntervalAsync(() => {
|
|
128
135
|
const start = Date.now();
|
|
129
136
|
let loaded = 0;
|
|
130
|
-
do{
|
|
137
|
+
do {
|
|
131
138
|
loaded = loadBatch();
|
|
132
|
-
}while(loaded > 0 && (Date.now() - start)<=
|
|
133
|
-
|
|
134
|
-
},10);
|
|
139
|
+
} while (loaded > 0 && (Date.now() - start) <= 1)
|
|
140
|
+
|
|
141
|
+
}, 10);
|
|
135
142
|
|
|
136
143
|
class TileLoader {
|
|
137
144
|
constructor(meshCallback, maxCachedItems) {
|
|
@@ -141,7 +148,7 @@ class TileLoader {
|
|
|
141
148
|
this.register = {};
|
|
142
149
|
}
|
|
143
150
|
|
|
144
|
-
get(tileIdentifier, path, callback, distanceFunction, getSiblings, level
|
|
151
|
+
get(tileIdentifier, path, callback, distanceFunction, getSiblings, level) {
|
|
145
152
|
const self = this;
|
|
146
153
|
const key = simplifyPath(path);
|
|
147
154
|
|
|
@@ -160,12 +167,14 @@ class TileLoader {
|
|
|
160
167
|
|
|
161
168
|
const cachedObject = self.cache.get(key);
|
|
162
169
|
if (!!cachedObject) {
|
|
163
|
-
meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level,
|
|
170
|
+
meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, tileIdentifier);
|
|
164
171
|
} else if (Object.keys(self.register[key]).length == 1) {
|
|
165
172
|
let downloadFunction;
|
|
166
173
|
if (path.includes(".b3dm")) {
|
|
167
174
|
downloadFunction = () => {
|
|
175
|
+
concurentDownloads++;
|
|
168
176
|
fetch(path).then(result => {
|
|
177
|
+
concurentDownloads--;
|
|
169
178
|
if (!result.ok) {
|
|
170
179
|
console.error("could not load tile with path : " + path)
|
|
171
180
|
throw new Error(`couldn't load "${path}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
@@ -173,14 +182,16 @@ class TileLoader {
|
|
|
173
182
|
result.arrayBuffer().then(buffer => B3DMDecoder.parseB3DM(buffer, self.meshCallback)).then(mesh => {
|
|
174
183
|
self.cache.put(key, mesh);
|
|
175
184
|
self.checkSize();
|
|
176
|
-
meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level,
|
|
185
|
+
meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, tileIdentifier);
|
|
177
186
|
});
|
|
178
187
|
|
|
179
188
|
});
|
|
180
189
|
}
|
|
181
|
-
}else if (path.includes(".json")) {
|
|
190
|
+
} else if (path.includes(".json")) {
|
|
182
191
|
downloadFunction = () => {
|
|
192
|
+
concurentDownloads++;
|
|
183
193
|
fetch(path).then(result => {
|
|
194
|
+
concurentDownloads--;
|
|
184
195
|
if (!result.ok) {
|
|
185
196
|
console.error("could not load tile with path : " + path)
|
|
186
197
|
throw new Error(`couldn't load "${path}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
@@ -201,7 +212,7 @@ class TileLoader {
|
|
|
201
212
|
"distanceFunction": distanceFunction,
|
|
202
213
|
"getSiblings": getSiblings,
|
|
203
214
|
"level": level,
|
|
204
|
-
"uuid":
|
|
215
|
+
"uuid": tileIdentifier
|
|
205
216
|
})
|
|
206
217
|
}
|
|
207
218
|
}
|
package/manifest.json
DELETED