@pirireis/webglobeplugins 0.17.0 → 0.17.1

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.
@@ -1,8 +1,80 @@
1
1
  import { TextureDemTriangles } from "./texture-dem-triangles";
2
- import { partialTest } from "../../Math/tessellation/triangle-tessellation";
2
+ import { RADIAN, radianToMercatorXY } from "../../Math/methods";
3
+ import { mergeMeshes } from "../../Math/tessellation/tile-merger";
4
+ import { createTriangleTessellationMeta, getAllPoints, partialTessellation } from "../../Math/tessellation/triangle-tessellation-meta";
3
5
  /**
4
6
  * Loads a plugin with test data for TextureDemTriangles
5
7
  */
8
+ function test1(zoomLevel, p1, p2, p3) {
9
+ const triangleMeta = createTriangleTessellationMeta(p1, p2, p3);
10
+ const { vec3s, longLats, indices } = getAllPoints(triangleMeta, zoomLevel);
11
+ return { vec3s, longLats, indices };
12
+ }
13
+ function partialTest(bboxZooms, p1, p2, p3) {
14
+ const triangleMeta = createTriangleTessellationMeta(p1, p2, p3);
15
+ return partialTessellation(triangleMeta, bboxZooms, 5);
16
+ }
17
+ function antalyaTestTriangle() {
18
+ const p1 = [30.5391 * RADIAN, 36.9083 * RADIAN];
19
+ const p2 = [32.9271 * RADIAN, 36.9083 * RADIAN];
20
+ const p3 = [31.7331 * RADIAN, 35.8145 * RADIAN];
21
+ const bboxZooms = [
22
+ // 12 zoom level
23
+ {
24
+ bbox: {
25
+ min: [30.5391 * RADIAN, 35.8145 * RADIAN],
26
+ max: [32.9271 * RADIAN, 36.9083 * RADIAN]
27
+ }, zoom: 15
28
+ },
29
+ // 11 zoom level
30
+ // {
31
+ // bbox: {
32
+ // min: [30.5391 * RADIAN, 35.8145 * RADIAN],
33
+ // max: [32.9271 * RADIAN, 36.9083 * RADIAN]
34
+ // }, zoom: 11
35
+ // },
36
+ ];
37
+ return partialTest(bboxZooms, p1, p2, p3);
38
+ }
39
+ function loadVec3sLongLatsIndices(gl, bufferInfo, data) {
40
+ // Calculate total sizes
41
+ let totalVec3s = 0;
42
+ let totalLongLats = 0;
43
+ let totalIndices = 0;
44
+ for (const item of data) {
45
+ totalVec3s += item.vec3s.length;
46
+ totalLongLats += item.longLats.length;
47
+ totalIndices += item.indices.length;
48
+ }
49
+ // Pre-allocate arrays
50
+ const vec3s = new Float32Array(totalVec3s);
51
+ const longLats = new Float32Array(totalLongLats);
52
+ const indices = new Uint32Array(totalIndices);
53
+ let vec3Offset = 0;
54
+ let longLatOffset = 0;
55
+ let indexOffset = 0;
56
+ let vertexOffset = 0;
57
+ for (const item of data) {
58
+ // Copy vec3s
59
+ vec3s.set(item.vec3s, vec3Offset);
60
+ vec3Offset += item.vec3s.length;
61
+ // Copy longLats
62
+ longLats.set(item.longLats, longLatOffset);
63
+ longLatOffset += item.longLats.length;
64
+ // Copy and adjust indices
65
+ for (let i = 0; i < item.indices.length; i++) {
66
+ indices[indexOffset + i] = item.indices[i] + vertexOffset;
67
+ }
68
+ indexOffset += item.indices.length;
69
+ vertexOffset += item.vec3s.length / 3; // Each vertex has 3 components
70
+ }
71
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.pos3dBufferInfo.buffer);
72
+ gl.bufferData(gl.ARRAY_BUFFER, vec3s, gl.STATIC_DRAW);
73
+ gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.longLatBufferInfo.buffer);
74
+ gl.bufferData(gl.ARRAY_BUFFER, longLats, gl.STATIC_DRAW);
75
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.elementBufferInfo.buffer);
76
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
77
+ }
6
78
  const createTestBBOXES = () => {
7
79
  const bboxes = [];
8
80
  for (let i = 0; i < 6; i++) {
@@ -10,9 +82,10 @@ const createTestBBOXES = () => {
10
82
  const west = Math.random() * -1 * Math.PI / 10; // random longitude
11
83
  const south = north - Math.PI / 30; // random latitude
12
84
  const east = west + Math.PI / 30; // random longitude
13
- const nw = [west, north]; // random northWest
14
- const se = [east, south]; // random southEast
15
- bboxes.push({ northWest: nw, southEast: se });
85
+ const ll = [west, north]; // random northWest
86
+ const ur = [east, south]; // random southEast
87
+ //
88
+ bboxes.push({ ll, ur });
16
89
  }
17
90
  return bboxes;
18
91
  };
@@ -20,7 +93,7 @@ const demTextureBBOX = createTestBBOXES();
20
93
  function showTextureBBoxes(bboxes, demData = []) {
21
94
  for (let i = 0; i < bboxes.length; i++) {
22
95
  const bbox = bboxes[i];
23
- console.log(`Texture BBOX ${i}: NW(${(bbox.northWest[0] * 180 / Math.PI).toFixed(2)}, ${(bbox.northWest[1] * 180 / Math.PI).toFixed(2)}) SE(${(bbox.southEast[0] * 180 / Math.PI).toFixed(2)}, ${(bbox.southEast[1] * 180 / Math.PI).toFixed(2)})`);
96
+ console.log(`Texture BBOX ${i}: LL(${(bbox.ll[0] * 180 / Math.PI).toFixed(2)}, ${(bbox.ll[1] * 180 / Math.PI).toFixed(2)}) UR(${(bbox.ur[0] * 180 / Math.PI).toFixed(2)}, ${(bbox.ur[1] * 180 / Math.PI).toFixed(2)})`);
24
97
  if (demData.length > i) {
25
98
  const dem = demData[i];
26
99
  let demStr = "DEM: \n";
@@ -70,6 +143,7 @@ export class TextureDemTrianglesTestPlugin {
70
143
  textureDemTriangles = null;
71
144
  vao = null;
72
145
  drawOptions = null;
146
+ _lastTilesUniqueIdentifier = "";
73
147
  bufferInfo = null;
74
148
  id;
75
149
  uboTriangleStyle = null;
@@ -139,15 +213,16 @@ export class TextureDemTrianglesTestPlugin {
139
213
  this.bboxZooms = demTextureBBOX.map((bbox, index) => {
140
214
  return {
141
215
  bbox: {
142
- min: [bbox.northWest[0], bbox.southEast[1]], max: [bbox.southEast[0], bbox.northWest[1]]
216
+ min: bbox.ll,
217
+ max: bbox.ur,
143
218
  }, zoom: index + zoomLevel + 1
144
219
  };
145
220
  });
146
- // all world
221
+ // all world - FIX: Convert to radians
147
222
  this.bboxZooms.push({
148
223
  bbox: {
149
- min: [-180, -90],
150
- max: [180, 90]
224
+ min: [-180 * RADIAN, -90 * RADIAN], // ✓ Now radians
225
+ max: [180 * RADIAN, 90 * RADIAN] // ✓ Now radians
151
226
  },
152
227
  zoom: zoomLevel
153
228
  });
@@ -159,31 +234,17 @@ export class TextureDemTrianglesTestPlugin {
159
234
  const p1 = [-60 * Math.PI / 180, 60 * Math.PI / 180];
160
235
  const p2 = [60 * Math.PI / 180, 60 * Math.PI / 180];
161
236
  const p3 = [0, -60 * Math.PI / 180];
162
- // const p1_1: LongLatRadian = [-20 * Math.PI / 180, 30 * Math.PI / 180];
163
- // const p2_2: LongLatRadian = [20 * Math.PI / 180, 20 * Math.PI / 180];
164
- // const p3_3: LongLatRadian = [5, -20 * Math.PI / 180];
165
- // const { vec3s, longLats, indices } = test1(zoomLevel, p1, p2, p3);
166
- // const {vec3s, longLats, indices} = test1(5, p1_1, p2_2, p3_3);
167
- const { vec3s, longLats, indices } = partialTest(this.bboxZooms, p1, p2, p3);
237
+ const bigTriangle = partialTest(this.bboxZooms, p1, p2, p3);
168
238
  const bufferInfo = this.bufferInfo;
239
+ const antalya = antalyaTestTriangle();
240
+ loadVec3sLongLatsIndices(this.globe.gl, bufferInfo, [
241
+ bigTriangle,
242
+ antalya
243
+ ]);
169
244
  bufferInfo.drawOptions.drawRange.first = 0;
170
- bufferInfo.drawOptions.drawRange.count = indices.length;
245
+ bufferInfo.drawOptions.drawRange.count = antalya.indices.length + bigTriangle.indices.length;
171
246
  bufferInfo.drawOptionsPoint.drawRange.first = 0;
172
- bufferInfo.drawOptionsPoint.drawRange.count = longLats.length / 2;
173
- const gl = this.globe.gl;
174
- // const longLatArray = createTestLongLatArray();
175
- // const pos3dArray = createTestPos3dArray(longLatArray);
176
- // @ts-ignore
177
- gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.pos3dBufferInfo.buffer);
178
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vec3s), gl.STATIC_DRAW);
179
- // @ts-ignore
180
- gl.bindBuffer(gl.ARRAY_BUFFER, bufferInfo.longLatBufferInfo.buffer);
181
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(longLats), gl.STATIC_DRAW);
182
- // @ts-ignore
183
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, bufferInfo.elementBufferInfo.buffer);
184
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint32Array(indices), gl.STATIC_DRAW);
185
- this.globe.DrawRender();
186
- console.log("DrawIInfo", this.bufferInfo);
247
+ bufferInfo.drawOptionsPoint.drawRange.count = (antalya.longLats.length + bigTriangle.longLats.length) / 2;
187
248
  }
