@pirireis/webglobeplugins 0.6.17 → 0.6.19

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,10 +1,14 @@
1
- import { programCache as ringProgramCache } from '../partialrings/program';
2
- import { LineOnGlobeCache } from '../programs/line-on-globe/naive';
3
- import { CircleCache } from '../programs/line-on-globe/circle';
1
+ import { pieceOfPieProgramCache } from '../programs/rings/partial-ring/piece-of-pie';
2
+ import { LineOnGlobeCache } from '../programs/line-on-globe/naive-accurate';
3
+ import { CircleCache as Circle3DCache } from '../programs/line-on-globe/circle-accurate-3d';
4
+ import { CircleCache, EDGE_COUNT as flatCircleEdgeCount } from '../programs/line-on-globe/circle-accurate-flat';
4
5
  import { BufferOrchestrator, BufferManager } from '../util/account';
5
- import { AngledLineProgramCache } from '../programs/line-on-globe/angled-line';
6
+ import { AngledLineProgramCache } from '../programs/line-on-globe/angled-line'; // TODO calculate the bearing target for 2d and 3d and use lineOnGlobeProgram
6
7
  import { mapGetOrThrow } from "../util/check/get";
8
+ import { populateFloat32Array } from "../util/jshelpers/data-filler";
7
9
  import { ContextTextWriter } from '../write-text/context-text'
