@pirireis/webglobeplugins 0.6.21 → 0.6.23-a

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.
@@ -29,14 +29,381 @@
29
29
  * @property {[number, number, number]} color
30
30
  *
31
31
  *
32
- * @method setOpacity
33
- * @method insertBulk
34
- * @method updateCentersXY
35
- * @method updateCentersColor
36
- * @method removeCenters
37
- * @method updateCentersHide
32
+ * @method insertBulk
33
+ * @typedef {Array<{ringID, radius, paddingRange}>} rings
34
+ * @param {Array<centerID:string, x:number, y:number, stepAngle:number, rgba:[4 numbers], rings:rings} items
35
+
36
+ * @method updateCentersXY @param {Array<{centerID, x, y}>} items
37
+ * @method updateCentersColor @param {Array<{centerID, rgba:[4 numbers]}>} centerColors
38
+ *
39
+ * @method updateCentersHide @param {Array<{centerID, hide, textHide}>} centerHides
40
+ * @method removeCenters @param {Array<{centerID}>} centerIds
41
+ * @method setOpacity @param {number} opacity
38
42
  *
39
43
  * @method setOneDegreePaddingOn // performance consuming, might be removed
40
44
  * @method setCompass // removed
41
45
  *
42
- */
46
+ */
47
+
48
+ import { centerCoords2dflatDataCreatorWithRadius, CircleCache as CircleCache2D } from "../programs/line-on-globe/circle-accurate-flat";
49
+ import { CircleCache as CircleCache3D } from "../programs/line-on-globe/circle-accurate-3d";
50
+ import { LinesColorInstancedFlatCache } from "../programs/line-on-globe/lines-color-instanced-flat";
51
+ import { BufferOrchestrator, BufferManager } from "../util/account";
52
+ import { populateFloat32Array } from "../util/jshelpers/data-filler";
53
+ import { RingAccount, ringKeyMethod, ringBigPaddingKeyMethod } from "./ring-account";
54
+ /**
55
+ * Programs:
56
+ *
57
+ * circle3d circle2d padding3d padding2d
58
+ *
59
+ *
60
+ * */
61
+
62
+
63
+ /**
64
+ * [+] Draw circles
65
+ * [-] BUG BUFFER OVERFLOW
66
+ * [-] Draw one degree paddings 2d
67
+ * [-] Create a program for accurate padding 3d
68
+ * [-] Draw one degree paddings 3d
69
+ * [-] Draw big paddings
70
+ * [-] DrawText
71
+ */
72
+
73
+ // TODO make x, y -> long, lat
74
+
75
+ class RangeRings {
76
+ constructor(id, { oneDegreePadding = true, showNumbers = true, numbersStyle = null, opacity = 1, } = {}) {
77
+
78
+ this.id = id;
79
+
80
+ this._oneDegreePadding = oneDegreePadding;
81
+ this._showNumbers = showNumbers;
82
+ this._numbersStyle = numbersStyle;
83
+ this._opacity = opacity;
84
+ this._circleFlatEdgeCount = 362;
85
+ this._ringAccount = new RingAccount();
86
+
87
+ }
88
+
89
+
90
+ init(globe, gl) {
91
+ this.globe = globe;
92
+ this.gl = gl;
93
+ this._initPrograms();
94
+ this._initBufferManagers();
95
+ }
96
+
97
+
98
+ _initPrograms() {
99
+ const { globe } = this;
100
+ this._circleProgram2D = CircleCache2D.get(globe);
101
+ this._circleProgram3D = CircleCache3D.get(globe);
102
+ this._padding2dProgram = LinesColorInstancedFlatCache.get(globe);
103
+ // this._padding3dProgram
104
+ }
105
+
106
+
107
+ _initBufferManagers() {
108
+ const { globe, gl, _circleFlatEdgeCount } = this;
109
+
110
+ const initialCapacity = 10;
111
+ const bufferType = "DYNAMIC_DRAW";
112
+ // circle2d, circle3d, 1 degree paddings,
113
+ this.bufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity });
114
+
115
+ this.bufferManagersCompMap = new Map(
116
+ [
117
+ // circle 3D
118
+ ["centerCoords3d", {
119
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
120
+ 'adaptor': (item) => new Float32Array(item.centerCoords3d),
121
+ }],
122
+ ["rgba", {
123
+ 'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
124
+ 'adaptor': (item) => new Float32Array(item.hide === 1 ? [0, 0, 0, 0] : item.rgba)
125
+ }],
126
+ ["radius3d", {
127
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
128
+ 'adaptor': (item) => new Float32Array([item.radius])
129
+ }],
130
+ ["circleDashAngle", {
131
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
132
+ 'adaptor': (item) => new Float32Array([1]),
133
+ }],
134
+ ["dashOpacity", {
135
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
136
+ 'adaptor': (item) => new Float32Array([1]),
137
+ }],
138
+
139
+ // circle 2D
140
+ // ["centerCoords2dflatForPadding", {
141
+ // 'bufferManager': new BufferManager(gl, (_circleFlatEdgeCount - 2) * 2, { bufferType, initialCapacity }),
142
+ // 'adaptor': (item) => item.centerCoords2dflatForPadding,
143
+ // }],
144
+ ["centerCoords2dflat", {
145
+ 'bufferManager': new BufferManager(gl, _circleFlatEdgeCount * 2, { bufferType, initialCapacity }),
146
+ 'adaptor': (item) => item.centerCoords2dflat,
147
+ }],
148
+ ["rgbaMercator", {
149
+ 'bufferManager': new BufferManager(gl, 4 * _circleFlatEdgeCount, { bufferType, initialCapacity }),
150
+ 'adaptor': (item) => populateFloat32Array.fillWithListData(_circleFlatEdgeCount, item.hide === 1 ? [0, 0, 0, 0] : item.rgba),
151
+ }],
152
+ ["circleDashAngleMercator", {
153
+ 'bufferManager': new BufferManager(gl, _circleFlatEdgeCount, { bufferType, initialCapacity }),
154
+ 'adaptor': (item) => populateFloat32Array.fillFloat32Array(_circleFlatEdgeCount, 1),
155
+ }],
156
+ ["dashOpacityMercator", {
157
+ 'bufferManager': new BufferManager(gl, _circleFlatEdgeCount, { bufferType, initialCapacity }),
158
+ 'adaptor': (item) => populateFloat32Array.fillFloat32Array(_circleFlatEdgeCount, 1),
159
+ }],
160
+ ]
161
+ );
162
+
163
+ const obj = function (bufferManagerComp, divisor = 1) {
164
+ return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0, divisor }
165
+
166
+ };
167
+ this.circle2DVao = this._circleProgram2D.createVAO(
168
+ ...["centerCoords2dflat", "rgbaMercator", "circleDashAngleMercator", "dashOpacityMercator"].map(key => obj(this.bufferManagersCompMap.get(key)))
169
+ );
170
+ this.circle3DVao = this._circleProgram3D.createVAO(
171
+ ...["centerCoords3d", "radius3d", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key)))
172
+ );
173
+
174
+
175
+ // PADDING
176
+ // this one needs glue to assosiate rings and their big paddings since the count for center is not fixed
177
+ this._paddingBufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity });
178
+ this.bufferManagersCompMapPadding = new Map();
179
+ }
180
+
181
+
182
+ // GLOBE API
183
+
184
+ draw3D() {
185
+ const { globe, gl, circle2DVao, circle3DVao, _circleProgram2D, _circleProgram3D, bufferOrchestrator, _circleFlatEdgeCount, _opacity } = this;
186
+ gl.disable(gl.DEPTH_TEST);
187
+ const is3D = this.globe.api_GetCurrentGeometry() === 0;
188
+ if (is3D) {
189
+ _circleProgram3D.draw(circle3DVao, bufferOrchestrator.length, _opacity);
190
+ } else {
191
+ _circleProgram2D.draw(circle2DVao, bufferOrchestrator.length, _circleFlatEdgeCount, _opacity);
192
+ }
193
+ gl.enable(gl.DEPTH_TEST);
194
+ }
195
+
196
+ free() {
197
+ if (this._isFreed) return;
198
+ const { globe } = this;
199
+ CircleCache2D.release(globe);
200
+ CircleCache3D.release(globe);
201
+ this._isFreed = true;
202
+ }
203
+
204
+
205
+ // API
206
+
207
+ /**
208
+ * @method updateCentersXY @param { Array < { centerID, x, y } >} items
209
+ */
210
+ updateCentersXY(items) {
211
+ // Algorithm
212
+ /**
213
+ * 1. ask centerRingAccount for existing rings COORDINATE RELATED KEYS
214
+ * 2. update centers
215
+ * 3. update buffer orchestators
216
+ */
217
+
218
+ this._ringAccount.updateCentersXY(items);
219
+ const { globe, bufferOrchestrator, bufferManagersCompMap } = this;
220
+ for (const { centerID } of items) {
221
+ const datas = this.__reconstructCenteralRings(centerID);
222
+ // TODO add big paddings when when implemented
223
+ bufferOrchestrator.updateBulk(datas, bufferManagersCompMap, ["centerCoords3d", "centerCoords2dflat",]);//"centerCoords2dflatForPadding"]);
224
+ }
225
+ globe.DrawRender();
226
+ }
227
+
228
+ /**
229
+ * @method insertBulk
230
+ * @typedef { Array < { ringID, radius, paddingRange } >} rings
231
+ * @param { Array < centerID: string, x: number, y: number, stepAngle: number, rgba: [4 numbers], rings: rings, hide, textHide } items
232
+ */
233
+ insertBulk(items) {
234
+ // Algorithm
235
+ /**
236
+ * 1 ask centerRingAccount for existing rings
237
+ * presizely: TODO
238
+ * 2. delete all existing keys with buffer orchestators
239
+ * 3. insert new centerRings to centerRingAccount
240
+ * 4. insert new keys with buffer orchestators
241
+ */
242
+ const { globe, _ringAccount, bufferOrchestrator, bufferManagersCompMap } = this;
243
+ // TODO add delete existing for padding
244
+ for (const item of items) {
245
+ const existingKeys = _ringAccount.ringKeys(item.centerID);
246
+ if (existingKeys.length) {
247
+ bufferOrchestrator.deleteBulk(existingKeys, bufferManagersCompMap);
248
+ }
249
+ }
250
+
251
+ for (const item of items) {
252
+ _ringAccount.insertCenter(item);
253
+ const datas = this.__reconstructCenteralRings(item.centerID);
254
+ bufferOrchestrator.insertBulk(datas, bufferManagersCompMap,);
255
+ }
256
+
257
+ // TODO insert text
258
+ globe.DrawRender();
259
+
260
+ }
261
+
262
+
263
+
264
+
265
+ /**
266
+ * @method updateCentersColor @param { Array < { centerID, rgba: [4 numbers] } >} centerColors
267
+ */
268
+ updateCentersColor(centerColors) {
269
+ // Algorithm
270
+ /**
271
+ * 1. ask centerRingAccount for existing rings COLOR KEYS
272
+ * 2. update centers
273
+ * 3. update buffer orchestators
274
+ */
275
+ this._ringAccount.updateCentersColor(centerColors);
276
+ const { globe, bufferOrchestrator, bufferManagersCompMap } = this;
277
+ for (const { centerID } of centerColors) {
278
+ const datas = this.__reconstructCenteralProperties(centerID);
279
+ bufferOrchestrator.updateBulk(datas, bufferManagersCompMap, ["rgba", "rgbaMercator"]);
280
+ }
281
+ globe.DrawRender();
282
+ }
283
+
284
+ /**
285
+ *
286
+ * @method updateCentersHide @param { Array < { centerID, hide, textHide } >} centerHides
287
+ */
288
+ updateCentersHide(centerHides) {
289
+ // Algorithm
290
+ /**
291
+ * Simple
292
+ * 1. update centers
293
+ * 2. reconstruct data,
294
+ * 3. update color buffer
295
+ * */
296
+
297
+
298
+
299
+ /**
300
+ * Complicated
301
+ * 1. ask centerRingAccount for existing rings HIDE KEYS
302
+ * 2. delete from buffer orchestators
303
+ * 3. mark centers as hidden
304
+ */
305
+
306
+ }
307
+
308
+ /**
309
+ * @method removeCenters @param { Array < { centerID } >} centerIDs
310
+ */
311
+ removeCenters(centerIDs) {
312
+ // Algorithm
313
+ /**
314
+ * 1. ask centerRingAccount for existing rings
315
+ * 2. delete from buffer orchestators
316
+ * 3. delete from centerRingAccount
317
+ */
318
+ const { globe, bufferOrchestrator, bufferManagersCompMap, _ringAccount } = this;
319
+ for (const centerID of centerIDs) {
320
+ const existingKeys = _ringAccount.ringKeys(centerID);
321
+ if (existingKeys.length) {
322
+ bufferOrchestrator.deleteBulk(existingKeys, bufferManagersCompMap);
323
+ }
324
+ }
325
+ globe.DrawRender();
326
+ }
327
+
328
+ /**
329
+ * @method setOpacity @param { number } opacity
330
+ */
331
+ setOpacity(opacity) {
332
+ if (typeof opacity !== "number" || opacity < 0 || opacity > 1) throw new Error("Invalid opacity value");
333
+ this._opacity = opacity;
334
+ this.globe.drawRender();
335
+ }
336
+
337
+
338
+ /**
339
+ * @method setOneDegreePaddingOn // performance consuming, might be removed
340
+ */
341
+ setOneDegreePaddingOn(isOneDegreePaddingOn) {
342
+ // TODO
343
+ if (this._oneDegreePadding === isOneDegreePaddingOn) return;
344
+ this._oneDegreePadding = isOneDegreePaddingOn;
345
+
346
+ // Complicated
347
+ // if (isOneDegreePaddingOn) {
348
+ // // fill the Coordinate Buffer for 1 degree Padding
349
+ // // Use orchastrator to create data for all rings
350
+
351
+ // } else {
352
+ // // empty the Coordinate Buffer for 1 degree Padding
353
+ // }
354
+ }
355
+
356
+
357
+ __reconstructCenteralRings(centerID) {
358
+ const { globe, _circleFlatEdgeCount } = this;
359
+ const centerItem = this._ringAccount.getCenter(centerID);
360
+ if (centerItem === undefined) throw new Error("Center not found");
361
+
362
+ const { x, y, stepAngle, rgba, rings, hide = 0, textHide = 0 } = centerItem;
363
+
364
+ const long = x;
365
+ const lat = y;
366
+ const centerCoords3d = globe.api_GetCartesian3DPoint(long, lat, 0, 0);
367
+
368
+ const result = [];
369
+
370
+ for (const { ringID, radius, paddingRange } of rings) {
371
+ const key = ringKeyMethod(centerID, ringID);
372
+ const centerCoords2dflat = centerCoords2dflatDataCreatorWithRadius(globe, x, y, radius, { edgeCount: _circleFlatEdgeCount });
373
+ // const centerCoords2dflatForPadding = centerCoords2dflatDataCreatorWithRadius(globe, x, y, radius - paddingRange, { edgeCount: _circleFlatEdgeCount - 2 });
374
+ result.push({
375
+ key,
376
+ centerCoords3d,
377
+ centerCoords2dflat,
378
+ radius,
379
+ paddingRange,
380
+ rgba,
381
+ // centerCoords2dflatForPadding,
382
+ hide,
383
+ textHide
384
+ });
385
+ }
386
+ return result;
387
+
388
+ }
389
+
390
+ __reconstructCenteralProperties(centerID) {
391
+ const centerItem = this._ringAccount.getCenter(centerID);
392
+ if (centerItem === undefined) throw new Error("Center not found");
393
+ const { rgba, rings, hide = 0, textHide = 0 } = centerItem;
394
+ const result = [];
395
+ for (const { ringID } of rings) {
396
+ const key = ringKeyMethod(centerID, ringID);
397
+ result.push({
398
+ key,
399
+ rgba,
400
+ hide,
401
+ textHide
402
+ });
403
+ }
404
+ return result;
405
+ }
406
+ }
407
+
408
+
409
+ export { RangeRings };