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
@@ -1,9 +1,8 @@
1
1
  import * as THREE from 'three';
2
2
  /* babel-plugin-inline-import './Shader/PointsVS.glsl' */
3
- const PointsVS = "#include <itowns/precision_qualifier>\n#if defined(USE_TEXTURES_PROJECTIVE)\n#include <itowns/projective_texturing_pars_vertex>\n#endif\n#include <common>\n#include <logdepthbuf_pars_vertex>\n\n#define NB_CLASS 8.\n\nuniform float size;\nuniform float scale;\n\nuniform bool picking;\nuniform int mode;\nuniform float opacity;\nuniform vec4 overlayColor;\n\nuniform vec2 elevationRange;\nuniform vec2 intensityRange;\nuniform vec2 angleRange;\n\nuniform sampler2D classificationTexture;\nuniform sampler2D discreteTexture;\nuniform sampler2D gradientTexture;\nuniform int sizeMode;\nuniform float minAttenuatedSize;\nuniform float maxAttenuatedSize;\n\nattribute vec3 color;\nattribute vec2 range;\nattribute vec4 unique_id;\nattribute float intensity;\nattribute float classification;\nattribute float pointSourceID;\n\nattribute float returnNumber;\nattribute float numberOfReturns;\nattribute float scanAngle;\n\n#if defined(NORMAL_OCT16)\nattribute vec2 oct16Normal;\n#elif defined(NORMAL_SPHEREMAPPED)\nattribute vec2 sphereMappedNormal;\n#endif\n\nvarying vec4 vColor;\n\n// see https://web.archive.org/web/20150303053317/http://lgdv.cs.fau.de/get/1602\n// and implementation in PotreeConverter (BINPointReader.cpp) and potree (BinaryDecoderWorker.js)\n#if defined(NORMAL_OCT16)\nvec3 decodeOct16Normal(vec2 encodedNormal) {\n vec2 nNorm = 2. * (encodedNormal / 255.) - 1.;\n vec3 n;\n n.z = 1. - abs(nNorm.x) - abs(nNorm.y);\n if (n.z >= 0.) {\n n.x = nNorm.x;\n n.y = nNorm.y;\n } else {\n n.x = sign(nNorm.x) - sign(nNorm.x) * sign(nNorm.y) * nNorm.y;\n n.y = sign(nNorm.y) - sign(nNorm.y) * sign(nNorm.x) * nNorm.x;\n }\n return normalize(n);\n}\n#elif defined(NORMAL_SPHEREMAPPED)\n// see http://aras-p.info/texts/CompactNormalStorage.html method #4\n// or see potree's implementation in BINPointReader.cpp\nvec3 decodeSphereMappedNormal(vec2 encodedNormal) {\n vec2 fenc = 2. * encodedNormal / 255. - 1.;\n float f = dot(fenc,fenc);\n float g = 2. * sqrt(1. - f);\n vec3 n;\n n.xy = fenc * g;\n n.z = 1. - 2. * f;\n return n;\n}\n#endif\n\nvoid main() {\n\n#if defined(NORMAL_OCT16)\n vec3 normal = decodeOct16Normal(oct16Normal);\n#elif defined(NORMAL_SPHEREMAPPED)\n vec3 normal = decodeSphereMappedNormal(sphereMappedNormal);\n#elif defined(NORMAL)\n // nothing to do\n#else\n // default to color\n vec3 normal = color;\n#endif\n\n if (picking) {\n vColor = unique_id;\n } else {\n vColor.a = 1.0;\n if (mode == PNTS_MODE_CLASSIFICATION) {\n vec2 uv = vec2(classification/255., 0.5);\n vColor = texture2D(classificationTexture, uv);\n } else if (mode == PNTS_MODE_NORMAL) {\n vColor.rgb = abs(normal);\n } else if (mode == PNTS_MODE_COLOR) {\n // default to color mode\n vColor.rgb = mix(color, overlayColor.rgb, overlayColor.a);\n } else if (mode == PNTS_MODE_RETURN_NUMBER) {\n vec2 uv = vec2(returnNumber/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_RETURN_TYPE) {\n float returnType;\n if (returnNumber > numberOfReturns) {\n returnType = 4.;\n } else if (returnNumber == 1.) {\n if (numberOfReturns == 1.) {\n // single\n returnType = 0.;\n } else {\n // first\n returnType = 1.;\n }\n } else {\n if (returnNumber == numberOfReturns) {\n // last\n returnType = 3.;\n } else {\n // intermediate\n returnType = 2.;\n }\n }\n vec2 uv = vec2(returnType/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_RETURN_COUNT) {\n vec2 uv = vec2(numberOfReturns/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_POINT_SOURCE_ID) {\n vec2 uv = vec2(mod(pointSourceID, NB_CLASS)/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_SCAN_ANGLE) {\n float i = (scanAngle - angleRange.x) / (angleRange.y - angleRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n } else if (mode == PNTS_MODE_INTENSITY) {\n float i = (intensity - intensityRange.x) / (intensityRange.y - intensityRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n } else if (mode == PNTS_MODE_ELEVATION) {\n float i = (position.z - elevationRange.x) / (elevationRange.y - elevationRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n }\n\n vColor.a *= opacity;\n }\n\n #include <begin_vertex>\n #include <project_vertex>\n\n gl_PointSize = size;\n\n if (sizeMode == PNTS_SIZE_MODE_ATTENUATED) {\n bool isPerspective = isPerspectiveMatrix(projectionMatrix);\n\n if (isPerspective) {\n gl_PointSize *= scale / -mvPosition.z;\n gl_PointSize = clamp(gl_PointSize, minAttenuatedSize, maxAttenuatedSize);\n }\n }\n\n#if defined(USE_TEXTURES_PROJECTIVE)\n #include <itowns/projective_texturing_vertex>\n#endif\n #include <logdepthbuf_vertex>\n}\n";
3
+ const PointsVS = "#include <common>\n#include <fog_pars_vertex>\n#include <morphtarget_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#include <clipping_planes_pars_vertex>\nvarying vec4 vColor; // color_pars_vertex\n\n#ifdef USE_POINTS_UV\n varying vec2 vUv;\n uniform mat3 uvTransform;\n#endif\n\n#define NB_CLASS 8.\n\nuniform float size;\nuniform float scale;\n\nuniform bool picking;\nuniform int mode;\n\nuniform vec2 elevationRange;\nuniform vec2 intensityRange;\nuniform vec2 angleRange;\n\nuniform sampler2D classificationTexture;\nuniform sampler2D discreteTexture;\nuniform sampler2D gradientTexture;\nuniform int sizeMode;\nuniform float minAttenuatedSize;\nuniform float maxAttenuatedSize;\n\nattribute vec4 unique_id;\nattribute float intensity;\nattribute float classification;\nattribute float pointSourceID;\n\nattribute float returnNumber;\nattribute float numberOfReturns;\nattribute float scanAngle;\n\nvoid main() {\n vColor = vec4(1.0);\n if (picking) {\n vColor = unique_id;\n } else {\n if (mode == PNTS_MODE_CLASSIFICATION) {\n vec2 uv = vec2(classification/255., 0.5);\n vColor = texture2D(classificationTexture, uv);\n } else if (mode == PNTS_MODE_NORMAL) {\n vColor.rgb = abs(normal);\n } else if (mode == PNTS_MODE_COLOR) {\n#if defined(USE_COLOR)\n vColor.rgb = color.rgb;\n#elif defined(USE_COLOR_ALPHA)\n vColor = color;\n#endif\n } else if (mode == PNTS_MODE_RETURN_NUMBER) {\n vec2 uv = vec2(returnNumber/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_RETURN_TYPE) {\n float returnType;\n if (returnNumber > numberOfReturns) {\n returnType = 4.;\n } else if (returnNumber == 1.) {\n if (numberOfReturns == 1.) {\n // single\n returnType = 0.;\n } else {\n // first\n returnType = 1.;\n }\n } else {\n if (returnNumber == numberOfReturns) {\n // last\n returnType = 3.;\n } else {\n // intermediate\n returnType = 2.;\n }\n }\n vec2 uv = vec2(returnType/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_RETURN_COUNT) {\n vec2 uv = vec2(numberOfReturns/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_POINT_SOURCE_ID) {\n vec2 uv = vec2(mod(pointSourceID, NB_CLASS)/255., 0.5);\n vColor = texture2D(discreteTexture, uv);\n } else if (mode == PNTS_MODE_SCAN_ANGLE) {\n float i = (scanAngle - angleRange.x) / (angleRange.y - angleRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n } else if (mode == PNTS_MODE_INTENSITY) {\n float i = (intensity - intensityRange.x) / (intensityRange.y - intensityRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n } else if (mode == PNTS_MODE_ELEVATION) {\n float z = (modelMatrix * vec4(position, 1.0)).z;\n float i = (z - elevationRange.x) / (elevationRange.y - elevationRange.x);\n vec2 uv = vec2(i, (1. - i));\n vColor = texture2D(gradientTexture, uv);\n }\n }\n\n#define USE_COLOR_ALPHA\n#include <morphcolor_vertex>\n#include <begin_vertex>\n#include <morphtarget_vertex>\n#include <project_vertex>\n\n gl_PointSize = size;\n\n if (sizeMode == PNTS_SIZE_MODE_ATTENUATED) {\n bool isPerspective = isPerspectiveMatrix(projectionMatrix);\n\n if (isPerspective) {\n gl_PointSize *= scale / -mvPosition.z;\n gl_PointSize = clamp(gl_PointSize, minAttenuatedSize, maxAttenuatedSize);\n }\n }\n\n#include <logdepthbuf_vertex>\n#include <clipping_planes_vertex>\n#include <worldpos_vertex>\n#include <fog_vertex>\n}\n";
4
4
  /* babel-plugin-inline-import './Shader/PointsFS.glsl' */
