@jdultra/threedtiles 3.1.2 → 3.1.3
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/package.json +1 -1
- package/src/index.js +4 -8
- package/src/tileset/OGC3DTile.js +73 -34
- package/src/tileset/TileLoader.js +170 -82
- package/src/tileset/TilesetStats.js +0 -65
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import "regenerator-runtime/runtime.js";
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import Stats from 'three/examples/jsm/libs/stats.module.js';
|
|
4
|
-
import TilesetStats from './tileset/TilesetStats';
|
|
5
4
|
import { OGC3DTile } from "./tileset/OGC3DTile";
|
|
6
5
|
import { TileLoader } from "./tileset/TileLoader";
|
|
7
6
|
import { MapControls, OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
const scene = initScene();
|
|
11
|
-
const tilesetStats = TilesetStats();
|
|
12
10
|
const domContainer = initDomContainer("screen");
|
|
13
11
|
const camera = initCamera();
|
|
14
12
|
const ogc3DTiles = initTileset(scene);
|
|
@@ -79,14 +77,13 @@ function initTileset(scene) {
|
|
|
79
77
|
|
|
80
78
|
const ogc3DTile = new OGC3DTile({
|
|
81
79
|
url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tileset.json",
|
|
82
|
-
geometricErrorMultiplier: 1,
|
|
80
|
+
geometricErrorMultiplier: 1.0,
|
|
83
81
|
loadOutsideView: true,
|
|
84
82
|
tileLoader: new TileLoader(mesh => {
|
|
85
83
|
//// Insert code to be called on every newly decoded mesh e.g.:
|
|
86
84
|
mesh.material.wireframe = false;
|
|
87
85
|
mesh.material.side = THREE.DoubleSide;
|
|
88
|
-
},
|
|
89
|
-
stats: tilesetStats
|
|
86
|
+
}, 2000)
|
|
90
87
|
});
|
|
91
88
|
|
|
92
89
|
|
|
@@ -95,7 +92,7 @@ function initTileset(scene) {
|
|
|
95
92
|
//ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -65)
|
|
96
93
|
//ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), -80)
|
|
97
94
|
//ogc3DTile.scale.set(0.0001,0.0001,0.0001);
|
|
98
|
-
//
|
|
95
|
+
//ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5) // Z-UP to Y-UP
|
|
99
96
|
// ogc3DTile.translateOnAxis(new THREE.Vector3(1,0,0), -16.5)
|
|
100
97
|
// ogc3DTile.translateOnAxis(new THREE.Vector3(0,1,0), 0)
|
|
101
98
|
// ogc3DTile.translateOnAxis(new THREE.Vector3(0,0,1), -9.5)
|
|
@@ -117,7 +114,7 @@ function initTileset(scene) {
|
|
|
117
114
|
function startInterval(){
|
|
118
115
|
interval = setInterval(function () {
|
|
119
116
|
ogc3DTile.update(camera);
|
|
120
|
-
},
|
|
117
|
+
}, 20);
|
|
121
118
|
}
|
|
122
119
|
startInterval();
|
|
123
120
|
|
|
@@ -141,7 +138,6 @@ function animate() {
|
|
|
141
138
|
|
|
142
139
|
camera.updateMatrixWorld();
|
|
143
140
|
renderer.render(scene, camera);
|
|
144
|
-
tilesetStats.update();
|
|
145
141
|
stats.update();
|
|
146
142
|
|
|
147
143
|
}
|
package/src/tileset/OGC3DTile.js
CHANGED
|
@@ -23,8 +23,9 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
23
23
|
* geometricErrorMultiplier: Double,
|
|
24
24
|
* loadOutsideView: Boolean,
|
|
25
25
|
* tileLoader : TileLoader,
|
|
26
|
-
*
|
|
27
|
-
*
|
|
26
|
+
* meshCallback: function,
|
|
27
|
+
* cameraOnLoad: camera,
|
|
28
|
+
* parentTile: OGC3DTile
|
|
28
29
|
* } properties
|
|
29
30
|
*/
|
|
30
31
|
constructor(properties) {
|
|
@@ -42,24 +43,11 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
42
43
|
}
|
|
43
44
|
// set properties general to the entire tileset
|
|
44
45
|
this.geometricErrorMultiplier = !!properties.geometricErrorMultiplier ? properties.geometricErrorMultiplier : 1.0;
|
|
45
|
-
if (properties.stats) {
|
|
46
|
-
// Automatic geometric error multiplier
|
|
47
|
-
this.stats = properties.stats;
|
|
48
|
-
|
|
49
|
-
setIntervalAsync(() => {
|
|
50
|
-
if (!!document.hidden) return;
|
|
51
|
-
const framerate = self.stats.fps();
|
|
52
|
-
if (framerate < 0) return;
|
|
53
|
-
if (framerate < 58) {
|
|
54
|
-
self.setGeometricErrorMultiplier(Math.max(0.05, self.geometricErrorMultiplier - 0.05));
|
|
55
|
-
} else if (framerate > 58) {
|
|
56
|
-
self.setGeometricErrorMultiplier(self.geometricErrorMultiplier + 0.05);
|
|
57
|
-
}
|
|
58
|
-
}, 1000);
|
|
59
|
-
}
|
|
60
46
|
|
|
61
47
|
this.meshCallback = properties.meshCallback;
|
|
62
48
|
this.loadOutsideView = properties.loadOutsideView;
|
|
49
|
+
this.cameraOnLoad = properties.cameraOnLoad;
|
|
50
|
+
this.parentTile = properties.parentTile;
|
|
63
51
|
|
|
64
52
|
// declare properties specific to the tile for clarity
|
|
65
53
|
this.childrenTiles = [];
|
|
@@ -179,23 +167,37 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
179
167
|
});
|
|
180
168
|
self.add(mesh);
|
|
181
169
|
self.meshContent = mesh;
|
|
182
|
-
})
|
|
170
|
+
}, !self.cameraOnLoad ? () => 0 : () => {
|
|
171
|
+
return self.calculateDistanceToCamera(self.cameraOnLoad);
|
|
172
|
+
}, () => self.getSiblings(), self.level, self.uuid);
|
|
183
173
|
} else if (url.includes(".json")) {
|
|
184
|
-
self.
|
|
185
|
-
|
|
186
|
-
if (!
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
174
|
+
self.tileLoader.get(this.uuid, url, json => {
|
|
175
|
+
if (!!self.deleted) return;
|
|
176
|
+
if (!self.json.children) self.json.children = [];
|
|
177
|
+
json.rootPath = path.dirname(url);
|
|
178
|
+
self.json.children.push(json);
|
|
179
|
+
delete self.json.content;
|
|
180
|
+
self.hasUnloadedJSONContent = false;
|
|
181
|
+
});
|
|
182
|
+
|
|
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 => { });
|
|
197
198
|
}).catch(error => { });
|
|
198
|
-
}
|
|
199
|
+
}, 0); */
|
|
200
|
+
|
|
199
201
|
}
|
|
200
202
|
|
|
201
203
|
}
|
|
@@ -216,6 +218,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
216
218
|
|
|
217
219
|
});
|
|
218
220
|
this.parent = null;
|
|
221
|
+
this.parentTile = null;
|
|
219
222
|
this.dispatchEvent({ type: 'removed' });
|
|
220
223
|
}
|
|
221
224
|
disposeChildren() {
|
|
@@ -324,6 +327,7 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
324
327
|
function loadJsonChildren() {
|
|
325
328
|
self.json.children.forEach(childJSON => {
|
|
326
329
|
let childTile = new OGC3DTile({
|
|
330
|
+
parentTile: self,
|
|
327
331
|
parentGeometricError: self.geometricError,
|
|
328
332
|
parentBoundingVolume: self.boundingVolume,
|
|
329
333
|
parentRefinement: self.refinement,
|
|
@@ -332,7 +336,8 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
332
336
|
geometricErrorMultiplier: self.geometricErrorMultiplier,
|
|
333
337
|
loadOutsideView: self.loadOutsideView,
|
|
334
338
|
level: self.level + 1,
|
|
335
|
-
tileLoader: self.tileLoader
|
|
339
|
+
tileLoader: self.tileLoader,
|
|
340
|
+
cameraOnLoad: camera
|
|
336
341
|
});
|
|
337
342
|
self.childrenTiles.push(childTile);
|
|
338
343
|
self.add(childTile);
|
|
@@ -455,9 +460,43 @@ class OGC3DTile extends THREE.Object3D {
|
|
|
455
460
|
//throw Error("Region bounding volume not supported");
|
|
456
461
|
return -1;
|
|
457
462
|
}
|
|
458
|
-
|
|
459
463
|
}
|
|
460
464
|
|
|
465
|
+
getSiblings() {
|
|
466
|
+
const self = this;
|
|
467
|
+
const tiles = [];
|
|
468
|
+
if (!self.parentTile) return tiles;
|
|
469
|
+
let p = self.parentTile;
|
|
470
|
+
while (!p.hasMeshContent && !!p.parentTile) {
|
|
471
|
+
p = p.parentTile;
|
|
472
|
+
}
|
|
473
|
+
p.childrenTiles.forEach(child => {
|
|
474
|
+
if (!!child && child != self) {
|
|
475
|
+
while (!child.hasMeshContent && !!child.childrenTiles[0]) {
|
|
476
|
+
child = child.childrenTiles[0];
|
|
477
|
+
}
|
|
478
|
+
tiles.push(child);
|
|
479
|
+
}
|
|
480
|
+
});
|
|
481
|
+
return tiles;
|
|
482
|
+
}
|
|
483
|
+
calculateDistanceToCamera(camera) {
|
|
484
|
+
if (this.boundingVolume instanceof OBB) {
|
|
485
|
+
// box
|
|
486
|
+
tempSphere.copy(this.boundingVolume.sphere);
|
|
487
|
+
tempSphere.applyMatrix4(this.matrixWorld);
|
|
488
|
+
//if (!frustum.intersectsSphere(tempSphere)) return -1;
|
|
489
|
+
} else if (this.boundingVolume instanceof THREE.Sphere) {
|
|
490
|
+
//sphere
|
|
491
|
+
tempSphere.copy(this.boundingVolume);
|
|
492
|
+
tempSphere.applyMatrix4(this.matrixWorld);
|
|
493
|
+
//if (!frustum.intersectsSphere(tempSphere)) return -1;
|
|
494
|
+
}
|
|
495
|
+
if (this.boundingVolume instanceof THREE.Box3) {
|
|
496
|
+
return -1; // region not supported
|
|
497
|
+
}
|
|
498
|
+
return Math.max(0, camera.position.distanceTo(tempSphere.center) - tempSphere.radius);
|
|
499
|
+
}
|
|
461
500
|
setGeometricErrorMultiplier(geometricErrorMultiplier) {
|
|
462
501
|
this.geometricErrorMultiplier = geometricErrorMultiplier;
|
|
463
502
|
this.childrenTiles.forEach(child => child.setGeometricErrorMultiplier(geometricErrorMultiplier));
|
|
@@ -1,64 +1,142 @@
|
|
|
1
1
|
import { LinkedHashMap } from 'js-utils-z';
|
|
2
2
|
import { B3DMDecoder } from "../decoder/B3DMDecoder";
|
|
3
|
-
import { setIntervalAsync } from 'set-interval-async/dynamic';
|
|
4
3
|
|
|
5
4
|
const ready = [];
|
|
6
5
|
const downloads = [];
|
|
6
|
+
const nextReady = [];
|
|
7
|
+
const nextDownloads = [];
|
|
8
|
+
|
|
7
9
|
function scheduleDownload(f) {
|
|
8
10
|
downloads.unshift(f);
|
|
11
|
+
//setTimeout(()=>download(),0);
|
|
9
12
|
}
|
|
10
13
|
function download() {
|
|
11
|
-
if(
|
|
12
|
-
|
|
14
|
+
if (nextDownloads.length == 0) {
|
|
15
|
+
getNextDownloads();
|
|
16
|
+
if (nextDownloads.length == 0) return;
|
|
17
|
+
}
|
|
18
|
+
const nextDownload = nextDownloads.shift();
|
|
13
19
|
if (!!nextDownload && nextDownload.shouldDoDownload()) {
|
|
14
20
|
nextDownload.doDownload();
|
|
15
21
|
}
|
|
16
22
|
}
|
|
17
|
-
function meshReceived(cache, register, key) {
|
|
18
|
-
ready.unshift([cache, register, key]);
|
|
23
|
+
function meshReceived(cache, register, key, distanceFunction, getSiblings, level, uuid) {
|
|
24
|
+
ready.unshift([cache, register, key, distanceFunction, getSiblings, level, uuid]);
|
|
25
|
+
//setTimeout(()=>loadBatch(),1);
|
|
19
26
|
}
|
|
20
27
|
function loadBatch() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
if (
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
if (nextReady.length == 0) {
|
|
29
|
+
getNextReady();
|
|
30
|
+
if (nextReady.length == 0) return;
|
|
31
|
+
}
|
|
32
|
+
const data = nextReady.shift();
|
|
33
|
+
if (!data) return;
|
|
34
|
+
const cache = data[0];
|
|
35
|
+
const register = data[1];
|
|
36
|
+
const key = data[2];
|
|
37
|
+
const mesh = cache.get(key);
|
|
38
|
+
if (!!mesh && !!register[key]) {
|
|
39
|
+
Object.keys(register[key]).forEach(tile => {
|
|
40
|
+
const callback = register[key][tile];
|
|
41
|
+
if (!!callback) {
|
|
42
|
+
callback(mesh);
|
|
43
|
+
register[key][tile] = null;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function getNextDownloads() {
|
|
50
|
+
let smallestLevel = Number.MAX_VALUE;
|
|
51
|
+
let smallestDistance = Number.MAX_VALUE;
|
|
52
|
+
let closest = -1;
|
|
53
|
+
for (let i = downloads.length - 1; i >= 0; i--) {
|
|
54
|
+
if (!downloads[i].shouldDoDownload()) {
|
|
55
|
+
downloads.splice(i, 1);
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if(!downloads[i].distanceFunction){ // if no distance function, must be a json, give absolute priority!
|
|
59
|
+
nextDownloads.push(downloads.splice(i, 1)[0]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if(nextDownloads.length>0) return;
|
|
63
|
+
for (let i = downloads.length - 1; i >= 0; i--) {
|
|
64
|
+
const dist = downloads[i].distanceFunction();
|
|
65
|
+
if (dist < smallestDistance) {
|
|
66
|
+
smallestDistance = dist;
|
|
67
|
+
closest = i;
|
|
68
|
+
} else if (dist == smallestDistance && downloads[i].level < smallestLevel) {
|
|
69
|
+
smallestLevel = downloads[i].level;
|
|
70
|
+
closest = i
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (closest >= 0) {
|
|
74
|
+
const closestItem = downloads.splice(closest, 1).pop();
|
|
75
|
+
nextDownloads.push(closestItem);
|
|
76
|
+
const siblings = closestItem.getSiblings();
|
|
77
|
+
for (let i = downloads.length - 1; i >= 0; i--) {
|
|
78
|
+
if (siblings.includes(downloads[i].uuid)) {
|
|
79
|
+
nextDownloads.push(downloads.splice(i, 1).pop());
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function getNextReady() {
|
|
86
|
+
let smallestLevel = Number.MAX_VALUE;
|
|
87
|
+
let smallestDistance = Number.MAX_VALUE;
|
|
88
|
+
let closest = -1;
|
|
89
|
+
for (let i = ready.length - 1; i >= 0; i--) {
|
|
90
|
+
|
|
91
|
+
if(!ready[i][3]){// if no distance function, must be a json, give absolute priority!
|
|
92
|
+
nextReady.push(ready.splice(i,1)[0]);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if(nextReady.length>0) return;
|
|
96
|
+
for (let i = ready.length - 1; i >= 0; i--) {
|
|
97
|
+
const dist = ready[i][3]();
|
|
98
|
+
if (dist < smallestDistance) {
|
|
99
|
+
smallestDistance = dist;
|
|
100
|
+
smallestLevel = ready[i][5]
|
|
101
|
+
closest = i
|
|
102
|
+
} else if (dist == smallestDistance && ready[i][5] < smallestLevel) {
|
|
103
|
+
smallestLevel = ready[i][5]
|
|
104
|
+
closest = i
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
if (closest >= 0) {
|
|
108
|
+
const closestItem = ready.splice(closest, 1).pop();
|
|
109
|
+
nextReady.push(closestItem);
|
|
110
|
+
const siblings = closestItem[4]();
|
|
111
|
+
for (let i = ready.length - 1; i >= 0; i--) {
|
|
112
|
+
if (siblings.includes(ready[i][6])) {
|
|
113
|
+
nextready.push(ready.splice(i, 1).pop());
|
|
114
|
+
}
|
|
36
115
|
}
|
|
37
116
|
}
|
|
38
117
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
},
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
118
|
+
setInterval(() => {
|
|
119
|
+
download()
|
|
120
|
+
}, 1)
|
|
121
|
+
setInterval(() => {
|
|
122
|
+
loadBatch()
|
|
123
|
+
}, 1)
|
|
45
124
|
|
|
46
125
|
class TileLoader {
|
|
47
|
-
constructor(meshCallback,
|
|
126
|
+
constructor(meshCallback, maxCachedItems) {
|
|
48
127
|
this.meshCallback = meshCallback;
|
|
49
128
|
this.cache = new LinkedHashMap();
|
|
50
|
-
this.
|
|
51
|
-
this.stats = stats;
|
|
129
|
+
this.maxCachedItems = !!maxCachedItems ? maxCachedItems : 1000;
|
|
52
130
|
this.register = {};
|
|
53
131
|
}
|
|
54
132
|
|
|
55
|
-
get(tileIdentifier, path, callback) {
|
|
133
|
+
get(tileIdentifier, path, callback, distanceFunction, getSiblings, level, uuid) {
|
|
56
134
|
const self = this;
|
|
57
135
|
const key = simplifyPath(path);
|
|
58
136
|
|
|
59
137
|
|
|
60
|
-
if (!path.includes(".b3dm")) {
|
|
61
|
-
console.error("the 3DTiles cache can only be used to load B3DM data");
|
|
138
|
+
if (!path.includes(".b3dm") && !path.includes(".json")) {
|
|
139
|
+
console.error("the 3DTiles cache can only be used to load B3DM and json data");
|
|
62
140
|
return;
|
|
63
141
|
}
|
|
64
142
|
if (!self.register[key]) {
|
|
@@ -71,13 +149,11 @@ class TileLoader {
|
|
|
71
149
|
|
|
72
150
|
const cachedObject = self.cache.get(key);
|
|
73
151
|
if (!!cachedObject) {
|
|
74
|
-
meshReceived(self.cache, self.register, key);
|
|
152
|
+
meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, uuid);
|
|
75
153
|
} else if (Object.keys(self.register[key]).length == 1) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
},
|
|
80
|
-
"doDownload": () => {
|
|
154
|
+
let downloadFunction;
|
|
155
|
+
if (path.includes(".b3dm")) {
|
|
156
|
+
downloadFunction = () => {
|
|
81
157
|
fetch(path).then(result => {
|
|
82
158
|
if (!result.ok) {
|
|
83
159
|
console.error("could not load tile with path : " + path)
|
|
@@ -86,25 +162,40 @@ class TileLoader {
|
|
|
86
162
|
result.arrayBuffer().then(buffer => B3DMDecoder.parseB3DM(buffer, self.meshCallback)).then(mesh => {
|
|
87
163
|
self.cache.put(key, mesh);
|
|
88
164
|
self.checkSize();
|
|
89
|
-
meshReceived(self.cache, self.register, key);
|
|
165
|
+
meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, uuid);
|
|
90
166
|
});
|
|
91
167
|
|
|
92
168
|
});
|
|
93
169
|
}
|
|
170
|
+
}else if (path.includes(".json")) {
|
|
171
|
+
downloadFunction = () => {
|
|
172
|
+
fetch(path).then(result => {
|
|
173
|
+
if (!result.ok) {
|
|
174
|
+
console.error("could not load tile with path : " + path)
|
|
175
|
+
throw new Error(`couldn't load "${path}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
176
|
+
}
|
|
177
|
+
result.json().then(json => {
|
|
178
|
+
self.cache.put(key, json);
|
|
179
|
+
self.checkSize();
|
|
180
|
+
meshReceived(self.cache, self.register, key);
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
scheduleDownload({
|
|
186
|
+
"shouldDoDownload": () => {
|
|
187
|
+
return !!self.register[key] && Object.keys(self.register[key]).length > 0;
|
|
188
|
+
},
|
|
189
|
+
"doDownload": downloadFunction,
|
|
190
|
+
"distanceFunction": distanceFunction,
|
|
191
|
+
"getSiblings": getSiblings,
|
|
192
|
+
"level": level,
|
|
193
|
+
"uuid": uuid
|
|
94
194
|
})
|
|
95
195
|
}
|
|
96
196
|
}
|
|
97
197
|
|
|
98
|
-
|
|
99
|
-
const self = this;
|
|
100
|
-
Object.keys(self.register[key]).forEach(tile => {
|
|
101
|
-
const callback = self.register[key][tile];
|
|
102
|
-
if (!!callback) {
|
|
103
|
-
callback(mesh);
|
|
104
|
-
self.register[key][tile] = null;
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
198
|
+
|
|
108
199
|
|
|
109
200
|
invalidate(path, tileIdentifier) {
|
|
110
201
|
const key = simplifyPath(path);
|
|
@@ -113,46 +204,43 @@ class TileLoader {
|
|
|
113
204
|
|
|
114
205
|
checkSize() {
|
|
115
206
|
const self = this;
|
|
116
|
-
|
|
207
|
+
|
|
117
208
|
let i = 0;
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
return true;
|
|
124
|
-
}
|
|
125
|
-
return self.cache.size() > self.maxSize;
|
|
126
|
-
}
|
|
127
|
-
while (memOverflowCheck() && i < self.cache.size()) {
|
|
209
|
+
|
|
210
|
+
while (self.cache.size() > self.maxCachedItems && i < self.cache.size()) {
|
|
211
|
+
console.log(self.cache.size())
|
|
128
212
|
i++;
|
|
129
213
|
const entry = self.cache.head();
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
if (o.material
|
|
141
|
-
|
|
142
|
-
|
|
214
|
+
const reg = self.register[entry.key];
|
|
215
|
+
if (!!reg) {
|
|
216
|
+
if (Object.keys(reg).length > 0) {
|
|
217
|
+
self.cache.remove(entry.key);
|
|
218
|
+
self.cache.put(entry.key, entry.value);
|
|
219
|
+
} else {
|
|
220
|
+
self.cache.remove(entry.key);
|
|
221
|
+
delete self.register[entry.key];
|
|
222
|
+
entry.value.traverse((o) => {
|
|
223
|
+
|
|
224
|
+
if (o.material) {
|
|
225
|
+
// dispose materials
|
|
226
|
+
if (o.material.length) {
|
|
227
|
+
for (let i = 0; i < o.material.length; ++i) {
|
|
228
|
+
o.material[i].dispose();
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
o.material.dispose()
|
|
143
233
|
}
|
|
144
234
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}
|
|
149
|
-
if (o.geometry) {
|
|
150
|
-
// dispose geometry
|
|
151
|
-
o.geometry.dispose();
|
|
235
|
+
if (o.geometry) {
|
|
236
|
+
// dispose geometry
|
|
237
|
+
o.geometry.dispose();
|
|
152
238
|
|
|
153
|
-
|
|
154
|
-
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
}
|
|
155
242
|
}
|
|
243
|
+
|
|
156
244
|
}
|
|
157
245
|
}
|
|
158
246
|
}
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
var TilesetStats = function () {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var beginTime = ( performance || Date ).now(), prevTime = beginTime, frames = 0;
|
|
5
|
-
|
|
6
|
-
var fps = -1;
|
|
7
|
-
|
|
8
|
-
if ( self.performance && self.performance.memory ) {
|
|
9
|
-
|
|
10
|
-
var mem = -1;
|
|
11
|
-
var maxMem = -1;
|
|
12
|
-
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return {
|
|
17
|
-
|
|
18
|
-
begin: function () {
|
|
19
|
-
|
|
20
|
-
beginTime = ( performance || Date ).now();
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
|
|
24
|
-
end: function () {
|
|
25
|
-
|
|
26
|
-
frames ++;
|
|
27
|
-
|
|
28
|
-
var time = ( performance || Date ).now();
|
|
29
|
-
|
|
30
|
-
if ( time >= prevTime + 1000 ) {
|
|
31
|
-
|
|
32
|
-
fps = ( frames * 1000 ) / ( time - prevTime );
|
|
33
|
-
|
|
34
|
-
prevTime = time;
|
|
35
|
-
frames = 0;
|
|
36
|
-
|
|
37
|
-
if ( !!mem ) {
|
|
38
|
-
|
|
39
|
-
var memory = performance.memory;
|
|
40
|
-
mem = memory.usedJSHeapSize;
|
|
41
|
-
maxMem = memory.jsHeapSizeLimit;
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
return time;
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
update: function () {
|
|
52
|
-
|
|
53
|
-
beginTime = this.end();
|
|
54
|
-
|
|
55
|
-
},
|
|
56
|
-
|
|
57
|
-
fps: ()=>fps,
|
|
58
|
-
memory: ()=>mem,
|
|
59
|
-
maxMemory: ()=>maxMem
|
|
60
|
-
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
export default TilesetStats;
|