itowns 2.43.2-next.9 → 2.44.1-next.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.
Files changed (62) hide show
  1. package/CONTRIBUTORS.md +1 -0
  2. package/changelog.md +107 -0
  3. package/dist/455.js +2 -0
  4. package/dist/455.js.map +1 -0
  5. package/dist/debug.js +1 -1
  6. package/dist/debug.js.LICENSE.txt +2 -2
  7. package/dist/debug.js.map +1 -1
  8. package/dist/itowns.js +1 -1
  9. package/dist/itowns.js.LICENSE.txt +1 -22
  10. package/dist/itowns.js.map +1 -1
  11. package/dist/itowns_lasparser.js +2 -0
  12. package/dist/itowns_lasparser.js.map +1 -0
  13. package/dist/itowns_lasworker.js +2 -0
  14. package/dist/itowns_lasworker.js.map +1 -0
  15. package/dist/itowns_potree2worker.js +2 -0
  16. package/dist/itowns_potree2worker.js.map +1 -0
  17. package/dist/itowns_widgets.js +1 -1
  18. package/dist/itowns_widgets.js.map +1 -1
  19. package/examples/3dtiles_loader.html +150 -0
  20. package/examples/config.json +5 -0
  21. package/examples/jsm/.eslintrc.cjs +38 -0
  22. package/examples/jsm/OGC3DTilesHelper.js +105 -0
  23. package/examples/misc_instancing.html +2 -1
  24. package/examples/potree2_25d_map.html +127 -0
  25. package/lib/Core/3DTiles/C3DTFeature.js +6 -6
  26. package/lib/Core/Potree2Node.js +206 -0
  27. package/lib/Core/Potree2PointAttributes.js +139 -0
  28. package/lib/Core/Scheduler/Scheduler.js +1 -1
  29. package/lib/Core/Style.js +52 -49
  30. package/lib/Core/View.js +3 -0
  31. package/lib/Layer/C3DTilesLayer.js +6 -6
  32. package/lib/Layer/OGC3DTilesLayer.js +386 -0
  33. package/lib/Layer/PointCloudLayer.js +1 -1
  34. package/lib/Layer/Potree2Layer.js +165 -0
  35. package/lib/Layer/ReferencingLayerProperties.js +5 -0
  36. package/lib/Layer/TiledGeometryLayer.js +4 -1
  37. package/lib/Loader/Potree2BrotliLoader.js +261 -0
  38. package/lib/Loader/Potree2Loader.js +207 -0
  39. package/lib/Main.js +9 -2
  40. package/lib/Parser/B3dmParser.js +11 -22
  41. package/lib/Parser/LASParser.js +48 -16
  42. package/lib/Parser/Potree2BinParser.js +92 -0
  43. package/lib/Parser/ShapefileParser.js +2 -2
  44. package/lib/Parser/deprecated/LegacyGLTFLoader.js +25 -5
  45. package/lib/Parser/iGLTFLoader.js +169 -0
  46. package/lib/Process/3dTilesProcessing.js +2 -1
  47. package/lib/Provider/3dTilesProvider.js +6 -4
  48. package/lib/Renderer/PointsMaterial.js +128 -94
  49. package/lib/Source/FileSource.js +1 -1
  50. package/lib/Source/OGC3DTilesGoogleSource.js +32 -0
  51. package/lib/Source/OGC3DTilesIonSource.js +37 -0
  52. package/lib/Source/OGC3DTilesSource.js +24 -0
  53. package/lib/Source/Potree2Source.js +172 -0
  54. package/lib/ThreeExtended/loaders/DRACOLoader.js +5 -3
  55. package/lib/ThreeExtended/loaders/GLTFLoader.js +38 -2
  56. package/lib/ThreeExtended/loaders/KTX2Loader.js +17 -10
  57. package/lib/ThreeExtended/utils/BufferGeometryUtils.js +32 -30
  58. package/lib/Worker/LASLoaderWorker.js +19 -0
  59. package/lib/Worker/Potree2Worker.js +21 -0
  60. package/package.json +33 -31
  61. package/lib/Parser/GLTFParser.js +0 -88
  62. /package/lib/{Parser → Loader}/LASLoader.js +0 -0
package/lib/Main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const conf = {
2
- version: '2.43.1'
2
+ version: '2.44.0'
3
3
  };
4
4
  export const REVISION = conf.version;
5
5
 
@@ -51,7 +51,9 @@ export { default as GeometryLayer } from "./Layer/GeometryLayer.js";
51
51
  export { default as FeatureGeometryLayer } from "./Layer/FeatureGeometryLayer.js";
52
52
  export { default as PointCloudLayer } from "./Layer/PointCloudLayer.js";
