@pirireis/webglobeplugins 0.15.21-alpha → 0.15.24
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.
- package/Math/arc.js +1 -2
- package/Math/circle-cdf-points.js +1 -170
- package/Math/circle.js +0 -25
- package/Math/vec3.js +1 -1
- package/altitude-locator/plugin.js +1 -1
- package/package.json +1 -1
- package/point-tracks/plugin.js +5 -6
- package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
- package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
- package/programs/totems/camerauniformblock.js +7 -0
- package/programs/totems/canvas-webglobe-info.js +9 -9
- package/programs/totems/globe-changes.js +21 -14
- package/range-tools-on-terrain/bearing-line/plugin.js +2 -5
- package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +4 -9
- package/range-tools-on-terrain/circle-line-chain/plugin.js +4 -2
- package/range-tools-on-terrain/range-ring/adapters.js +25 -9
- package/range-tools-on-terrain/range-ring/plugin.js +200 -5
- package/range-tools-on-terrain/range-ring/types.js +9 -1
- package/semiplugins/lightweight/line-plugin.js +33 -15
- package/semiplugins/shape-on-terrain/arc-plugin.js +162 -99
- package/semiplugins/shape-on-terrain/circle-plugin.js +170 -83
- package/semiplugins/shape-on-terrain/padding-1-degree.js +244 -63
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +1 -1
- package/util/build-strategy/static-dynamic.js +11 -1
- package/util/frame-counter-trigger.js +84 -0
- package/wind/imagetovectorfieldandmagnitude.js +23 -0
- package/wind/index.js +2 -2
- package/wind/plugin.js +30 -9
- package/write-text/context-text4.js +140 -0
- package/Math/arc-generate-points copy.js +0 -366
- package/Math/globe-util/horizon-plane.js +0 -112
- package/altitude-locator/draw-subset-obj.js +0 -16
- package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
|
@@ -16,23 +16,23 @@ import { BufferManager } from '../../util/account/single-attribute-buffer-manage
|
|
|
16
16
|
import { BufferOrchestrator } from '../../util/account/single-attribute-buffer-management/buffer-orchestrator';
|
|
17
17
|
import { LineStripProgramCache } from '../../programs/line-on-globe/linestrip/linestrip';
|
|
18
18
|
import { opacityCheck, colorCheck } from '../../util/check/typecheck';
|
|
19
|
+
import { FrameCounterTrigger } from '../../util/frame-counter-trigger';
|
|
19
20
|
const initialCapacity = 2; // initial capacity for the buffer managers
|
|
20
21
|
// const _float32Array = new Float32Array(360 * 3 * 2).fill(NaN);
|
|
21
22
|
export class Padding1DegreePlugin {
|
|
22
23
|
id;
|
|
23
24
|
globe = null;
|
|
24
25
|
bufferOrchestrator;
|
|
25
|
-
|
|
26
|
+
bufferManagerMap;
|
|
26
27
|
lineProgram = null;
|
|
27
|
-
|
|
28
|
-
_pluginOpacity = 1; // this is used to set the opacity of the plugin
|
|
29
|
-
_innerPaddingRatio = 0.9; //
|
|
28
|
+
_innerPaddingRatio = 0.95; //
|
|
30
29
|
_float32Array = null; // this is used to forward the data to the buffer manager
|
|
31
30
|
_uboHandler = null; // this is used to forward the data to the shader program
|
|
32
31
|
_bufferNames = ["position2d", "position3d"];
|
|
33
32
|
_vao = null; // this is used to store the VAO for the plugin
|
|
34
33
|
_freed = false; // this is used to check if the plugin is freed or not
|
|
35
|
-
|
|
34
|
+
_userOpacity = 1;
|
|
35
|
+
_adaptiveOpacityMultiplier = 1;
|
|
36
36
|
_dataMap = new Map();
|
|
37
37
|
_options = {
|
|
38
38
|
bufferType: "STATIC_DRAW",
|
|
@@ -43,9 +43,10 @@ export class Padding1DegreePlugin {
|
|
|
43
43
|
adaptiveOpacity: true, // if true, the opacity will be adaptive to the LOD
|
|
44
44
|
isMSL: false // if true, no elevation of terrain
|
|
45
45
|
};
|
|
46
|
+
_frameCounterTrigger = null;
|
|
46
47
|
constructor(id, options = null) {
|
|
47
48
|
this.id = id;
|
|
48
|
-
this.
|
|
49
|
+
this.bufferManagerMap = new Map();
|
|
49
50
|
this.lineProgram = null;
|
|
50
51
|
this._options = options ? { ...this._options, ...options } : this._options;
|
|
51
52
|
this.bufferOrchestrator = new BufferOrchestrator();
|
|
@@ -53,6 +54,21 @@ export class Padding1DegreePlugin {
|
|
|
53
54
|
this._bufferNames.push("color");
|
|
54
55
|
}
|
|
55
56
|
}
|
|
57
|
+
increaseSpace(amount) {
|
|
58
|
+
if (this._freed) {
|
|
59
|
+
console.warn("Plugin is freed, cannot increase space");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (this.globe === null) {
|
|
63
|
+
console.warn("Globe is not initialized.");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (typeof amount !== "number" || amount <= 0) {
|
|
67
|
+
console.warn("Invalid amount, must be a positive number");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
this.bufferOrchestrator.ensureSpace(amount, this.bufferManagerMap);
|
|
71
|
+
}
|
|
56
72
|
insertBulk(inputs) {
|
|
57
73
|
if (this.globe === null) {
|
|
58
74
|
console.warn("Globe is not initialized, cannot insert input");
|
|
@@ -64,16 +80,78 @@ export class Padding1DegreePlugin {
|
|
|
64
80
|
}
|
|
65
81
|
const wrapper = [null];
|
|
66
82
|
this._float32Array = new Float32Array(360 * 4 * 4); // largest float32Array
|
|
83
|
+
let newItemCount = 0;
|
|
84
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
85
|
+
if (!this._dataMap.has(inputs[i].key)) {
|
|
86
|
+
newItemCount++;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
this.bufferOrchestrator.ensureSpace(newItemCount, this.bufferManagerMap);
|
|
67
90
|
for (let i = 0; i < inputs.length; i++) {
|
|
68
91
|
const coords = preAdapter(this.globe, inputs[i], this._innerPaddingRatio, null);
|
|
69
92
|
const paddingInput = { ...inputs[i], ...coords };
|
|
70
93
|
this._dataMap.set(paddingInput.key, paddingInput);
|
|
71
94
|
wrapper[0] = paddingInput;
|
|
72
|
-
this.bufferOrchestrator.insertBulk(wrapper, this.
|
|
95
|
+
this.bufferOrchestrator.insertBulk(wrapper, this.bufferManagerMap, this._bufferNames);
|
|
73
96
|
}
|
|
74
97
|
this._float32Array = null;
|
|
75
98
|
this.globe?.DrawRender();
|
|
76
99
|
}
|
|
100
|
+
updateColorRatios(key, colorRatios, drawRender = true) {
|
|
101
|
+
if (this._freed) {
|
|
102
|
+
console.warn("Plugin is freed, cannot update color");
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (this.globe === null) {
|
|
106
|
+
console.warn("Globe is not initialized, cannot update color");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (!this._options.variativeColorsOn) {
|
|
110
|
+
console.warn("VariativeColors are not enabled");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
if (!this._dataMap.has(key)) {
|
|
114
|
+
console.warn(`Key ${key} does not exist in the data map`);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const paddingInput = this._dataMap.get(key);
|
|
118
|
+
if (!paddingInput) {
|
|
119
|
+
console.warn(`Padding input for key ${key} is not found`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
this._float32Array = new Float32Array(360 * 4 * 4); // largest float32Array
|
|
123
|
+
paddingInput.colorsRatios = colorRatios;
|
|
124
|
+
this.bufferOrchestrator.updateBulk([paddingInput], this.bufferManagerMap, ["color"]);
|
|
125
|
+
this._float32Array = null;
|
|
126
|
+
if (drawRender) {
|
|
127
|
+
this.globe.DrawRender();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
updateCoordinates(items) {
|
|
131
|
+
if (this._freed) {
|
|
132
|
+
console.warn("Plugin is freed, cannot update coordinates");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (this.globe === null) {
|
|
136
|
+
console.warn("Globe is not initialized, cannot update coordinates");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
this._float32Array = new Float32Array(360 * 4 * 4); // largest float32Array
|
|
140
|
+
const updateKeys = [];
|
|
141
|
+
for (const item of items) {
|
|
142
|
+
const paddingInput = this._dataMap.get(item.key);
|
|
143
|
+
if (!paddingInput) {
|
|
144
|
+
console.warn(`Padding input for key ${item.key} is not found`);
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
paddingInput.center = item.center;
|
|
148
|
+
paddingInput.radius = item.radius;
|
|
149
|
+
updateKeys.push(item.key);
|
|
150
|
+
}
|
|
151
|
+
this._buildPaddings("input", updateKeys);
|
|
152
|
+
this._float32Array = null;
|
|
153
|
+
this.globe.DrawRender();
|
|
154
|
+
}
|
|
77
155
|
deleteBulk(keys) {
|
|
78
156
|
if (this.globe === null) {
|
|
79
157
|
console.warn("Globe is not initialized, cannot delete data");
|
|
@@ -83,10 +161,10 @@ export class Padding1DegreePlugin {
|
|
|
83
161
|
console.warn("Plugin is freed, cannot delete data");
|
|
84
162
|
return;
|
|
85
163
|
}
|
|
86
|
-
this.bufferOrchestrator.deleteBulk(keys, this.
|
|
164
|
+
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagerMap);
|
|
87
165
|
this.globe?.DrawRender();
|
|
88
166
|
}
|
|
89
|
-
setPluginOpacity(opacity) {
|
|
167
|
+
setPluginOpacity(opacity, drawRender = false) {
|
|
90
168
|
if (this._freed) {
|
|
91
169
|
console.warn("Plugin is freed, cannot set opacity");
|
|
92
170
|
return;
|
|
@@ -96,9 +174,10 @@ export class Padding1DegreePlugin {
|
|
|
96
174
|
return;
|
|
97
175
|
}
|
|
98
176
|
opacityCheck(opacity);
|
|
99
|
-
this.
|
|
100
|
-
|
|
101
|
-
|
|
177
|
+
this._userOpacity = opacity;
|
|
178
|
+
if (drawRender) {
|
|
179
|
+
this.globe.DrawRender();
|
|
180
|
+
}
|
|
102
181
|
}
|
|
103
182
|
setDefaultColor(color) {
|
|
104
183
|
if (this._freed) {
|
|
@@ -128,10 +207,18 @@ export class Padding1DegreePlugin {
|
|
|
128
207
|
this._buildPaddings("elevation");
|
|
129
208
|
this.globe?.DrawRender();
|
|
130
209
|
}
|
|
131
|
-
init(globe) {
|
|
210
|
+
init(globe, gl) {
|
|
132
211
|
this.globe = globe;
|
|
133
212
|
this.lineProgram = LineStripProgramCache.get(globe);
|
|
134
|
-
|
|
213
|
+
this._frameCounterTrigger = new FrameCounterTrigger(globe, 10, 1000, (globeChanges) => {
|
|
214
|
+
if (this._freed)
|
|
215
|
+
return;
|
|
216
|
+
this.__build(globeChanges);
|
|
217
|
+
globe.DrawRender();
|
|
218
|
+
});
|
|
219
|
+
this.__updateLODRelatedParameters();
|
|
220
|
+
this.__updateAdaptiveOpacityMultiplier();
|
|
221
|
+
const bufferManagerMap = new Map([
|
|
135
222
|
["position2d", {
|
|
136
223
|
bufferManager: new BufferManager(globe.gl, 360 * 2 * 3, // plus 1 to cut
|
|
137
224
|
{ bufferType: this._options.bufferType, initialCapacity: initialCapacity }),
|
|
@@ -143,19 +230,19 @@ export class Padding1DegreePlugin {
|
|
|
143
230
|
this._float32Array.fill(NaN); // reset the float32Array
|
|
144
231
|
}
|
|
145
232
|
for (let i = 0; i < 360; i++) {
|
|
146
|
-
const
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
233
|
+
const outerCoords = paddingInput.outerCoords[i];
|
|
234
|
+
const innerCoords = paddingInput.innerCoords[i];
|
|
235
|
+
if (outerCoords === null || innerCoords === null) {
|
|
149
236
|
continue;
|
|
150
237
|
}
|
|
151
|
-
let
|
|
238
|
+
let coordsOuter = globe.api_GetMercator2DPoint(outerCoords[0], outerCoords[1]);
|
|
152
239
|
// fill the second coordinate with 0
|
|
153
|
-
this._float32Array[i * 6] =
|
|
154
|
-
this._float32Array[i * 6 + 1] =
|
|
155
|
-
let
|
|
240
|
+
this._float32Array[i * 6] = coordsOuter[0];
|
|
241
|
+
this._float32Array[i * 6 + 1] = coordsOuter[1];
|
|
242
|
+
let coordsInner = globe.api_GetMercator2DPoint(innerCoords[0], innerCoords[1]);
|
|
156
243
|
// fill the second coordinate with 0
|
|
157
|
-
this._float32Array[i * 6 + 2] =
|
|
158
|
-
this._float32Array[i * 6 + 3] =
|
|
244
|
+
this._float32Array[i * 6 + 2] = coordsInner[0];
|
|
245
|
+
this._float32Array[i * 6 + 3] = coordsInner[1];
|
|
159
246
|
}
|
|
160
247
|
return this._float32Array.subarray(0, 360 * 2 * 3);
|
|
161
248
|
}
|
|
@@ -174,22 +261,22 @@ export class Padding1DegreePlugin {
|
|
|
174
261
|
}
|
|
175
262
|
const _float32Array = this._float32Array;
|
|
176
263
|
for (let i = 0; i < 360; i++) {
|
|
177
|
-
const
|
|
178
|
-
const
|
|
179
|
-
if (
|
|
264
|
+
const outerCoords = paddingInput.outerCoords[i];
|
|
265
|
+
const innerCoords = paddingInput.innerCoords[i];
|
|
266
|
+
if (outerCoords === null || innerCoords === null) {
|
|
180
267
|
continue;
|
|
181
268
|
}
|
|
182
269
|
const height = paddingInput.heightFromGroundIn3D ?? this._options.defaultHeightFromGroundIn3D;
|
|
183
|
-
let coords = globe.api_GetCartesian3DPoint(
|
|
270
|
+
let coords = globe.api_GetCartesian3DPoint(outerCoords[0], outerCoords[1], height, this._options.isMSL);
|
|
184
271
|
// fill the second coordinate with 0
|
|
185
272
|
_float32Array[i * 9] = coords[0];
|
|
186
273
|
_float32Array[i * 9 + 1] = coords[1];
|
|
187
274
|
_float32Array[i * 9 + 2] = coords[2];
|
|
188
|
-
let
|
|
275
|
+
let coordsInner = globe.api_GetCartesian3DPoint(innerCoords[0], innerCoords[1], height, this._options.isMSL);
|
|
189
276
|
// fill the second coordinate with 0
|
|
190
|
-
_float32Array[i * 9 + 3] =
|
|
191
|
-
_float32Array[i * 9 + 4] =
|
|
192
|
-
_float32Array[i * 9 + 5] =
|
|
277
|
+
_float32Array[i * 9 + 3] = coordsInner[0];
|
|
278
|
+
_float32Array[i * 9 + 4] = coordsInner[1];
|
|
279
|
+
_float32Array[i * 9 + 5] = coordsInner[2];
|
|
193
280
|
}
|
|
194
281
|
return _float32Array.subarray(0, 360 * 3 * 3);
|
|
195
282
|
}
|
|
@@ -197,7 +284,7 @@ export class Padding1DegreePlugin {
|
|
|
197
284
|
],
|
|
198
285
|
]);
|
|
199
286
|
if (this._options.variativeColorsOn) {
|
|
200
|
-
|
|
287
|
+
bufferManagerMap.set("color", {
|
|
201
288
|
bufferManager: new BufferManager(globe.gl, 360 * 4 * 3, // 4 for RGBA
|
|
202
289
|
{ bufferType: this._options.bufferType, initialCapacity: initialCapacity }),
|
|
203
290
|
adaptor: (paddingInput) => {
|
|
@@ -215,11 +302,11 @@ export class Padding1DegreePlugin {
|
|
|
215
302
|
this._float32Array[i * 12] = color[0];
|
|
216
303
|
this._float32Array[i * 12 + 1] = color[1];
|
|
217
304
|
this._float32Array[i * 12 + 2] = color[2];
|
|
218
|
-
this._float32Array[i * 12 + 3] = color[3]
|
|
305
|
+
this._float32Array[i * 12 + 3] = color[3];
|
|
219
306
|
this._float32Array[i * 12 + 4] = color[0];
|
|
220
307
|
this._float32Array[i * 12 + 5] = color[1];
|
|
221
308
|
this._float32Array[i * 12 + 6] = color[2];
|
|
222
|
-
this._float32Array[i * 12 + 7] = 0; //color[3]
|
|
309
|
+
this._float32Array[i * 12 + 7] = 0; //color[3] ;
|
|
223
310
|
}
|
|
224
311
|
return this._float32Array.subarray(0, 360 * 4 * 3);
|
|
225
312
|
}
|
|
@@ -233,11 +320,11 @@ export class Padding1DegreePlugin {
|
|
|
233
320
|
this._float32Array[i * 12] = color[0];
|
|
234
321
|
this._float32Array[i * 12 + 1] = color[1];
|
|
235
322
|
this._float32Array[i * 12 + 2] = color[2];
|
|
236
|
-
this._float32Array[i * 12 + 3] = color[3]
|
|
323
|
+
this._float32Array[i * 12 + 3] = color[3];
|
|
237
324
|
this._float32Array[i * 12 + 4] = color[0];
|
|
238
325
|
this._float32Array[i * 12 + 5] = color[1];
|
|
239
326
|
this._float32Array[i * 12 + 6] = color[2];
|
|
240
|
-
this._float32Array[i * 12 + 7] = 0; // color[3]
|
|
327
|
+
this._float32Array[i * 12 + 7] = 0.1; // color[3];
|
|
241
328
|
i++;
|
|
242
329
|
}
|
|
243
330
|
}
|
|
@@ -247,7 +334,7 @@ export class Padding1DegreePlugin {
|
|
|
247
334
|
});
|
|
248
335
|
}
|
|
249
336
|
const vaoInput = ["position3d", "position2d", "color"].map((name) => {
|
|
250
|
-
const bufferManager =
|
|
337
|
+
const bufferManager = bufferManagerMap.get(name);
|
|
251
338
|
if (!bufferManager) {
|
|
252
339
|
return null;
|
|
253
340
|
}
|
|
@@ -258,8 +345,8 @@ export class Padding1DegreePlugin {
|
|
|
258
345
|
};
|
|
259
346
|
});
|
|
260
347
|
this._vao = this.lineProgram.createVAO(vaoInput[0], vaoInput[1], vaoInput[2]);
|
|
261
|
-
this.
|
|
262
|
-
this.bufferOrchestrator.resetWithCapacity(
|
|
348
|
+
this.bufferManagerMap = bufferManagerMap;
|
|
349
|
+
this.bufferOrchestrator.resetWithCapacity(bufferManagerMap, initialCapacity);
|
|
263
350
|
this._uboHandler = this.lineProgram.createUBO("STATIC_DRAW");
|
|
264
351
|
this._uboHandler.updateSingle("u_color", new Float32Array(this._options.defaultColor));
|
|
265
352
|
}
|
|
@@ -272,6 +359,8 @@ export class Padding1DegreePlugin {
|
|
|
272
359
|
console.warn("Globe or LineProgram or VAO is not initialized, cannot draw");
|
|
273
360
|
return;
|
|
274
361
|
}
|
|
362
|
+
this._frameCounterTrigger?.trigger();
|
|
363
|
+
// this.__build();
|
|
275
364
|
const gl = this.globe.gl;
|
|
276
365
|
const drawOptions = {
|
|
277
366
|
drawRange: {
|
|
@@ -280,7 +369,7 @@ export class Padding1DegreePlugin {
|
|
|
280
369
|
},
|
|
281
370
|
};
|
|
282
371
|
gl.disable(gl.DEPTH_TEST);
|
|
283
|
-
this.lineProgram.draw(this._vao, drawOptions, this.
|
|
372
|
+
this.lineProgram.draw(this._vao, drawOptions, this._userOpacity * this._adaptiveOpacityMultiplier, this._uboHandler);
|
|
284
373
|
gl.enable(gl.DEPTH_TEST);
|
|
285
374
|
}
|
|
286
375
|
free() {
|
|
@@ -293,6 +382,7 @@ export class Padding1DegreePlugin {
|
|
|
293
382
|
return;
|
|
294
383
|
}
|
|
295
384
|
this._freed = true;
|
|
385
|
+
this._frameCounterTrigger?.free();
|
|
296
386
|
LineStripProgramCache.release(this.lineProgram);
|
|
297
387
|
this.lineProgram = null;
|
|
298
388
|
this._uboHandler?.free();
|
|
@@ -300,58 +390,149 @@ export class Padding1DegreePlugin {
|
|
|
300
390
|
this.globe.gl.deleteVertexArray(this._vao);
|
|
301
391
|
this.globe = null;
|
|
302
392
|
this._vao = null;
|
|
303
|
-
this.
|
|
393
|
+
this.bufferManagerMap.forEach((bufferManager) => {
|
|
304
394
|
bufferManager.bufferManager.free();
|
|
305
395
|
});
|
|
306
396
|
this._float32Array = null;
|
|
307
397
|
}
|
|
398
|
+
_buildPaddings(level, subSetIDs = null) {
|
|
399
|
+
if (level === "input") {
|
|
400
|
+
this.__inner(subSetIDs);
|
|
401
|
+
this.__elevation(subSetIDs);
|
|
402
|
+
}
|
|
403
|
+
else if (level === "innerCircle") {
|
|
404
|
+
// Build inner circle paddings
|
|
405
|
+
if (this._options.adativePaddingSize) {
|
|
406
|
+
this.__innerCircle(subSetIDs);
|
|
407
|
+
}
|
|
408
|
+
this.__elevation(subSetIDs);
|
|
409
|
+
}
|
|
410
|
+
else if (level === "elevation") {
|
|
411
|
+
// Build elevation paddings
|
|
412
|
+
this.__elevation(subSetIDs);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
__inner(subSetIDs = null) {
|
|
416
|
+
// Implement inner circle padding logic
|
|
417
|
+
console.log("innerCircle Level Update");
|
|
418
|
+
const datas = this._dataMap;
|
|
419
|
+
let keys;
|
|
420
|
+
if (subSetIDs) {
|
|
421
|
+
keys = subSetIDs;
|
|
422
|
+
}
|
|
423
|
+
else {
|
|
424
|
+
keys = Array.from(datas.keys());
|
|
425
|
+
}
|
|
426
|
+
for (const key of keys) {
|
|
427
|
+
const value = datas.get(key);
|
|
428
|
+
if (!value)
|
|
429
|
+
continue;
|
|
430
|
+
// Implement inner circle padding logic using key and value
|
|
431
|
+
const { innerCoords, outerCoords } = preAdapter(this.globe, value, this._innerPaddingRatio, null);
|
|
432
|
+
value.outerCoords = outerCoords;
|
|
433
|
+
value.innerCoords = innerCoords;
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
__innerCircle(subSetIDs = null) {
|
|
437
|
+
// Implement inner circle padding logic
|
|
438
|
+
console.log("innerCircle Level Update");
|
|
439
|
+
const datas = this._dataMap;
|
|
440
|
+
let keys;
|
|
441
|
+
if (subSetIDs) {
|
|
442
|
+
keys = subSetIDs;
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
keys = Array.from(datas.keys());
|
|
446
|
+
}
|
|
447
|
+
for (const key of keys) {
|
|
448
|
+
const value = datas.get(key);
|
|
449
|
+
if (!value)
|
|
450
|
+
continue;
|
|
451
|
+
// Implement inner circle padding logic using key and value
|
|
452
|
+
const { innerCoords } = preAdapter(this.globe, value, this._innerPaddingRatio, value.outerCoords);
|
|
453
|
+
value.innerCoords = innerCoords;
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
__elevation(subSetIDs = null) {
|
|
457
|
+
this.__updateAdaptiveOpacityMultiplier();
|
|
458
|
+
const bufferToUpdate = [this.globe?.api_GetCurrentGeometry() === 1 ? "position2d" : "position3d"];
|
|
459
|
+
const datas = this._dataMap;
|
|
460
|
+
const wrapper = [null];
|
|
461
|
+
this._float32Array = new Float32Array(360 * 4 * 4); // largest float32Array
|
|
462
|
+
let keys;
|
|
463
|
+
if (subSetIDs) {
|
|
464
|
+
keys = subSetIDs;
|
|
465
|
+
}
|
|
466
|
+
else {
|
|
467
|
+
keys = Array.from(datas.keys());
|
|
468
|
+
}
|
|
469
|
+
for (const key of keys) {
|
|
470
|
+
const value = datas.get(key);
|
|
471
|
+
if (!value)
|
|
472
|
+
continue;
|
|
473
|
+
wrapper[0] = value;
|
|
474
|
+
this.bufferOrchestrator.updateBulk(wrapper, this.bufferManagerMap, bufferToUpdate);
|
|
475
|
+
}
|
|
476
|
+
this._float32Array = null; // reset the float32Array
|
|
477
|
+
}
|
|
478
|
+
__build(globeChanges) {
|
|
479
|
+
if (globeChanges.lod) {
|
|
480
|
+
this.__updateLODRelatedParameters();
|
|
481
|
+
this._buildPaddings("innerCircle");
|
|
482
|
+
}
|
|
483
|
+
else if (globeChanges.look || globeChanges.geometry) {
|
|
484
|
+
this._buildPaddings("elevation");
|
|
485
|
+
}
|
|
486
|
+
}
|
|
308
487
|
__updateLODRelatedParameters() {
|
|
309
488
|
const lod = this.globe?.api_GetCurrentLODWithDecimal();
|
|
310
489
|
this._innerPaddingRatio = 1 - Math.pow(0.7, lod);
|
|
311
490
|
}
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
491
|
+
__updateAdaptiveOpacityMultiplier() {
|
|
492
|
+
if (this._options.adaptiveOpacity === true) {
|
|
493
|
+
const currentLod = this.globe?.api_GetCurrentLODWithDecimal();
|
|
494
|
+
this._adaptiveOpacityMultiplier = Math.max(1 - (2.9 / currentLod), 0.1);
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
this._adaptiveOpacityMultiplier = 1; // TODO: set this once on adaptiveOpacity is Set to false
|
|
498
|
+
}
|
|
318
499
|
}
|
|
319
500
|
}
|
|
320
|
-
function preAdapter(globe, paddingInput, paddingRatio,
|
|
321
|
-
const
|
|
322
|
-
if (
|
|
323
|
-
|
|
501
|
+
function preAdapter(globe, paddingInput, paddingRatio, outerCoords) {
|
|
502
|
+
const innerCoords = new Array(360);
|
|
503
|
+
if (outerCoords === null) {
|
|
504
|
+
outerCoords = new Array(360);
|
|
324
505
|
for (let i = 0; i < 360; i++) {
|
|
325
506
|
const { long, lat } = globe.Math.FindPointByPolar(paddingInput.center[0], // center long
|
|
326
507
|
paddingInput.center[1], // center lat
|
|
327
|
-
paddingInput.
|
|
508
|
+
paddingInput.radius, // outer radius
|
|
328
509
|
i);
|
|
329
510
|
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(paddingInput.center[0], // center long
|
|
330
511
|
paddingInput.center[1], // center lat
|
|
331
|
-
paddingInput.
|
|
512
|
+
paddingInput.radius * paddingRatio, // inner radius
|
|
332
513
|
i);
|
|
333
514
|
const longDifference = Math.abs(long - endLong);
|
|
334
515
|
const latDifference = Math.abs(lat - endLat);
|
|
335
516
|
if (longDifference > 45) {
|
|
336
|
-
|
|
337
|
-
|
|
517
|
+
outerCoords[i] = null;
|
|
518
|
+
innerCoords[i] = null;
|
|
338
519
|
continue;
|
|
339
520
|
}
|
|
340
521
|
// Assign the calculated coordinates
|
|
341
|
-
|
|
342
|
-
|
|
522
|
+
outerCoords[i] = [long, lat];
|
|
523
|
+
innerCoords[i] = [endLong, endLat];
|
|
343
524
|
}
|
|
344
525
|
}
|
|
345
526
|
else {
|
|
346
|
-
// Handle case when
|
|
527
|
+
// Handle case when outerCoords is provided
|
|
347
528
|
for (let i = 0; i < 360; i++) {
|
|
348
|
-
if (
|
|
349
|
-
|
|
529
|
+
if (outerCoords[i] === null) {
|
|
530
|
+
innerCoords[i] = null;
|
|
350
531
|
continue;
|
|
351
532
|
}
|
|
352
|
-
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(paddingInput.center[0], paddingInput.center[1], paddingInput.
|
|
353
|
-
|
|
533
|
+
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(paddingInput.center[0], paddingInput.center[1], paddingInput.radius * paddingRatio, i);
|
|
534
|
+
innerCoords[i] = [endLong, endLat];
|
|
354
535
|
}
|
|
355
536
|
}
|
|
356
|
-
return {
|
|
537
|
+
return { outerCoords, innerCoords };
|
|
357
538
|
}
|
|
@@ -188,7 +188,7 @@ export class BufferOrchestrator {
|
|
|
188
188
|
offsets.push(offset);
|
|
189
189
|
}
|
|
190
190
|
else {
|
|
191
|
-
throw new Error(
|
|
191
|
+
throw new Error(`updateBulk item Key does not exist, cannot update: ${item.key}`);
|
|
192
192
|
}
|
|
193
193
|
}
|
|
194
194
|
if (bufferKeys) {
|
|
@@ -9,21 +9,31 @@ export class StaticDynamicStrategy {
|
|
|
9
9
|
_staticDynamicState = StaticDynamicState.DYNAMIC;
|
|
10
10
|
_transitionLevel = 8; // Default transition level
|
|
11
11
|
_lastStaticDynamicState = StaticDynamicState.STATIC;
|
|
12
|
-
|
|
12
|
+
_lastGeometry = null;
|
|
13
|
+
_toStatic;
|
|
14
|
+
constructor(globe, transitionLevel = 8, toStatic) {
|
|
13
15
|
this.globe = globe;
|
|
14
16
|
this._transitionLevel = transitionLevel;
|
|
17
|
+
this._toStatic = toStatic;
|
|
15
18
|
this.updateState();
|
|
16
19
|
}
|
|
17
20
|
updateState() {
|
|
18
21
|
const currentLOD = this.globe.api_GetCurrentLODWithDecimal();
|
|
19
22
|
const state = currentLOD < this._transitionLevel ? StaticDynamicState.STATIC : StaticDynamicState.DYNAMIC;
|
|
23
|
+
const currentGeometry = this.globe.api_GetCurrentGeometry();
|
|
20
24
|
if (this._lastStaticDynamicState === StaticDynamicState.DYNAMIC && state === StaticDynamicState.STATIC) {
|
|
21
25
|
this._staticDynamicState = StaticDynamicState.TO_STATIC;
|
|
26
|
+
this._toStatic();
|
|
27
|
+
}
|
|
28
|
+
else if ((currentGeometry !== this._lastGeometry) && state === StaticDynamicState.STATIC) {
|
|
29
|
+
this._staticDynamicState = StaticDynamicState.TO_STATIC;
|
|
30
|
+
this._toStatic();
|
|
22
31
|
}
|
|
23
32
|
else {
|
|
24
33
|
this._staticDynamicState = state;
|
|
25
34
|
}
|
|
26
35
|
this._lastStaticDynamicState = this._staticDynamicState;
|
|
36
|
+
this._lastGeometry = currentGeometry;
|
|
27
37
|
}
|
|
28
38
|
getState() {
|
|
29
39
|
return this._staticDynamicState;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { CameraUniformBlockTotemCache } from "../programs/totems/camerauniformblock";
|
|
2
|
+
export class FrameCounterTrigger {
|
|
3
|
+
globe;
|
|
4
|
+
count = 0;
|
|
5
|
+
threshold;
|
|
6
|
+
timeoutMs;
|
|
7
|
+
timeoutId = null;
|
|
8
|
+
accumulatedChanges = {
|
|
9
|
+
geometry: false,
|
|
10
|
+
look: false,
|
|
11
|
+
lod: false,
|
|
12
|
+
lod2DWheel: false,
|
|
13
|
+
elevationScale: false,
|
|
14
|
+
screenMoved: false
|
|
15
|
+
};
|
|
16
|
+
cameraBlockTotem;
|
|
17
|
+
updateCallback;
|
|
18
|
+
constructor(globe, threshold, timeoutMs, updateCallback) {
|
|
19
|
+
this.threshold = threshold;
|
|
20
|
+
this.timeoutMs = timeoutMs;
|
|
21
|
+
this.updateCallback = updateCallback;
|
|
22
|
+
this.globe = globe;
|
|
23
|
+
this.cameraBlockTotem = CameraUniformBlockTotemCache.get(globe);
|
|
24
|
+
}
|
|
25
|
+
trigger(level = null) {
|
|
26
|
+
const globeChanges = this.cameraBlockTotem.getGlobeChanges();
|
|
27
|
+
if (!globeChanges.screenMoved)
|
|
28
|
+
return;
|
|
29
|
+
this.setChanges(globeChanges);
|
|
30
|
+
if (globeChanges.geometry || globeChanges.elevationScale || globeChanges.lod2DWheel) {
|
|
31
|
+
this.triggerUpdate();
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
this.count++;
|
|
35
|
+
if (this.count === 1) {
|
|
36
|
+
this.startTimeout();
|
|
37
|
+
}
|
|
38
|
+
if (this.count >= this.threshold) {
|
|
39
|
+
this.triggerUpdate();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
startTimeout() {
|
|
43
|
+
this.clearTimeout();
|
|
44
|
+
this.timeoutId = setTimeout(() => {
|
|
45
|
+
this.triggerUpdate();
|
|
46
|
+
}, this.timeoutMs);
|
|
47
|
+
}
|
|
48
|
+
triggerUpdate() {
|
|
49
|
+
this.clearTimeout();
|
|
50
|
+
this.updateCallback(this.accumulatedChanges);
|
|
51
|
+
this.reset();
|
|
52
|
+
}
|
|
53
|
+
clearTimeout() {
|
|
54
|
+
if (this.timeoutId) {
|
|
55
|
+
clearTimeout(this.timeoutId);
|
|
56
|
+
this.timeoutId = null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
setChanges(changes) {
|
|
60
|
+
// accumulate true states until reset
|
|
61
|
+
this.accumulatedChanges.geometry = this.accumulatedChanges.geometry || changes.geometry;
|
|
62
|
+
this.accumulatedChanges.look = this.accumulatedChanges.look || changes.look;
|
|
63
|
+
this.accumulatedChanges.lod = this.accumulatedChanges.lod || changes.lod;
|
|
64
|
+
this.accumulatedChanges.elevationScale = this.accumulatedChanges.elevationScale || changes.elevationScale;
|
|
65
|
+
this.accumulatedChanges.screenMoved = this.accumulatedChanges.screenMoved || changes.screenMoved;
|
|
66
|
+
this.accumulatedChanges.lod2DWheel = this.accumulatedChanges.lod2DWheel || changes.lod2DWheel;
|
|
67
|
+
}
|
|
68
|
+
getLevel() {
|
|
69
|
+
return this.accumulatedChanges;
|
|
70
|
+
}
|
|
71
|
+
reset() {
|
|
72
|
+
this.count = 0;
|
|
73
|
+
this.accumulatedChanges.geometry = false;
|
|
74
|
+
this.accumulatedChanges.look = false;
|
|
75
|
+
this.accumulatedChanges.lod = false;
|
|
76
|
+
this.accumulatedChanges.lod2DWheel = false;
|
|
77
|
+
this.accumulatedChanges.elevationScale = false;
|
|
78
|
+
this.accumulatedChanges.screenMoved = false;
|
|
79
|
+
this.clearTimeout();
|
|
80
|
+
}
|
|
81
|
+
free() {
|
|
82
|
+
CameraUniformBlockTotemCache.release(this.globe);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
@@ -30,3 +30,26 @@ export default function imageToMagnitude(imageData) {
|
|
|
30
30
|
}
|
|
31
31
|
return magnitudeArray;
|
|
32
32
|
}
|
|
33
|
+
export function imageToRadianAngle(imageData) {
|
|
34
|
+
const { image, uMax, vMax, uMin, vMin, height, width } = imageData;
|
|
35
|
+
const canvas = document.createElement('canvas');
|
|
36
|
+
const ctx = canvas.getContext('2d');
|
|
37
|
+
canvas.width = width;
|
|
38
|
+
canvas.height = height;
|
|
39
|
+
ctx.drawImage(image, 0, 0, width, height);
|
|
40
|
+
const img = ctx.getImageData(0, 0, width, height);
|
|
41
|
+
const data = img.data;
|
|
42
|
+
const angleArray = new Float32Array(height * width);
|
|
43
|
+
const uDiff = uMax - uMin;
|
|
44
|
+
const vDiff = vMax - vMin;
|
|
45
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
46
|
+
const r = data[i];
|
|
47
|
+
const g = data[i + 1];
|
|
48
|
+
const u = uMin + (uDiff * r) / 255;
|
|
49
|
+
const v = vMin + (vDiff * g) / 255;
|
|
50
|
+
const angle = Math.atan2(v, u);
|
|
51
|
+
const index = i / 4;
|
|
52
|
+
angleArray[index] = angle;
|
|
53
|
+
}
|
|
54
|
+
return angleArray;
|
|
55
|
+
}
|
package/wind/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import WindPlugin from "./plugin";
|
|
2
2
|
import createVectorFieldImage from "./vectorfieldimage";
|
|
3
|
-
import imageToMagnitude from "./imagetovectorfieldandmagnitude";
|
|
3
|
+
import imageToMagnitude, { imageToRadianAngle } from "./imagetovectorfieldandmagnitude";
|
|
4
4
|
import { createImageFromBase64 } from "../util/webglobjectbuilders";
|
|
5
|
-
export { createVectorFieldImage, imageToMagnitude, WindPlugin, createImageFromBase64 };
|
|
5
|
+
export { createVectorFieldImage, imageToMagnitude, WindPlugin, createImageFromBase64, imageToRadianAngle };
|