5
- const PointsFS = "#include <itowns/precision_qualifier>\n#include <logdepthbuf_pars_fragment>\n#if defined(USE_TEXTURES_PROJECTIVE)\n#include <itowns/projective_texturing_pars_fragment>\n#endif\n\nvarying vec4 vColor;\nuniform bool picking;\nuniform int shape;\n\nvoid main() {\n #include <logdepthbuf_fragment>\n //square shape does not require any change.\n if (shape == PNTS_SHAPE_CIRCLE) {\n //circular rendering in glsl\n if ((length(gl_PointCoord - 0.5) > 0.5) || (vColor.a == 0.0)) {\n discard;\n }\n }\n\n#if defined(USE_TEXTURES_PROJECTIVE)\n vec4 color = vColor;\n if (!picking) {\n #pragma unroll_loop\n for (int i = 0; i < ORIENTED_IMAGES_COUNT; i++) {\n color = projectiveTextureColor(projectiveTextureCoords[ ORIENTED_IMAGES_COUNT - 1 - i ], projectiveTextureDistortion[ ORIENTED_IMAGES_COUNT - 1 - i ], projectiveTexture[ ORIENTED_IMAGES_COUNT - 1 - i ], mask[ORIENTED_IMAGES_COUNT - 1 - i], color);\n }\n gl_FragColor = vec4(color.rgb, color.a * opacity);\n } else {\n gl_FragColor = color;\n }\n#else\n gl_FragColor = vColor;\n#endif\n}\n";
6
- import ShaderUtils from "./Shader/ShaderUtils.js";
5
+ const PointsFS = "#define USE_COLOR_ALPHA\n\n#include <color_pars_fragment>\n#include <map_particle_pars_fragment>\n#include <alphatest_pars_fragment>\n#include <alphahash_pars_fragment>\n#include <fog_pars_fragment>\n#include <logdepthbuf_pars_fragment>\n#include <clipping_planes_pars_fragment>\n\nuniform vec3 diffuse;\nuniform float opacity;\n\nuniform bool picking;\nuniform int shape;\n\nvoid main() {\n\n// Early discard (clipping planes and shape)\n#include <clipping_planes_pars_fragment>\n if (shape == PNTS_SHAPE_CIRCLE) {\n //circular rendering in glsl\n if ((length(gl_PointCoord - 0.5) > 0.5)) {\n discard;\n }\n }\n\n#include <logdepthbuf_fragment>\n\n vec4 diffuseColor = vec4(diffuse, opacity);\n#include <map_particle_fragment>\n#include <color_fragment>\n\n#include <alphatest_fragment>\n#include <alphahash_fragment>\n\n vec3 outgoingLight = diffuseColor.rgb;\n#include <opaque_fragment> // gl_FragColor\n#include <tonemapping_fragment>\n#include <fog_fragment>\n#include <premultiplied_alpha_fragment>\n\n}\n";
7
6
  import CommonMaterial from "./CommonMaterial.js";