53
53
  export { default as PotreeLayer } from "./Layer/PotreeLayer.js";
54
+ export { default as Potree2Layer } from "./Layer/Potree2Layer.js";
54
55
  export { default as C3DTilesLayer, C3DTILES_LAYER_EVENTS } from "./Layer/C3DTilesLayer.js";
56
+ export { default as OGC3DTilesLayer, OGC3DTILES_LAYER_EVENTS, enableDracoLoader, enableKtx2Loader } from "./Layer/OGC3DTilesLayer.js";
55
57
  export { default as TiledGeometryLayer } from "./Layer/TiledGeometryLayer.js";
56
58
  export { default as OrientedImageLayer } from "./Layer/OrientedImageLayer.js";
57
59
  export { STRATEGY_MIN_NETWORK_TRAFFIC, STRATEGY_GROUP, STRATEGY_PROGRESSIVE, STRATEGY_DICHOTOMY } from "./Layer/LayerUpdateStrategy.js";
@@ -75,9 +77,13 @@ export { default as WMTSSource } from "./Source/WMTSSource.js";
75
77
  export { default as VectorTilesSource } from "./Source/VectorTilesSource.js";
76
78
  export { default as OrientedImageSource } from "./Source/OrientedImageSource.js";
77
79
  export { default as PotreeSource } from "./Source/PotreeSource.js";
80
+ export { default as Potree2Source } from "./Source/Potree2Source.js";
78
81
  export { default as C3DTilesSource } from "./Source/C3DTilesSource.js";
79
82
  export { default as C3DTilesIonSource } from "./Source/C3DTilesIonSource.js";
80
83
  export { default as C3DTilesGoogleSource } from "./Source/C3DTilesGoogleSource.js";
84
+ export { default as OGC3DTilesSource } from "./Source/OGC3DTilesSource.js";
85
+ export { default as OGC3DTilesIonSource } from "./Source/OGC3DTilesIonSource.js";
86
+ export { default as OGC3DTilesGoogleSource } from "./Source/OGC3DTilesGoogleSource.js";
81
87
  export { default as EntwinePointTileSource } from "./Source/EntwinePointTileSource.js";
82
88
  export { default as CopcSource } from "./Source/CopcSource.js";
83
89
 
@@ -93,7 +99,8 @@ export { default as LASParser } from "./Parser/LASParser.js";
93
99
  export { default as ISGParser } from "./Parser/ISGParser.js";
94
100
  export { default as GDFParser } from "./Parser/GDFParser.js";
95
101
  export { default as GTXParser } from "./Parser/GTXParser.js";
96
- export { default as GLTFParser, enableDracoLoader, enableKtx2Loader, glTFLoader, legacyGLTFLoader } from "./Parser/GLTFParser.js";
102
+ export { default as B3dmParser } from "./Parser/B3dmParser.js";
103
+ export { default as iGLTFLoader } from "./Parser/iGLTFLoader.js";
97
104
 
98
105
  // 3D Tiles classes and extensions
99
106
  // Exported to allow one to implement its own 3D Tiles extension which needs to
@@ -5,8 +5,10 @@ import { MeshBasicMaterial } from 'three';
5
5
  import disposeThreeMaterial from "../Utils/ThreeUtils.js";
6
6
  import shaderUtils from "../Renderer/Shader/ShaderUtils.js";
7
7
  import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
8
- import GLTFParser from "./GLTFParser.js";
9
- const matrixChangeUpVectorYtoZInv = new THREE.Matrix4().makeRotationX(-Math.PI / 2);
8
+ // A bit weird but temporary until we remove this deprecated parser. Mainly to benefit from the enableDracoLoader and enableKtx2Loader
9
+ // methods.
10
+ import { itownsGLTFLoader } from "../Layer/OGC3DTilesLayer.js";
11
+ const matrixChangeUpVectorYtoZ = new THREE.Matrix4().makeRotationX(Math.PI / 2);
10
12
  const matrixChangeUpVectorXtoZ = new THREE.Matrix4().makeRotationZ(-Math.PI / 2);
11
13
  const utf8Decoder = new TextDecoder();
12
14
 
@@ -34,18 +36,15 @@ function filterUnsupportedSemantics(obj) {
34
36
  }
35
37
 
36
38
  /**
37
- * 3D Tiles pre-1.0 had a gltfUpAxis parameter that defined the up vector of the gltf file that might be different from
38
- * the standard y-up for gltf. Manage the case when this gltfUpAxis is defined (i.e. apply the correct rotation to the
39
- * gltf file to have it z-up in the end).
39
+ * Transforms loaded gltf model to z-up (either from y-up or from the up axis defined in gltfUpAxis). Note that
40
+ * gltfUpAxis was an attribut of pre-1.0 3D Tiles and is now deprecated.
40
41
  * @param {THREE.Object3D} gltfScene - the parsed glTF scene
41
42
  * @param {String} gltfUpAxis - the gltfUpAxis parameter
42
43
  */