10
+
11
+
8
12
  export const RINGPARTIAL_DRAW_MODE = Object.freeze({
9
13
  LINE_STRIP: "LINE_STRIP",
10
14
  TRIANGLE_FAN: "TRIANGLE_FAN",
@@ -15,7 +19,10 @@ const constraintFloat = (x, lowerBound, upperBound) => {
15
19
  if (lowerBound > x || x > upperBound) throw new Error(`input must be between ${lowerBound} - ${upperBound}`)
16
20
  }
17
21
 
18
-
22
+ /**
23
+ * partial ring angle should be different on globe and mercator.
24
+ *
25
+ */
19
26
 
20
27
 
21
28
  /**
@@ -27,6 +34,8 @@ const constraintFloat = (x, lowerBound, upperBound) => {
27
34
  *
28
35
  */
29
36
 
37
+
38
+
30
39
  export default class Plugin {
31
40
  /**
32
41
  *
@@ -107,9 +116,10 @@ export default class Plugin {
107
116
  this.gl = gl;
108
117
  this.globe = globe;
109
118
  this.lineProgram = LineOnGlobeCache.get(globe);
110
- this.ringProgram = ringProgramCache.get(globe);
119
+ this.ringProgram = pieceOfPieProgramCache.get(globe);
111
120
  this.angledLineProgram = AngledLineProgramCache.get(globe);
112
121
  this.circleProgram = CircleCache.get(globe);
122
+ this.circle3DProgram = Circle3DCache.get(globe);
113
123
  // this.angleTextContext = new ContextTextWriter(globe);
114
124
  // this.distanceTextContext = new ContextTextWriter(globe);
115
125
  {
@@ -118,13 +128,34 @@ export default class Plugin {
118
128
  const initialCapacity = this.bufferOrchestrator.capacity;
119
129
  this.bufferManagersCompMap = new Map(
120
130
  [
121
- ["centerCoords", {
131
+
132
+ ["centerCoords2d", {
133
+ 'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
134
+ 'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.long, item.lat)),
135
+ }],
136
+ ["centerCoords2dflat", {
137
+ 'bufferManager': new BufferManager(gl, flatCircleEdgeCount * 2, { bufferType, initialCapacity }),
138
+ 'adaptor': (item) => item.centerCoords2dflat,
139
+ }],
140
+ ["centerCoords3d", {
141
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
142
+ 'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.long, item.lat, 0, 0)),
143
+ }],
144
+ ["targetCoords2d", {
122
145
  'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
123
- 'adaptor': (item) => new Float32Array([item.long, item.lat]),
146
+ 'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.endLong, item.endLat))
147
+ }],
148
+ ["targetCoords3d", {
149
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
150
+ 'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.endLong, item.endLat, 0, 0))
124
151
  }],
125
- ["targetCoords", {
152
+ ["bearingTargetCoords2d", {
126
153
  'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
127
- 'adaptor': (item) => new Float32Array([item.endLong, item.endLat])
154
+ 'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.bearingLong, item.bearingLat))
155
+ }],
156
+ ["bearingTargetCoords3d", {
157
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
158
+ 'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.bearingLong, item.bearingLat, 0, 0))
128
159
  }],
129
160
  ["startAngle", {
130
161
  'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
@@ -134,6 +165,26 @@ export default class Plugin {
134
165
  'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
135
166
  'adaptor': (item) => new Float32Array([item.tailAngle])
136
167
  }],
168
+ ["startAngle2d", {
169
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
170
+ 'adaptor': (item) => new Float32Array([item.startAngle2d])
171
+ }],
172
+ ["tailAngle2d", {
173
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
174
+ 'adaptor': (item) => new Float32Array([item.tailAngle2d])
175
+ }],
176
+ ["startAngle3d", {
177
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
178
+ 'adaptor': (item) => new Float32Array([item.startAngle3d])
179
+ }],
180
+ ["tailAngle3d", {
181
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
182
+ 'adaptor': (item) => new Float32Array([item.tailAngle3d])
183
+ }],
184
+ ["bearingDashRatio", {
185
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
186
+ 'adaptor': (item) => new Float32Array([0])
187
+ }],
137
188
  ["rgba", {
138
189
  'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
139
190
  'adaptor': (item) => new Float32Array(item.rgba)
@@ -160,54 +211,83 @@ export default class Plugin {
160
211
  }],
161
212
  ["dashOpacity", {
162
213
  'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
163
- 'adaptor': (item) => new Float32Array([item.dashOpacity])
214
+ 'adaptor': (item) => new Float32Array([item.dashOpacity]),
164
215
  }],
216
+
217
+ // normal circle
165
218
  ["circleDashAngle", {
166
- 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
167
- 'adaptor': (item) => new Float32Array([item.circleDashAngle / 360])
168
- }]
219
+ 'bufferManager': new BufferManager(gl, flatCircleEdgeCount, { bufferType, initialCapacity }),
220
+ 'adaptor': (item) => new Float32Array(item.rgba),
221
+ }],
222
+ // CIRCLE Mercator
223
+ ["rgbaMercator", {
224
+ 'bufferManager': new BufferManager(gl, 4 * flatCircleEdgeCount, { bufferType, initialCapacity }),
225
+ 'adaptor': (item) => populateFloat32Array.fillWithListData(flatCircleEdgeCount, item.rgba),
226
+ }],
227
+ ["circleDashAngleMercator", {
228
+ 'bufferManager': new BufferManager(gl, flatCircleEdgeCount, { bufferType, initialCapacity }),
229
+ 'adaptor': (item) => populateFloat32Array.fillFloat32Array(flatCircleEdgeCount, item.circleDashAngle / 360),
230
+ }],
231
+ ["dashOpacityMercator", {
232
+ 'bufferManager': new BufferManager(gl, flatCircleEdgeCount, { bufferType, initialCapacity }),
233
+ 'adaptor': (item) => populateFloat32Array.fillFloat32Array(flatCircleEdgeCount, item.dashOpacity),
234
+ }],
235
+
169
236
  ]
170
237
  );
171
238
  }
172
239
 
173
240
 
174
- const obj = function (bufferManagerComp) {
175
- return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
241
+ const obj = function (bufferManagerComp, divisor = 1) {
242
+ return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0, divisor }
243
+
176
244
  };
177
245
 
178
246
  this.lineVao = this.lineProgram.createVAO(
179
- ...['centerCoords', 'targetCoords', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
247
+ ...['centerCoords2d', 'centerCoords3d', 'targetCoords2d', 'targetCoords3d', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
180
248
  this.ringVao = this.ringProgram.createVAO(
181
- ...['centerCoords', 'startAngle', 'tailAngle', 'rgba', 'radius', 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
249
+ ...['centerCoords2d', 'centerCoords3d',
250
+ 'startAngle2d',
251
+ 'tailAngle2d',
252
+ 'startAngle3d',
253
+ 'tailAngle3d',
254
+ 'rgba',
255
+ 'radius',
256
+ 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
182
257
  {
183
- const angledLineBuffers = ["centerCoords", "bearingAngle", "bigRadius", "rgba", "dashRatio"].map(key => obj(this.bufferManagersCompMap.get(key)));
184
- // dashOpacity is same as rgba.a to eleminate effect of dashOpacity.
185
- const colorBuffer = this.bufferManagersCompMap.get("rgba");
186
- angledLineBuffers.push(
187
- { 'buffer': colorBuffer.bufferManager.buffer, 'stride': 16, 'offset': 12 },
188
- )
189
- this.angledLineVao = this.angledLineProgram.createVAO(...angledLineBuffers);
258
+ this.bearingLineVAO = this.lineProgram.createVAO(
259
+ ...['centerCoords2d', 'centerCoords3d', 'bearingTargetCoords2d', 'bearingTargetCoords3d', 'bearingDashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
190
260
  }
191
261
  // centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
192
262
  this.circleVao = this.circleProgram.createVAO(
193
- ...["centerCoords", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
263
+ ...["centerCoords2dflat", "rgbaMercator", "circleDashAngleMercator", "dashOpacityMercator"].map(key => obj(this.bufferManagersCompMap.get(key)))
264
+ );
265
+ this.circle3DVao = this.circle3DProgram.createVAO(
266
+ ...["centerCoords3d", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key)))
267
+ );
268
+
194
269
  }
195
270
 
196
271
 
197
272
 
198
273
  draw3D() {
199
274
  const { gl } = this;
200
- this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
201
275
  gl.disable(gl.DEPTH_TEST);
276
+ const is3D = this.globe.api_GetCurrentGeometry() === 0;
277
+ this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
202
278
  if (this.drawAngleRing) {
203
279
  this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity * 0.8, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
204
280
  this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
205
281
  }
206
282
  if (this.drawBearingLine) {
207
- this.angledLineProgram.draw(this.angledLineVao, this.bufferOrchestrator.length, this._opacity * 0.8);
283
+ this.lineProgram.draw(this.bearingLineVAO, this.bufferOrchestrator.length, this._opacity * 0.8);
208
284
  }
209
285
  if (this.drawVRM) {
210
- this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
286
+ if (is3D) {
287
+ this.circle3DProgram.draw(this.circle3DVao, this.bufferOrchestrator.length, this._opacity);
288
+ } else {
289
+ this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
290
+ }
211
291
  }
212
292
  if (this.drawText) {
213
293
  this._textContextInjectionMap.forEach((e) => { e.writer.draw(); });
@@ -254,7 +334,7 @@ export default class Plugin {
254
334
 
255
335
 
256
336
  deleteBulk(keys) {
257
- this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap, ["radius", "centerCoords", "targetCoords", "rgba"]);
337
+ this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap);
258
338
  this._deleteTexts(keys);
259
339
  this.globe.DrawRender();
260
340
  }
@@ -278,7 +358,9 @@ export default class Plugin {
278
358
  data.push(this.__updateCoordsAdaptor(item));
279
359
  }
280
360
 
281
- bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords", "targetCoords", "startAngle", "tailAngle", "bearingAngle", "bigRadius", "radius"]);
361
+ bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords2d", "centerCoords3d", "targetCoords2d", "targetCoords3d", "startAngle", "tailAngle",
362
+ "startAngle2d", "tailAngle2d", "startAngle3d", "tailAngle3d", "bearingTargetCoords2d", "bearingTargetCoords3d", "centerCoords2dflat",
363
+ "bearingAngle", "bigRadius", "radius"]);
282
364
  globe.DrawRender();
283
365
  }
284
366
 
@@ -292,12 +374,13 @@ export default class Plugin {
292
374
  */
293
375
  updatePartial(items, propertyIDs = [], textWriterInjectionSubSetIDs = []) { // textWriterInjectionSubSetIDs = []
294
376
  if (propertyIDs.length === 0) console.warn("updatePartial is called with no target propertyIDs");
377
+ const fixedPropertyIDs = this.__fixPartialProperties(propertyIDs)
295
378
  const { _textContextInjectionMap, bufferOrchestrator, bufferManagersCompMap } = this;
296
379
  const writers = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
297
380
  for (let item of items) { this._insertTexts(item, writers) }
298
- bufferOrchestrator.updateBulk(items, bufferManagersCompMap, propertyIDs);
381
+ bufferOrchestrator.updateBulk(items, bufferManagersCompMap, fixedPropertyIDs);
299
382
  // patch to update text opacity
300
- for (const property of propertyIDs) {
383
+ for (const property of fixedPropertyIDs) {
301
384
  if (property === "rgba") {
302
385
  _textContextInjectionMap.forEach((v) => {
303
386
  const { writer } = v;
@@ -310,34 +393,17 @@ export default class Plugin {
310
393
 
311
394
 
312
395
  __insertAdaptor(item) {
313
- const lat = radian(item.lat)
314
- const long = radian(item.long)
315
- const endLat = radian(item.endLat)
316
- const endLong = radian(item.endLong)
396
+
317
397
  const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
318
398
  const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
319
399
  const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
320
400
  const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
321
401
  const circleDashAngle = item.circleDashAngle !== undefined ? item.circleDashAngle : 360;
322
- const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
323
- const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
324
- const startAngle = calculateStartAngle(long, lat, endLong, endLat);
325
- const bearingAngle = radian(item.bearingAngle - 90);
326
- let tailAngle = bearingAngle - startAngle;
327
- if (tailAngle > 0) {
328
- tailAngle -= Math.PI * 2;
329
- }
402
+
403
+ const coordsData = this.__updateCoordsAdaptor(item);
404
+
330
405
  return {
331
- key: item.key,
332
- lat,
333
- long,
334
- endLat,
335
- endLong,
336
- bearingAngle,
337
- radius,
338
- bigRadius,
339
- startAngle,
340
- tailAngle,
406
+ ...coordsData,
341
407
  rgba,
342
408
  dashRatio,
343
409
  dashOpacity,
@@ -346,44 +412,96 @@ export default class Plugin {
346
412
  };
347
413
  }
348
414
 
415
+
349
416
  __updateCoordsAdaptor(item) {
417
+ const { globe } = this;
350
418
  const lat = radian(item.lat)
351
419
  const long = radian(item.long)
352
420
  const endLat = radian(item.endLat)
353
421
  const endLong = radian(item.endLong)
354
- const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
422
+ const bigRadius = item.bigRadius !== undefined ? item.bigRadius : globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
355
423
  const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
356
- const startAngle = calculateStartAngle(long, lat, endLong, endLat);
424
+ const { long: bearingLong, lat: bearingLat } = globe.Math.FindPointByPolar(item.long, item.lat, bigRadius, item.bearingAngle)
425
+ const startAngle2d = calculateStartAngle(long, lat, endLong, endLat);
426
+ const bearingAngle2d = calculateStartAngle(long, lat, radian(bearingLong), radian(bearingLat))
427
+ let tailAngle2d = bearingAngle2d - startAngle2d;
428
+ if (tailAngle2d > 0) {
429
+ tailAngle2d -= Math.PI * 2;
430
+ }
357
431
  const bearingAngle = radian(item.bearingAngle - 90);
358
- let tailAngle = bearingAngle - startAngle;
359
- if (tailAngle > 0) {
360
- tailAngle -= Math.PI * 2;
432
+ const startAngleOfCircle = globe.Math.GetAzimuthAngle(item.long, item.lat, item.endLong, item.endLat) //startAngle2d * 180 / Math.PI;
433
+ const startAngle3d = radian(startAngleOfCircle) - radian(90);
434
+ let tailAngle3d = bearingAngle - startAngle3d;
435
+ if (tailAngle3d > 0) {
436
+ tailAngle3d -= Math.PI * 2;
361
437
  }
438
+
439
+ const centerCoords2dflat = new Float32Array(flatCircleEdgeCount * 2);
440
+ const radius2d = globe.Math.GetDist2D(item.long, item.lat, item.endLong, item.endLat);
441
+ const pointsLongLat = globe.Math.GetEllipseGeo(
442
+ item.long,
443
+ item.lat,
444
+ radius2d,
445
+ radius2d,
446
+ startAngleOfCircle,
447
+ 360 / (flatCircleEdgeCount - 2), // 1 for return to start point, 1 for cutting circles
448
+ );
449
+
450
+ for (let i = 1; i < flatCircleEdgeCount; i++) {
451
+ const { long: lg, lat: lt } = pointsLongLat[i - 1];
452
+ centerCoords2dflat.set(globe.api_GetMercator2DPoint(lg, lt), i * 2);
453
+ }
454
+
362
455
  return {
363
456
  key: item.key,
364
- lat,
365
- long,
366
- endLat,
367
- endLong,
457
+ lat: item.lat,
458
+ long: item.long,
459
+ endLat: item.endLat,
460
+ endLong: item.endLong,
368
461
  bearingAngle,
369
462
  radius,
370
463
  bigRadius,
371
- startAngle,
372
- tailAngle,
464
+ startAngle2d,
465
+ tailAngle2d,
466
+ startAngle3d,
467
+ tailAngle3d,
468
+ bearingLong,
469
+ bearingLat,
470
+ centerCoords2dflat
373
471
  };
374
472
  }
375
473
 
376
474
 
475
+ __fixPartialProperties(propertyIDs) {
476
+ const s = new Set("rgba", "dashOpacity", "circleDashAngle");
477
+ const result = []
478
+ for (const item of propertyIDs) {
479
+ result.push(item);
480
+ if (s.has(item)) {
481
+ result.push(item + "Mercator");
482
+ }
483
+ }
484
+ return result;
485
+ }
486
+
377
487
  //TODO free
378
488
  free() {
379
489
  if (this.isFreed) return;
380
490
  this.bufferManagersCompMap.forEach(({ bufferManager, adaptor }) => {
381
491
  bufferManager.free();
382
492
  });
383
- LineOnGlobeCache.release(this.globe);
384
- ringProgramCache.release(this.globe);
385
- CircleCache.release(this.globe);
386
- AngledLineProgramCache.release(this.globe);
493
+
494
+ const { gl, globe } = this;
495
+ gl.deleteVertexArray(this.lineVao);
496
+ gl.deleteVertexArray(this.ringVao);
497
+ gl.deleteVertexArray(this.bearingLineVAO);
498
+ gl.deleteVertexArray(this.circleVao);
499
+ gl.deleteVertexArray(this.circle3DVao);
500
+ LineOnGlobeCache.release(globe);
501
+ pieceOfPieProgramCache.release(globe);
502
+ CircleCache.release(globe);
503
+ AngledLineProgramCache.release(globe);
504
+ Circle3DCache.release(globe)
387
505
  this.isFreed = true;
388
506
  }
389
507
 
@@ -418,7 +536,7 @@ const integralSec = (angle) => {
418
536
  return Math.log(Math.tan(angle / 2 + Math.PI / 4));
419
537
  }
420
538
 
421
- const textWriterGetOrThrow = mapGetOrThrow("textContextInjection id does not exist in map:")
539
+ const textWriterGetOrThrow = mapGetOrThrow("BearingLine textContextInjection id does not exist in map")
422
540
 
423
541
  const calculateStartAngle = (long, lat, endLong, endLat) => {
424
542
  const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.