188
249
  setShowDemPoints(show) {
189
250
  this.showDemPoints = show;
@@ -192,6 +253,7 @@ export class TextureDemTrianglesTestPlugin {
192
253
  if (!this.globe || !this.textureDemTriangles || !this.vao || !this.bufferInfo)
193
254
  return;
194
255
  const gl = this.globe.gl;
256
+ this._prepareDem();
195
257
  gl.frontFace(gl.CW);
196
258
  // @ts-ignore
197
259
  this.textureDemTriangles.draw(this.vao, this.bufferInfo.drawOptions, this.uboTriangleStyle);
@@ -201,4 +263,66 @@ export class TextureDemTrianglesTestPlugin {
201
263
  }
202
264
  gl.frontFace(gl.CCW);
203
265
  }
266
+ _prepareDem() {
267
+ if (!this.globe || !this.textureDemTriangles)
268
+ return;
269
+ const drawnTiles = this.globe.api_GetDrawedTilesInfo();
270
+ if (this._checkTileChange(drawnTiles))
271
+ return;
272
+ const mergedTiles = mergeMeshes(drawnTiles, 12, 5, 4);
273
+ // let I = 6;
274
+ for (const tile of mergedTiles) {
275
+ const bbox = globeBBoxToXYBBOX(tile.bbox);
276
+ // Validation: Check if values are in expected radian range
277
+ // if (Math.abs(bbox.northWest[0]) > Math.PI * 2 || Math.abs(bbox.northWest[1]) > Math.PI) {
278
+ // console.error(`⚠️ BBOX out of radian range! Raw bbox:`, tile.bbox);
279
+ // }
280
+ if (bbox.ll[0] > bbox.ur[0]) {
281
+ console.warn(`⚠️ BBOX longitudes seem incorrect! ll longitude is greater than ur longitude. Raw bbox:`, bbox);
282
+ }
283
+ if (bbox.ll[1] > bbox.ur[1]) {
284
+ console.warn(`⚠️ BBOX latitudes seem incorrect! ll latitude is greater than ur latitude. Raw bbox:`, bbox);
285
+ }
286
+ // console.log(` BBox LL (${(bbox.ll[0]).toFixed(2)}°, ${(bbox.ll[1]).toFixed(2)}°) UR (${(bbox.ur[0]).toFixed(2)}°, ${(bbox.ur[1]).toFixed(2)}°), Cover: ${tile.coverRatio.x.toFixed(2)}x${tile.coverRatio.y.toFixed(2)}`);
287
+ // console.log(`${I} Cover: ${tile.coverRatio.x.toFixed(2)} ${tile.coverRatio.y.toFixed(2)}`);
288
+ // I--;
289
+ }
290
+ // console.log("...............................")
291
+ this.textureDemTriangles.setDemTextures(mergedTiles.map(t => Array.from(t.mesh)), mergedTiles.map(t => globeBBoxToXYBBOX(t.bbox)), mergedTiles.map(t => ({ x: t.coverRatio.x, y: t.coverRatio.y })));
292
+ }
293
+ _checkTileChange(drawnTiles) {
294
+ let maxLevel = 0;
295
+ let minLevel = Number.MAX_VALUE;
296
+ const tileMap = new Map();
297
+ for (const tile of drawnTiles) {
298
+ if (tile.level > maxLevel) {
299
+ maxLevel = tile.level;
300
+ }
301
+ if (tile.level < minLevel) {
302
+ minLevel = tile.level;
303
+ }
304
+ if (!tileMap.has(tile.level)) {
305
+ tileMap.set(tile.level, []);
306
+ }
307
+ tileMap.get(tile.level).push(tile);
308
+ }
309
+ let tilesUniqueId = "";
310
+ for (let level = minLevel; level <= maxLevel; level++) {
311
+ const tiles = tileMap.get(level);
312
+ if (!tiles)
313
+ continue;
314
+ tilesUniqueId += `L${level}_C${tiles.length}_`;
315
+ }
316
+ if (tilesUniqueId === this._lastTilesUniqueIdentifier)
317
+ return true;
318
+ this._lastTilesUniqueIdentifier = tilesUniqueId;
319
+ return false;
320
+ }
321
+ }
322
+ function globeBBoxToXYBBOX(t) {
323
+ // this code scales Y to linear integration
324
+ return {
325
+ ll: radianToMercatorXY([t.ll.x * RADIAN, t.ll.y * RADIAN]), // west longitude, north latitude
326
+ ur: radianToMercatorXY([t.ur.x * RADIAN, t.ur.y * RADIAN]) // east longitude, south latitude
327
+ };
204
328
  }
