itowns 2.45.2-next.2 → 2.45.2-next.4

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.
@@ -189,6 +189,7 @@ declare class OGC3DTilesLayer extends GeometryLayer {
189
189
  * @private
190
190
  */
191
191
  private _setupCacheAndQueues;
192
+ _viewId: any;
192
193
  /**
193
194
  * Binds 3d-tiles-renderer events to this layer.
194
195
  * @private
@@ -271,7 +272,7 @@ declare class OGC3DTilesLayer extends GeometryLayer {
271
272
  * 1. tile (Object) - the JSON tile
272
273
  * 2. scene (THREE.Object3D | null) - The tile content. Contains a `batchTable` property. Can be null if the tile
273
274
  * has not yet been loaded.
274
- */
275
+ */
275
276
  forEachTile(callback: Function): void;
276
277
  }
277
278
  import GeometryLayer from '../Layer/GeometryLayer';
@@ -291,16 +291,12 @@ class OGC3DTilesLayer extends GeometryLayer {
291
291
  if (config.sseThreshold) {
292
292
  this.sseThreshold = config.sseThreshold;
293
293
  }
294
+
294
295
  // Used for custom schedule callbacks (VR)
295
296
  this.tasks = [];
296
297
  this.tilesSchedulingCB = func => {
297
298
  this.tasks.push(func);
298
299
  };
299
- // We set our scheduling callback for tiles downloading and parsing -> MANDATORY for VR
300
- // (WebXR session has its own requestAnimationFrame method separate from that of the window
301
- // https://github.com/NASA-AMMOS/3DTilesRendererJS/issues/213#issuecomment-947943386)
302
- this.tilesRenderer.downloadQueue.schedulingCallback = this.tilesSchedulingCB;
303
- this.tilesRenderer.parseQueue.schedulingCallback = this.tilesSchedulingCB;
304
300
  }
305
301
 
306
302
  /**
@@ -311,20 +307,46 @@ class OGC3DTilesLayer extends GeometryLayer {
311
307
  */
312
308
  _setupCacheAndQueues(view) {
313
309
  const id = view.id;
310
+ // Share the caches and queues to cut down on memory and correctly prioritize downloads.
311
+ // https://github.com/NASA-AMMOS/3DTilesRendererJS?tab=readme-ov-file#multiple-tilesrenderers-with-shared-caches-and-queues
314
312
  if (viewers[id]) {
315
313
  this.tilesRenderer.lruCache = viewers[id].lruCache;
316
314
  this.tilesRenderer.downloadQueue = viewers[id].downloadQueue;
317
315
  this.tilesRenderer.parseQueue = viewers[id].parseQueue;
316
+
317
+ // Add this layer's callback to the map
318
+ viewers[id].layerCallbacks[this.id] = this.tilesSchedulingCB;
318
319
  } else {
320
+ // Create a combined callback that calls all layer callbacks
321
+ const combinedCallback = func => {
322
+ Object.values(viewers[id].layerCallbacks).forEach(callback => {
323
+ callback(func);
324
+ });
325
+ };
326
+
327
+ // Set the combined callback
328
+ // We set our scheduling callback for tiles downloading and parsing -> MANDATORY for VR
329
+ // (WebXR session has its own requestAnimationFrame method separate from that of the window
330
+ // https://github.com/NASA-AMMOS/3DTilesRendererJS/issues/213#issuecomment-947943386)
331
+ // Necessary to update rendering of the tiles in VR
332
+ // Example: https://github.com/NASA-AMMOS/3DTilesRendererJS/blob/de25d27dc0e75278962b5f401faee30f8dce2fe0/example/vr.js
333
+ this.tilesRenderer.downloadQueue.schedulingCallback = combinedCallback;
334
+ this.tilesRenderer.parseQueue.schedulingCallback = combinedCallback;
319
335
  viewers[id] = {
320
336
  lruCache: this.tilesRenderer.lruCache,
321
337
  downloadQueue: this.tilesRenderer.downloadQueue,
322
- parseQueue: this.tilesRenderer.parseQueue
338
+ parseQueue: this.tilesRenderer.parseQueue,
339
+ layerCallbacks: {
340
+ [this.id]: this.tilesSchedulingCB
341
+ }
323
342
  };
324
343
  view.addEventListener(VIEW_EVENTS.DISPOSED, evt => {
325
344
  delete viewers[evt.target.id];
326
345
  });
327
346
  }
347
+
348
+ // Store the view reference for cleanup
349
+ this._viewId = id;
328
350
  }
