itowns 2.44.3-next.22 → 2.44.3-next.23

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 (37) hide show
  1. package/dist/debug.js +1 -1
  2. package/dist/debug.js.map +1 -1
  3. package/dist/itowns.js +1 -1
  4. package/dist/itowns.js.map +1 -1
  5. package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
  6. package/examples/source_file_geojson_3d.html +0 -1
  7. package/examples/source_stream_wfs_raster.html +0 -7
  8. package/lib/Converter/Feature2Texture.js +3 -1
  9. package/lib/Converter/convertToTile.js +3 -3
  10. package/lib/Core/Prefab/Globe/Atmosphere.js +4 -2
  11. package/lib/Core/Prefab/Globe/GlobeLayer.js +19 -11
  12. package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
  13. package/lib/Core/Prefab/Planar/PlanarLayer.js +15 -8
  14. package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
  15. package/lib/Core/Prefab/TileBuilder.js +27 -32
  16. package/lib/Core/Prefab/computeBufferTileGeometry.js +189 -130
  17. package/lib/Core/TileGeometry.js +112 -28
  18. package/lib/Layer/C3DTilesLayer.js +7 -4
  19. package/lib/Layer/ColorLayer.js +35 -9
  20. package/lib/Layer/CopcLayer.js +5 -0
  21. package/lib/Layer/ElevationLayer.js +39 -7
  22. package/lib/Layer/EntwinePointTileLayer.js +12 -5
  23. package/lib/Layer/FeatureGeometryLayer.js +20 -6
  24. package/lib/Layer/GeometryLayer.js +42 -11
  25. package/lib/Layer/LabelLayer.js +11 -5
  26. package/lib/Layer/Layer.js +83 -57
  27. package/lib/Layer/OGC3DTilesLayer.js +3 -2
  28. package/lib/Layer/OrientedImageLayer.js +12 -4
  29. package/lib/Layer/PointCloudLayer.js +69 -23
  30. package/lib/Layer/Potree2Layer.js +7 -2
  31. package/lib/Layer/PotreeLayer.js +8 -3
  32. package/lib/Layer/RasterLayer.js +12 -2
  33. package/lib/Layer/TiledGeometryLayer.js +69 -13
  34. package/lib/Provider/Fetcher.js +5 -1
  35. package/lib/Renderer/OBB.js +9 -11
  36. package/package.json +1 -1
  37. package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +0 -110
@@ -3,14 +3,52 @@ export function getBufferIndexSize(segments, noSkirt) {
3
3
  const triangles = segments * segments * 2 + (noSkirt ? 0 : 4 * segments * 2);
4
4
  return triangles * 3;
5
5
  }