@@ -25,19 +25,14 @@ ${CameraUniformBlockString}
25
25
 
26
26
  ${cartesian3DToGLPosition}
27
27
  in vec3 a_position;
28
- in vec2 a_longLat;
28
+ in vec2 a_xy;
29
29
  uniform sampler2DArray u_demTexture; // <-- changed from array to single
30
30
  uniform vec4 u_demTextureBBOX[6];
31
-
31
+ uniform vec2 u_textureDataCoverRatio[6];
32
+ uniform int u_breakLoopIndex;
32
33
 
33
34
  ${styleBlockManager.glslCode()}
34
-
35
-
36
- // TODO: light directioni
37
- // out vec3 v_position;
38
- // out vec3 v_normal;
39
- // out vec2 v_textureCoord;
40
-
35
+ // Todo: light direction.
41
36
  out vec4 v_color;
42
37
 
43
38
 
@@ -46,23 +41,35 @@ ${isPointInBBox}
46
41
  void main() {
47
42
 
48
43
  float elevation = ${WORLD_RADIUS_3D}; // default elevation at sea level
44
+ float altitude = 0.0;
49
45
  v_color = vec4(1.0, 1.0, 1.0, 1.0); // default color white
46
+
50
47
  for (int i = 0; i < 6; i++) {
51
- if (isPointInBBox(a_longLat, u_demTextureBBOX[i])) {
52
- vec2 uv = (a_longLat - u_demTextureBBOX[i].xy) / (u_demTextureBBOX[i].zw - u_demTextureBBOX[i].xy);
53
- float altitude = texture(u_demTexture, vec3(uv, float(i))).r;
54
- elevation += altitude;
55
- v_color = mix(vec4(0.0, 0.0, 1.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), altitude / 100.0); // color from blue to red based on altitude
56
- break;
57
- }
48
+ if (isPointInBBox(a_xy, u_demTextureBBOX[i])) {
49
+ vec2 uv = (a_xy - u_demTextureBBOX[i].xy) / (u_demTextureBBOX[i].zw - u_demTextureBBOX[i].xy);
50
+ // uv.y = 1.0 - uv.y; // flip y coordinate
51
+ // rescale and transform uv to fit in the texture data cover bbox
52
+ uv *= u_textureDataCoverRatio[i];
53
+ altitude = texture(u_demTexture, vec3(uv, float(i))).r;
54
+ if (altitude != 0.0) {
55
+ break;
56
+ }
57
+ }
58
58
  }
59
59
  if (u_color.a > 0.0) {
60
60
  v_color = u_color;
61
+ } else {
62
+ if ( altitude > 0.00001 ) {
63
+ v_color = mix(vec4(1.0, 1.0, 1.0, 1.0), vec4(1.0, 0.2, 0.2, 1.0), altitude / 2.0); // color from white to red based on altitude
64
+ } else {
65
+ // white
66
+ v_color = vec4(1.0, 1.0, 1.0, 0.5);
67
+ }
61
68
  }
62
69
  v_color.a *= u_opacity;
63
- vec3 position = a_position * elevation;
70
+ vec3 position = a_position * (elevation + altitude * 2.0);
64
71
  gl_Position = cartesian3DToGLPosition(position);
65
- gl_PointSize = 5.0; //u_pointSize;
72
+ gl_PointSize = 6.0; //u_pointSize;
66
73
  }