43
- function applyDeprecatedGltfUpAxis(gltfScene, gltfUpAxis) {
44
- if (gltfUpAxis === 'Z') {
45
- // If gltf up was already z-up, apply the inverse transform matrix that was applied in the glTFParser
46
- gltfScene.applyMatrix4(matrixChangeUpVectorYtoZInv);
44
+ function transformToZUp(gltfScene, gltfUpAxis) {
45
+ if (!gltfUpAxis || gltfUpAxis === 'Y') {
46
+ gltfScene.applyMatrix4(matrixChangeUpVectorYtoZ);
47
47
  } else if (gltfUpAxis === 'X') {
48
- gltfScene.applyMatrix4(matrixChangeUpVectorYtoZInv);
49
48
  gltfScene.applyMatrix4(matrixChangeUpVectorXtoZ);
50
49
  }
51
50
  }
@@ -127,7 +126,6 @@ export default {
127
126
  }
128
127
  const posGltf = headerByteLength + b3dmHeader.FTJSONLength + b3dmHeader.FTBinaryLength + b3dmHeader.BTJSONLength + b3dmHeader.BTBinaryLength;
129
128
  const gltfBuffer = buffer.slice(posGltf);
130
- const headerView = new DataView(gltfBuffer, 0, 20);
131
129
  const init_mesh = function (mesh) {
132
130
  mesh.frustumCulled = frustumCulled;
133
131
  if (mesh.material) {
@@ -147,11 +145,11 @@ export default {
147
145
  ReferLayerProperties(mesh.material, options.layer);
148
146
  }
149
147
  };
150
- promises.push(GLTFParser.parse(gltfBuffer, options).then(gltf => {
148
+ promises.push(itownsGLTFLoader.parseAsync(gltfBuffer, options).then(gltf => {
151
149
  for (const scene of gltf.scenes) {
152
150
  scene.traverse(filterUnsupportedSemantics);
153
151
  }
154
- applyDeprecatedGltfUpAxis(gltf.scene, options.gltfUpAxis);
152
+ transformToZUp(gltf.scene, options.gltfUpAxis);
155
153
  const shouldBePatchedForLogDepthSupport = Capabilities.isLogDepthBufferSupported() && !options.doNotPatchMaterial;
156
154
  if (options.frustumCulling === false || options.overrideMaterials || shouldBePatchedForLogDepthSupport || options.layer) {
157
155
  gltf.scene.traverse(init_mesh);
@@ -159,15 +157,6 @@ export default {
159
157
 
160
158
  // Apply relative center from Feature table.
161
159
  gltf.scene.position.copy(FT_RTC);
162
-
163
- // Apply relative center from gltf json.
164
- const contentArray = new Uint8Array(gltfBuffer, 20, headerView.getUint32(12, true));
165
- const content = utf8Decoder.decode(new Uint8Array(contentArray));
166
- const json = JSON.parse(content);
167
- if (json.extensions && json.extensions.CESIUM_RTC) {
168
- gltf.scene.position.fromArray(json.extensions.CESIUM_RTC.center);
169
- gltf.scene.updateMatrixWorld(true);
170
- }
171
160
  return gltf;
172
161
  }).catch(e => {
173
162
  throw new Error(e);
@@ -1,6 +1,23 @@
1
1
  import * as THREE from 'three';
2
- import LASLoader from "./LASLoader.js";
3
- const lasLoader = new LASLoader();
2
+ import { spawn, Thread, Transfer } from 'threads';
3
+ let _lazPerf;
4
+ let _thread;
5
+ function workerInstance() {
6
+ return new Worker( /* webpackChunkName: "itowns_lasparser" */
7
+ new URL('../Worker/LASLoaderWorker.js', import.meta.url), {
8
+ type: 'module'
9
+ });
10
+ }
11
+ async function loader() {
12
+ if (_thread) {
13
+ return _thread;
14
+ }
15
+ _thread = await spawn(workerInstance());
16
+ if (_lazPerf) {
17
+ _thread.lazPerf(_lazPerf);
18
+ }
19
+ return _thread;
20
+ }
4
21
  function buildBufferGeometry(attributes) {
5
22
  const geometry = new THREE.BufferGeometry();
6
23
  const positionBuffer = new THREE.BufferAttribute(attributes.position, 3);
@@ -42,7 +59,16 @@ export default {
42
59
  if (!path) {
43
60
  throw new Error('Path to laz-perf is mandatory');
44
61
  }
45
- lasLoader.lazPerf = path;
62
+ _lazPerf = path;
63
+ },
64
+ /**
65
+ * Terminate all worker instances.
66
+ * @returns {Promise<void>}
67
+ */
68
+ terminate() {
69
+ const currentThread = _thread;
70
+ _thread = undefined;
71
+ return Thread.terminate(currentThread);
46
72
  },
47
73
  /**
48
74
  * Parses a chunk of a LAS or LAZ (LASZip) and returns the corresponding
@@ -66,13 +92,18 @@ export default {
66
92
  * @return {Promise<THREE.BufferGeometry>} A promise resolving with a
67
93
  * `THREE.BufferGeometry`.
68
94
  */
69
- parseChunk(data) {
95
+ async parseChunk(data) {
70
96
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
71
- return lasLoader.parseChunk(data, options.in).then(parsedData => {
72
- const geometry = buildBufferGeometry(parsedData.attributes);
73
- geometry.computeBoundingBox();
74
- return geometry;
97
+ const lasLoader = await loader();
98
+ const parsedData = await lasLoader.parseChunk(Transfer(data), {
99
+ pointCount: options.in.pointCount,
100
+ header: options.in.header,
101
+ eb: options.eb,
102
+ colorDepth: options.in.colorDepth
75
103
  });
104
+ const geometry = buildBufferGeometry(parsedData.attributes);
105
+ geometry.computeBoundingBox();
106
+ return geometry;
76
107
  },
77
108
  /**
78
109
  * Parses a LAS file or a LAZ (LASZip) file and return the corresponding
@@ -88,18 +119,19 @@ export default {
88
119
  * @return {Promise} A promise resolving with a `THREE.BufferGeometry`. The
89
120
  * header of the file is contained in `userData`.
90
121
  */
91
- parse(data) {
122
+ async parse(data) {
92
123
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
93
124
  if (options.out?.skip) {
94
125
  console.warn("Warning: options 'skip' not supported anymore");
95
126
  }
96
- return lasLoader.parseFile(data, {
97
- colorDepth: options.in?.colorDepth
98
- }).then(parsedData => {
99
- const geometry = buildBufferGeometry(parsedData.attributes);
100
- geometry.userData.header = parsedData.header;
101
- geometry.computeBoundingBox();
102
- return geometry;
127
+ const input = options.in;
128
+ const lasLoader = await loader();
129
+ const parsedData = await lasLoader.parseFile(Transfer(data), {
130
+ colorDepth: input?.colorDepth
103
131
  });
132
+ const geometry = buildBufferGeometry(parsedData.attributes);
133
+ geometry.userData.header = parsedData.header;
134
+ geometry.computeBoundingBox();
135
+ return geometry;
104
136
  }
105
137
  };
@@ -0,0 +1,92 @@
1
+ import * as THREE from 'three';
2
+ import { spawn, Thread, Transfer } from 'threads';
3
+ let _thread;
4
+ function workerInstance() {
5
+ return new Worker( /* webpackChunkName: "itowns_potree2worker" */
6
+ new URL('../Worker/Potree2Worker.js', import.meta.url), {
7
+ type: 'module'
8
+ });
9
+ }
10
+ async function loader() {
11
+ if (_thread) {
12
+ return _thread;
13
+ }
14
+ _thread = await spawn(workerInstance());
15
+ return _thread;
16
+ }
17
+ function decoder(w, metadata) {
18
+ return metadata.encoding === 'BROTLI' ? w.parseBrotli : w.parse;
19
+ }
20
+ export default {
21
+ /**
22
+ * @return {Promise<void>}
23
+ */
24
+ terminate() {
25
+ const currentThread = _thread;
26
+ _thread = undefined;
27
+ return Thread.terminate(currentThread);
28
+ },
29
+ /** @module Potree2BinParser */
30
+ /** Parse .bin PotreeConverter 2.0 format and convert to a THREE.BufferGeometry
31
+ * @function parse
32
+ * @param {ArrayBuffer} buffer - the bin buffer.
33
+ * @param {Object} options
34
+ * @param {string[]} options.in.pointAttributes - the point attributes information contained in metadata.js
35
+ * @return {Promise} - a promise that resolves with a THREE.BufferGeometry.
36
+ *
37
+ */
38
+ parse: async function (buffer, options) {
39
+ const metadata = options.in.source.metadata;
40
+ const layer = options.out;
41
+ const pointAttributes = layer.pointAttributes;
42
+ const scale = metadata.scale;
43
+ const box = options.in.bbox;
44
+ const min = box.min;
45
+ const size = box.max.clone().sub(box.min);
46
+ const max = box.max;
47
+ const offset = metadata.offset;
48
+ const numPoints = options.in.numPoints;
49
+ const potreeLoader = await loader();
50
+ const decode = decoder(potreeLoader, metadata);
51
+ const data = await decode(Transfer(buffer), {
52
+ pointAttributes,
53
+ scale,
54
+ min,
55
+ max,
56
+ size,
57
+ offset,
58
+ numPoints
59
+ });
60
+ const buffers = data.attributeBuffers;
61
+ const geometry = new THREE.BufferGeometry();
62
+ Object.keys(buffers).forEach(property => {
63
+ const buffer = buffers[property].buffer;
64
+ if (property === 'position') {
65
+ geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(buffer), 3));
66
+ } else if (property === 'rgba') {
67
+ geometry.setAttribute('color', new THREE.BufferAttribute(new Uint8Array(buffer), 4, true));
68
+ } else if (property === 'NORMAL') {
69
+ geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(buffer), 3));
70
+ } else if (property === 'INDICES') {
71
+ const bufferAttribute = new THREE.BufferAttribute(new Uint8Array(buffer), 4);
72
+ bufferAttribute.normalized = true;
73
+ geometry.setAttribute('indices', bufferAttribute);
74
+ } else {
75
+ const bufferAttribute = new THREE.BufferAttribute(new Float32Array(buffer), 1);
76
+ const batchAttribute = buffers[property].attribute;
77
+ bufferAttribute.potree = {
78
+ offset: buffers[property].offset,
79
+ scale: buffers[property].scale,
80
+ preciseBuffer: buffers[property].preciseBuffer,
81
+ range: batchAttribute.range
82
+ };
83
+ geometry.setAttribute(property, bufferAttribute);
84
+ }
85
+ });
86
+ geometry.computeBoundingBox();
87
+ return {
88
+ geometry,
89
+ density: data.density
90
+ };
91
+ }
92
+ };
@@ -68,9 +68,9 @@ export default {
68
68
 
69
69
  // If a zip is present, don't read anything else
70
70
  if (data.zip) {
71
- result = shp.parseZip(data.zip);
71
+ result = shp(data.zip);
72
72
  } else if (data.shp && data.shx && data.dbf) {
73
- result = Promise.all([shp.parseShp(data.shp, data.prj), shp.parseDbf(data.dbf)]).then(shp.combine);
73
+ result = shp(data);
74
74
  }
75
75
  options.in = options.in || {};
76
76
  options.in.crs = data.prj ? proj4(data.prj).oProj.datumName : options.in.crs;
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable */
2
- // Copy LegacyGLTFLoader file from THREE v110 because it was removed in THREE v111
2
+ // LegacyGLTFLoader for loading gltf 1.0 files taken from THREE v110 because it was removed in THREE v111 and maintained
3
+ // since
3
4
  import * as THREE from 'three';
4
5
  const threeExamples = {};
5
6
  /**
@@ -45,6 +46,9 @@ threeExamples.LegacyGLTFLoader = function () {
45
46
  if (json.extensionsUsed && json.extensionsUsed.indexOf(EXTENSIONS.KHR_MATERIALS_COMMON) >= 0) {
46
47
  extensions[EXTENSIONS.KHR_MATERIALS_COMMON] = new GLTFMaterialsCommonExtension(json);
47
48
  }
49
+ if (json.extensionsUsed && json.extensionsUsed.indexOf(EXTENSIONS.CESIUM_RTC) >= 0) {
50
+ extensions[EXTENSIONS.CESIUM_RTC] = new CesiumRTCExtension(json);
51
+ }
48
52
  var parser = new GLTFParser(json, extensions, {
49
53
  crossOrigin: this.crossOrigin,
50
54
  manager: this.manager,
@@ -175,7 +179,8 @@ threeExamples.LegacyGLTFLoader = function () {
175
179
 
176
180
  var EXTENSIONS = {
177
181
  KHR_BINARY_GLTF: 'KHR_binary_glTF',
178
- KHR_MATERIALS_COMMON: 'KHR_materials_common'
182
+ KHR_MATERIALS_COMMON: 'KHR_materials_common',
183
+ CESIUM_RTC: 'CESIUM_RTC'
179
184
  };
180
185
 
181
186
  /* MATERIALS COMMON EXTENSION */
@@ -247,6 +252,17 @@ threeExamples.LegacyGLTFLoader = function () {
247
252
  return THREE.LoaderUtils.decodeText(array);
248
253
  };
249
254
 
255
+ // Ref spec https://github.com/KhronosGroup/glTF/blob/main/extensions/1.0/Vendor/CESIUM_RTC/README.md
256
+ // Only the json storage method is implemented since it is the only one we've seen out there and since this extension
257
+ // is specific to deprecated 3D tiles with GLTF 1.0
258
+ function CesiumRTCExtension(json) {
259
+ this.name = EXTENSIONS.CESIUM_RTC;
260
+ this.center = [0, 0, 0];
261
+ if (json.extensions && json.extensions[EXTENSIONS.CESIUM_RTC] && json.extensions[EXTENSIONS.CESIUM_RTC].center && json.extensions[EXTENSIONS.CESIUM_RTC].center.length === 3) {
262
+ this.center = json.extensions[EXTENSIONS.CESIUM_RTC].center;
263
+ }
264
+ }
265
+
250
266
  /*********************************/
251
267
  /********** INTERNALS ************/
252
268
  /*********************************/
@@ -526,9 +542,9 @@ threeExamples.LegacyGLTFLoader = function () {
526
542
  }
527
543
 
528
544
  /**
529
- * Verifies if the shaders are Cesium specific: if they contain attributes, uniforms or functions starting with
530
- * `czm_`. The cesium gltf-pipeline (the ancestor of cesium ion) used to create 3D Tiles tilesets they are only
531
- * defined in Cesium.
545
+ * Verifies if the shaders are Cesium specific: if they contain attributes, uniforms or functions starting with
546
+ * `czm_`. The cesium gltf-pipeline (the ancestor of cesium ion) used to create 3D Tiles tilesets they are only
547
+ * defined in Cesium.
532
548
  * @param {Object} shaders
533
549
  */
534
550
  function areShadersCesiumSpecific(shaders) {
@@ -1323,6 +1339,7 @@ threeExamples.LegacyGLTFLoader = function () {
1323
1339
  };
1324
1340
  GLTFParser.prototype.loadScenes = function () {
1325
1341
  var json = this.json;
1342
+ var extensions = this.extensions;
1326
1343
 
1327
1344
  // scene node hierachy builder
1328
1345
 
@@ -1357,6 +1374,9 @@ threeExamples.LegacyGLTFLoader = function () {
1357
1374
  };
1358
1375
  }
1359
1376
  });
1377
+ if (extensions[EXTENSIONS.CESIUM_RTC]) {
1378
+ _scene.position.fromArray(extensions[EXTENSIONS.CESIUM_RTC].center);
1379
+ }
1360
1380
  return _scene;
1361
1381
  });
1362
1382
  });
@@ -0,0 +1,169 @@
1
+ import * as THREE from 'three';
2
+ import LegacyGLTFLoader from "./deprecated/LegacyGLTFLoader.js";
3
+ import { GLTFLoader } from "../ThreeExtended/loaders/GLTFLoader.js";
4
+ class iGLTFLoader extends THREE.Loader {
5
+ /**
6
+ * Parses [glTF](https://www.khronos.org/gltf/) 1.0 and 2.0 files.
7
+ *
8
+ * Under the hood, glTF 2.0 files are parsed with THREE.GLTFLoader and GLTF 1.0 are parsed with the previous THREE
9
+ * GltfLoader (for 1.0 glTF) that has been kept and maintained in iTowns.
10
+ *
11
+ * Beware that gltf convention is y-up while itowns is z-up. You can apply a PI/2 rotation around the X axis to the
12
+ * loaded model to transform from y-up to z-up. Note that you can also use Coordinates.geodesicNormal to get the normal
13
+ * to a position on the globe (i.e. in GlobeView) to correctly orient a model on a GlobeView.
14
+ *
15
+ * @constructor
16
+ * @param {THREE.LoadingManager} [manager] - The loadingManager for the loader to use. Default is THREE.DefaultLoadingManager.
17
+ */
18
+ constructor(manager) {
19
+ super(manager);
20
+ this.legacyGLTFLoader = new LegacyGLTFLoader();
21
+ this.glTFLoader = new GLTFLoader();
22
+ }
23
+
24
+ /**
25
+ * Loads a gltf model from url and call the callback function with the parsed response content.
26
+ * Adapted from threejs.
27
+ * @param {String} url - the path/URL of the .gltf or .glb file.
28
+ * @param {Function} onLoad - A function to be called after the loading is successfully completed. The function
29
+ * receives the loaded JSON response returned from {@link parse}.
30
+ * @param {Function} onProgress
31
+ * @param {Function} onError
32
+ */
33
+ load(url, onLoad, onProgress, onError) {
34
+ const scope = this;
35
+ let resourcePath;
36
+ if (this.resourcePath !== '') {
37
+ resourcePath = this.resourcePath;
38
+ } else if (this.path !== '') {
39
+ // If a base path is set, resources will be relative paths from that plus the relative path of the gltf file
40
+ // Example path = 'https://my-cnd-server.com/', url = 'assets/models/model.gltf'
41
+ // resourcePath = 'https://my-cnd-server.com/assets/models/'
42
+ // referenced resource 'model.bin' will be loaded from 'https://my-cnd-server.com/assets/models/model.bin'
43
+ // referenced resource '../textures/texture.png' will be loaded from 'https://my-cnd-server.com/assets/textures/texture.png'
44
+ const relativeUrl = THREE.LoaderUtils.extractUrlBase(url);
45
+ resourcePath = THREE.LoaderUtils.resolveURL(relativeUrl, this.path);
46
+ } else {
47
+ resourcePath = THREE.LoaderUtils.extractUrlBase(url);
48
+ }
49
+
50
+ // Tells the LoadingManager to track an extra item, which resolves after
51
+ // the model is fully loaded. This means the count of items loaded will
52
+ // be incorrect, but ensures manager.onLoad() does not fire early.
53
+ this.manager.itemStart(url);
54
+ const _onError = e => {
55
+ if (onError) {
56
+ onError(e);
57
+ } else {
58
+ console.error(e);
59
+ }
60
+ scope.manager.itemError(url);
61
+ scope.manager.itemEnd(url);
62
+ };
63
+ const loader = new THREE.FileLoader(this.manager);
64
+ loader.setPath(this.path);
65
+ loader.setResponseType('arraybuffer');
66
+ loader.setRequestHeader(this.requestHeader);
67
+ loader.setWithCredentials(this.withCredentials);
68
+ loader.load(url, data => {
69
+ try {
70
+ scope.parse(data, resourcePath, gltf => {
71
+ onLoad(gltf);
72
+ scope.manager.itemEnd(url);
73
+ }, _onError);
74
+ } catch (e) {
75
+ _onError(e);
76
+ }
77
+ }, onProgress, _onError);
78
+ }
79
+
80
+ /**
81
+ * Sets the draco loader instance for this gltf parser. Enable loading files with
82
+ * [Draco](https://google.github.io/draco/) geometry extension. See Threejs
83
+ * [DracoLoader](https://threejs.org/docs/index.html#examples/en/loaders/DRACOLoader) for more information.
84
+ * Only works for GLTF 2.0 files.
85
+ * @param {THREE.DracoLoader} dracoLoader - the threejs DracoLoader instance.
86
+ */
87
+ setDRACOLoader(dracoLoader) {
88
+ this.glTFLoader.setDRACOLoader(dracoLoader);
89
+ }
90
+
91
+ /**
92
+ * Sets the KTX2 loader instance for this gltf parser. Enable loading files with
93
+ * [KTX2](https://www.khronos.org/ktx/) texture extension. See Threejs
94
+ * [KTX2Loader](https://threejs.org/docs/index.html?q=KTX2#examples/en/loaders/KTX2Loader) for more information.
95
+ * Only works for GLTF 2.0 files.
96
+ * @param {THREE.KTX2Loader} ktx2Loader - the threejs KTX2Loader instance.
97
+ */
98
+ setKTX2Loader(ktx2Loader) {
99
+ this.glTFLoader.setKTX2Loader(ktx2Loader);
100
+ }
101
+
102
+ /**
103
+ * Sets the Mesh Optimizer decoder instance for this gltf parser. Enable loading files with
104
+ * [MeshOptimizer](https://meshoptimizer.org/) geometry extension.
105
+ * Only works for GLTF 2.0 files.
106
+ * @param {Object} meshoptDecoder - the threejs meshopt decoder instance.
107
+ */
108
+ setMeshoptDecoder(meshoptDecoder) {
109
+ this.glTFLoader.setMeshoptDecoder(meshoptDecoder);
110
+ }
111
+
112
+ /**
113
+ * Registers a callback to load specific unknown or not standard GLTF extensions.
114
+ * See Threejs [GltfLoader](https://threejs.org/docs/?q=gltflo#examples/en/loaders/GLTFLoader) for more
115
+ * information.
116
+ * @param {Function} callback - the callback function
117
+ */
118
+ register(callback) {
119
+ this.glTFLoader.register(callback);
120
+ }
121
+
122
+ /**
123
+ * Unregisters a load callback.
124
+ * See Threejs [GltfLoader](https://threejs.org/docs/?q=gltflo#examples/en/loaders/GLTFLoader) for more
125
+ * information.
126
+ * @param {Function} callback - the callback function
127
+ */
128
+ unregister(callback) {
129
+ this.glTFLoader.unregister(callback);
130
+ }
131
+
132
+ /** Parse a glTF-based ArrayBuffer, JSON string or object and fire onLoad callback when complete.
133
+ * Calls Threejs [GLTFLoader.parse](https://threejs.org/docs/?q=gltflo#examples/en/loaders/GLTFLoader.parse) for
134
+ * glTF 2.0 files and LegacyGLTFLoader.parse for gtTF 1.0 files.
135
+ * @param {ArrayBuffer|String|Object} buffer - the glTF asset to parse, as an ArrayBuffer, JSON string or object.
136
+ * @param {String} path - the base path from which to find subsequent glTF resources such as textures and .bin data files.
137
+ * @param {Function} onLoad — A function to be called when parse completes. The argument to the onLoad function will
138
+ * be an Object that contains loaded parts: .scene, .scenes, .cameras, .animations, and .asset.
139
+ * @param {Function} [onError] — A function to be called if an error occurs during parsing. The function receives error as an argument.
140
+ */
141
+ parse(buffer, path, onLoad, onError) {
142
+ if (!buffer || !path) {
143
+ onError('[iGLTFLoader]: Buffer and path are mandatory to parse a glTF.');
144
+ return;
145
+ }
146
+ const headerView = new DataView(buffer, 0, 20);
147
+ const version = headerView.getUint32(4, true);
148
+ if (version === 1) {
149
+ this.legacyGLTFLoader.parse(buffer, path, onLoad, onError);
150
+ } else {
151
+ this.glTFLoader.parse(buffer, path, onLoad, onError);
152
+ }
153
+ }
154
+
155
+ /**
156
+ * Async promise-based parsing of a glTF-based ArrayBuffer, JSON string or object.
157
+ * @param {ArrayBuffer|String|Object} data - the glTF asset to parse, as an ArrayBuffer, JSON string or object.
158
+ * @param {String} path - the base path from which to find subsequent glTF resources such as textures and .bin data files.
159
+ * @returns {Promise<Object>} A promise that resolves an Object that contains loaded parts:
160
+ * .scene, .scenes, .cameras, .animations, and .asset, when parsing is done.
161
+ */
162
+ parseAsync(data, path) {
163
+ const scope = this;
164
+ return new Promise((resolve, reject) => {
165
+ scope.parse(data, path, resolve, reject);
166
+ });
167
+ }
168
+ }
169
+ export default iGLTFLoader;
@@ -160,10 +160,11 @@ function cleanup3dTileset(layer, n) {
160
160
  }
161
161
 
162
162
  // this is a layer
163
- export function pre3dTilesUpdate() {
163
+ export function pre3dTilesUpdate(context) {
164
164
  if (!this.visible) {
165
165
  return [];
166
166
  }
167
+ this.scale = context.camera._preSSE;
167
168
 
168
169
  // Elements removed are added in the layer._cleanableTiles list.
169
170
  // Since we simply push in this array, the first item is always
@@ -1,10 +1,12 @@
1
1
  import * as THREE from 'three';
2
2
  import B3dmParser from "../Parser/B3dmParser.js";
3
3
  import PntsParser from "../Parser/PntsParser.js";
4
- import GLTFParser from "../Parser/GLTFParser.js";
5
4
  import Fetcher from "./Fetcher.js";
6
5
  import ReferLayerProperties from "../Layer/ReferencingLayerProperties.js";
7
6
  import PointsMaterial from "../Renderer/PointsMaterial.js";
7
+ // A bit weird but temporary until we remove this deprecated provider. Mainly to benefit from the enableDracoLoader and enableKtx2Loader
8
+ // methods.
9
+ import { itownsGLTFLoader } from "../Layer/OGC3DTilesLayer.js";
8
10
  const utf8Decoder = new TextDecoder();
9
11
  function b3dmToMesh(data, layer, url) {
10
12
  const urlBase = THREE.LoaderUtils.extractUrlBase(url);
@@ -28,17 +30,17 @@ function b3dmToMesh(data, layer, url) {
28
30
  }
29
31
  function gltfToMesh(data, layer, url) {
30
32
  const urlBase = THREE.LoaderUtils.extractUrlBase(url);
31
- return GLTFParser.parse(data, urlBase).then(result => ({
33
+ return itownsGLTFLoader.parseAsync(data, urlBase).then(result => ({
32
34
  object3d: result.scene
33
35
  }));
34
36
  }
35
37
  function pntsParse(data, layer) {
36
38
  return PntsParser.parse(data, layer.registeredExtensions).then(result => {
37
39
  const material = layer.material ? layer.material.clone() : new PointsMaterial({
38
- size: 0.05,
40
+ size: 1,
39
41
  mode: layer.pntsMode,
40
42
  shape: layer.pntsShape,
41
- classification: layer.classification,
43
+ classificationScheme: layer.classification,
42
44
  sizeMode: layer.pntsSizeMode,
43
45
  minAttenuatedSize: layer.pntsMinAttenuatedSize,
44
46
  maxAttenuatedSize: layer.pntsMaxAttenuatedSize