8
7
  import Gradients from "../Utils/Gradients.js";
9
8
  export const PNTS_MODE = {
@@ -251,7 +250,7 @@ function recomputeTexture(scheme, texture, nbClass) {
251
250
  data[j + 1] = parseInt(255 * color.g, 10);
252
251
  data[j + 2] = parseInt(255 * color.b, 10);
253
252
  data[j + 3] = visible ? parseInt(255 * opacity, 10) : 0;
254
- needTransparency = needTransparency || opacity < 1;
253
+ needTransparency = needTransparency || opacity < 1 || !visible;
255
254
  }
256
255
  texture.needsUpdate = true;
257
256
  return needTransparency;
@@ -262,12 +261,12 @@ class PointsMaterial extends THREE.ShaderMaterial {
262
261
  * @param {object} [options={}] The options
263
262
  * @param {number} [options.size=0] size point
264
263
  * @param {number} [options.mode=PNTS_MODE.COLOR] display mode.
265
- * @param {number} [options.mode=PNTS_SHAPE.CIRCLE] rendered points shape.
264
+ * @param {number} [options.shape=PNTS_SHAPE.CIRCLE] rendered points shape.
266
265
  * @param {THREE.Vector4} [options.overlayColor=new THREE.Vector4(0, 0, 0, 0)] overlay color.
267
266
  * @param {THREE.Vector2} [options.intensityRange=new THREE.Vector2(1, 65536)] intensity range.
268
267
  * @param {THREE.Vector2} [options.elevationRange=new THREE.Vector2(0, 1000)] elevation range.
269
268
  * @param {THREE.Vector2} [options.angleRange=new THREE.Vector2(-90, 90)] scan angle range.
270
- * @param {Scheme} [options.classification] LUT for point classification colorization.
269
+ * @param {Scheme} [options.classificationScheme] LUT for point classification colorization.
271
270
  * @param {Scheme} [options.discreteScheme] LUT for other discret point values colorization.
272
271
  * @param {string} [options.gradient] Descrition of the gradient to use for continuous point values.
273
272
  * (Default value will be the 'SPECTRAL' gradient from Utils/Gradients)
@@ -289,54 +288,49 @@ class PointsMaterial extends THREE.ShaderMaterial {
289
288
  */
290
289
  constructor() {
291
290
  let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
292
- const intensityRange = options.intensityRange || new THREE.Vector2(1, 65536);
293
- const elevationRange = options.elevationRange || new THREE.Vector2(0, 1000);
294
- const angleRange = options.angleRange || new THREE.Vector2(-90, 90);
295
- const oiMaterial = options.orientedImageMaterial;
296
- const classificationScheme = options.classification || ClassificationScheme.DEFAULT;
297
- const discreteScheme = options.discreteScheme || DiscreteScheme.DEFAULT;
298
- const size = options.size || 0;
299
- const mode = options.mode || PNTS_MODE.COLOR;
300
- const shape = options.shape || PNTS_SHAPE.CIRCLE;
301
- const sizeMode = size === 0 ? PNTS_SIZE_MODE.ATTENUATED : options.sizeMode || PNTS_SIZE_MODE.VALUE;
302
- const minAttenuatedSize = options.minAttenuatedSize || 3;
303
- const maxAttenuatedSize = options.maxAttenuatedSize || 10;
304
- let gradients = Gradients;
305
- if (options.gradient) {
306
- gradients = {
307
- ...options.gradient,
308
- ...Gradients
309
- };
310
- }
311
- delete options.intensityRange;
312
- delete options.elevationRange;
313
- delete options.angleRange;
314
- delete options.orientedImageMaterial;
315
- delete options.classification;
316
- delete options.discreteScheme;
317
- delete options.size;
318
- delete options.mode;
319
- delete options.shape;
320
- delete options.sizeMode;
321
- delete options.minAttenuatedSize;
322
- delete options.maxAttenuatedSize;
323
- delete options.gradient;
324
- super(options);
291
+ const gradients = {
292
+ ...options.gradient,
293
+ ...Gradients
294
+ };
295
+ options.gradient = Object.values(gradients)[0];
296
+ const {
297
+ intensityRange = new THREE.Vector2(1, 65536),
298
+ elevationRange = new THREE.Vector2(0, 1000),
299
+ angleRange = new THREE.Vector2(-90, 90),
300
+ classificationScheme = ClassificationScheme.DEFAULT,
301
+ discreteScheme = DiscreteScheme.DEFAULT,
302
+ size = 1,
303
+ mode = PNTS_MODE.COLOR,
304
+ shape = PNTS_SHAPE.CIRCLE,
305
+ sizeMode = PNTS_SIZE_MODE.ATTENUATED,
306
+ minAttenuatedSize = 3,
307
+ maxAttenuatedSize = 10,
308
+ gradient,
309
+ scale = 0.05 * 0.5 / Math.tan(1.0 / 2.0),
310
+ ...materialOptions
311
+ } = options;
312
+ super({
313
+ ...materialOptions,
314
+ fog: true,
315
+ precision: 'highp',
316
+ vertexColors: true
317
+ });
318
+ this.uniforms = THREE.UniformsUtils.merge([
319
+ // THREE.PointsMaterial uniforms
320
+ THREE.UniformsLib.points, THREE.UniformsLib.fog]);
321
+ this.vertexShader = PointsVS;
322
+ this.fragmentShader = PointsFS;
325
323
  this.userData.needTransparency = {};
326
324
  this.gradients = gradients;
327
325
  this.gradientTexture = new THREE.CanvasTexture();
328
- this.vertexShader = PointsVS;
329
- const scale = options.scale || 0.05 * 0.5 / Math.tan(1.0 / 2.0); // autosizing scale
330
-
331
326
  CommonMaterial.setDefineMapping(this, 'PNTS_MODE', PNTS_MODE);
332
327
  CommonMaterial.setDefineMapping(this, 'PNTS_SHAPE', PNTS_SHAPE);
333
328
  CommonMaterial.setDefineMapping(this, 'PNTS_SIZE_MODE', PNTS_SIZE_MODE);
334
- CommonMaterial.setUniformProperty(this, 'size', size);
329
+ this.size = size;
335
330
  CommonMaterial.setUniformProperty(this, 'mode', mode);
336
331
  CommonMaterial.setUniformProperty(this, 'shape', shape);
337
332
  CommonMaterial.setUniformProperty(this, 'picking', false);
338
333
  CommonMaterial.setUniformProperty(this, 'opacity', this.opacity);
339
- CommonMaterial.setUniformProperty(this, 'overlayColor', options.overlayColor || new THREE.Vector4(0, 0, 0, 0));
340
334
  CommonMaterial.setUniformProperty(this, 'intensityRange', intensityRange);
341
335
  CommonMaterial.setUniformProperty(this, 'elevationRange', elevationRange);
342
336
  CommonMaterial.setUniformProperty(this, 'angleRange', angleRange);
@@ -368,26 +362,99 @@ class PointsMaterial extends THREE.ShaderMaterial {
368
362
  this.recomputeDiscreteTexture();
369
363
 
370
364
  // Gradient texture for continuous values
371
- this.gradient = Object.values(gradients)[0];
365
+ this.gradient = gradient;
372
366
  CommonMaterial.setUniformProperty(this, 'gradientTexture', this.gradientTexture);
373
- if (oiMaterial) {
374
- this.uniforms.projectiveTextureAlphaBorder = oiMaterial.uniforms.projectiveTextureAlphaBorder;
375
- this.uniforms.projectiveTextureDistortion = oiMaterial.uniforms.projectiveTextureDistortion;
376
- this.uniforms.projectiveTextureMatrix = oiMaterial.uniforms.projectiveTextureMatrix;
377
- this.uniforms.projectiveTexture = oiMaterial.uniforms.projectiveTexture;
378
- this.uniforms.mask = oiMaterial.uniforms.mask;
379
- this.uniforms.boostLight = oiMaterial.uniforms.boostLight;
380
- this.defines.ORIENTED_IMAGES_COUNT = oiMaterial.defines.ORIENTED_IMAGES_COUNT;
381
- this.defines.USE_DISTORTION = oiMaterial.defines.USE_DISTORTION;
382
- this.defines.DEBUG_ALPHA_BORDER = oiMaterial.defines.DEBUG_ALPHA_BORDER;
383
- this.defines.USE_TEXTURES_PROJECTIVE = true;
384
- this.defines.USE_BASE_MATERIAL = true;
385
- // three loop unrolling of ShaderMaterial only supports integer
386
- // bounds, see https://github.com/mrdoob/three.js/issues/28020
387
- this.fragmentShader = ShaderUtils.unrollLoops(PointsFS, this.defines);
367
+ }
368
+
369
+ /**
370
+ * Copy the parameters from the passed material into this material.
371
+ * @override
372
+ * @param {THREE.PointsMaterial} source
373
+ * @returns {this}
374
+ */
375
+ copy(source) {
376
+ // Manually copy this needTransparency if source doesn't have one. Prevents losing it when copying a three
377
+ // PointsMaterial into this PointsMaterial
378
+ const needTransparency = source.userData.needTransparency !== undefined ? source.userData.needTransparency : this.userData.needTransparency;
379
+ if (source.isShaderMaterial) {
380
+ super.copy(source);
388
381
  } else {
389
- this.fragmentShader = PointsFS;
382
+ THREE.Material.prototype.copy.call(this, source);
383
+ }
384
+
385
+ // Parameters of THREE.PointsMaterial
386
+ this.color.copy(source.color);
387
+ this.map = source.map;
388
+ this.alphaMap = source.alphaMap;
389
+ this.size = source.size;
390
+ this.sizeAttenuation = source.sizeAttenuation;
391
+ this.fog = source.fog;
392
+ this.userData.needTransparency = needTransparency;
393
+ return this;
394
+ }
395
+
396
+ /** @returns {THREE.Color} */
397
+ get color() {
398
+ return this.uniforms.diffuse.value;
399
+ }
400
+
401
+ /** @param {THREE.Color} color */
402
+ set color(color) {
403
+ this.uniforms.diffuse.value.copy(color);
404
+ }
405
+
406
+ /** @returns {THREE.Texture | null} */
407
+ get map() {
408
+ return this.uniforms.map.value;
409
+ }
410
+
411
+ /** @param {THREE.Texture | null} map */
412
+ set map(map) {
413
+ this.uniforms.map.value = map;
414
+ if (!map) {
415
+ return;
390
416
  }
417
+ if (map.matrixAutoUpdate) {
418
+ map.updateMatrix();
419
+ }
420
+ this.uniforms.uvTransform.value.copy(map.matrix);
421
+ }
422
+
423
+ /** @returns {THREE.Texture | null} */
424
+ get alphaMap() {
425
+ return this.uniforms.alphaMap.value;
426
+ }
427
+
428
+ /** @param {THREE.Texture | null} map */
429
+ set alphaMap(map) {
430
+ this.uniforms.alphaMap.value = map;
431
+ if (!map) {
432
+ return;
433
+ }
434
+ if (map.matrixAutoUpdate) {
435
+ map.updateMatrix();
436
+ }
437
+ this.uniforms.alphaMapTransform.value.copy(map.matrix);
438
+ }
439
+
440
+ /** @returns {number} */
441
+ get size() {
442
+ return this.uniforms.size.value;
443
+ }
444
+
445
+ /** @param {number} size */
446
+ set size(size) {
447
+ this.uniforms.size.value = size;
448
+ }
449
+
450
+ /** @returns {boolean} */
451
+ get sizeAttenuation() {
452
+ return this.sizeMode !== PNTS_SIZE_MODE.VALUE;
453
+ }
454
+
455
+ /** @param {boolean} value */
456
+ set sizeAttenuation(value) {
457
+ this.sizeMode = value ? PNTS_SIZE_MODE.ATTENUATED : PNTS_SIZE_MODE.VALUE;
391
458
  }
392
459
  recomputeClassification() {
393
460
  const needTransparency = recomputeTexture(this.classificationScheme, this.classificationTexture, 256);
@@ -408,43 +475,10 @@ class PointsMaterial extends THREE.ShaderMaterial {
408
475
  target: this.uniforms
409
476
  });
410
477
  }
411
- copy(source) {
412
- super.copy(source);
413
- if (source.uniforms.projectiveTextureAlphaBorder) {
414
- // Don't copy oriented image because, it's a link to oriented image material.
415
- // It needs a reference to oriented image material.
416
- this.uniforms.projectiveTextureAlphaBorder = source.uniforms.projectiveTextureAlphaBorder;
417
- this.uniforms.projectiveTextureDistortion = source.uniforms.projectiveTextureDistortion;
418
- this.uniforms.projectiveTextureMatrix = source.uniforms.projectiveTextureMatrix;
419
- this.uniforms.projectiveTexture = source.uniforms.projectiveTexture;
420
- this.uniforms.mask = source.uniforms.mask;
421
- this.uniforms.boostLight = source.uniforms.boostLight;
422
- }
423
- return this;
424
- }
425
478
  enablePicking(picking) {
426
479
  this.picking = picking;
427
480
  this.blending = picking ? THREE.NoBlending : THREE.NormalBlending;
428
481
  }
429
- update(source) {
430
- this.visible = source.visible;
431
- this.opacity = source.opacity;
432
- this.transparent = source.transparent;
433
- this.size = source.size;
434
- this.mode = source.mode;
435
- this.shape = source.shape;
436
- this.sizeMode = source.sizeMode;
437
- this.minAttenuatedSize = source.minAttenuatedSize;
438
- this.maxAttenuatedSize = source.maxAttenuatedSize;
439
- this.picking = source.picking;
440
- this.scale = source.scale;
441
- this.overlayColor.copy(source.overlayColor);
442
- this.intensityRange.copy(source.intensityRange);
443
- this.elevationRange.copy(source.elevationRange);
444
- this.angleRange.copy(source.angleRange);
445
- Object.assign(this.defines, source.defines);
446
- return this;
447
- }
448
482
  set gradient(value) {
449
483
  this.gradientTexture = generateGradientTexture(value);
450
484
  }
@@ -130,7 +130,7 @@ class FileSource extends Source {
130
130
  }
131
131
 
132
132
  // the fake url is for when we use the fetchedData or features mode
133
- source.url = source.url || 'fake-file-url';
133
+ source.url = source.url || 'none';
134
134
  super(source);
135
135
  this.isFileSource = true;
136
136
  this.fetchedData = source.fetchedData;
@@ -0,0 +1,32 @@
1
+ import OGC3DTilesSource from "./OGC3DTilesSource.js";
2
+ class OGC3DTilesGoogleSource extends OGC3DTilesSource {
3
+ /**
4
+ * @classdesc
5
+ * An object defining the source connection to a 3D Tiles asset from [Google Tiles API](https://tile.googleapis.com).
6
+ *
7
+ * @extends OGC3DTilesSource
8
+ *
9
+ * @property {boolean} isOGC3DTilesGoogleSource - Used to check if this source is an OGC3DTilesGoogleSource. Set to true.
10
+ * You should not change this, as it is used internally for optimisation.
11
+ * @property {string} url - The URL to the tileset json.
12
+ * @property {string} baseUrl - The base URL to access tiles.
13
+ *
14
+ * @constructor
15
+ *
16
+ * @property {boolean} isOGC3DTilesGoogleSource - Used to check if this source is an OGC3DTilesGoogleSource. Set to
17
+ * true. You should not change this, as it is used internally for optimisation.
18
+ * @param {Object} source An object that can contain all properties of an OGC3DTilesGoogleSource and {@link Source}.
19
+ * @param {String} source.key Your google tiles map API access key
20
+ */
21
+ constructor(source) {
22
+ if (!source.key) {
23
+ throw new Error('[OGC3DTilesGoogleSource]: A API key for the google map tiles API is required');
24
+ }
25
+ // URL to the root tileset
26
+ source.url = `https://tile.googleapis.com/v1/3dtiles/root.json?key=${source.key}`;
27
+ super(source);
28
+ this.isOGC3DTilesGoogleSource = true;
29
+ this.key = source.key;
30
+ }
31
+ }
32
+ export default OGC3DTilesGoogleSource;
@@ -0,0 +1,37 @@
1
+ import OGC3DTilesSource from "./OGC3DTilesSource.js";
2
+ class OGC3DTilesIonSource extends OGC3DTilesSource {
3
+ /**
4
+ * @classdesc
5
+ * An object defining the source connection to a 3DTiles asset of a [Cesium ion server](https://cesium.com/learn/ion/).
6
+ *
7
+ * @extends Source
8
+ *
9
+ * @property {boolean} isOGC3DTilesIonSource - Used to check if this source is an OGC3DTilesIonSource. Set to true.
10
+ * You should not change this, as it is used internally for optimisation.
11
+ * @property {string} accessToken - The Cesium ion access token used to retrieve the resource.
12
+ * @property {string} assetId - The id of the asset on Cesium ion.
13
+ *
14
+ * @constructor
15
+ *
16
+ * @param {Object} source An object that can contain all properties of an OGC3DTilesIonSource and {@link Source}.
17
+ * Only `accessToken` and `assetId` are mandatory.
18
+ * @param {string} source.accessToken - The Cesium ion access token used to retrieve the resource.
19
+ * @param {string} source.assetId - The id of the asset on Cesium ion.
20
+ */
21
+ constructor(source) {
22
+ if (!source.accessToken) {
23
+ throw new Error('[OGC3DTilesIonSource]: accessToken is required');
24
+ }
25
+ if (!source.assetId) {
26
+ throw new Error('[OGC3DTilesIonSource]: assetId is required');
27
+ }
28
+
29
+ // Url to query cesium ion the first time to retrieve metadata of the asset with assetId
30
+ source.url = `https://api.cesium.com/v1/assets/${source.assetId}/endpoint?access_token=${source.accessToken}`;
31
+ super(source);
32
+ this.isOGC3DTilesIonSource = true;
33
+ this.accessToken = source.accessToken;
34
+ this.assetId = source.assetId;
35
+ }
36
+ }
37
+ export default OGC3DTilesIonSource;
@@ -0,0 +1,24 @@
1
+ import Source from "./Source.js";
2
+ class OGC3DTilesSource extends Source {
3
+ /**
4
+ * @classdesc
5
+ * An object defining the source connection to a 3DTiles dataset from a web server.
6
+ *
7
+ * @extends Source
8
+ *
9
+ * @property {boolean} isOGC3DTilesSource - Used to check if this source is an isOGC3DTilesSource. Set to true.
10
+ * You should not change this, as it is used internally for optimisation.
11
+ * @property {string} url - The URL of the tileset json.
12
+ *
13
+ * @constructor
14
+ *
15
+ * @param {Object} source An object that can contain all properties of OGC3DTilesSource and of {@link Source}.
16
+ * Only `url` is mandatory.
17
+ * @param {string} source.url - The URL of the tileset json.
18
+ */
19
+ constructor(source) {
20
+ super(source);
21
+ this.isOGC3DTilesSource = true;
22
+ }
23
+ }
24
+ export default OGC3DTilesSource;
@@ -0,0 +1,172 @@
1
+ import Source from "./Source.js";
2
+ import Fetcher from "../Provider/Fetcher.js";
3
+ import Potree2BinParser from "../Parser/Potree2BinParser.js";
4
+
5
+ /**
6
+ * @classdesc
7
+ * Potree2Source are object containing informations on how to fetch potree 2.0 points cloud resources.
8
+ *
9
+ *
10
+ */
11
+
12
+ class Potree2Source extends Source {
13
+ /**
14
+ * @param {Object} source - An object that can contain all properties of a
15
+ * Potree2Source
16
+ * @param {string} source.url - folder url.
17
+ * @param {string} source.file - metadata file name.
18
+ *
19
+ * This `metadata` file stores information about the potree cloud 2.0 in JSON format. the structure is :
20
+ *
21
+ * * __`version`__ - The metadata.json format may change over time. The version number is
22
+ * necessary so that parsers know how to interpret the data.
23
+ * * __`name`__ - Point cloud name.
24
+ * * __`description`__ - Point cloud description.
25
+ * * __`points`__ - Total number of points.
26
+ * * __`projection`__ - Point cloud geographic projection system.
27
+ * * __`hierarchy`__ - Information about point cloud hierarchy (first chunk size, step size, octree depth).
28
+ * * __`offset`__ - Position offset used to determine the global point position.
29
+ * * __`scale`__ - Point cloud scale.
30
+ * * __`spacing`__ - The minimum distance between points at root level.
31
+ * * __`boundingBox`__ - Contains the minimum and maximum of the axis aligned bounding box. This bounding box is cubic and aligned to fit to the octree root.
32
+ * * __`encoding`__ - Encoding type: BROTLI or DEFAULT (uncompressed).
33
+ * * __`attributes`__ - Array of attributes (position, intensity, return number, number of returns, classification, scan angle rank, user data, point source id, gps-time, rgb).
34
+ * ```
35
+ * {
36
+ * version: '2.0',
37
+ * name: "sample",
38
+ * description: "",
39
+ * points: 534909153,
40
+ * projection: "",
41
+ * hierarchy: {
42
+ * firstChunkSize: 1276,
43
+ * stepSize: 4,
44
+ * depth: 16
45
+ * },
46
+ * offset: [1339072.07, 7238866.339, 85.281],
47
+ * scale: [0.001, 0.001, 0.002],
48
+ * spacing: 24.476062500005355,
49
+ * boundingBox: {
50
+ * min: [1339072.07, 7238866.339, 85.281],
51
+ * max: [1342205.0060000008, 7241999.275, 3218.2170000006854]
52
+ * },
53
+ * encoding: "BROTLI",
54
+ * attributes: [
55
+ * {
56
+ * name: "position",
57
+ * description: "",
58
+ * size: 12,
59
+ * numElements: 3,
60
+ * elementSize: 4,
61
+ * type: "int32",
62
+ * min: [-0.74821299314498901, -2.7804059982299805, 2.5478212833404541],
63
+ * max: [2.4514148223438199, 1.4893437627414672, 7.1957106576508663]
64
+ * },
65
+ * {
66
+ * name: "intensity",
67
+ * description: "",
68
+ * size: 2,
69
+ * numElements: 1,
70
+ * elementSize: 2,
71
+ * type: "uint16",
72
+ * min: [0],
73
+ * max: [0]
74
+ * },{
75
+ * name: "return number",
76
+ * description: "",
77
+ * size: 1,
78
+ * numElements: 1,
79
+ * elementSize: 1,
80
+ * type: "uint8",
81
+ * min: [0],
82
+ * max: [0]
83
+ * },{
84
+ * name: "number of returns",
85
+ * description: "",
86
+ * size: 1,
87
+ * numElements: 1,
88
+ * elementSize: 1,
89
+ * type: "uint8",
90
+ * min: [0],
91
+ * max: [0]
92
+ * },{
93
+ * name: "classification",
94
+ * description: "",
95
+ * size: 1,
96
+ * numElements: 1,
97
+ * elementSize: 1,
98
+ * type: "uint8",
99
+ * min: [0],
100
+ * max: [0]
101
+ * },{
102
+ * name: "scan angle rank",
103
+ * description: "",
104
+ * size: 1,
105
+ * numElements: 1,
106
+ * elementSize: 1,
107
+ * type: "uint8",
108
+ * min: [0],
109
+ * max: [0]
110
+ * },{
111
+ * name: "user data",
112
+ * description: "",
113
+ * size: 1,
114
+ * numElements: 1,
115
+ * elementSize: 1,
116
+ * type: "uint8",
117
+ * min: [0],
118
+ * max: [0]
119
+ * },{
120
+ * name: "point source id",
121
+ * description: "",
122
+ * size: 2,
123
+ * numElements: 1,
124
+ * elementSize: 2,
125
+ * type: "uint16",
126
+ * min: [0],
127
+ * max: [0]
128
+ * },{
129
+ * name: "gps-time",
130
+ * description: "",
131
+ * size: 8,
132
+ * numElements: 1,
133
+ * elementSize: 8,
134
+ * type: "double",
135
+ * min: [0],
136
+ * max: [0]
137
+ * },{
138
+ * name: "rgb",
139
+ * description: "",
140
+ * size: 6,
141
+ * numElements: 3,
142
+ * elementSize: 2,
143
+ * type: "uint16",
144
+ * min: [5632, 5376, 4864],
145
+ * max: [65280, 65280, 65280]
146
+ * }
147
+ * ]
148
+ * }
149
+ * ```
150
+ *
151
+ * @extends Source
152
+ *
153
+ * @constructor
154
+ */
155
+ constructor(source) {
156
+ if (!source.file) {
157
+ throw new Error('New Potree2Source: file is required');
158
+ }
159
+ super(source);
160
+ this.file = source.file;
161
+ this.fetcher = Fetcher.arrayBuffer;
162
+ this.whenReady = (source.metadata ? Promise.resolve(source.metadata) : Fetcher.json(`${this.url}/${this.file}`, this.networkOptions)).then(metadata => {
163
+ this.metadata = metadata;
164
+ this.pointAttributes = metadata.attributes;
165
+ this.baseurl = `${this.url}`;
166
+ this.extension = 'bin';
167
+ this.parser = Potree2BinParser.parse;
168
+ return metadata;
169
+ });
170
+ }
171
+ }
172
+ export default Potree2Source;
@@ -46,18 +46,20 @@ class DRACOLoader extends Loader {
46
46
  this.parse(buffer, onLoad, onError);
47
47
  }, onProgress, onError);
48
48
  }
49
- parse(buffer, onLoad, onError) {
50
- this.decodeDracoFile(buffer, onLoad, null, null, SRGBColorSpace).catch(onError);
49
+ parse(buffer, onLoad) {
50
+ let onError = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : () => {};
51
+ this.decodeDracoFile(buffer, onLoad, null, null, SRGBColorSpace, onError).catch(onError);
51
52
  }
52
53
  decodeDracoFile(buffer, callback, attributeIDs, attributeTypes) {
53
54
  let vertexColorSpace = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : LinearSRGBColorSpace;
55
+ let onError = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : () => {};
54
56
  const taskConfig = {
55
57
  attributeIDs: attributeIDs || this.defaultAttributeIDs,
56
58
  attributeTypes: attributeTypes || this.defaultAttributeTypes,
57
59
  useUniqueIDs: !!attributeIDs,
58
60
  vertexColorSpace: vertexColorSpace
59
61
  };
60
- return this.decodeGeometry(buffer, taskConfig).then(callback);
62
+ return this.decodeGeometry(buffer, taskConfig).then(callback).catch(onError);
61
63
  }
62
64
  decodeGeometry(buffer, taskConfig) {
63
65
  const taskKey = JSON.stringify(taskConfig);