@jdultra/threedtiles 8.0.0 → 9.0.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/README.md +45 -20
- package/dist/threedtiles.min.js +2 -0
- package/package.json +17 -13
- package/.babelrc +0 -8
- package/.vscode/settings.json +0 -2
- package/index.html +0 -56
- package/src/decoder/B3DMDecoder.js +0 -125
- package/src/decoder/FeatureTable.js +0 -169
- package/src/decoder/LegacyGLTFLoader.js +0 -2216
- package/src/geometry/obb.js +0 -47
- package/src/images/skybox/back.png +0 -0
- package/src/images/skybox/bottom.png +0 -0
- package/src/images/skybox/front.png +0 -0
- package/src/images/skybox/left.png +0 -0
- package/src/images/skybox/right.png +0 -0
- package/src/images/skybox/top.png +0 -0
- package/src/index.js +0 -331
- package/src/tileset/OGC3DTile.js +0 -676
- package/src/tileset/OcclusionCullingService.js +0 -79
- package/src/tileset/TileLoader.js +0 -381
- package/src/tileset/instanced/InstancedOGC3DTile.js +0 -55
- package/src/tileset/instanced/InstancedTile.js +0 -588
- package/src/tileset/instanced/InstancedTileLoader.js +0 -396
- package/src/tileset/instanced/JsonTile.js +0 -41
- package/src/tileset/instanced/MeshTile.js +0 -81
- package/threedtiles.js +0 -82894
- package/threedtiles.js.map +0 -1
- package/webpack.config.js +0 -142
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import { clamp } from "three/src/math/MathUtils";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class OcclusionCullingService {
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @param {
|
|
11
|
-
* json: optional,
|
|
12
|
-
* url: optional,
|
|
13
|
-
* rootPath: optional,
|
|
14
|
-
* parentGeometricError: optional,
|
|
15
|
-
* parentBoundingVolume: optional,
|
|
16
|
-
* parentRefinement: optional,
|
|
17
|
-
* geometricErrorMultiplier: Double,
|
|
18
|
-
* loadOutsideView: Boolean,
|
|
19
|
-
* tileLoader : TileLoader,
|
|
20
|
-
* meshCallback: function,
|
|
21
|
-
* cameraOnLoad: camera,
|
|
22
|
-
* parentTile: OGC3DTile,
|
|
23
|
-
* onLoadCallback: function,
|
|
24
|
-
* occlusionCullingService: OcclusionCullingService
|
|
25
|
-
* } properties
|
|
26
|
-
*/
|
|
27
|
-
constructor() {
|
|
28
|
-
this.cullMap = [];
|
|
29
|
-
this.cullMaterial = new THREE.MeshBasicMaterial({ vertexColors: true });
|
|
30
|
-
this.cullMaterial.side = THREE.FrontSide;
|
|
31
|
-
this.cullTarget = this.createCullTarget();
|
|
32
|
-
this.cullPixels = new Uint8Array(4 * this.cullTarget.width * this.cullTarget.height);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
setSide(side){
|
|
36
|
-
this.cullMaterial.side = side;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
createCullTarget() {
|
|
40
|
-
const target = new THREE.WebGLRenderTarget(Math.floor(window.innerWidth * 0.05), Math.floor(window.innerHeight * 0.05));
|
|
41
|
-
target.texture.format = THREE.RGBAFormat;
|
|
42
|
-
target.texture.encoding = THREE.LinearEncoding;
|
|
43
|
-
target.texture.minFilter = THREE.NearestFilter;
|
|
44
|
-
target.texture.magFilter = THREE.NearestFilter;
|
|
45
|
-
target.texture.generateMipmaps = false;
|
|
46
|
-
target.stencilBuffer = false;
|
|
47
|
-
target.depthBuffer = true;
|
|
48
|
-
target.depthTexture = new THREE.DepthTexture();
|
|
49
|
-
target.depthTexture.format = THREE.DepthFormat;
|
|
50
|
-
target.depthTexture.type = THREE.UnsignedShortType;
|
|
51
|
-
return target;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
update(scene, renderer, camera) {
|
|
55
|
-
let tempRenderTarget = renderer.getRenderTarget();
|
|
56
|
-
let tempOverrideMaterial = scene.overrideMaterial;
|
|
57
|
-
|
|
58
|
-
scene.overrideMaterial = this.cullMaterial;
|
|
59
|
-
renderer.setRenderTarget(this.cullTarget);
|
|
60
|
-
renderer.render(scene, camera);
|
|
61
|
-
|
|
62
|
-
scene.overrideMaterial = tempOverrideMaterial;
|
|
63
|
-
renderer.setRenderTarget(tempRenderTarget);
|
|
64
|
-
|
|
65
|
-
renderer.readRenderTargetPixels(this.cullTarget, 0, 0, this.cullTarget.width, this.cullTarget.height, this.cullPixels);
|
|
66
|
-
this.cullMap = [];
|
|
67
|
-
|
|
68
|
-
for (let i = 0; i < this.cullPixels.length; i += 4) {
|
|
69
|
-
const c = clamp(this.cullPixels[i], 0, 255) << 16 ^ clamp(this.cullPixels[i + 1], 0, 255) << 8 ^ clamp(this.cullPixels[i + 2], 0, 255) << 0;
|
|
70
|
-
this.cullMap[c] = true;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
hasID(id) {
|
|
76
|
-
return this.cullMap[id];
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
export { OcclusionCullingService };
|
|
@@ -1,381 +0,0 @@
|
|
|
1
|
-
import { LinkedHashMap } from 'js-utils-z';
|
|
2
|
-
import { B3DMDecoder } from "../decoder/B3DMDecoder";
|
|
3
|
-
import { setIntervalAsync } from 'set-interval-async/dynamic';
|
|
4
|
-
import { initial } from 'lodash';
|
|
5
|
-
import * as THREE from 'three';
|
|
6
|
-
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
|
|
7
|
-
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
|
|
8
|
-
import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
|
|
9
|
-
|
|
10
|
-
let concurentDownloads = 0;
|
|
11
|
-
const zUpToYUpMatrix = new THREE.Matrix4();
|
|
12
|
-
zUpToYUpMatrix.set(1, 0, 0, 0,
|
|
13
|
-
0, 0, -1, 0,
|
|
14
|
-
0, 1, 0, 0,
|
|
15
|
-
0, 0, 0, 1);
|
|
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
|
-
*/
|
|
33
|
-
class TileLoader {
|
|
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
|
-
|
|
58
|
-
this.cache = new LinkedHashMap();
|
|
59
|
-
this.register = {};
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.ready = [];
|
|
63
|
-
this.downloads = [];
|
|
64
|
-
this.nextReady = [];
|
|
65
|
-
this.nextDownloads = [];
|
|
66
|
-
this.init();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
init() {
|
|
71
|
-
|
|
72
|
-
const self = this;
|
|
73
|
-
setIntervalAsync(() => {
|
|
74
|
-
self.download();
|
|
75
|
-
}, 10);
|
|
76
|
-
setIntervalAsync(() => {
|
|
77
|
-
const start = Date.now();
|
|
78
|
-
let loaded = 0;
|
|
79
|
-
do {
|
|
80
|
-
loaded = self.loadBatch();
|
|
81
|
-
} while (loaded > 0 && (Date.now() - start) <= 0)
|
|
82
|
-
|
|
83
|
-
}, 10);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
scheduleDownload(f) {
|
|
87
|
-
this.downloads.unshift(f);
|
|
88
|
-
}
|
|
89
|
-
download() {
|
|
90
|
-
if (this.nextDownloads.length == 0) {
|
|
91
|
-
this.getNextDownloads();
|
|
92
|
-
if (this.nextDownloads.length == 0) return;
|
|
93
|
-
}
|
|
94
|
-
while (this.nextDownloads.length > 0 && concurentDownloads < 500) {
|
|
95
|
-
const nextDownload = this.nextDownloads.shift();
|
|
96
|
-
if (!!nextDownload && nextDownload.shouldDoDownload()) {
|
|
97
|
-
nextDownload.doDownload();
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
meshReceived(cache, register, key, distanceFunction, getSiblings, level, uuid) {
|
|
103
|
-
this.ready.unshift([cache, register, key, distanceFunction, getSiblings, level, uuid]);
|
|
104
|
-
}
|
|
105
|
-
loadBatch() {
|
|
106
|
-
if (this.nextReady.length == 0) {
|
|
107
|
-
this.getNextReady();
|
|
108
|
-
if (this.nextReady.length == 0) return 0;
|
|
109
|
-
}
|
|
110
|
-
const data = this.nextReady.shift();
|
|
111
|
-
if (!data) return 0;
|
|
112
|
-
const cache = data[0];
|
|
113
|
-
const register = data[1];
|
|
114
|
-
const key = data[2];
|
|
115
|
-
const mesh = cache.get(key);
|
|
116
|
-
|
|
117
|
-
if (!!mesh && !!register[key]) {
|
|
118
|
-
Object.keys(register[key]).forEach(tile => {
|
|
119
|
-
const callback = register[key][tile];
|
|
120
|
-
if (!!callback) {
|
|
121
|
-
callback(mesh);
|
|
122
|
-
register[key][tile] = null;
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
return 1;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
getNextDownloads() {
|
|
130
|
-
let smallestDistance = Number.MAX_VALUE;
|
|
131
|
-
let closest = -1;
|
|
132
|
-
for (let i = this.downloads.length - 1; i >= 0; i--) {
|
|
133
|
-
if (!this.downloads[i].shouldDoDownload()) {
|
|
134
|
-
this.downloads.splice(i, 1);
|
|
135
|
-
continue;
|
|
136
|
-
}
|
|
137
|
-
if (!this.downloads[i].distanceFunction) { // if no distance function, must be a json, give absolute priority!
|
|
138
|
-
this.nextDownloads.push(this.downloads.splice(i, 1)[0]);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (this.nextDownloads.length > 0) return;
|
|
142
|
-
for (let i = this.downloads.length - 1; i >= 0; i--) {
|
|
143
|
-
const dist = this.downloads[i].distanceFunction() * this.downloads[i].level;
|
|
144
|
-
if (dist < smallestDistance) {
|
|
145
|
-
smallestDistance = dist;
|
|
146
|
-
closest = i;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (closest >= 0) {
|
|
150
|
-
const closestItem = this.downloads.splice(closest, 1).pop();
|
|
151
|
-
this.nextDownloads.push(closestItem);
|
|
152
|
-
const siblings = closestItem.getSiblings();
|
|
153
|
-
for (let i = this.downloads.length - 1; i >= 0; i--) {
|
|
154
|
-
if (siblings.includes(this.downloads[i].uuid)) {
|
|
155
|
-
this.nextDownloads.push(this.downloads.splice(i, 1).pop());
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
getNextReady() {
|
|
162
|
-
let smallestDistance = Number.MAX_VALUE;
|
|
163
|
-
let closest = -1;
|
|
164
|
-
for (let i = this.ready.length - 1; i >= 0; i--) {
|
|
165
|
-
|
|
166
|
-
if (!this.ready[i][3]) {// if no distance function, must be a json, give absolute priority!
|
|
167
|
-
this.nextReady.push(this.ready.splice(i, 1)[0]);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (this.nextReady.length > 0) return;
|
|
171
|
-
for (let i = this.ready.length - 1; i >= 0; i--) {
|
|
172
|
-
const dist = this.ready[i][3]() * this.ready[i][5];
|
|
173
|
-
if (dist < smallestDistance) {
|
|
174
|
-
smallestDistance = dist;
|
|
175
|
-
closest = i
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
if (closest >= 0) {
|
|
179
|
-
const closestItem = this.ready.splice(closest, 1).pop();
|
|
180
|
-
this.nextReady.push(closestItem);
|
|
181
|
-
const siblings = closestItem[4]();
|
|
182
|
-
for (let i = this.ready.length - 1; i >= 0; i--) {
|
|
183
|
-
if (siblings.includes(this.ready[i][6])) {
|
|
184
|
-
this.nextready.push(this.ready.splice(i, 1).pop());
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
get(abortController, tileIdentifier, path, callback, distanceFunction, getSiblings, level, zUpToYUp, geometricError) {
|
|
192
|
-
const self = this;
|
|
193
|
-
const key = simplifyPath(path);
|
|
194
|
-
|
|
195
|
-
const realAbortController = new AbortController();
|
|
196
|
-
abortController.signal.addEventListener("abort", () => {
|
|
197
|
-
if (!self.register[key] || Object.keys(self.register[key]).length == 0) {
|
|
198
|
-
realAbortController.abort();
|
|
199
|
-
}
|
|
200
|
-
})
|
|
201
|
-
|
|
202
|
-
if (!path.includes(".b3dm") && !path.includes(".json") && !path.includes(".gltf") && !path.includes(".glb")) {
|
|
203
|
-
console.error("the 3DTiles cache can only be used to load B3DM, gltf and json data");
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
if (!self.register[key]) {
|
|
207
|
-
self.register[key] = {};
|
|
208
|
-
}
|
|
209
|
-
if (!!self.register[key][tileIdentifier]) {
|
|
210
|
-
console.error(" a tile should only be loaded once");
|
|
211
|
-
}
|
|
212
|
-
self.register[key][tileIdentifier] = callback;
|
|
213
|
-
|
|
214
|
-
const cachedObject = self.cache.get(key);
|
|
215
|
-
if (!!cachedObject) {
|
|
216
|
-
this.meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, tileIdentifier);
|
|
217
|
-
} else if (Object.keys(self.register[key]).length == 1) {
|
|
218
|
-
let downloadFunction;
|
|
219
|
-
if (path.includes(".b3dm")) {
|
|
220
|
-
downloadFunction = () => {
|
|
221
|
-
concurentDownloads++;
|
|
222
|
-
fetch(path, { signal: realAbortController.signal }).then(result => {
|
|
223
|
-
concurentDownloads--;
|
|
224
|
-
if (!result.ok) {
|
|
225
|
-
console.error("could not load tile with path : " + path)
|
|
226
|
-
throw new Error(`couldn't load "${path}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
227
|
-
}
|
|
228
|
-
return result.arrayBuffer();
|
|
229
|
-
|
|
230
|
-
})
|
|
231
|
-
.then(resultArrayBuffer => {
|
|
232
|
-
return this.b3dmDecoder.parseB3DM(resultArrayBuffer, self.meshCallback, geometricError, zUpToYUp);
|
|
233
|
-
})
|
|
234
|
-
.then(mesh => {
|
|
235
|
-
self.cache.put(key, mesh);
|
|
236
|
-
self.checkSize();
|
|
237
|
-
this.meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, tileIdentifier);
|
|
238
|
-
})
|
|
239
|
-
.catch(() => { });;
|
|
240
|
-
}
|
|
241
|
-
} else if (path.includes(".glb") || path.includes(".gltf")) {
|
|
242
|
-
downloadFunction = () => {
|
|
243
|
-
concurentDownloads++;
|
|
244
|
-
this.gltfLoader.load(path, gltf => {
|
|
245
|
-
gltf.scene.traverse((o) => {
|
|
246
|
-
o.geometricError = geometricError;
|
|
247
|
-
if (o.isMesh) {
|
|
248
|
-
if (zUpToYUp) {
|
|
249
|
-
o.applyMatrix4(zUpToYUpMatrix);
|
|
250
|
-
}
|
|
251
|
-
if (!!self.meshCallback) {
|
|
252
|
-
self.meshCallback(o);
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
if (o.isPoints) {
|
|
256
|
-
if (zUpToYUp) {
|
|
257
|
-
o.applyMatrix4(zUpToYUpMatrix);
|
|
258
|
-
}
|
|
259
|
-
if (!!self.pointsCallback) {
|
|
260
|
-
self.pointsCallback(o);
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
self.cache.put(key, gltf.scene);
|
|
265
|
-
self.checkSize();
|
|
266
|
-
self.meshReceived(self.cache, self.register, key, distanceFunction, getSiblings, level, tileIdentifier);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
}
|
|
270
|
-
} else if (path.includes(".json")) {
|
|
271
|
-
downloadFunction = () => {
|
|
272
|
-
concurentDownloads++;
|
|
273
|
-
fetch(path, { signal: realAbortController.signal }).then(result => {
|
|
274
|
-
concurentDownloads--;
|
|
275
|
-
if (!result.ok) {
|
|
276
|
-
console.error("could not load tile with path : " + path)
|
|
277
|
-
throw new Error(`couldn't load "${path}". Request failed with status ${result.status} : ${result.statusText}`);
|
|
278
|
-
}
|
|
279
|
-
return result.json();
|
|
280
|
-
|
|
281
|
-
}).then(json => {
|
|
282
|
-
self.cache.put(key, json);
|
|
283
|
-
self.checkSize();
|
|
284
|
-
self.meshReceived(self.cache, self.register, key);
|
|
285
|
-
})
|
|
286
|
-
.catch(e => console.error("tile download aborted"));
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
this.scheduleDownload({
|
|
290
|
-
"shouldDoDownload": () => {
|
|
291
|
-
return !abortController.signal.aborted && !!self.register[key] && Object.keys(self.register[key]).length > 0;
|
|
292
|
-
},
|
|
293
|
-
"doDownload": downloadFunction,
|
|
294
|
-
"distanceFunction": distanceFunction,
|
|
295
|
-
"getSiblings": getSiblings,
|
|
296
|
-
"level": level,
|
|
297
|
-
"uuid": tileIdentifier
|
|
298
|
-
})
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
invalidate(path, tileIdentifier) {
|
|
305
|
-
const key = simplifyPath(path);
|
|
306
|
-
if (!!this.register[key]) {
|
|
307
|
-
delete this.register[key][tileIdentifier];
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
checkSize() {
|
|
312
|
-
const self = this;
|
|
313
|
-
|
|
314
|
-
let i = 0;
|
|
315
|
-
|
|
316
|
-
while (self.cache.size() > self.maxCachedItems && i < self.cache.size()) {
|
|
317
|
-
i++;
|
|
318
|
-
const entry = self.cache.head();
|
|
319
|
-
const reg = self.register[entry.key];
|
|
320
|
-
if (!!reg) {
|
|
321
|
-
if (Object.keys(reg).length > 0) {
|
|
322
|
-
self.cache.remove(entry.key);
|
|
323
|
-
self.cache.put(entry.key, entry.value);
|
|
324
|
-
} else {
|
|
325
|
-
self.cache.remove(entry.key);
|
|
326
|
-
delete self.register[entry.key];
|
|
327
|
-
entry.value.traverse((o) => {
|
|
328
|
-
|
|
329
|
-
if (o.material) {
|
|
330
|
-
// dispose materials
|
|
331
|
-
if (o.material.length) {
|
|
332
|
-
for (let i = 0; i < o.material.length; ++i) {
|
|
333
|
-
o.material[i].dispose();
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
o.material.dispose()
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
if (o.geometry) {
|
|
341
|
-
// dispose geometry
|
|
342
|
-
o.geometry.dispose();
|
|
343
|
-
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
function simplifyPath(main_path) {
|
|
354
|
-
|
|
355
|
-
var parts = main_path.split('/'),
|
|
356
|
-
new_path = [],
|
|
357
|
-
length = 0;
|
|
358
|
-
for (var i = 0; i < parts.length; i++) {
|
|
359
|
-
var part = parts[i];
|
|
360
|
-
if (part === '.' || part === '' || part === '..') {
|
|
361
|
-
if (part === '..' && length > 0) {
|
|
362
|
-
length--;
|
|
363
|
-
}
|
|
364
|
-
continue;
|
|
365
|
-
}
|
|
366
|
-
new_path[length++] = part;
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (length === 0) {
|
|
370
|
-
return '/';
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
var result = '';
|
|
374
|
-
for (var i = 0; i < length; i++) {
|
|
375
|
-
result += '/' + new_path[i];
|
|
376
|
-
}
|
|
377
|
-
|
|
378
|
-
return result;
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
export { TileLoader };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import * as THREE from 'three';
|
|
2
|
-
import {InstancedTile} from "./InstancedTile.js"
|
|
3
|
-
|
|
4
|
-
class InstancedOGC3DTile extends THREE.Object3D {
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* @param {
|
|
9
|
-
* json: optional,
|
|
10
|
-
* url: optional,
|
|
11
|
-
* rootPath: optional,
|
|
12
|
-
* parentGeometricError: optional,
|
|
13
|
-
* parentBoundingVolume: optional,
|
|
14
|
-
* parentRefinement: optional,
|
|
15
|
-
* geometricErrorMultiplier: Double,
|
|
16
|
-
* loadOutsideView: Boolean,
|
|
17
|
-
* tileLoader : InstancedTileLoader,
|
|
18
|
-
* meshCallback: function,
|
|
19
|
-
* cameraOnLoad: camera,
|
|
20
|
-
* parentTile: OGC3DTile,
|
|
21
|
-
* onLoadCallback: function,
|
|
22
|
-
* renderer: Renderer
|
|
23
|
-
* static: Boolean
|
|
24
|
-
* } properties
|
|
25
|
-
*/
|
|
26
|
-
constructor(properties) {
|
|
27
|
-
super();
|
|
28
|
-
properties.master = this;
|
|
29
|
-
this.renderer = properties.renderer;
|
|
30
|
-
this.geometricErrorMultiplier = properties.geometricErrorMultiplier? properties.geometricErrorMultiplier:1.0;
|
|
31
|
-
this.tileset = new InstancedTile(properties);
|
|
32
|
-
if (properties.static) {
|
|
33
|
-
this.matrixAutoUpdate = false;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
update(camera, frustum){
|
|
38
|
-
if(!!frustum){
|
|
39
|
-
this.tileset._update(camera, frustum);
|
|
40
|
-
}else{
|
|
41
|
-
const frustum = new THREE.Frustum();
|
|
42
|
-
frustum.setFromProjectionMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));
|
|
43
|
-
this.tileset._update(camera, frustum);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
}
|
|
47
|
-
updateWithFrustum(camera, frustum){
|
|
48
|
-
this.tileset._update(camera, frustum);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
setGeometricErrorMultiplier(geometricErrorMultiplier) {
|
|
52
|
-
this.geometricErrorMultiplier = geometricErrorMultiplier?geometricErrorMultiplier:1.0;
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
export { InstancedOGC3DTile };
|