@pirireis/webglobeplugins 0.15.22-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/package.json +1 -1
- package/point-tracks/plugin.js +4 -4
- 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 -4
- 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 +180 -49
- 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
|
@@ -16,15 +16,16 @@ 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
|
-
_innerPaddingRatio = 0.
|
|
28
|
+
_innerPaddingRatio = 0.95; //
|
|
28
29
|
_float32Array = null; // this is used to forward the data to the buffer manager
|
|
29
30
|
_uboHandler = null; // this is used to forward the data to the shader program
|
|
30
31
|
_bufferNames = ["position2d", "position3d"];
|
|
@@ -42,9 +43,10 @@ export class Padding1DegreePlugin {
|
|
|
42
43
|
adaptiveOpacity: true, // if true, the opacity will be adaptive to the LOD
|
|
43
44
|
isMSL: false // if true, no elevation of terrain
|
|
44
45
|
};
|
|
46
|
+
_frameCounterTrigger = null;
|
|
45
47
|
constructor(id, options = null) {
|
|
46
48
|
this.id = id;
|
|
47
|
-
this.
|
|
49
|
+
this.bufferManagerMap = new Map();
|
|
48
50
|
this.lineProgram = null;
|
|
49
51
|
this._options = options ? { ...this._options, ...options } : this._options;
|
|
50
52
|
this.bufferOrchestrator = new BufferOrchestrator();
|
|
@@ -52,6 +54,21 @@ export class Padding1DegreePlugin {
|
|
|
52
54
|
this._bufferNames.push("color");
|
|
53
55
|
}
|
|
54
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
|
+
}
|
|
55
72
|
insertBulk(inputs) {
|
|
56
73
|
if (this.globe === null) {
|
|
57
74
|
console.warn("Globe is not initialized, cannot insert input");
|
|
@@ -63,16 +80,78 @@ export class Padding1DegreePlugin {
|
|
|
63
80
|
}
|
|
64
81
|
const wrapper = [null];
|
|
65
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);
|
|
66
90
|
for (let i = 0; i < inputs.length; i++) {
|
|
67
91
|
const coords = preAdapter(this.globe, inputs[i], this._innerPaddingRatio, null);
|
|
68
92
|
const paddingInput = { ...inputs[i], ...coords };
|
|
69
93
|
this._dataMap.set(paddingInput.key, paddingInput);
|
|
70
94
|
wrapper[0] = paddingInput;
|
|
71
|
-
this.bufferOrchestrator.insertBulk(wrapper, this.
|
|
95
|
+
this.bufferOrchestrator.insertBulk(wrapper, this.bufferManagerMap, this._bufferNames);
|
|
72
96
|
}
|
|
73
97
|
this._float32Array = null;
|
|
74
98
|
this.globe?.DrawRender();
|
|
75
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
|
+
}
|
|
76
155
|
deleteBulk(keys) {
|
|
77
156
|
if (this.globe === null) {
|
|
78
157
|
console.warn("Globe is not initialized, cannot delete data");
|
|
@@ -82,7 +161,7 @@ export class Padding1DegreePlugin {
|
|
|
82
161
|
console.warn("Plugin is freed, cannot delete data");
|
|
83
162
|
return;
|
|
84
163
|
}
|
|
85
|
-
this.bufferOrchestrator.deleteBulk(keys, this.
|
|
164
|
+
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagerMap);
|
|
86
165
|
this.globe?.DrawRender();
|
|
87
166
|
}
|
|
88
167
|
setPluginOpacity(opacity, drawRender = false) {
|
|
@@ -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 }),
|
|
@@ -148,10 +235,10 @@ export class Padding1DegreePlugin {
|
|
|
148
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] =
|
|
240
|
+
this._float32Array[i * 6] = coordsOuter[0];
|
|
241
|
+
this._float32Array[i * 6 + 1] = coordsOuter[1];
|
|
155
242
|
let coordsInner = globe.api_GetMercator2DPoint(innerCoords[0], innerCoords[1]);
|
|
156
243
|
// fill the second coordinate with 0
|
|
157
244
|
this._float32Array[i * 6 + 2] = coordsInner[0];
|
|
@@ -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) => {
|
|
@@ -237,7 +324,7 @@ export class Padding1DegreePlugin {
|
|
|
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,9 +359,8 @@ export class Padding1DegreePlugin {
|
|
|
272
359
|
console.warn("Globe or LineProgram or VAO is not initialized, cannot draw");
|
|
273
360
|
return;
|
|
274
361
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
362
|
+
this._frameCounterTrigger?.trigger();
|
|
363
|
+
// this.__build();
|
|
278
364
|
const gl = this.globe.gl;
|
|
279
365
|
const drawOptions = {
|
|
280
366
|
drawRange: {
|
|
@@ -296,6 +382,7 @@ export class Padding1DegreePlugin {
|
|
|
296
382
|
return;
|
|
297
383
|
}
|
|
298
384
|
this._freed = true;
|
|
385
|
+
this._frameCounterTrigger?.free();
|
|
299
386
|
LineStripProgramCache.release(this.lineProgram);
|
|
300
387
|
this.lineProgram = null;
|
|
301
388
|
this._uboHandler?.free();
|
|
@@ -303,68 +390,112 @@ export class Padding1DegreePlugin {
|
|
|
303
390
|
this.globe.gl.deleteVertexArray(this._vao);
|
|
304
391
|
this.globe = null;
|
|
305
392
|
this._vao = null;
|
|
306
|
-
this.
|
|
393
|
+
this.bufferManagerMap.forEach((bufferManager) => {
|
|
307
394
|
bufferManager.bufferManager.free();
|
|
308
395
|
});
|
|
309
396
|
this._float32Array = null;
|
|
310
397
|
}
|
|
311
|
-
|
|
312
|
-
const lod = this.globe?.api_GetCurrentLODWithDecimal();
|
|
313
|
-
this._innerPaddingRatio = 1 - Math.pow(0.7, lod);
|
|
314
|
-
}
|
|
315
|
-
_buildPaddings(level) {
|
|
398
|
+
_buildPaddings(level, subSetIDs = null) {
|
|
316
399
|
if (level === "input") {
|
|
317
|
-
|
|
400
|
+
this.__inner(subSetIDs);
|
|
401
|
+
this.__elevation(subSetIDs);
|
|
318
402
|
}
|
|
319
403
|
else if (level === "innerCircle") {
|
|
320
404
|
// Build inner circle paddings
|
|
321
|
-
this.
|
|
322
|
-
|
|
405
|
+
if (this._options.adativePaddingSize) {
|
|
406
|
+
this.__innerCircle(subSetIDs);
|
|
407
|
+
}
|
|
408
|
+
this.__elevation(subSetIDs);
|
|
323
409
|
}
|
|
324
410
|
else if (level === "elevation") {
|
|
325
411
|
// Build elevation paddings
|
|
326
|
-
this.__elevation();
|
|
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;
|
|
327
434
|
}
|
|
328
435
|
}
|
|
329
|
-
__innerCircle() {
|
|
436
|
+
__innerCircle(subSetIDs = null) {
|
|
330
437
|
// Implement inner circle padding logic
|
|
331
438
|
console.log("innerCircle Level Update");
|
|
332
439
|
const datas = this._dataMap;
|
|
333
|
-
|
|
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;
|
|
334
451
|
// Implement inner circle padding logic using key and value
|
|
335
452
|
const { innerCoords } = preAdapter(this.globe, value, this._innerPaddingRatio, value.outerCoords);
|
|
336
453
|
value.innerCoords = innerCoords;
|
|
337
454
|
}
|
|
338
455
|
}
|
|
339
|
-
__elevation() {
|
|
340
|
-
this.
|
|
341
|
-
const bufferToUpdate = this.globe?.api_GetCurrentGeometry() === 1 ? "position2d" : "position3d";
|
|
342
|
-
console.log(bufferToUpdate);
|
|
456
|
+
__elevation(subSetIDs = null) {
|
|
457
|
+
this.__updateAdaptiveOpacityMultiplier();
|
|
458
|
+
const bufferToUpdate = [this.globe?.api_GetCurrentGeometry() === 1 ? "position2d" : "position3d"];
|
|
343
459
|
const datas = this._dataMap;
|
|
344
460
|
const wrapper = [null];
|
|
345
461
|
this._float32Array = new Float32Array(360 * 4 * 4); // largest float32Array
|
|
346
|
-
|
|
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;
|
|
347
473
|
wrapper[0] = value;
|
|
348
|
-
this.bufferOrchestrator.updateBulk(wrapper, this.
|
|
474
|
+
this.bufferOrchestrator.updateBulk(wrapper, this.bufferManagerMap, bufferToUpdate);
|
|
349
475
|
}
|
|
350
476
|
this._float32Array = null; // reset the float32Array
|
|
351
477
|
}
|
|
352
|
-
__build() {
|
|
353
|
-
|
|
354
|
-
if (globeChanges.lodChanged) {
|
|
355
|
-
console.log("lod changed");
|
|
356
|
-
}
|
|
357
|
-
if (globeChanges.lodChanged) {
|
|
478
|
+
__build(globeChanges) {
|
|
479
|
+
if (globeChanges.lod) {
|
|
358
480
|
this.__updateLODRelatedParameters();
|
|
359
481
|
this._buildPaddings("innerCircle");
|
|
360
482
|
}
|
|
361
|
-
else if (globeChanges.
|
|
483
|
+
else if (globeChanges.look || globeChanges.geometry) {
|
|
362
484
|
this._buildPaddings("elevation");
|
|
363
485
|
}
|
|
364
486
|
}
|
|
365
|
-
|
|
366
|
-
const
|
|
367
|
-
this.
|
|
487
|
+
__updateLODRelatedParameters() {
|
|
488
|
+
const lod = this.globe?.api_GetCurrentLODWithDecimal();
|
|
489
|
+
this._innerPaddingRatio = 1 - Math.pow(0.7, lod);
|
|
490
|
+
}
|
|
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
|
+
}
|
|
368
499
|
}
|
|
369
500
|
}
|
|
370
501
|
function preAdapter(globe, paddingInput, paddingRatio, outerCoords) {
|
|
@@ -374,11 +505,11 @@ function preAdapter(globe, paddingInput, paddingRatio, outerCoords) {
|
|
|
374
505
|
for (let i = 0; i < 360; i++) {
|
|
375
506
|
const { long, lat } = globe.Math.FindPointByPolar(paddingInput.center[0], // center long
|
|
376
507
|
paddingInput.center[1], // center lat
|
|
377
|
-
paddingInput.
|
|
508
|
+
paddingInput.radius, // outer radius
|
|
378
509
|
i);
|
|
379
510
|
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(paddingInput.center[0], // center long
|
|
380
511
|
paddingInput.center[1], // center lat
|
|
381
|
-
paddingInput.
|
|
512
|
+
paddingInput.radius * paddingRatio, // inner radius
|
|
382
513
|
i);
|
|
383
514
|
const longDifference = Math.abs(long - endLong);
|
|
384
515
|
const latDifference = Math.abs(lat - endLat);
|
|
@@ -399,7 +530,7 @@ function preAdapter(globe, paddingInput, paddingRatio, outerCoords) {
|
|
|
399
530
|
innerCoords[i] = null;
|
|
400
531
|
continue;
|
|
401
532
|
}
|
|
402
|
-
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(paddingInput.center[0], paddingInput.center[1], paddingInput.
|
|
533
|
+
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(paddingInput.center[0], paddingInput.center[1], paddingInput.radius * paddingRatio, i);
|
|
403
534
|
innerCoords[i] = [endLong, endLat];
|
|
404
535
|
}
|
|
405
536
|
}
|
|
@@ -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 };
|
package/wind/plugin.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Author: Toprak Nihat Deniz Ozturk
|
|
3
3
|
*/
|
|
4
4
|
import * as util from "../util";
|
|
5
|
-
import imageToMagnitude from "./imagetovectorfieldandmagnitude";
|
|
5
|
+
import imageToMagnitude, { imageToRadianAngle } from "./imagetovectorfieldandmagnitude";
|
|
6
6
|
import { TexturePointSampler } from "../util/heatwavedatamanager/texture-point-sampler";
|
|
7
7
|
/**
|
|
8
8
|
* Shader Dökümanı:
|
|
@@ -531,22 +531,43 @@ export default class WindPlugin {
|
|
|
531
531
|
this.setWind(windData);
|
|
532
532
|
};
|
|
533
533
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
534
|
+
/**
|
|
535
|
+
* @param
|
|
536
|
+
* @returns
|
|
537
|
+
*/
|
|
538
|
+
getTexturePointSampler(type = `magnitude`) {
|
|
539
|
+
if (type == `magnitude`) {
|
|
540
|
+
if (!this.texturePointSampler)
|
|
541
|
+
this._createTexturePointSampler();
|
|
542
|
+
return this.texturePointSampler;
|
|
543
|
+
}
|
|
544
|
+
else if (type == `angle`) {
|
|
545
|
+
if (!this.texturePointSamplerAngle)
|
|
546
|
+
this._createTexturePointSamplerAngle();
|
|
547
|
+
return this.texturePointSamplerAngle;
|
|
548
|
+
}
|
|
549
|
+
this._setCoorcinatesDataCalculatorData();
|
|
550
|
+
}
|
|
551
|
+
_createTexturePointSamplerAngle() {
|
|
552
|
+
const { bbox, width, height } = this._windDataMeta;
|
|
553
|
+
this.texturePointSamplerAngle = new TexturePointSampler(bbox, width, height);
|
|
538
554
|
}
|
|
539
555
|
_createTexturePointSampler() {
|
|
540
556
|
const { bbox, width, height } = this._windDataMeta;
|
|
541
557
|
this.texturePointSampler = new TexturePointSampler(bbox, width, height);
|
|
542
|
-
this._setCoorcinatesDataCalculatorData();
|
|
543
558
|
}
|
|
544
559
|
_setCoorcinatesDataCalculatorData() {
|
|
545
|
-
if (!this.windData
|
|
560
|
+
if (!this.windData) {
|
|
546
561
|
return;
|
|
547
562
|
}
|
|
548
|
-
|
|
549
|
-
|
|
563
|
+
if (this.texturePointSamplerAngle) {
|
|
564
|
+
const angle = imageToRadianAngle(this.windData);
|
|
565
|
+
this.texturePointSamplerAngle.updateTextureData(0, angle, angle);
|
|
566
|
+
}
|
|
567
|
+
if (this.texturePointSampler) {
|
|
568
|
+
const magnitude = imageToMagnitude(this.windData);
|
|
569
|
+
this.texturePointSampler.updateTextureData(0, magnitude, magnitude);
|
|
570
|
+
}
|
|
550
571
|
}
|
|
551
572
|
// -----------------------------------------------
|
|
552
573
|
// --- inner methods ---
|