67
74
  `;
68
75
  const fragmentShaderSource = `#version 300 es
@@ -75,6 +82,10 @@ void main() {
75
82
  outColor = v_color;
76
83
  }
77
84
  `;
85
+ function resCalculation(sourceResolution, mergeCount) {
86
+ return sourceResolution + (mergeCount - 1) * (sourceResolution - 1);
87
+ }
88
+ const RESOLUTION = resCalculation(5, 12); // 5 is tile dimension length, 12 is merge count
78
89
  export class TextureDemTriangles {
79
90
  globe;
80
91
  gl;
@@ -88,12 +99,14 @@ export class TextureDemTriangles {
88
99
  locations = {
89
100
  attributes: {
90
101
  a_position: -1,
91
- a_longLat: -1,
102
+ a_xy: -1,
92
103
  },
93
104
  uniforms: {
94
105
  u_demTexture: -1,
95
106
  u_demTextureBBOX: -1,
107
+ u_textureDataCoverRatio: -1,
96
108
  u_style: -1,
109
+ u_breakLoopIndex: -1,
97
110
  }
98
111
  };
99
112
  constructor(globe) {
@@ -104,17 +117,20 @@ export class TextureDemTriangles {
104
117
  this.cameraUniformBlock.assignBindingPoint(this.program, uniformBindingPoints.camera);
105
118
  // get attribute locations
106
119
  this.locations.attributes.a_position = this.gl.getAttribLocation(this.program, 'a_position');
107
- this.locations.attributes.a_longLat = this.gl.getAttribLocation(this.program, 'a_longLat');
120
+ this.locations.attributes.a_xy = this.gl.getAttribLocation(this.program, 'a_xy');
108
121
  // get uniform locations
109
122
  this.locations.uniforms.u_demTexture = this.gl.getUniformLocation(this.program, 'u_demTexture');
110
123
  this.locations.uniforms.u_demTextureBBOX = this.gl.getUniformLocation(this.program, 'u_demTextureBBOX');
124
+ this.locations.uniforms.u_textureDataCoverRatio = this.gl.getUniformLocation(this.program, 'u_textureDataCoverRatio');
125
+ this.locations.uniforms.u_breakLoopIndex = this.gl.getUniformLocation(this.program, 'u_breakLoopIndex');
111
126
  this.locations.uniforms.u_style = this.gl.getUniformBlockIndex(this.program, 'Style');
112
127
  this.gl.uniformBlockBinding(this.program, this.locations.uniforms.u_style, uniformBindingPoints.style);
113
128
  // create 3d texture
114
129
  const texture = this.gl.createTexture();
115
130
  this.gl.bindTexture(this.gl.TEXTURE_2D_ARRAY, texture);
116
- // this.gl.texImage3D(this.gl.TEXTURE_2D_ARRAY, 0, this.gl.R32F, 25, 25, 6, 0, this.gl.RED, this.gl.FLOAT, null);
117
- this.gl.texStorage3D(this.gl.TEXTURE_2D_ARRAY, 1, this.gl.R32F, 5, 5, 6);
131
+ // Calculate correct size: tileDimensionLength + (mergeCount - 1) * (tileDimensionLength - 1)
132
+ // For tileDimensionLength=5, mergeCount=8: 5 + 7*4 = RESOLUTION
133
+ this.gl.texStorage3D(this.gl.TEXTURE_2D_ARRAY, 1, this.gl.R32F, RESOLUTION, RESOLUTION, 6);
118
134
  // set texture parameters
119
135
  const ext = this.gl.getExtension('OES_texture_float_linear');
120
136
  console.log('OES_texture_float_linear extension:', ext);
@@ -129,11 +145,17 @@ export class TextureDemTriangles {
129
145
  const vao = this.gl.createVertexArray();
130
146
  this.gl.bindVertexArray(vao);
131
147
  attributeLoader(this.gl, pos3dBufferInfo, this.locations.attributes.a_position, 3);
132
- attributeLoader(this.gl, longLatBufferInfo, this.locations.attributes.a_longLat, 2);
148
+ attributeLoader(this.gl, longLatBufferInfo, this.locations.attributes.a_xy, 2);
133
149
  this.gl.bindVertexArray(null);
134
150
  return vao;
135
151
  }
136
- setDemTextures(demTexturesData, demTextureBBOX) {
152
+ setDemTextures(demTexturesData, demTextureBBOX, coverRatio) {
153
+ // Add validation for maximum layers
154
+ const maxLayers = this.gl.getParameter(this.gl.MAX_ARRAY_TEXTURE_LAYERS);
155
+ if (demTexturesData.length > Math.min(maxLayers, 6)) {
156
+ console.error(`Too many DEM textures: ${demTexturesData.length}, max supported: ${Math.min(maxLayers, 6)}`);
157
+ return;
158
+ }
137
159
  // bind textures to texture units
138
160
  const gl = this.gl;
139
161
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, this.texture);
@@ -143,23 +165,33 @@ export class TextureDemTriangles {
143
165
  // bind and upload each texture to the 3D texture array
144
166
  for (let i = 0; i < demTexturesData.length; i++) {
145
167
  const data = demTexturesData[i];
146
- if (data.length === 5 * 5) { // <-- FIXED
147
- gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, i, 5, 5, 1, gl.RED, gl.FLOAT, new Float32Array(data));
168
+ if (data.length === RESOLUTION * RESOLUTION) { // <-- FIXED
169
+ gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, i, RESOLUTION, RESOLUTION, 1, gl.RED, gl.FLOAT, new Float32Array(data));
170
+ }
171
+ else {
172
+ console.warn(`DEM texture ${i} has incorrect size: ${data.length}, expected: ${RESOLUTION * RESOLUTION}`);
148
173
  }
149
174
  }
150
175
  // set uniform for texture units
151
176
  const bboxVec4Array = new Float32Array(6 * 4);
152
177
  for (let i = 0; i < demTextureBBOX.length; i++) {
153
178
  const bbox = demTextureBBOX[i];
154
- bboxVec4Array[i * 4 + 0] = bbox.northWest[0];
155
- bboxVec4Array[i * 4 + 1] = bbox.southEast[1];
156
- bboxVec4Array[i * 4 + 2] = bbox.southEast[0];
157
- bboxVec4Array[i * 4 + 3] = bbox.northWest[1];
179
+ bboxVec4Array[i * 4 + 0] = bbox.ll[0];
180
+ bboxVec4Array[i * 4 + 1] = bbox.ll[1];
181
+ bboxVec4Array[i * 4 + 2] = bbox.ur[0];
182
+ bboxVec4Array[i * 4 + 3] = bbox.ur[1];
158
183
  }
159
184
  const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
160
185
  gl.useProgram(this.program);
161
186
  gl.uniform4fv(this.locations.uniforms.u_demTextureBBOX, bboxVec4Array);
187
+ if (coverRatio) {
188
+ gl.uniform2fv(this.locations.uniforms.u_textureDataCoverRatio, new Float32Array(coverRatio.flatMap(ratio => [ratio.x, ratio.y])));
189
+ }
190
+ else {
191
+ gl.uniform2fv(this.locations.uniforms.u_textureDataCoverRatio, new Float32Array(12).fill(1.0));
192
+ }
162
193
  gl.bindTexture(gl.TEXTURE_2D_ARRAY, null);
194
+ gl.uniform1i(this.locations.uniforms.u_breakLoopIndex, demTexturesData.length);
163
195
  gl.useProgram(currentProgram);
164
196
  }
165
197
  createUBO(bufferReadType = "STATIC_DRAW") {
@@ -213,10 +245,10 @@ export class TextureDemTriangles {
213
245
  }
214
246
  }
215
247
  function drawOnTopBegin(gl) {
216
- // gl.disable(gl.DEPTH_TEST);
248
+ gl.disable(gl.DEPTH_TEST);
217
249
  // gl.enable(gl.POLYGON_OFFSET_FILL);
218
250
  // // Use an offset to "nudge" the depth value slightly closer or farther.
219
- // // Common values are gl.polygonOffset(1.0, 1.0) or gl.polygonOffset(0.5, 0.5)
251
+ // // Common values are gl.polygonOffset(1.0, 1.0) or gl.polygonOffset(0.RESOLUTION, 0.RESOLUTION)
220
252
  // gl.polygonOffset(1.0, 1.0);
221
253
  // gl.depthRange(0.0, 0.0001); // Use near 0.01% of depth range
222
254
  // gl.enable(gl.POLYGON_OFFSET_FILL);
@@ -224,13 +256,13 @@ function drawOnTopBegin(gl) {
224
256
  // A good starting point is -1.0, -1.0.
225
257
  // Negative values "pull" the fragments closer to the camera.
226
258
  // gl.polygonOffset(-1.0, -1.0);
227
- gl.enable(gl.POLYGON_OFFSET_FILL);
228
- gl.polygonOffset(-1.0, -2.0);
259
+ // gl.enable(gl.POLYGON_OFFSET_FILL);
260
+ // gl.polygonOffset(-1.0, -2.0);
229
261
  }
230
262
  function drawOnTopEnd(gl) {
231
- // gl.enable(gl.DEPTH_TEST);
263
+ gl.enable(gl.DEPTH_TEST);
232
264
  // gl.disable(gl.POLYGON_OFFSET_FILL);
233
265
  // gl.disable(gl.POLYGON_OFFSET_FILL);
234
266
  // gl.depthRange(0.0, 1.0); // Restore full depth range
235
- gl.disable(gl.POLYGON_OFFSET_FILL);
267
+ // gl.disable(gl.POLYGON_OFFSET_FILL);
236
268
  }
@@ -63,10 +63,12 @@ void main(){
63
63
  outColor = vec4(base_color, 1.0);
64
64
  }`;