6
- export default function computeBuffers(params) {
7
- // Create output buffers.
8
- const outBuffers = {
9
- index: null,
10
- position: null,
11
- normal: null,
12
- // 2 UV set per tile: wgs84 (uv[0]) and pm (uv[1])
13
- // - wgs84: 1 texture per tile because tiles are using wgs84 projection
6
+ function getUintArrayConstructor(highestValue) {
7
+ let picked = null;
8
+ if (highestValue < 2 ** 8) {
9
+ picked = Uint8Array;
10
+ } else if (highestValue < 2 ** 16) {
11
+ picked = Uint16Array;
12
+ } else if (highestValue < 2 ** 32) {
13
+ picked = Uint32Array;
14
+ } else {
15
+ throw new Error('Value is too high');
16
+ }
17
+ return picked;
18
+ }
19
+ function allocateIndexBuffer(nVertex, nSeg, params) {
20
+ if (!params.buildIndexAndUv_0) {
21
+ return undefined;
22
+ }
23
+ const indexBufferSize = getBufferIndexSize(nSeg, params.disableSkirt);
24
+ const indexConstructor = getUintArrayConstructor(nVertex);
25
+ const tileLen = indexBufferSize;
26
+ const skirtLen = 4 * nSeg;
27
+ const indexBuffer = new ArrayBuffer((
28
+ // Tile
29
+ tileLen
30
+ // Skirt
31
+ + (params.disableSkirt ? 0 : skirtLen)) * indexConstructor.BYTES_PER_ELEMENT);
32
+ const index = new indexConstructor(indexBuffer);
33
+ const skirt = !params.disableSkirt ? index.subarray(tileLen, tileLen + skirtLen) : undefined;
34
+ return {
35
+ index,
36
+ skirt
37
+ };
38
+ }
39
+ function allocateBuffers(nVertex, nSeg, builder, params) {
40
+ const {
41
+ index,
42
+ skirt
43
+ } = allocateIndexBuffer(nVertex, nSeg, params) ?? {};
44
+ return {
45
+ index,
46
+ skirt,
47
+ position: new Float32Array(nVertex * 3),
48
+ normal: new Float32Array(nVertex * 3),
49
+ // 2 UV set per tile: wgs84 (uv[0]) and pseudo-mercator (pm, uv[1])
50
+ // - wgs84: 1 texture per tile because tiles are using wgs84
51
+ // projection
14
52
  // - pm: use multiple textures per tile.
15
53
  // +-------------------------+
16
54
  // | |
@@ -24,142 +62,157 @@ export default function computeBuffers(params) {
24
62
  // +-------------------------+
25
63
  // * u = wgs84.u
26
64
  // * v = textureid + v in builder texture
27
- uvs: []
65
+ uvs: [params.buildIndexAndUv_0 ? new Float32Array(nVertex * 2) : undefined, builder.computeExtraOffset !== undefined ? new Float32Array(nVertex) : undefined]
66
+ };
67
+ }
68
+ function computeUv0(uv, id, u, v) {
69
+ uv[id * 2 + 0] = u;
70
+ uv[id * 2 + 1] = v;
71
+ }
72
+ function initComputeUv1(value) {
73
+ return (uv, id) => {
74
+ uv[id] = value;
28
75
  };
29
- const computeUvs = [];
30
- const builder = params.builder;
31
- const nSeg = params.segments;
32
- // segments count :
33
- // Tile : (nSeg + 1) * (nSeg + 1)
34
- // Skirt : 8 * (nSeg - 1)
35
- const nVertex = (nSeg + 1) * (nSeg + 1) + (params.disableSkirt ? 0 : 4 * nSeg);
36
- if (nVertex > 2 ** 32) {
76
+ }
77
+ /** Compute buffers describing a tile according to a builder and its params. */
78
+ // TODO: Split this even further into subfunctions
79
+ export function computeBuffers(builder, params) {
80
+ // n seg, n+1 vert + <- skirt, n verts per side
81
+ // <---------------> / |
82
+ // +---+---+---+---+ |
83
+ // | / | / | / | / | | Vertices:
84
+ // +---+---+---+---+ - + tile = (n + 1)^2
85
+ // | / | / | / | / | | skirt = 4n
86
+ // +---+---+---+---+ - +
87
+ // | / | / | / | / | | Segments:
88
+ // +---+---+---+---+ - + tile = 2 * n * (n + 1) + n^2
89
+ // | / | / | / | / | | skirt = 2n * 4
90
+ // +---+---+---+---+ |
91
+ const nSeg = Math.max(2, params.segments);
92
+ const nVertex = nSeg + 1;
93
+ const nTileVertex = nVertex ** 2;
94
+ const nSkirtVertex = params.disableSkirt ? 0 : 4 * nSeg;
95
+ const nTotalVertex = nTileVertex + nSkirtVertex;
96
+
97
+ // Computer should combust before this happens
98
+ if (nTotalVertex > 2 ** 32) {
37
99
  throw new Error('Tile segments count is too big');
38
100
  }
39
- outBuffers.position = new Float32Array(nVertex * 3);
40
- outBuffers.normal = new Float32Array(nVertex * 3);
41
- const uvCount = params.builder.uvCount;
42
- if (uvCount > 1) {
43
- outBuffers.uvs[1] = new Float32Array(nVertex);
44
- }
45
- computeUvs[0] = () => {};
46
- const bufferIndexSize = getBufferIndexSize(nSeg, params.disableSkirt);
47
- if (params.buildIndexAndUv_0) {
48
- if (nVertex < 2 ** 8) {
49
- outBuffers.index = new Uint8Array(bufferIndexSize);
50
- } else if (nVertex < 2 ** 16) {
51
- outBuffers.index = new Uint16Array(bufferIndexSize);
52
- } else if (nVertex < 2 ** 32) {
53
- outBuffers.index = new Uint32Array(bufferIndexSize);
101
+ const outBuffers = allocateBuffers(nTotalVertex, nSeg, builder, params);
102
+ const computeUvs = [params.buildIndexAndUv_0 ? computeUv0 : () => {}];
103
+ params = builder.prepare(params);
104
+ for (let y = 0; y <= nSeg; y++) {
105
+ const v = y / nSeg;
106
+ params.coordinates.y = builder.vProject(v, params.extent);
107
+ if (builder.computeExtraOffset !== undefined) {
108
+ computeUvs[1] = initComputeUv1(builder.computeExtraOffset(params));
54
109
  }
55
- outBuffers.uvs[0] = new Float32Array(nVertex * 2);
56
- computeUvs[0] = (id, u, v) => {
57
- outBuffers.uvs[0][id * 2 + 0] = u;
58
- outBuffers.uvs[0][id * 2 + 1] = v;
59
- };
60
- }
61
- const widthSegments = Math.max(2, Math.floor(nSeg) || 2);
62
- const heightSegments = Math.max(2, Math.floor(nSeg) || 2);
63
- let idVertex = 0;
64
- const vertices = [];
65
- let skirt = [];
66
- const skirtEnd = [];
67
- builder.prepare(params);
68
- for (let y = 0; y <= heightSegments; y++) {
69
- const verticesRow = [];
70
- const v = y / heightSegments;
71
- builder.vProjecte(v, params);
72
- if (uvCount > 1) {
73
- const u = builder.computeUvs[1](params);
74
- computeUvs[1] = id => {
75
- outBuffers.uvs[1][id] = u;
76
- };
77
- }
78
- for (let x = 0; x <= widthSegments; x++) {
79
- const u = x / widthSegments;
80
- const id_m3 = idVertex * 3;
81
- builder.uProjecte(u, params);
82
- const vertex = builder.vertexPosition(params, params.projected);
83
- const normal = builder.vertexNormal(params);
110
+ for (let x = 0; x <= nSeg; x++) {
111
+ const u = x / nSeg;
112
+ const id_m3 = (y * nVertex + x) * 3;
113
+ params.coordinates.x = builder.uProject(u, params.extent);
114
+ const vertex = builder.vertexPosition(params.coordinates);
115
+ const normal = builder.vertexNormal();
84
116
 
85
117
  // move geometry to center world
86
118
  vertex.sub(params.center);
87
119
 
88
120
  // align normal to z axis
89
- if (params.quatNormalToZ) {
90
- vertex.applyQuaternion(params.quatNormalToZ);
91
- normal.applyQuaternion(params.quatNormalToZ);
121
+ // HACK: this check style is not great
122
+ if ('quatNormalToZ' in params) {
123
+ const quat = params.quatNormalToZ;
124
+ vertex.applyQuaternion(quat);
125
+ normal.applyQuaternion(quat);
92
126
  }
93
127
  vertex.toArray(outBuffers.position, id_m3);
94
128
  normal.toArray(outBuffers.normal, id_m3);
95
- for (const computeUv of computeUvs) {
96
- computeUv(idVertex, u, v);
97
- }
98
- if (!params.disableSkirt) {
99
- if (y !== 0 && y !== heightSegments) {
100
- if (x === widthSegments) {
101
- skirt.push(idVertex);
102
- } else if (x === 0) {
103
- skirtEnd.push(idVertex);
104
- }
129
+ for (const [index, computeUv] of computeUvs.entries()) {
130
+ if (computeUv !== undefined) {
131
+ computeUv(outBuffers.uvs[index], y * nVertex + x, u, v);
105
132
  }
106
133
  }
107
- verticesRow.push(idVertex);
108
- idVertex++;
109
- }
110
- vertices.push(verticesRow);
111
- if (y === 0) {
112
- skirt = skirt.concat(verticesRow);
113
- } else if (y === heightSegments) {
114
- skirt = skirt.concat(verticesRow.slice().reverse());
115
134
  }
116
135
  }
117
- if (!params.disableSkirt) {
118
- skirt = skirt.concat(skirtEnd.reverse());
136
+
137
+ // Fill skirt index buffer
138
+ if (params.buildIndexAndUv_0 && !params.disableSkirt) {
139
+ for (let x = 0; x < nVertex; x++) {
140
+ // -------->
141
+ // 0---1---2
142
+ // | / | / | [0-9] = assign order
143
+ // +---+---+
144
+ // | / | / |
145
+ // +---+---+
146
+ outBuffers.skirt[x] = x;
147
+ // +---+---+
148
+ // | / | / | [0-9] = assign order
149
+ // +---+---x x = skipped for now
150
+ // | / | / |
151
+ // 0---1---2
152
+ // <--------
153
+ outBuffers.skirt[2 * nVertex - 2 + x] = nVertex ** 2 - (x + 1);
154
+ }
155
+ for (let y = 1; y < nVertex - 1; y++) {
156
+ // +---+---s |
157
+ // | / | / | | o = stored vertices
158
+ // +---+---o | s = already stored
159
+ // | / | / | |
160
+ // +---+---s v
161
+ outBuffers.skirt[nVertex - 1 + y] = y * nVertex + (nVertex - 1);
162
+ // ^ s---+---+
163
+ // | | / | / | o = stored vertices
164
+ // | o---+---+ s = already stored
165
+ // | | / | / |
166
+ // | s---+---+
167
+ outBuffers.skirt[3 * nVertex - 3 + y] = nVertex * (nVertex - 1 - y);
168
+ }
119
169
  }
120
- function bufferize(va, vb, vc, idVertex) {
121
- outBuffers.index[idVertex + 0] = va;
122
- outBuffers.index[idVertex + 1] = vb;
123
- outBuffers.index[idVertex + 2] = vc;
124
- return idVertex + 3;
170
+
171
+ /** Copy passed indices at the desired index of the output index buffer. */
172
+ function bufferizeTri(id, va, vb, vc) {
173
+ outBuffers.index[id + 0] = va;
174
+ outBuffers.index[id + 1] = vb;
175
+ outBuffers.index[id + 2] = vc;
125
176
  }
126
- let idVertex2 = 0;
127
177
  if (params.buildIndexAndUv_0) {
128
- for (let y = 0; y < heightSegments; y++) {
129
- for (let x = 0; x < widthSegments; x++) {
130
- const v1 = vertices[y][x + 1];
131
- const v2 = vertices[y][x];
132
- const v3 = vertices[y + 1][x];
133
- const v4 = vertices[y + 1][x + 1];
134
- idVertex2 = bufferize(v4, v2, v1, idVertex2);
135
- idVertex2 = bufferize(v4, v3, v2, idVertex2);
178
+ for (let y = 0; y < nSeg; y++) {
179
+ for (let x = 0; x < nSeg; x++) {
180
+ const v1 = y * nVertex + (x + 1);
181
+ const v2 = y * nVertex + x;
182
+ const v3 = (y + 1) * nVertex + x;
183
+ const v4 = (y + 1) * nVertex + (x + 1);
184
+ const id = (y * nSeg + x) * 6;
185
+ bufferizeTri(id, /**/v4, v2, v1);
186
+ bufferizeTri(id + 3, v4, v3, v2);
136
187
  }
137
188
  }
138
189
  }
139
- const iStart = idVertex;
140
190
 
141
- // TODO: WARNING beware skirt's size influences performance
142
- // The size of the skirt is now a ratio of the size of the tile.
143
- // To be perfect it should depend on the real elevation delta but too heavy to compute
144
- if (!params.disableSkirt) {
145
- // We compute the actual size of tile segment to use later for the skirt.
191
+ // PERF: Beware skirt's size influences performance
192
+ // INFO: The size of the skirt is now a ratio of the size of the tile.
193
+ // To be perfect it should depend on the real elevation delta but too heavy
194
+ // to compute
195
+ if (params.buildIndexAndUv_0 && !params.disableSkirt) {
196
+ // We compute the actual size of tile segment to use later for
197
+ // the skirt.
146
198
  const segmentSize = new THREE.Vector3().fromArray(outBuffers.position).distanceTo(new THREE.Vector3().fromArray(outBuffers.position, 3));
147
- let buildIndexSkirt = function () {};
148
- let buildUVSkirt = function () {};
149
- if (params.buildIndexAndUv_0) {
150
- buildIndexSkirt = function (id, v1, v2, v3, v4) {
151
- id = bufferize(v1, v2, v3, id);
152
- id = bufferize(v1, v3, v4, id);
153
- return id;
154
- };
155
- buildUVSkirt = function (id) {
156
- outBuffers.uvs[0][idVertex * 2 + 0] = outBuffers.uvs[0][id * 2 + 0];
157
- outBuffers.uvs[0][idVertex * 2 + 1] = outBuffers.uvs[0][id * 2 + 1];
158
- };
159
- }
160
- for (let i = 0; i < skirt.length; i++) {
161
- const id = skirt[i];
162
- const id_m3 = idVertex * 3;
199
+ const buildSkirt = {
200
+ index: (id, v1, v2, v3, v4) => {
201
+ bufferizeTri(id, v1, v2, v3);
202
+ bufferizeTri(id + 3, v1, v3, v4);
203
+ return id + 6;
204
+ },
205
+ uv: (buf, idTo, idFrom) => {
206
+ buf[idTo * 2 + 0] = buf[idFrom * 2 + 0];
207
+ buf[idTo * 2 + 1] = buf[idFrom * 2 + 1];
208
+ }
209
+ };
210
+
211
+ // Alias for readability
212
+ const start = nTileVertex;
213
+ for (let i = 0; i < outBuffers.skirt.length; i++) {
214
+ const id = outBuffers.skirt[i];
215
+ const id_m3 = (start + i) * 3;
163
216
  const id2_m3 = id * 3;
164
217
  outBuffers.position[id_m3 + 0] = outBuffers.position[id2_m3 + 0] - outBuffers.normal[id2_m3 + 0] * segmentSize;
165
218
  outBuffers.position[id_m3 + 1] = outBuffers.position[id2_m3 + 1] - outBuffers.normal[id2_m3 + 1] * segmentSize;
@@ -167,17 +220,23 @@ export default function computeBuffers(params) {
167
220
  outBuffers.normal[id_m3 + 0] = outBuffers.normal[id2_m3 + 0];
168
221
  outBuffers.normal[id_m3 + 1] = outBuffers.normal[id2_m3 + 1];
169
222
  outBuffers.normal[id_m3 + 2] = outBuffers.normal[id2_m3 + 2];
170
- buildUVSkirt(id);
171
- if (uvCount > 1) {
172
- outBuffers.uvs[1][idVertex] = outBuffers.uvs[1][id];
223
+ buildSkirt.uv(outBuffers.uvs[0], start + i, id);
224
+ if (outBuffers.uvs[1] !== undefined) {
225
+ outBuffers.uvs[1][start + i] = outBuffers.uvs[1][id];
173
226
  }
174
- const idf = (i + 1) % skirt.length;
175
- const v2 = idVertex;
176
- const v3 = idf === 0 ? iStart : idVertex + 1;
177
- const v4 = skirt[idf];
178
- idVertex2 = buildIndexSkirt(idVertex2, id, v2, v3, v4);
179
- idVertex++;
227
+ const idf = (i + 1) % outBuffers.skirt.length;
228
+ const v2 = start + i;
229
+ const v3 = idf === 0 ? start : start + i + 1;
230
+ const v4 = outBuffers.skirt[idf];
231
+ buildSkirt.index(6 * nSeg ** 2 + i * 6, id, v2, v3, v4);
180
232
  }
181
233
  }
182
- return outBuffers;
234
+
235
+ // Dropping skirt view
236
+ return {
237
+ index: outBuffers.index,
238
+ position: outBuffers.position,
239
+ uvs: outBuffers.uvs,
240
+ normal: outBuffers.normal
241
+ };
183
242
  }
@@ -1,40 +1,124 @@
1
1
  import * as THREE from 'three';
2
- import computeBuffers, { getBufferIndexSize } from "./Prefab/computeBufferTileGeometry.js";
3
- function defaultBuffers(params) {
4
- params.buildIndexAndUv_0 = true;
5
- params.center = params.builder.center(params.extent).clone();
6
- const buffers = computeBuffers(params);
7
- buffers.index = new THREE.BufferAttribute(buffers.index, 1);
8
- buffers.uvs[0] = new THREE.BufferAttribute(buffers.uvs[0], 2);
9
- buffers.position = new THREE.BufferAttribute(buffers.position, 3);
10
- buffers.normal = new THREE.BufferAttribute(buffers.normal, 3);
11
- for (let i = 1; i < params.builder.uvCount; i++) {
12
- buffers.uvs[1] = new THREE.BufferAttribute(buffers.uvs[1], 1);
13
- }
14
- return buffers;
2
+ import { computeBuffers, getBufferIndexSize } from "./Prefab/computeBufferTileGeometry.js";
3
+ import Coordinates from "./Geographic/Coordinates.js";
4
+ function defaultBuffers(builder, params) {
5
+ const fullParams = {
6
+ disableSkirt: false,
7
+ hideSkirt: false,
8
+ buildIndexAndUv_0: true,
9
+ segments: 16,
10
+ coordinates: new Coordinates(builder.crs),
11
+ center: builder.center(params.extent).clone(),
12
+ ...params
13
+ };
14
+ const buffers = computeBuffers(builder, fullParams);
15
+ const bufferAttributes = {
16
+ index: buffers.index ? new THREE.BufferAttribute(buffers.index, 1) : null,
17
+ uvs: [...(buffers.uvs[0] ? [new THREE.BufferAttribute(buffers.uvs[0], 2)] : []), ...(buffers.uvs[1] ? [new THREE.BufferAttribute(buffers.uvs[1], 1)] : [])],
18
+ position: new THREE.BufferAttribute(buffers.position, 3),
19
+ normal: new THREE.BufferAttribute(buffers.normal, 3)
20
+ };
21
+ return bufferAttributes;
15
22
  }
16
- class TileGeometry extends THREE.BufferGeometry {
17
- constructor(params) {
18
- let buffers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultBuffers(params);
23
+ export class TileGeometry extends THREE.BufferGeometry {
24
+ /** Oriented Bounding Box of the tile geometry. */
25
+
26
+ /** Ground area covered by this tile geometry. */
27
+
28
+ /** Resolution of the tile geometry in segments per side. */
29
+
30
+ /**
31
+ * [TileGeometry] instances are shared between tiles. Since a geometry
32
+ * handles its own GPU resource, it needs a reference counter to dispose of
33
+ * that resource only when it is discarded by every single owner of a
34
+ * reference to the geometry.
35
+ */
36
+ // https://github.com/iTowns/itowns/pull/2440#discussion_r1860743294
37
+ // TODO: Remove nullability by reworking OBB:setFromExtent
38
+
39
+ constructor(builder, params) {
40
+ let bufferAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultBuffers(builder, params);
19
41
  super();
20
- this.center = params.center;
21
42
  this.extent = params.extent;
22
43
  this.segments = params.segments;
23
- this.setIndex(buffers.index);
24
- this.setAttribute('position', buffers.position);
25
- this.setAttribute('normal', buffers.normal);
26
- this.setAttribute('uv', buffers.uvs[0]);
27
- for (let i = 1; i < buffers.uvs.length; i++) {
28
- this.setAttribute(`uv_${i}`, buffers.uvs[i]);
44
+ this.setIndex(bufferAttributes.index);
45
+ this.setAttribute('position', bufferAttributes.position);
46
+ this.setAttribute('normal', bufferAttributes.normal);
47
+ this.setAttribute('uv', bufferAttributes.uvs[0]);
48
+ for (let i = 1; i < bufferAttributes.uvs.length; i++) {
49
+ this.setAttribute(`uv_${i}`, bufferAttributes.uvs[i]);
29
50
  }
30
51
  this.computeBoundingBox();
31
- this.OBB = {};
52
+ this.OBB = null;
32
53
  if (params.hideSkirt) {
33
54
  this.hideSkirt = params.hideSkirt;
34
55
  }
56
+ this._refCount = null;
35
57
  }
36
- set hideSkirt(value) {
37
- this.setDrawRange(0, getBufferIndexSize(this.segments, value));
58
+
59
+ /**
60
+ * Enables or disables skirt rendering.
61
+ *
62
+ * @param toggle - Whether to hide the skirt; true hides, false shows.
63
+ */
64
+ set hideSkirt(toggle) {
65
+ this.setDrawRange(0, getBufferIndexSize(this.segments, toggle));
38
66
  }
39
- }
40
- export default TileGeometry;
67
+
68
+ /**
69
+ * Initialize reference count for this geometry if it is currently null.
70
+ *
71
+ * @param cacheTile - The [Cache] used to store this geometry.
72
+ * @param keys - The [south, level, epsg] key of this geometry.
73
+ */
74
+ initRefCount(cacheTile, keys) {
75
+ if (this._refCount !== null) {
76
+ return;
77
+ }
78
+ this._refCount = {
79
+ count: 0,
80
+ fn: () => {
81
+ this._refCount.count--;
82
+ if (this._refCount.count <= 0) {
83
+ // To avoid remove index buffer and attribute buffer uv
84
+ // error un-bound buffer in webgl with VAO rendering.
85
+ // Could be removed if the attribute buffer deleting is
86
+ // taken into account in the buffer binding state
87
+ // (in THREE.WebGLBindingStates code).
88
+ this.index = null;
89
+ delete this.attributes.uv;
90
+ cacheTile.delete(...keys);
91
+ super.dispose();
92
+ // THREE.BufferGeometry.prototype.dispose.call(this);
93
+ }
94
+ }
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Increase reference count.
100
+ *
101
+ * @throws If reference count has not been initialized.
102
+ */
103
+ increaseRefCount() {
104
+ if (this._refCount === null) {
105
+ throw new Error('[TileGeometry::increaseRefCount] ' + 'Tried to increment an unitialized reference count.');
106
+ }
107
+ this._refCount.count++;
108
+ }
109
+
110
+ /**
111
+ * The current reference count of this [TileGeometry] if it has been
112
+ * initialized.
113
+ */
114
+ get refCount() {
115
+ return this._refCount?.count;
116
+ }
117
+ dispose() {
118
+ if (this._refCount == null) {
119
+ super.dispose();
120
+ } else {
121
+ this._refCount.fn();
122
+ }
123
+ }
124
+ }
@@ -51,11 +51,14 @@ function findTileID(object) {
51
51
  function object3DHasFeature(object3d) {
52
52
  return object3d.geometry && object3d.geometry.attributes._BATCHID;
53
53
  }
54
+
55
+ /**
56
+ * @extends GeometryLayer
57
+ */
54
58
  class C3DTilesLayer extends GeometryLayer {
55
59
  #fillColorMaterialsBuffer;
56
60
  /**
57
61
  * @deprecated Deprecated 3D Tiles layer. Use {@link OGC3DTilesLayer} instead.
58
- * @extends GeometryLayer
59
62
  *
60
63
  * @example
61
64
  * // Create a new 3d-tiles layer from a web server
@@ -83,7 +86,7 @@ class C3DTilesLayer extends GeometryLayer {
83
86
  * {@link View} that already has a layer going by that id.
84
87
  * @param {object} config configuration, all elements in it
85
88
  * will be merged as is in the layer.
86
- * @param {C3TilesSource} config.source The source of 3d Tiles.
89
+ * @param {C3DTilesSource} config.source The source of 3d Tiles.
87
90
  *
88
91
  * name.
89
92
  * @param {Number} [config.sseThreshold=16] The [Screen Space Error](https://github.com/CesiumGS/3d-tiles/blob/main/specification/README.md#geometric-error)
@@ -143,8 +146,8 @@ class C3DTilesLayer extends GeometryLayer {
143
146
  }
144
147
  }
145
148
 
146
- /** @type {Style} */
147
- this.style = config.style || null;
149
+ /** @type {Style | null} */
150
+ this._style = config.style || null;
148
151
 
149
152
  /** @type {Map<string, THREE.MeshStandardMaterial>} */
150
153
  this.#fillColorMaterialsBuffer = new Map();
@@ -44,6 +44,8 @@ import { deprecatedColorLayerOptions } from "../Core/Deprecated/Undeprecator.js"
44
44
  * * `1`: used to amplify the transparency effect.
45
45
  * * `2`: unused.
46
46
  * * `3`: could be used by your own glsl code.
47
+ *
48
+ * @extends RasterLayer
47
49
  */
48
50
  class ColorLayer extends RasterLayer {
49
51
  /**
@@ -51,8 +53,6 @@ class ColorLayer extends RasterLayer {
51
53
  * it can be an aerial view of the ground or a simple transparent layer with the
52
54
  * roads displayed.
53
55
  *
54
- * @extends Layer
55
- *
56
56
  * @param {string} id - The id of the layer, that should be unique. It is
57
57
  * not mandatory, but an error will be emitted if this layer is added a
58
58
  * {@link View} that already has a layer going by that id.
@@ -92,15 +92,41 @@ class ColorLayer extends RasterLayer {
92
92
  constructor(id) {
93
93
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
94
94
  deprecatedColorLayerOptions(config);
95
- super(id, config);
95
+ const {
96
+ effect_type = 0,
97
+ effect_parameter = 1.0,
98
+ transparent,
99
+ ...rasterConfig
100
+ } = config;
101
+ super(id, rasterConfig);
102
+
103
+ /**
104
+ * @type {boolean}
105
+ * @readonly
106
+ */
96
107
  this.isColorLayer = true;
97
- this.defineLayerProperty('visible', true);
98
- this.defineLayerProperty('opacity', 1.0);
99
- this.defineLayerProperty('sequence', 0);
100
- this.transparent = config.transparent || this.opacity < 1.0;
108
+
109
+ /**
110
+ * @type {boolean}
111
+ */
112
+ this.visible = true;
113
+ this.defineLayerProperty('visible', this.visible);
114
+
115
+ /**
116
+ * @type {number}
117
+ */
118
+ this.opacity = 1.0;
119
+ this.defineLayerProperty('opacity', this.opacity);
120
+
121
+ /**
122
+ * @type {number}
123
+ */
124
+ this.sequence = 0;
125
+ this.defineLayerProperty('sequence', this.sequence);
126
+ this.transparent = transparent || this.opacity < 1.0;
101
127
  this.noTextureParentOutsideLimit = config.source ? config.source.isFileSource : false;
102
- this.effect_type = config.effect_type ?? 0;
103
- this.effect_parameter = config.effect_parameter ?? 1.0;
128
+ this.effect_type = effect_type;
129
+ this.effect_parameter = effect_parameter;
104
130
 
105
131
  // Feature options
106
132
  this.buildExtent = true;
@@ -30,6 +30,11 @@ class CopcLayer extends PointCloudLayer {
30
30
  */
31
31
  constructor(id, config) {
32
32
  super(id, config);
33
+
34
+ /**
35
+ * @type {boolean}
36
+ * @readonly
37
+ */
33
38
  this.isCopcLayer = true;
34
39
  const resolve = () => this;
35
40
  this.whenReady = this.source.whenReady.then((/** @type {CopcSource} */source) => {