329
351
 
330
352
  /**
@@ -439,7 +461,20 @@ class OGC3DTilesLayer extends GeometryLayer {
439
461
  * Deletes the layer and frees associated memory
440
462
  */
441
463
  delete() {
464
+ // Clean up the callback reference from the shared callbacks
465
+ if (this._viewId != null && viewers[this._viewId]?.layerCallbacks) {
466
+ delete viewers[this._viewId].layerCallbacks[this.id];
467
+
468
+ // If no more layers are using this view's queues, clean up completely
469
+ if (Object.keys(viewers[this._viewId].layerCallbacks).length === 0) {
470
+ delete viewers[this._viewId];
471
+ }
472
+ }
442
473
  this.tilesRenderer.dispose();
474
+
475
+ // Clean up references
476
+ this.tilesSchedulingCB = null;
477
+ this._viewId = null;
443
478
  }
444
479
 
445
480
  /**
@@ -488,7 +523,7 @@ class OGC3DTilesLayer extends GeometryLayer {
488
523
 
489
524
  /** @type{number|null} */
490
525
  let batchId;
491
- if (object.isPoints && index) {
526
+ if (object.isPoints && index != null) {
492
527
  batchId = object.geometry.getAttribute('_BATCHID')?.getX(index) ?? index;
493
528
  } else if (object.isMesh && face) {
494
529
  batchId = object.geometry.getAttribute('_BATCHID')?.getX(face.a) ?? instanceId;
@@ -554,7 +589,7 @@ class OGC3DTilesLayer extends GeometryLayer {
554
589
  * 1. tile (Object) - the JSON tile
555
590
  * 2. scene (THREE.Object3D | null) - The tile content. Contains a `batchTable` property. Can be null if the tile
556
591
  * has not yet been loaded.
557
- */
592
+ */
558
593
  forEachTile(callback) {
559
594
  this.tilesRenderer.traverse(tile => {
560
595
  callback(tile, tile.cached.scene);
package/lib/Main.js CHANGED
@@ -1,5 +1,5 @@
1
1
  const conf = {
2
- version: '2.45.2-next.2'
2
+ version: '2.45.2-next.4'
3
3
  };
4
4
  export const REVISION = conf.version;
5
5
 
@@ -44,8 +44,10 @@ interface LayeredMaterialRawUniforms {
44
44
  opacity: number;
45
45
  lightingEnabled: boolean;
46
46
  lightPosition: THREE.Vector3;
47
- fogDistance: number;
47
+ fogNear: number;
48
+ fogFar: number;
48
49
  fogColor: THREE.Color;
50
+ fogDensity: number;
49
51
  overlayAlpha: number;
50
52
  overlayColor: THREE.Color;
51
53
  objectId: number;
@@ -75,7 +77,6 @@ type RenderModeDefines = DefineMapping<'MODE', typeof RenderMode.MODES>;
75
77
  type LayeredMaterialDefines = {
76
78
  NUM_VS_TEXTURES: number;
77
79
  NUM_FS_TEXTURES: number;
78
- USE_FOG: number;
79
80
  NUM_CRS: number;
80
81
  DEBUG: number;
81
82
  MODE: number;
@@ -2,7 +2,7 @@ import * as THREE from 'three';
2
2
  /* babel-plugin-inline-import './Shader/TileVS.glsl' */
3
3
  const TileVS = "#include <itowns/precision_qualifier>\n#include <common>\n#include <itowns/elevation_pars_vertex>\n#include <logdepthbuf_pars_vertex>\n#if NUM_CRS > 1\nattribute float uv_1;\n#endif\n\nuniform bool lightingEnabled;\nvarying vec2 vHighPrecisionZW;\n\n#if MODE == MODE_FINAL\n#include <fog_pars_vertex>\nvarying vec3 vUv;\nvarying vec3 vNormal;\n#endif\nvoid main() {\n #include <begin_vertex>\n #include <itowns/elevation_vertex>\n #include <itowns/geoid_vertex>\n #include <project_vertex>\n #include <logdepthbuf_vertex>\n vHighPrecisionZW = gl_Position.zw;\n#if MODE == MODE_FINAL\n #include <fog_vertex>\n #if NUM_CRS > 1\n vUv = vec3(uv, (uv_1 > 0.) ? uv_1 : uv.y); // set uv_1 = uv if uv_1 is undefined\n #else\n vUv = vec3(uv, 0.0);\n #endif\n vNormal = normalize ( mat3( modelMatrix[0].xyz, modelMatrix[1].xyz, modelMatrix[2].xyz ) * normal );\n#endif\n}\n";
4
4
  /* babel-plugin-inline-import './Shader/TileFS.glsl' */
5
- const TileFS = "#include <itowns/precision_qualifier>\n#include <logdepthbuf_pars_fragment>\n#include <itowns/pitUV>\n#include <itowns/color_layers_pars_fragment>\n#if MODE == MODE_FINAL\n#include <itowns/fog_pars_fragment>\n#include <itowns/overlay_pars_fragment>\n#include <itowns/lighting_pars_fragment>\n#endif\n#include <itowns/mode_pars_fragment>\n\nuniform vec3 diffuse;\nuniform float opacity;\nvarying vec3 vUv; // uv.x/uv_1.x, uv.y, uv_1.y\nvarying vec2 vHighPrecisionZW;\n\nvoid main() {\n #include <logdepthbuf_fragment>\n\n#if MODE == MODE_ID\n\n #include <itowns/mode_id_fragment>\n\n#elif MODE == MODE_DEPTH\n\n #include <itowns/mode_depth_fragment>\n\n#else\n\n gl_FragColor = vec4(diffuse, opacity);\n\n uvs[0] = vec3(vUv.xy, 0.);\n\n#if NUM_CRS > 1\n uvs[1] = vec3(vUv.x, fract(vUv.z), floor(vUv.z));\n#endif\n\n vec4 color;\n #pragma unroll_loop\n for ( int i = 0; i < NUM_FS_TEXTURES; i ++ ) {\n color = getLayerColor( i , colorTextures[ i ], colorOffsetScales[ i ], colorLayers[ i ]);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);\n }\n\n #if DEBUG == 1\n if (showOutline) {\n #pragma unroll_loop\n for ( int i = 0; i < NUM_CRS; i ++) {\n color = getOutlineColor( outlineColors[ i ], uvs[ i ].xy);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);\n }\n }\n #endif\n\n #include <itowns/fog_fragment>\n #include <itowns/lighting_fragment>\n #include <itowns/overlay_fragment>\n\n#endif\n}\n";
5
+ const TileFS = "#include <itowns/precision_qualifier>\n#include <logdepthbuf_pars_fragment>\n#include <itowns/pitUV>\n#include <itowns/color_layers_pars_fragment>\n#if MODE == MODE_FINAL\n#include <fog_pars_fragment>\n#include <itowns/overlay_pars_fragment>\n#include <itowns/lighting_pars_fragment>\n#endif\n#include <itowns/mode_pars_fragment>\n\nuniform vec3 diffuse;\nuniform float opacity;\nvarying vec3 vUv; // uv.x/uv_1.x, uv.y, uv_1.y\nvarying vec2 vHighPrecisionZW;\n\nvoid main() {\n #include <logdepthbuf_fragment>\n\n#if MODE == MODE_ID\n\n #include <itowns/mode_id_fragment>\n\n#elif MODE == MODE_DEPTH\n\n #include <itowns/mode_depth_fragment>\n\n#else\n\n gl_FragColor = vec4(diffuse, opacity);\n\n uvs[0] = vec3(vUv.xy, 0.);\n\n#if NUM_CRS > 1\n uvs[1] = vec3(vUv.x, fract(vUv.z), floor(vUv.z));\n#endif\n\n vec4 color;\n #pragma unroll_loop\n for ( int i = 0; i < NUM_FS_TEXTURES; i ++ ) {\n color = getLayerColor( i , colorTextures[ i ], colorOffsetScales[ i ], colorLayers[ i ]);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);\n }\n\n #if DEBUG == 1\n if (showOutline) {\n #pragma unroll_loop\n for ( int i = 0; i < NUM_CRS; i ++) {\n color = getOutlineColor( outlineColors[ i ], uvs[ i ].xy);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, color.rgb, color.a);\n }\n }\n #endif\n\n #include <fog_fragment>\n #include <itowns/lighting_fragment>\n #include <itowns/overlay_fragment>\n\n#endif\n}\n";
6
6
  import ShaderUtils from "./Shader/ShaderUtils.js";
7
7
  import Capabilities from "../Core/System/Capabilities.js";
8
8
  import RenderMode from "./RenderMode.js";
@@ -123,14 +123,13 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
123
123
  const defines = {};
124
124
  fillInProp(defines, 'NUM_VS_TEXTURES', nbSamplers[0]);
125
125
  fillInProp(defines, 'NUM_FS_TEXTURES', nbSamplers[1]);
126
- // TODO: We do not use the fog from the scene, is this a desired
127
- // behavior?
128
- fillInProp(defines, 'USE_FOG', 1);
129
126
  fillInProp(defines, 'NUM_CRS', crsCount);
130
127
  initModeDefines(defines);
131
128
  fillInProp(defines, 'MODE', RenderMode.MODES.FINAL);
132
129
  fillInProp(defines, 'DEBUG', +false);
133
130
  this.defines = defines;
131
+ this.fog = true; // receive the fog defined on the scene, if any
132
+
134
133
  this.vertexShader = TileVS;
135
134
  // three loop unrolling of ShaderMaterial only supports integer bounds,
136
135
  // see https://github.com/mrdoob/three.js/issues/28020
@@ -144,8 +143,10 @@ export class LayeredMaterial extends THREE.ShaderMaterial {
144
143
  lightingEnabled: false,
145
144
  lightPosition: new THREE.Vector3(-0.5, 0.0, 1.0),
146
145
  // Misc properties
147
- fogDistance: 1000000000.0,
146
+ fogNear: 1,
147
+ fogFar: 1000,
148
148
  fogColor: new THREE.Color(0.76, 0.85, 1.0),
149
+ fogDensity: 0.00025,
149
150
  overlayAlpha: 0,
150
151
  overlayColor: new THREE.Color(1.0, 0.3, 0.0),
151
152
  objectId: 0,
@@ -7,10 +7,6 @@ const elevation_pars_vertex = "#if NUM_VS_TEXTURES > 0\n struct Layer {\n
7
7
  const elevation_vertex = "#if NUM_VS_TEXTURES > 0\n if(elevationTextureCount > 0) {\n float elevation = getElevation(uv, elevationTextures[0], elevationOffsetScales[0], elevationLayers[0]);\n transformed += elevation * normal;\n }\n#endif\n";
8
8
  /* babel-plugin-inline-import './Chunk/geoid_vertex.glsl' */
9
9
  const geoid_vertex = "transformed += geoidHeight * normal;\n";
10
- /* babel-plugin-inline-import './Chunk/fog_fragment.glsl' */
11
- const fog_fragment = "#if defined(USE_FOG)\n float fogFactor = 1. - min( exp(-vFogDepth / fogDistance), 1.);\n gl_FragColor.rgb = mix(gl_FragColor.rgb, fogColor, fogFactor);\n#endif\n";
12
- /* babel-plugin-inline-import './Chunk/fog_pars_fragment.glsl' */
13
- const fog_pars_fragment = "#if defined(USE_FOG)\nuniform vec3 fogColor;\nuniform float fogDistance;\nvarying float vFogDepth;\n#endif\n";
14
10
  /* babel-plugin-inline-import './Chunk/lighting_fragment.glsl' */
15
11
  const lighting_fragment = "if (lightingEnabled) {\n float light = min(2. * dot(vNormal, lightPosition), 1.);\n gl_FragColor.rgb *= light;\n}\n";
16
12
  /* babel-plugin-inline-import './Chunk/lighting_pars_fragment.glsl' */
@@ -44,8 +40,6 @@ const itownsShaderChunk = {
44
40
  elevation_pars_vertex,
45
41
  elevation_vertex,
46
42
  geoid_vertex,
47
- fog_fragment,
48
- fog_pars_fragment,
49
43
  lighting_fragment,
50
44
  lighting_pars_fragment,
51
45
  mode_depth_fragment,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "itowns",
3
- "version": "2.45.2-next.2",
3
+ "version": "2.45.2-next.4",
4
4
  "description": "A JS/WebGL framework for 3D geospatial data visualization",
5
5
  "type": "module",
6
6
  "main": "lib/Main.js",
@@ -51,7 +51,7 @@
51
51
  "url": "https://github.com/iTowns/itowns/issues"
52
52
  },
53
53
  "dependencies": {
54
- "@itowns/geographic": "^2.45.2-next.2",
54
+ "@itowns/geographic": "^2.45.2-next.4",
55
55
  "@mapbox/vector-tile": "^2.0.3",
56
56
  "@maplibre/maplibre-gl-style-spec": "^23.1.0",
57
57
  "@tmcw/togeojson": "^7.0.0",