65
65
  class Logic {
66
+ gl;
67
+ program;
68
+ _vector_field_location;
66
69
  constructor(gl) {
67
70
  this.gl = gl;
68
- [this.program,
69
- this._vector_field_location] = this._createProgram();
71
+ [this.program, this._vector_field_location] = this._createProgram();
70
72
  // this.decoyBuffer = new DecoyBufferManager(gl);
71
73
  }
72
74
  _createProgram() {
@@ -75,13 +77,13 @@ class Logic {
75
77
  // ubo point
76
78
  // const ubo_location = gl.getUniformBlockIndex(program, 'UBO');
77
79
  // gl.uniformBlockBinding(program, ubo_location, UBO_BINDING_POINT);
78
- SeaWaveUbo.assignBindingPoint(gl, program, 0);
80
+ SeaWaveUbo.assignBindingPoint(gl, program);
79
81
  return [program, gl.getUniformLocation(program, 'u_vector_field')];
80
82
  }
81
83
  /**
82
- * @param {*} bufferManager | PingPongBufferManager
83
- * @param {*} vectorTexture | RG32F texture R: x, G: y
84
- * @param {*} uboManager | WaveParticalUboManager under ubo.js
84
+ * @param bufferManager | PingPongBufferManager
85
+ * @param vectorTexture | RG32F texture R: x, G: y
86
+ * @param uboManager | WaveParticalUboManager under ubo.js
85
87
  */
86
88
  draw(bufferManager, vectorTexture, uboManager) {
87
89
  const { gl, program } = this;
@@ -0,0 +1,112 @@
1
+ import { createProgram } from "../../../util/webglobjectbuilders";
2
+ import { glProgramCache } from "../../programcache";
3
+ import { SeaWaveUbo } from "./ubo-new";
4
+ /**
5
+ * [+] ubo
6
+ */
7
+ const vertexShaderSource = `#version 300 es
8
+ precision highp float;
9
+ ` + SeaWaveUbo.glslCode() + `
10
+ uniform sampler2D u_vector_field;
11
+ in vec2 in_position;
12
+ out vec3 base_color;
13
+
14
+
15
+ vec2 read_value(const vec2 uv) {
16
+ vec2 value = texture(u_vector_field, uv).rg;
17
+ if ( value.x == escape_value || value.y == escape_value) {
18
+ return vec2(0.0);
19
+ }
20
+ return value;
21
+ }
22
+
23
+
24
+ vec2 lookup_wind(const vec2 uv) { // gerek kalmayabilir. sampler linear methodu ayni isi yapiyor
25
+ // return texture(u_vector_field, uv).rg; // lower-res hardware filtering
26
+ vec2 res = vec2(textureSize(u_vector_field, 0));
27
+ vec2 px = 1.0 / res;
28
+ vec2 vc = (floor(uv * res)) * px;
29
+ vec2 f = fract(uv * res);
30
+ vec2 tl = read_value(vc).rg;
31
+ vec2 tr = read_value(vc + vec2(px.x, 0)).rg;
32
+ vec2 bl = read_value(vc + vec2(0, px.y)).rg;
33
+ vec2 br = read_value(vc + px).rg;
34
+
35
+ return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);
36
+ }
37
+
38
+
39
+ void main(){
40
+ vec2 direction_vector = lookup_wind(in_position);
41
+ if (direction_vector.r == 0.0 && direction_vector.g == 0.0) return;
42
+
43
+
44
+ vec2 limp;
45
+ if ( 0 == gl_VertexID) { limp = -tail_wing_base_limp; }
46
+ else if ( 1 == gl_VertexID) { limp = vec2( tail_wing_base_limp.x, -tail_wing_base_limp.y); }
47
+ else if ( 2 == gl_VertexID) { limp = tail_wing_base_limp; }
48
+ else { limp = vec2(-tail_wing_base_limp.x, tail_wing_base_limp.y); } // if ( 3 == gl_VertexID)
49
+
50
+ limp = (limp * mat2(
51
+ direction_vector.x, -direction_vector.y,
52
+ direction_vector.y, direction_vector.x)) / draw_texture_size;
53
+
54
+ vec2 pos = in_position * 2.0 - 1.0;
55
+ gl_Position = vec4(pos + limp, 0.0, 1.0);
56
+ base_color = color;
57
+ }`;
58
+ const fragmentShaderSource = `#version 300 es
59
+ precision highp float;
60
+ out vec4 outColor;
61
+ in vec3 base_color;
62
+ void main(){
63
+ outColor = vec4(base_color, 1.0);
64
+ }`;
65
+ class Logic {
66
+ constructor(gl) {
67
+ this.gl = gl;
68
+ [this.program,
69
+ this._vector_field_location] = this._createProgram();
70
+ // this.decoyBuffer = new DecoyBufferManager(gl);
71
+ }
72
+ _createProgram() {
73
+ const gl = this.gl;
74
+ const program = createProgram(gl, vertexShaderSource, fragmentShaderSource);
75
+ // ubo point
76
+ // const ubo_location = gl.getUniformBlockIndex(program, 'UBO');
77
+ // gl.uniformBlockBinding(program, ubo_location, UBO_BINDING_POINT);
78
+ SeaWaveUbo.assignBindingPoint(gl, program, 0);
79
+ return [program, gl.getUniformLocation(program, 'u_vector_field')];
80
+ }
81
+ /**
82
+ * @param {*} bufferManager | PingPongBufferManager
83
+ * @param {*} vectorTexture | RG32F texture R: x, G: y
84
+ * @param {*} uboManager | WaveParticalUboManager under ubo.js
85
+ */
86
+ draw(bufferManager, vectorTexture, uboManager) {
87
+ const { gl, program } = this;
88
+ gl.useProgram(program);
89
+ gl.bindVertexArray(bufferManager.getSourceVao());
90
+ // gl.bindVertexArray(this.decoyBuffer.getSourceVao());
91
+ uboManager.bind();
92
+ gl.activeTexture(gl.TEXTURE0);
93
+ gl.uniform1i(this._vector_field_location, 0);
94
+ gl.bindTexture(gl.TEXTURE_2D, vectorTexture);
95
+ gl.drawArraysInstanced(gl.TRIANGLE_FAN, 0, 4, bufferManager.length);
96
+ gl.drawArraysInstanced(gl.POINTS, 0, 4, bufferManager.length);
97
+ gl.bindVertexArray(null);
98
+ uboManager.unbind();
99
+ }
100
+ free() {
101
+ this.gl.deleteProgram(this.program);
102
+ this.program = null;
103
+ }
104
+ }
105
+ export const drawRectangleParticlesProgramCache = Object.freeze({
106
+ getProgram: (gl) => {
107
+ return glProgramCache.getProgram(gl, Logic);
108
+ },
109
+ releaseProgram: (gl) => {
110
+ glProgramCache.releaseProgram(gl, Logic);
111
+ }
112
+ });
@@ -137,6 +137,15 @@ export class ArcOnTerrainPlugin {
137
137
  this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
138
138
  this.globe.DrawRender();
139
139
  }
140
+ deleteAll() {
141
+ if (!this.bufferOrchestrator || !this.bufferManagersMap || !this.globe) {
142
+ console.warn("Buffer orchestrator or buffer manager map is not initialized.");
143
+ return;
144
+ }
145
+ this.bufferOrchestrator.resetWithCapacity(this.bufferManagersMap, this._arcMap.size);
146
+ this._arcMap.clear();
147
+ this.globe.DrawRender();
148
+ }
140
149
  updateColors(keyColorCouples, drawRender = true) {
141
150
  if (this._freed) {
142
151
  console.warn("Plugin is freed, cannot update color");
@@ -1,6 +1,7 @@
1
1
  import { BufferOrchestrator, BufferManager, ObjectStore } from "../../util/account/index";
2
2
  import { PickerDisplayer } from "../../util/picking/picker-displayer";
3
3
  import { PointOnGlobeProgramCache } from "../../programs/point-on-globe/square-pixel-point";
4
+ import { defaultblendfunction } from "../../util/webglobe/gldefaultstates";
4
5
  import { wgs84ToCartesian3d, wgs84ToMercator } from "../../Math/methods";
5
6
  const _0vec3 = /* @__PURE__ */ [0, 0, 0];
6
7
  /**
@@ -60,8 +60,8 @@ class PickerDisplayer {
60
60
  }
61
61
  // call after drawing the scene with gl picker shader
62
62
  drawColorTexture() {
63
- const { colorTexture } = this;
64
- this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
63
+ const { gl, colorTexture } = this;
64
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null);
65
65
  this.displayer.draw(colorTexture);
66
66
  }
67
67
  pickXY(x, y, selectionPointFilling = 1, callback = () => { }) {
@@ -200,7 +200,7 @@ float realDistanceOnSphereR1(vec2 longLat1, vec2 longLat2) {
200
200
  `;
201
201
  export const isPointInBBox = `
202
202
  bool isPointInBBox(vec2 point, vec4 bbox) {
203
- return point.x + ${EPSILON} >= bbox.x && point.x <= bbox.z + ${EPSILON} && point.y + ${EPSILON} >= bbox.y && point.y <= bbox.w + ${EPSILON};
203
+ return point.x >= bbox.x && point.x <= bbox.z && point.y >= bbox.y && point.y <= bbox.w;
204
204
  }
205
205
  `;
206
206
  const pointsOnSphereBetween = `