@jdultra/threedtiles 7.0.2 → 8.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/.babelrc ADDED
@@ -0,0 +1,8 @@
1
+ {
2
+ "presets": [
3
+ "@babel/preset-env"
4
+ ],
5
+ "plugins": [
6
+ "@babel/plugin-syntax-dynamic-import"
7
+ ]
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jdultra/threedtiles",
3
- "version": "7.0.2",
3
+ "version": "8.0.0",
4
4
  "description": "An OGC 3DTiles viewer for Three.js",
5
5
  "main": "tileset.js",
6
6
  "scripts": {
@@ -35,17 +35,18 @@
35
35
  "uuid": "^8.3.2"
36
36
  },
37
37
  "devDependencies": {
38
- "@babel/core": "^7.20.12",
39
- "@babel/preset-env": "^7.20.2",
40
- "babel-loader": "^8.3.0",
38
+ "@babel/core": "^7.21.4",
39
+ "@babel/plugin-syntax-dynamic-import": "^7.8.3",
40
+ "@babel/preset-env": "^7.21.4",
41
+ "babel-loader": "^9.1.2",
41
42
  "copy-webpack-plugin": "^6.3.2",
42
43
  "core-js": "^3.27.1",
43
44
  "html-loader": "^1.3.2",
44
45
  "html-webpack-plugin": "^4.5.0",
45
46
  "mini-css-extract-plugin": "^1.6.2",
46
- "webpack": "^5.76.2",
47
- "webpack-cli": "4.9.1",
48
- "webpack-dev-server": "^4.11.1",
47
+ "webpack": "^5.79.0",
48
+ "webpack-cli": "^5.0.1",
49
+ "webpack-dev-server": "^4.13.2",
49
50
  "webpack-glsl-loader": "^1.0.1",
50
51
  "whatwg-fetch": "^3.5.0"
51
52
  }
@@ -1,109 +1,114 @@
1
1
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
2
2
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
3
+ import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
3
4
  import * as THREE from 'three';
4
- import {FeatureTable, BatchTable} from './FeatureTable';
5
+ import { FeatureTable, BatchTable } from './FeatureTable';
5
6
 
6
- const gltfLoader = new GLTFLoader();
7
- const dracoLoader = new DRACOLoader();
8
- dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
9
- gltfLoader.setDRACOLoader(dracoLoader);
10
- const tempMatrix = new THREE.Matrix4();
11
7
  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
- //const legacyGLTFLoader = new LegacyGLTFLoader();
8
+ zUpToYUpMatrix.set(
9
+ 1, 0, 0, 0,
10
+ 0, 0, -1, 0,
11
+ 0, 1, 0, 0,
12
+ 0, 0, 0, 1);
13
+
14
+ export class B3DMDecoder {
15
+ constructor(renderer) {
16
+ this.gltfLoader = new GLTFLoader();
17
+ const dracoLoader = new DRACOLoader();
18
+ dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
19
+ this.gltfLoader.setDRACOLoader(dracoLoader);
20
+ if (renderer) {
21
+ const ktx2Loader = new KTX2Loader();
22
+ ktx2Loader.setTranscoderPath('https://storage.googleapis.com/ogc-3d-tiles/basis/').detectSupport(renderer);
23
+ this.gltfLoader.setKTX2Loader(ktx2Loader)
24
+ }
18
25
 
19
- function parseB3DM(arrayBuffer, meshCallback, geometricError, zUpToYUp) {
20
- const dataView = new DataView(arrayBuffer);
26
+ this.tempMatrix = new THREE.Matrix4();
27
+ }
21
28
 
22
- const magic =
23
- String.fromCharCode(dataView.getUint8(0)) +
24
- String.fromCharCode(dataView.getUint8(1)) +
25
- String.fromCharCode(dataView.getUint8(2)) +
26
- String.fromCharCode(dataView.getUint8(3));
27
- console.assert(magic === 'b3dm');
29
+ parseB3DM(arrayBuffer, meshCallback, geometricError, zUpToYUp) {
30
+ const dataView = new DataView(arrayBuffer);
28
31
 
29
- //const version = dataView.getUint32(4, true);
30
- //console.assert(version === 1);
32
+ const magic =
33
+ String.fromCharCode(dataView.getUint8(0)) +
34
+ String.fromCharCode(dataView.getUint8(1)) +
35
+ String.fromCharCode(dataView.getUint8(2)) +
36
+ String.fromCharCode(dataView.getUint8(3));
37
+ console.assert(magic === 'b3dm');
31
38
 
32
- const byteLength = dataView.getUint32(8, true);
33
- console.assert(byteLength === arrayBuffer.byteLength);
39
+ const byteLength = dataView.getUint32(8, true);
40
+ console.assert(byteLength === arrayBuffer.byteLength);
34
41
 
35
- const featureTableJSONByteLength = dataView.getUint32(12, true);
36
- const featureTableBinaryByteLength = dataView.getUint32(16, true);
37
- const batchTableJSONByteLength = dataView.getUint32(20, true);
38
- const batchTableBinaryByteLength = dataView.getUint32(24, true);
42
+ const featureTableJSONByteLength = dataView.getUint32(12, true);
43
+ const featureTableBinaryByteLength = dataView.getUint32(16, true);
44
+ const batchTableJSONByteLength = dataView.getUint32(20, true);
45
+ const batchTableBinaryByteLength = dataView.getUint32(24, true);
39
46
 
40
- const featureTableStart = 28;
41
- const featureTable = new FeatureTable(arrayBuffer, featureTableStart, featureTableJSONByteLength, featureTableBinaryByteLength);
47
+ const featureTableStart = 28;
48
+ const featureTable = new FeatureTable(arrayBuffer, featureTableStart, featureTableJSONByteLength, featureTableBinaryByteLength);
42
49
 
43
- const batchTableStart = featureTableStart + featureTableJSONByteLength + featureTableBinaryByteLength;
44
- const batchTable = new BatchTable(arrayBuffer, featureTable.getData('BATCH_LENGTH'), batchTableStart, batchTableJSONByteLength, batchTableBinaryByteLength);
50
+ const batchTableStart = featureTableStart + featureTableJSONByteLength + featureTableBinaryByteLength;
51
+ const batchTable = new BatchTable(arrayBuffer, featureTable.getData('BATCH_LENGTH'), batchTableStart, batchTableJSONByteLength, batchTableBinaryByteLength);
45
52
 
46
- const glbStart = batchTableStart + batchTableJSONByteLength + batchTableBinaryByteLength;
47
- const glbBytes = new Uint8Array(arrayBuffer, glbStart, byteLength - glbStart);
53
+ const glbStart = batchTableStart + batchTableJSONByteLength + batchTableBinaryByteLength;
54
+ const glbBytes = new Uint8Array(arrayBuffer, glbStart, byteLength - glbStart);
48
55
 
49
56
 
50
- const gltfBuffer = glbBytes.slice().buffer;
57
+ const gltfBuffer = glbBytes.slice().buffer;
51
58
 
52
59
 
53
- return new Promise((resolve, reject) => {
60
+ return new Promise((resolve, reject) => {
54
61
 
55
- gltfLoader.parse(gltfBuffer, null, model => {
62
+ this.gltfLoader.parse(gltfBuffer, null, model => {
56
63
 
57
- ////TODO
64
+ ////TODO
58
65
 
59
- //model.batchTable = b3dm.batchTable;
60
- //model.featureTable = b3dm.featureTable;
66
+ //model.batchTable = b3dm.batchTable;
67
+ //model.featureTable = b3dm.featureTable;
61
68
 
62
- //model.scene.batchTable = b3dm.batchTable;
63
- //model.scene.featureTable = b3dm.featureTable;
69
+ //model.scene.batchTable = b3dm.batchTable;
70
+ //model.scene.featureTable = b3dm.featureTable;
64
71
 
65
- //const scene = mergeColoredObject(model.scene);
72
+ //const scene = mergeColoredObject(model.scene);
66
73
 
67
- //model.scene.applyMatrix4(ytozUpMatrix);
74
+ //model.scene.applyMatrix4(ytozUpMatrix);
68
75
 
69
- const rtcCenter = featureTable.getData('RTC_CENTER');
70
- if (rtcCenter) {
71
- tempMatrix.makeTranslation(rtcCenter[0], rtcCenter[1], rtcCenter[2])
72
- model.scene.applyMatrix4(tempMatrix);
73
- }else if(!!model.userData.gltfExtensions && !!model.userData.gltfExtensions.CESIUM_RTC){
74
- tempMatrix.makeTranslation(model.userData.gltfExtensions.CESIUM_RTC.center[0], model.userData.gltfExtensions.CESIUM_RTC.center[1], model.userData.gltfExtensions.CESIUM_RTC.center[2])
75
- model.scene.applyMatrix4(tempMatrix);
76
- }
77
-
78
- if(!zUpToYUp){
79
- model.scene.applyMatrix4(zUpToYUpMatrix);
80
- }
81
-
82
- model.scene.traverse((o) => {
83
-
84
- if (o.isMesh) {
85
- o.geometricError = geometricError
86
- if(zUpToYUp){
87
- o.applyMatrix4(zUpToYUpMatrix);
88
- }
89
- if (!!meshCallback) {
90
- meshCallback(o);
91
- }
76
+ const rtcCenter = featureTable.getData('RTC_CENTER');
77
+ if (rtcCenter) {
78
+ this.tempMatrix.makeTranslation(rtcCenter[0], rtcCenter[1], rtcCenter[2])
79
+ model.scene.applyMatrix4(this.tempMatrix);
80
+ } else if (!!model.userData.gltfExtensions && !!model.userData.gltfExtensions.CESIUM_RTC) {
81
+ this.tempMatrix.makeTranslation(model.userData.gltfExtensions.CESIUM_RTC.center[0], model.userData.gltfExtensions.CESIUM_RTC.center[1], model.userData.gltfExtensions.CESIUM_RTC.center[2])
82
+ model.scene.applyMatrix4(this.tempMatrix);
83
+ }
92
84
 
85
+ if (!zUpToYUp) {
86
+ model.scene.applyMatrix4(zUpToYUpMatrix);
93
87
  }
88
+
89
+ model.scene.traverse((o) => {
90
+
91
+ if (o.isMesh) {
92
+ o.geometricError = geometricError
93
+ if (zUpToYUp) {
94
+ o.applyMatrix4(zUpToYUpMatrix);
95
+ }
96
+ if (!!meshCallback) {
97
+ meshCallback(o);
98
+ }
99
+
100
+ }
101
+ });
102
+ resolve(model.scene);
103
+ }, error => {
104
+ console.error(error);
94
105
  });
95
- resolve(model.scene);
96
- }, error => {
97
- console.error(error);
98
106
  });
99
- });
100
- }
107
+ }
101
108
 
102
- const B3DMDecoder = {
103
- parseB3DM: parseB3DM,
104
- parseB3DMInstanced: (arrayBuffer, meshCallback, maxCount, zUpToYUp) => { // expects GLTF with one node level
109
+ parseB3DMInstanced(arrayBuffer, meshCallback, maxCount, zUpToYUp) { // expects GLTF with one node level
105
110
 
106
- return parseB3DM(arrayBuffer, meshCallback, zUpToYUp).then(mesh => {
111
+ return this.parseB3DM(arrayBuffer, meshCallback, zUpToYUp).then(mesh => {
107
112
  // todo several meshes in a single gltf
108
113
  let instancedMesh;
109
114
  mesh.updateWorldMatrix(false, true)
@@ -117,130 +122,4 @@ const B3DMDecoder = {
117
122
  });
118
123
 
119
124
  }
120
- }
121
-
122
- /**
123
- * //TODO find something else than this workaround
124
- *
125
- * Because B3DM doesn't support colored faces, they are usually encoded as separate meshes each one with a global color.
126
- * However, when a mesh has many different face colors, this becomes very inneficient.
127
- * This method doesn't fix the slow decoding of the GLTFLoader but at least merges meshes together and transfers the face color to vertex color
128
- * which is much more efficient at render time.
129
- * Textured meshes with the same texture are also merged and color is discarded
130
- *
131
- * Big assumption! all the meshes are assumed to have the same transformation matrix
132
- *
133
- * @param {*} scene
134
- * @returns
135
- */
136
- /*function mergeColoredObject(scene) {
137
-
138
- const coloredMeshes = {};
139
- const texturedMeshes = {};
140
- scene.traverse((element) => {
141
- if (element.isMesh) {
142
- if (element.material) {
143
- // dispose materials
144
- if (element.material.length) {
145
- // not supported
146
- }
147
- else {
148
- if (!element.material.map) {
149
- let color = element.material.color;
150
- color = "rgb("+Math.floor(color.r*255)+","+Math.floor(color.g*255)+","+Math.floor(color.b*255)+")";
151
- if (!coloredMeshes[color]) {
152
- coloredMeshes[color] = [];
153
- }
154
- coloredMeshes[color].push(element);
155
- } else {
156
- if (!texturedMeshes[element.material.map]) {
157
- texturedMeshes[element.material.map] = [];
158
- }
159
- texturedMeshes[element.material.map].push(element);
160
- }
161
- }
162
- }
163
- }
164
- });
165
-
166
- let coloredMeshMaterial;
167
- const fullColoredGeometriesToMerge = [];
168
- for (const color in coloredMeshes) {
169
- if (coloredMeshes.hasOwnProperty(color)) {
170
- const threeColor = new Color(color);
171
- //const geometriesToMerge = [];
172
- coloredMeshes[color].forEach(mesh => {
173
- if(!coloredMeshMaterial){
174
- coloredMeshMaterial = mesh.material.clone();
175
- delete coloredMeshMaterial.color;
176
- coloredMeshMaterial.vertexColors = true;
177
- }
178
- const colors = [];
179
- for (let i = 0; i < mesh.geometry.attributes.position.count; i++) {
180
- colors.push(threeColor.r);
181
- colors.push(threeColor.g);
182
- colors.push(threeColor.b);
183
- }
184
- mesh.geometry.setAttribute('color', new BufferAttribute(new Float32Array(colors), 3));
185
-
186
- fullColoredGeometriesToMerge.push(mesh.geometry);
187
- });
188
-
189
- }
190
- }
191
-
192
- let mergedColoredMesh;
193
- if(fullColoredGeometriesToMerge.length>0){
194
- let mergedColoredGeometry = BufferGeometryUtils.mergeBufferGeometries(fullColoredGeometriesToMerge, false);
195
- mergedColoredMesh = new Mesh(mergedColoredGeometry, coloredMeshMaterial);
196
- //mergedColoredMesh.matrix = matrix;
197
- for (const color in coloredMeshes) {
198
- if (coloredMeshes.hasOwnProperty(color)) {
199
- coloredMeshes[color].forEach(mesh => {
200
- mesh.material.dispose();
201
- mesh.geometry.dispose();
202
- });
203
- }
204
- }
205
- }
206
-
207
-
208
- const mergedTexturedMeshes = [];
209
- for(const map in texturedMeshes){
210
- if (texturedMeshes.hasOwnProperty(map)) {
211
- if(texturedMeshes[map].length==1){
212
- mergedTexturedMeshes.push(texturedMeshes[map][0]);
213
- continue;
214
- }
215
- const geometries = [];
216
- let material;
217
- texturedMeshes[map].forEach(mesh => {
218
- if(!material){
219
- material = mesh.material.clone();
220
- delete material.color;
221
- material.vertexColors = false;
222
- }
223
- geometries.push(mesh.geometry);
224
- });
225
-
226
- const mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(geometries, false);
227
- const mesh = new Mesh(mergedGeometry, material);
228
- //mesh.matrix = matrix;
229
- mergedTexturedMeshes.push(mesh);
230
- texturedMeshes[map].forEach(mesh => {
231
- mesh.material.dispose();
232
- mesh.geometry.dispose();
233
- });
234
- }
235
- }
236
-
237
- scene.clear();
238
- if(!!mergedColoredMesh) scene.add(mergedColoredMesh);
239
- mergedTexturedMeshes.forEach(mesh=>scene.add(mesh));
240
- console.log();
241
- scene.matrix = new THREE.Matrix4();
242
- return scene;
243
- }*/
244
-
245
- export { B3DMDecoder }
246
-
125
+ }
package/src/index.js CHANGED
@@ -13,6 +13,9 @@ import { InstancedOGC3DTile } from "./tileset/instanced/InstancedOGC3DTile.js"
13
13
  import { InstancedTileLoader } from "./tileset/instanced/InstancedTileLoader.js"
14
14
  import { Sky } from 'three/addons/objects/Sky.js';
15
15
 
16
+ import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';
17
+ import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
18
+ import { KTX2Loader } from "three/examples/jsm/loaders/KTX2Loader";
16
19
 
17
20
  const occlusionCullingService = new OcclusionCullingService();
18
21
  occlusionCullingService.setSide(THREE.DoubleSide);
@@ -23,6 +26,43 @@ const camera = initCamera(domContainer.offsetWidth, domContainer.offsetHeight);
23
26
  const stats = initStats(domContainer);
24
27
  const renderer = initRenderer(camera, domContainer);
25
28
  const ogc3DTiles = initTileset(scene, 2.0);
29
+ //const instancedTileLoader = createInstancedTileLoader(scene);
30
+ //const ogc3DTiles = initInstancedTilesets(instancedTileLoader);
31
+
32
+
33
+ /*const gltfLoader = new GLTFLoader();
34
+ const dracoLoader = new DRACOLoader();
35
+ dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.4.3/');
36
+ gltfLoader.setDRACOLoader(dracoLoader);
37
+
38
+ const ktx2Loader = new KTX2Loader();
39
+ ktx2Loader.setTranscoderPath('jsm/libs/basis/');
40
+ //gltfLoader.setKTX2Loader(ktx2Loader)
41
+
42
+
43
+ gltfLoader.load(
44
+ // resource URL
45
+ 'http://localhost:8080/3/15.glb',
46
+ // called when the resource is loaded
47
+ function (gltf) {
48
+
49
+ scene.add(gltf.scene);
50
+
51
+ },
52
+ // called while loading is progressing
53
+ function (xhr) {
54
+
55
+ console.log((xhr.loaded / xhr.total * 100) + '% loaded');
56
+
57
+ },
58
+ // called when loading has errors
59
+ function (error) {
60
+
61
+ console.log('An error happened : ' + error);
62
+
63
+ }
64
+ );*/
65
+ // Optional: Provide a DRACOLoader instance to decode compressed mesh data
26
66
 
27
67
  const controller = initController(camera, domContainer);
28
68
 
@@ -150,21 +190,26 @@ function initStats(dom) {
150
190
 
151
191
  function initTileset(scene, gem) {
152
192
 
153
- const tileLoader = new TileLoader(100, mesh => {
154
- //// Insert code to be called on every newly decoded mesh e.g.:
155
- mesh.material.wireframe = false;
156
- mesh.material.side = THREE.DoubleSide;
157
- //mesh.material.metalness = 0.0
158
- }, points => {
159
- points.material.size = Math.min(1.0, 0.5 * Math.sqrt(points.geometricError));
160
- points.material.sizeAttenuation = true;
193
+ const tileLoader = new TileLoader({
194
+ renderer: renderer,
195
+ maxCachedItems: 100,
196
+ meshCallback: mesh => {
197
+ //// Insert code to be called on every newly decoded mesh e.g.:
198
+ mesh.material.wireframe = false;
199
+ mesh.material.side = THREE.DoubleSide;
200
+ //mesh.material.metalness = 0.0
201
+ },
202
+ pointsCallback: points => {
203
+ points.material.size = Math.min(1.0, 0.5 * Math.sqrt(points.geometricError));
204
+ points.material.sizeAttenuation = true;
205
+ }
161
206
  });
162
207
 
163
208
  const ogc3DTile = new OGC3DTile({
164
209
  //url: "https://storage.googleapis.com/ogc-3d-tiles/berlinTileset/tileset.json",
165
- url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tiledWithSkirts/tileset.json",
166
- //url: "http://localhost:8080/tileset.json",
167
- geometricErrorMultiplier: 1,
210
+ //url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tiledWithSkirts/tileset.json",
211
+ url: "http://localhost:8080/tileset.json",
212
+ geometricErrorMultiplier: gem,
168
213
  loadOutsideView: true,
169
214
  tileLoader: tileLoader,
170
215
  //occlusionCullingService: occlusionCullingService,
@@ -179,7 +224,7 @@ function initTileset(scene, gem) {
179
224
 
180
225
  //ogc3DTile.scale.set(0.1,0.1,0.1)
181
226
 
182
- //ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI * 0.5) // Z-UP to Y-UP
227
+ ogc3DTile.rotateOnAxis(new THREE.Vector3(1, 0, 0), -Math.PI * 0.5) // Z-UP to Y-UP
183
228
  //ogc3DTile.translateOnAxis(new THREE.Vector3(0, 0, 1), 1)
184
229
  /*
185
230
  ogc3DTile.translateOnAxis(new THREE.Vector3(0, 0, 1), 10) // Z-UP to Y-UP
@@ -191,13 +236,20 @@ function initTileset(scene, gem) {
191
236
 
192
237
 
193
238
  function createInstancedTileLoader(scene) {
194
- return new InstancedTileLoader(scene, 100, 1,
195
- mesh => {
239
+ return new InstancedTileLoader(scene, {
240
+ renderer: renderer,
241
+ maxCachedItems : 100,
242
+ maxInstances : 1,
243
+ meshCallback: mesh => {
196
244
  //// Insert code to be called on every newly decoded mesh e.g.:
197
245
  mesh.material.wireframe = false;
198
246
  mesh.material.side = THREE.DoubleSide;
199
- mesh.material.metalness = 0.0;
200
- });
247
+ },
248
+ pointsCallback: points => {
249
+ points.material.size = Math.min(1.0, 0.5 * Math.sqrt(points.geometricError));
250
+ points.material.sizeAttenuation = true;
251
+ }
252
+ });
201
253
  }
202
254
  function initInstancedTilesets(instancedTileLoader) {
203
255
 
@@ -211,14 +263,14 @@ function initInstancedTilesets(instancedTileLoader) {
211
263
  const tileset = new InstancedOGC3DTile({
212
264
  //url: "https://storage.googleapis.com/ogc-3d-tiles/berlinTileset/tileset.json",
213
265
  url: "http://localhost:8080/tileset.json",
214
- geometricErrorMultiplier: 0.1,
266
+ geometricErrorMultiplier: 1,
215
267
  loadOutsideView: true,
216
268
  tileLoader: instancedTileLoader,
217
269
  static: false,
218
270
  centerModel: true,
219
271
  renderer: renderer
220
272
  });
221
- //tileset.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -0.5) // Z-UP to Y-UP
273
+ tileset.rotateOnAxis(new THREE.Vector3(1, 0, 0), Math.PI * -1) // Z-UP to Y-UP
222
274
 
223
275
  tileset.updateMatrix()
224
276
  scene.add(tileset);
@@ -242,18 +294,6 @@ function initInstancedTilesets(instancedTileLoader) {
242
294
  //initLODMultiplierSlider(instancedTilesets);
243
295
  }
244
296
 
245
- function initLODMultiplierSlider(instancedTilesets) {
246
- var slider = document.getElementById("lodMultiplier");
247
- var output = document.getElementById("multiplierValue");
248
- output.innerHTML = slider.value;
249
-
250
- slider.oninput = () => {
251
- instancedTilesets.forEach(tileset => {
252
- tileset.setGeometricErrorMultiplier(slider.value * 0.1)
253
- })
254
- output.innerHTML = slider.value;
255
- }
256
- }
257
297
 
258
298
  function initCamera(width, height) {
259
299
  const camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 20000);
@@ -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
- this.tileLoader = new TileLoader(
50
- 200,
51
- !properties.meshCallback ? mesh => {
52
- mesh.material.wireframe = false;
53
- mesh.material.side = THREE.DoubleSide;
54
- } : properties.meshCallback,
55
- !properties.pointsCallback ? points => {
56
- points.material.size = 0.1;
57
- points.material.sizeAttenuation = true;
58
- } : properties.pointsCallback);
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
- self.level,
271
- !!self.json.boundingVolume.region,
272
- self.geometricError
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;