@jdultra/threedtiles 7.0.1 → 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.1",
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.75.0",
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
 
@@ -80,12 +120,12 @@ function initScene() {
80
120
  scene.matrixAutoUpdate = false;
81
121
  //scene.matrixWorldAutoUpdate = false;
82
122
  scene.background = new THREE.Color(0xE5E3E4);
83
- const dirLight = new THREE.DirectionalLight(0xFFFFFF, 1.0);
84
- dirLight.position.set(100,100,100);
85
- dirLight.lookAt(new THREE.Vector3(0,0,0));
86
- //scene.add(new THREE.AmbientLight(0xFFFFFF, 1.0));
123
+ //const dirLight = new THREE.DirectionalLight(0xFFFFFF, 1.0);
124
+ //dirLight.position.set(100,100,100);
125
+ //dirLight.lookAt(new THREE.Vector3(0,0,0));
126
+ scene.add(new THREE.AmbientLight(0xFFFFFF, 1.0));
87
127
 
88
- scene.add(dirLight)
128
+ //scene.add(dirLight)
89
129
 
90
130
  /* const light = new THREE.PointLight(0xbbbbff, 2, 5000);
91
131
  const sphere = new THREE.SphereGeometry(2, 16, 8);
@@ -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
210
  //url: "https://storage.googleapis.com/ogc-3d-tiles/ayutthaya/tiledWithSkirts/tileset.json",
166
211
  url: "http://localhost:8080/tileset.json",
167
- geometricErrorMultiplier: 1,
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);