@pirireis/webglobeplugins 0.6.17 → 0.6.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,8 @@
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 } from '../programs/line-on-globe/circle-accurate';
4
4
  import { BufferOrchestrator, BufferManager } from '../util/account';
5
- import { AngledLineProgramCache } from '../programs/line-on-globe/angled-line';
5
+ import { AngledLineProgramCache } from '../programs/line-on-globe/angled-line'; // TODO calculate the bearing target for 2d and 3d and use lineOnGlobeProgram
6
6
  import { mapGetOrThrow } from "../util/check/get";
7
7
  import { ContextTextWriter } from '../write-text/context-text'
8
8
  export const RINGPARTIAL_DRAW_MODE = Object.freeze({
@@ -15,7 +15,10 @@ const constraintFloat = (x, lowerBound, upperBound) => {
15
15
  if (lowerBound > x || x > upperBound) throw new Error(`input must be between ${lowerBound} - ${upperBound}`)
16
16
  }
17
17
 
18
-
18
+ /**
19
+ * partial ring angle should be different on globe and mercator.
20
+ *
21
+ */
19
22
 
20
23
 
21
24
  /**
@@ -107,7 +110,7 @@ export default class Plugin {
107
110
  this.gl = gl;
108
111
  this.globe = globe;
109
112
  this.lineProgram = LineOnGlobeCache.get(globe);
110
- this.ringProgram = ringProgramCache.get(globe);
113
+ this.ringProgram = pieceOfPieProgramCache.get(globe);
111
114
  this.angledLineProgram = AngledLineProgramCache.get(globe);
112
115
  this.circleProgram = CircleCache.get(globe);
113
116
  // this.angleTextContext = new ContextTextWriter(globe);
@@ -118,13 +121,30 @@ export default class Plugin {
118
121
  const initialCapacity = this.bufferOrchestrator.capacity;
119
122
  this.bufferManagersCompMap = new Map(
120
123
  [
121
- ["centerCoords", {
124
+
125
+ ["centerCoords2d", {
126
+ 'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
127
+ 'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.long, item.lat)),
128
+ }],
129
+ ["centerCoords3d", {
130
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
131
+ 'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.long, item.lat, 0, 0)),
132
+ }],
133
+ ["targetCoords2d", {
122
134
  'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
123
- 'adaptor': (item) => new Float32Array([item.long, item.lat]),
135
+ 'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.endLong, item.endLat))
136
+ }],
137
+ ["targetCoords3d", {
138
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
139
+ 'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.endLong, item.endLat, 0, 0))
124
140
  }],
125
- ["targetCoords", {
141
+ ["bearingTargetCoords2d", {
126
142
  'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
127
- 'adaptor': (item) => new Float32Array([item.endLong, item.endLat])
143
+ 'adaptor': (item) => new Float32Array(globe.api_GetMercator2DPoint(item.bearingLong, item.bearingLat))
144
+ }],
145
+ ["bearingTargetCoords3d", {
146
+ 'bufferManager': new BufferManager(gl, 3, { bufferType, initialCapacity }),
147
+ 'adaptor': (item) => new Float32Array(globe.api_GetCartesian3DPoint(item.bearingLong, item.bearingLat, 0, 0))
128
148
  }],
129
149
  ["startAngle", {
130
150
  'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
@@ -134,6 +154,26 @@ export default class Plugin {
134
154
  'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
135
155
  'adaptor': (item) => new Float32Array([item.tailAngle])
136
156
  }],
157
+ ["startAngle2d", {
158
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
159
+ 'adaptor': (item) => new Float32Array([item.startAngle2d])
160
+ }],
161
+ ["tailAngle2d", {
162
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
163
+ 'adaptor': (item) => new Float32Array([item.tailAngle2d])
164
+ }],
165
+ ["startAngle3d", {
166
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
167
+ 'adaptor': (item) => new Float32Array([item.startAngle3d])
168
+ }],
169
+ ["tailAngle3d", {
170
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
171
+ 'adaptor': (item) => new Float32Array([item.tailAngle3d])
172
+ }],
173
+ ["bearingDashRatio", {
174
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
175
+ 'adaptor': (item) => new Float32Array([0])
176
+ }],
137
177
  ["rgba", {
138
178
  'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
139
179
  'adaptor': (item) => new Float32Array(item.rgba)
@@ -173,38 +213,42 @@ export default class Plugin {
173
213
 
174
214
  const obj = function (bufferManagerComp) {
175
215
  return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
216
+
176
217
  };
177
218
 
178
219
  this.lineVao = this.lineProgram.createVAO(
179
- ...['centerCoords', 'targetCoords', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
220
+ ...['centerCoords2d', 'centerCoords3d', 'targetCoords2d', 'targetCoords3d', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
180
221
  this.ringVao = this.ringProgram.createVAO(
181
- ...['centerCoords', 'startAngle', 'tailAngle', 'rgba', 'radius', 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
222
+ ...['centerCoords2d', 'centerCoords3d',
223
+ 'startAngle2d',
224
+ 'tailAngle2d',
225
+ 'startAngle3d',
226
+ 'tailAngle3d',
227
+ 'rgba',
228
+ 'radius',
229
+ 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
182
230
  {
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);
231
+ this.bearingLineVAO = this.lineProgram.createVAO(
232
+ ...['centerCoords2d', 'centerCoords3d', 'bearingTargetCoords2d', 'bearingTargetCoords3d', 'bearingDashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
190
233
  }
191
234
  // centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
192
235
  this.circleVao = this.circleProgram.createVAO(
193
- ...["centerCoords", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
236
+ ...["centerCoords2d", "centerCoords3d", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
194
237
  }
195
238
 
196
239
 
197
240
 
198
241
  draw3D() {
199
242
  const { gl } = this;
200
- this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
201
243
  gl.disable(gl.DEPTH_TEST);
244
+
245
+ this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
202
246
  if (this.drawAngleRing) {
203
247
  this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity * 0.8, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
204
248
  this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
205
249
  }
206
250
  if (this.drawBearingLine) {
207
- this.angledLineProgram.draw(this.angledLineVao, this.bufferOrchestrator.length, this._opacity * 0.8);
251
+ this.lineProgram.draw(this.bearingLineVAO, this.bufferOrchestrator.length, this._opacity * 0.8);
208
252
  }
209
253
  if (this.drawVRM) {
210
254
  this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
@@ -254,7 +298,7 @@ export default class Plugin {
254
298
 
255
299
 
256
300
  deleteBulk(keys) {
257
- this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap, ["radius", "centerCoords", "targetCoords", "rgba"]);
301
+ this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap);
258
302
  this._deleteTexts(keys);
259
303
  this.globe.DrawRender();
260
304
  }
@@ -278,7 +322,9 @@ export default class Plugin {
278
322
  data.push(this.__updateCoordsAdaptor(item));
279
323
  }
280
324
 
281
- bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords", "targetCoords", "startAngle", "tailAngle", "bearingAngle", "bigRadius", "radius"]);
325
+ bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords2d", "centerCoords3d", "targetCoords2d", "targetCoords3d", "startAngle", "tailAngle",
326
+ "startAngle2d", "tailAngle2d", "startAngle3d", "tailAngle3d", "bearingTargetCoords2d", "bearingTargetCoords3d",
327
+ "bearingAngle", "bigRadius", "radius"]);
282
328
  globe.DrawRender();
283
329
  }
284
330
 
@@ -310,34 +356,17 @@ export default class Plugin {
310
356
 
311
357
 
312
358
  __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)
359
+
317
360
  const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
318
361
  const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
319
362
  const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
320
363
  const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
321
364
  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
- }
365
+
366
+ const coordsData = this.__updateCoordsAdaptor(item);
367
+
330
368
  return {
331
- key: item.key,
332
- lat,
333
- long,
334
- endLat,
335
- endLong,
336
- bearingAngle,
337
- radius,
338
- bigRadius,
339
- startAngle,
340
- tailAngle,
369
+ ...coordsData,
341
370
  rgba,
342
371
  dashRatio,
343
372
  dashOpacity,
@@ -353,27 +382,44 @@ export default class Plugin {
353
382
  const endLong = radian(item.endLong)
354
383
  const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
355
384
  const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
356
- const startAngle = calculateStartAngle(long, lat, endLong, endLat);
385
+
386
+
387
+ const { long: bearingLong, lat: bearingLat } = this.globe.Math.FindPointByPolar(item.long, item.lat, bigRadius, item.bearingAngle)
388
+
389
+ const startAngle2d = calculateStartAngle(long, lat, endLong, endLat);
390
+ const bearingAngle2d = calculateStartAngle(long, lat, radian(bearingLong), radian(bearingLat))
391
+ let tailAngle2d = bearingAngle2d - startAngle2d;
392
+ if (tailAngle2d > 0) {
393
+ tailAngle2d -= Math.PI * 2;
394
+ }
395
+
357
396
  const bearingAngle = radian(item.bearingAngle - 90);
358
- let tailAngle = bearingAngle - startAngle;
359
- if (tailAngle > 0) {
360
- tailAngle -= Math.PI * 2;
397
+ const startAngle3d = radian(this.globe.Math.GetAzimuthAngle(item.long, item.lat, item.endLong, item.endLat)) - radian(90);
398
+ let tailAngle3d = bearingAngle - startAngle3d;
399
+ if (tailAngle3d > 0) {
400
+ tailAngle3d -= Math.PI * 2;
361
401
  }
402
+
362
403
  return {
363
404
  key: item.key,
364
- lat,
365
- long,
366
- endLat,
367
- endLong,
405
+ lat: item.lat,
406
+ long: item.long,
407
+ endLat: item.endLat,
408
+ endLong: item.endLong,
368
409
  bearingAngle,
369
410
  radius,
370
411
  bigRadius,
371
- startAngle,
372
- tailAngle,
412
+ startAngle2d,
413
+ tailAngle2d,
414
+ startAngle3d,
415
+ tailAngle3d,
416
+ bearingLong,
417
+ bearingLat
373
418
  };
374
419
  }
375
420
 
376
421
 
422
+
377
423
  //TODO free
378
424
  free() {
379
425
  if (this.isFreed) return;
@@ -381,7 +427,7 @@ export default class Plugin {
381
427
  bufferManager.free();
382
428
  });
383
429
  LineOnGlobeCache.release(this.globe);
384
- ringProgramCache.release(this.globe);
430
+ pieceOfPieProgramCache.release(this.globe);
385
431
  CircleCache.release(this.globe);
386
432
  AngledLineProgramCache.release(this.globe);
387
433
  this.isFreed = true;
@@ -418,7 +464,7 @@ const integralSec = (angle) => {
418
464
  return Math.log(Math.tan(angle / 2 + Math.PI / 4));
419
465
  }
420
466
 
421
- const textWriterGetOrThrow = mapGetOrThrow("textContextInjection id does not exist in map:")
467
+ const textWriterGetOrThrow = mapGetOrThrow("BearingLine textContextInjection id does not exist in map")
422
468
 
423
469
  const calculateStartAngle = (long, lat, endLong, endLat) => {
424
470
  const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.
@@ -0,0 +1,430 @@
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';
4
+ import { BufferOrchestrator, BufferManager } from '../util/account';
5
+ import { AngledLineProgramCache } from '../programs/line-on-globe/angled-line';
6
+ import { mapGetOrThrow } from "../util/check/get";
7
+ import { ContextTextWriter } from '../write-text/context-text'
8
+ export const RINGPARTIAL_DRAW_MODE = Object.freeze({
9
+ LINE_STRIP: "LINE_STRIP",
10
+ TRIANGLE_FAN: "TRIANGLE_FAN",
11
+ });
12
+
13
+ const constraintFloat = (x, lowerBound, upperBound) => {
14
+ if (typeof x !== "number") throw new Error("type must be numberic")
15
+ if (lowerBound > x || x > upperBound) throw new Error(`input must be between ${lowerBound} - ${upperBound}`)
16
+ }
17
+
18
+
19
+
20
+
21
+ /**
22
+ * @typedef {Object}textContextInjection
23
+ * @property {string} id
24
+ * @property {function} coordsAdaptor
25
+ * @property {function} textAdaptor
26
+ * @property {ContextTextWriter} writer
27
+ *
28
+ */
29
+
30
+ export default class Plugin {
31
+ /**
32
+ *
33
+ * @param {*} id
34
+ * @param {Map<[K ,{writer:ContextTextWriter, coordsAdaptor, textAdaptor}]} textContextInjectionMap import { ContextTextWriter } from '@pirireis/webglobeplugins/write-text/context-text';
35
+ *
36
+ */
37
+
38
+ constructor(id, { opacity = 1, textContextInjectionMap = new Map(), drawVRM = true, drawBearingLine = true, drawAngleRing = true, drawText = true } = {}) {
39
+ this.id = id;
40
+ this._opacity = opacity;
41
+ this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
42
+ this._checkTextContextInjectionMap(textContextInjectionMap);
43
+ this._textContextInjectionMap = textContextInjectionMap;
44
+ this.drawVRM = drawVRM;
45
+ this.drawBearingLine = drawBearingLine;
46
+ this.drawAngleRing = drawAngleRing;
47
+ this.drawText = drawText;
48
+ }
49
+
50
+ setDoDrawVRM(bool) {
51
+ if (bool === this.drawVRM) return;
52
+ this.drawVRM = bool;
53
+ this.globe.DrawRender();
54
+ }
55
+
56
+ setDoDrawText(bool) {
57
+ if (bool === this.drawText) return;
58
+ this.drawText = bool;
59
+ this.globe.DrawRender();
60
+ }
61
+
62
+ setDoDrawText(bool) {
63
+ if (bool === this.drawText) return;
64
+ this.drawText = bool;
65
+ this.globe.DrawRender();
66
+ }
67
+
68
+ _checkTextContextInjectionMap(textContextInjectionMap) {
69
+ if (!(textContextInjectionMap instanceof Map)) throw new TypeError("textContextInjectionMap is not instance of Map");
70
+ textContextInjectionMap.forEach((v) => {
71
+ if (typeof v !== 'object') throw new TypeError("textContextInjectionMap format is wrong");
72
+ if (typeof v.coordsAdaptor !== 'function') throw new TypeError("textContextInjectionMap coordsAdaptor format is wrong");
73
+ if (typeof v.textAdaptor !== 'function') throw new TypeError("textContextInjectionMap textAdaptor format is wrong");
74
+ if (!(v.writer instanceof ContextTextWriter)) throw new TypeError("textContextInjectionMap writer is not instance of ContextTextWriter");
75
+ })
76
+ }
77
+
78
+ setDoDrawAngleRing(bool) {
79
+ if (bool === this.drawAngleRing) return;
80
+ this.drawAngleRing = bool;
81
+ this.globe.DrawRender();
82
+ }
83
+
84
+
85
+ settextContextInjectionMap(textContextInjectionMap, data = null) {
86
+ this._textContextInjectionMap = textContextInjectionMap;
87
+ this._textContextInjectionMap.forEach(({ writer }) => writer.clear());
88
+ if (data) {
89
+ for (const item of data) {
90
+ this._insertTexts(item);
91
+ }
92
+ }
93
+ }
94
+
95
+
96
+ setOpacity(opacity) {
97
+ constraintFloat(opacity, 0, 1);
98
+ this._opacity = opacity;
99
+ this._textContextInjectionMap.forEach(({ writer }) => writer.setOpacity(opacity));
100
+ this.globe.DrawRender();
101
+ }
102
+
103
+
104
+
105
+
106
+ init(globe, gl) {
107
+ this.gl = gl;
108
+ this.globe = globe;
109
+ this.lineProgram = LineOnGlobeCache.get(globe);
110
+ this.ringProgram = ringProgramCache.get(globe);
111
+ this.angledLineProgram = AngledLineProgramCache.get(globe);
112
+ this.circleProgram = CircleCache.get(globe);
113
+ // this.angleTextContext = new ContextTextWriter(globe);
114
+ // this.distanceTextContext = new ContextTextWriter(globe);
115
+ {
116
+ // createBuffers
117
+ const bufferType = "DYNAMIC_DRAW";
118
+ const initialCapacity = this.bufferOrchestrator.capacity;
119
+ this.bufferManagersCompMap = new Map(
120
+ [
121
+ ["centerCoords", {
122
+ 'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
123
+ 'adaptor': (item) => new Float32Array([item.long, item.lat]),
124
+ }],
125
+ ["targetCoords", {
126
+ 'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
127
+ 'adaptor': (item) => new Float32Array([item.endLong, item.endLat])
128
+ }],
129
+ ["startAngle", {
130
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
131
+ 'adaptor': (item) => new Float32Array([item.startAngle])
132
+ }],
133
+ ["tailAngle", {
134
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
135
+ 'adaptor': (item) => new Float32Array([item.tailAngle])
136
+ }],
137
+ ["rgba", {
138
+ 'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
139
+ 'adaptor': (item) => new Float32Array(item.rgba)
140
+ }],
141
+ ["radius", {
142
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
143
+ 'adaptor': (item) => new Float32Array([item.radius])
144
+ }],
145
+ ["rgbaMode", {
146
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
147
+ 'adaptor': (item) => new Float32Array([item.rgbaMode])
148
+ }],
149
+ ["dashRatio", {
150
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
151
+ 'adaptor': (item) => new Float32Array([item.dashRatio])
152
+ }],
153
+ ["bearingAngle", {
154
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
155
+ 'adaptor': (item) => new Float32Array([item.bearingAngle])
156
+ }],
157
+ ["bigRadius", {
158
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
159
+ 'adaptor': (item) => new Float32Array([item.bigRadius])
160
+ }],
161
+ ["dashOpacity", {
162
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
163
+ 'adaptor': (item) => new Float32Array([item.dashOpacity])
164
+ }],
165
+ ["circleDashAngle", {
166
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
167
+ 'adaptor': (item) => new Float32Array([item.circleDashAngle / 360])
168
+ }]
169
+ ]
170
+ );
171
+ }
172
+
173
+
174
+ const obj = function (bufferManagerComp) {
175
+ return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
176
+ };
177
+
178
+ this.lineVao = this.lineProgram.createVAO(
179
+ ...['centerCoords', 'targetCoords', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
180
+ this.ringVao = this.ringProgram.createVAO(
181
+ ...['centerCoords', 'startAngle', 'tailAngle', 'rgba', 'radius', 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
182
+ {
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);
190
+ }
191
+ // centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
192
+ this.circleVao = this.circleProgram.createVAO(
193
+ ...["centerCoords", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
194
+ }
195
+
196
+
197
+
198
+ draw3D() {
199
+ const { gl } = this;
200
+ this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
201
+ gl.disable(gl.DEPTH_TEST);
202
+ if (this.drawAngleRing) {
203
+ this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity * 0.8, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
204
+ this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
205
+ }
206
+ if (this.drawBearingLine) {
207
+ this.angledLineProgram.draw(this.angledLineVao, this.bufferOrchestrator.length, this._opacity * 0.8);
208
+ }
209
+ if (this.drawVRM) {
210
+ this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
211
+ }
212
+ if (this.drawText) {
213
+ this._textContextInjectionMap.forEach((e) => { e.writer.draw(); });
214
+ }
215
+ gl.enable(gl.DEPTH_TEST);
216
+ }
217
+
218
+
219
+ /**
220
+ * @typedef {{key, long, lat, endLong, endLat, bearingAngle, radius, rgba:[4numbers], rgbaMode, bigRadius, dashRatio, dashOpacity, circleDashAngle}} item
221
+ * @property {string} key
222
+ * @property {number} long
223
+ * @property {number} lat
224
+ * @property {number} endLong
225
+ * @property {number} endLat
226
+ * @property {number} bearingAngle 0-360
227
+ * @property {number} radius angle ring radius
228
+ * @property {Array<4numbers>} rgba [r,g,b,a]
229
+ * @property {number} rgbaMode 0 constant, 1 fading, 2 hides angle ring
230
+ * @property {number} bigRadius undefined means it will be calculated from long, lat, endLong, endLat
231
+ * @property {number} dashRatio 0-1
232
+ * @property {number} dashOpacity 0-1
233
+ * @property {number} circleDashAngle 0-360
234
+ * @param {Array<item>} items
235
+ * @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
236
+ */
237
+ insertBulk(items, textWriterInjectionSubSetIDs = []) {
238
+ const { globe, bufferOrchestrator, bufferManagersCompMap } = this;// angleTextContext, distanceTextContext,
239
+ const textWriterInjectionSubSets = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
240
+ const data = []
241
+ for (let item of items) {
242
+ this._insertTexts(item, textWriterInjectionSubSets);
243
+ data.push(this.__insertAdaptor(item));
244
+ }
245
+ bufferOrchestrator.insertBulk(data, bufferManagersCompMap);
246
+ this._textContextInjectionMap.forEach((v) => {
247
+ const { writer } = v;
248
+ writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
249
+ })
250
+ globe.DrawRender();
251
+ }
252
+
253
+
254
+
255
+
256
+ deleteBulk(keys) {
257
+ this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap, ["radius", "centerCoords", "targetCoords", "rgba"]);
258
+ this._deleteTexts(keys);
259
+ this.globe.DrawRender();
260
+ }
261
+
262
+
263
+ defrag() {
264
+ this.bufferOrchestrator.defrag(this.bufferManagersCompMap);
265
+ }
266
+
267
+ /**
268
+ *
269
+ * @param {Array<{key, long, lat, endLong, endLat, bearingAngle}>} items
270
+ * @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
271
+ */
272
+ updateCoordinatesBulk(items, textWriterInjectionSubSetIDs = []) { //TODO
273
+ const injectionsSubSet = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);;
274
+ const { globe, bufferOrchestrator, bufferManagersCompMap, } = this;
275
+ const data = []
276
+ for (let item of items) {
277
+ this._insertTexts(item, injectionsSubSet);
278
+ data.push(this.__updateCoordsAdaptor(item));
279
+ }
280
+
281
+ bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords", "targetCoords", "startAngle", "tailAngle", "bearingAngle", "bigRadius", "radius"]);
282
+ globe.DrawRender();
283
+ }
284
+
285
+
286
+ /**
287
+ *
288
+ * @param {*} items some colums EXCEPT positional ones
289
+ * @param {string} propertyIDs
290
+ * @param {string} textWriterInjectionSubSetIDs
291
+ * Do NOT send empty data if property ID of this data is entered or NaN is loaded to the buffer, resulting in an unwanted behaviour.
292
+ */
293
+ updatePartial(items, propertyIDs = [], textWriterInjectionSubSetIDs = []) { // textWriterInjectionSubSetIDs = []
294
+ if (propertyIDs.length === 0) console.warn("updatePartial is called with no target propertyIDs");
295
+ const { _textContextInjectionMap, bufferOrchestrator, bufferManagersCompMap } = this;
296
+ const writers = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
297
+ for (let item of items) { this._insertTexts(item, writers) }
298
+ bufferOrchestrator.updateBulk(items, bufferManagersCompMap, propertyIDs);
299
+ // patch to update text opacity
300
+ for (const property of propertyIDs) {
301
+ if (property === "rgba") {
302
+ _textContextInjectionMap.forEach((v) => {
303
+ const { writer } = v;
304
+ writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
305
+ })
306
+ }
307
+ }
308
+ this.globe.DrawRender();
309
+ }
310
+
311
+
312
+ __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)
317
+ const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
318
+ const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
319
+ const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
320
+ const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
321
+ 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
+ }
330
+ return {
331
+ key: item.key,
332
+ lat,
333
+ long,
334
+ endLat,
335
+ endLong,
336
+ bearingAngle,
337
+ radius,
338
+ bigRadius,
339
+ startAngle,
340
+ tailAngle,
341
+ rgba,
342
+ dashRatio,
343
+ dashOpacity,
344
+ circleDashAngle,
345
+ rgbaMode
346
+ };
347
+ }
348
+
349
+ __updateCoordsAdaptor(item) {
350
+ const lat = radian(item.lat)
351
+ const long = radian(item.long)
352
+ const endLat = radian(item.endLat)
353
+ 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);
355
+ const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
356
+ const startAngle = calculateStartAngle(long, lat, endLong, endLat);
357
+ const bearingAngle = radian(item.bearingAngle - 90);
358
+ let tailAngle = bearingAngle - startAngle;
359
+ if (tailAngle > 0) {
360
+ tailAngle -= Math.PI * 2;
361
+ }
362
+ return {
363
+ key: item.key,
364
+ lat,
365
+ long,
366
+ endLat,
367
+ endLong,
368
+ bearingAngle,
369
+ radius,
370
+ bigRadius,
371
+ startAngle,
372
+ tailAngle,
373
+ };
374
+ }
375
+
376
+
377
+ //TODO free
378
+ free() {
379
+ if (this.isFreed) return;
380
+ this.bufferManagersCompMap.forEach(({ bufferManager, adaptor }) => {
381
+ bufferManager.free();
382
+ });
383
+ LineOnGlobeCache.release(this.globe);
384
+ ringProgramCache.release(this.globe);
385
+ CircleCache.release(this.globe);
386
+ AngledLineProgramCache.release(this.globe);
387
+ this.isFreed = true;
388
+ }
389
+
390
+
391
+
392
+
393
+ _insertTexts(item, textWriterInjectionSubSet) {
394
+ //TODO This method can be more performant if it works horizontally, tabular
395
+ textWriterInjectionSubSet.forEach((v) => {
396
+ const { coordsAdaptor, textAdaptor, writer } = v
397
+ const { lat, long } = coordsAdaptor(item);
398
+ const text = textAdaptor(item);
399
+ writer.insertText(item.key, lat, long, text);
400
+ });
401
+ }
402
+
403
+
404
+ _deleteTexts(keys) {
405
+ this._textContextInjectionMap.forEach((e) => {
406
+ e.writer.deleteTextBulk(keys);
407
+ });
408
+ }
409
+
410
+
411
+ }
412
+
413
+
414
+
415
+ const radian = (degree) => degree * Math.PI / 180;
416
+
417
+ const integralSec = (angle) => {
418
+ return Math.log(Math.tan(angle / 2 + Math.PI / 4));
419
+ }
420
+
421
+ const textWriterGetOrThrow = mapGetOrThrow("BearingLine textContextInjection id does not exist in map")
422
+
423
+ const calculateStartAngle = (long, lat, endLong, endLat) => {
424
+ const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.
425
+ const dLong = endLong - long;
426
+
427
+ let angle = -Math.atan2(dLat, dLong);
428
+ return angle;
429
+ }
430
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.6.17",
3
+ "version": "0.6.18",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT"
@@ -0,0 +1,77 @@
1
+ /**
2
+ * This class registered as globe plugin one for each globe. to the head of plugin call stack.
3
+ */
4
+
5
+ class PinPointTotem {
6
+ constructor(globe) {
7
+
8
+ this.objectArrayMap = new Map()
9
+ }
10
+
11
+
12
+ /**
13
+ * objectArray
14
+ * callbacks ={
15
+ * mouseDown,
16
+ * mouseMove,
17
+ * mouseUp,
18
+ * mouseClick,
19
+ * mouseDbClick,
20
+ * keyDown,
21
+ * keyUp
22
+ * }
23
+ */
24
+ registerPinMap(objectArray, callbacks) {
25
+ this.objectArrayMap.set(objectArray, callbacks);
26
+ }
27
+
28
+ unregisterPinMap(objectArray) {
29
+ if (this.objectArrayMap.has(objectArray)) {
30
+ this.objectArrayMap.delete(objectArray);
31
+ } else {
32
+ console.warn('PinPointTotem objectArrayMap does not contain the objectArray')
33
+ }
34
+ }
35
+
36
+
37
+ // GlobeMethods
38
+ // haritada sol butona basıldığında çağrılır
39
+ mouseDown(x, y, event) {
40
+
41
+ return false
42
+ }
43
+
44
+ // mouse'a basılıp hareket ettirildiğinde, mouseDown'dan true dönmüşse çağrılır
45
+ mouseMove(x, y, event) {
46
+
47
+ }
48
+
49
+ // mouse up'ın left'i mouseDown'dan true dönmüşse çağrılır, edit mode içindir
50
+ // right'i ise sağ tıka basılıp bırakıldığında çağrılır
51
+ mouseUp(x, y, event) {
52
+
53
+ }
54
+
55
+ // harita üzerinde tıklandığında çağrılır
56
+ mouseClick(x, y, event) {
57
+
58
+ return false
59
+ }
60
+
61
+ // harita üzerinde çift tıklandığında çağrılır
62
+ mouseDblClick(x, y, event) {
63
+ return false
64
+ }
65
+
66
+ // klavyeden bir tuşa basıldığı anda ve tuşa basılı kalınmaya devam edildiği durumlarda çalışır
67
+ keyDown(event) {
68
+ return false
69
+ }
70
+
71
+ // klavyedeki bir tuştan parmak çekildiği anda çalışır
72
+ keyUp(event) {
73
+
74
+ return false
75
+ }
76
+
77
+ }
@@ -58,7 +58,7 @@ void main() {
58
58
  v_limp = vec2(0.0, 0.0);
59
59
  } else {
60
60
  vec2 position;
61
- if ( radius < 1000.0) {
61
+ if ( radius < 0.0) {
62
62
  float cosine1 = cos(asin(tanh(center_position.y / 6378137.0)));
63
63
  position = circleLimpFromLongLatRadCenterMercatorCompass_accurate(center_position, radius / cosine1 , angle);
64
64
  } else {
@@ -5,7 +5,7 @@ import { noRegisterGlobeProgramCache, globeProgramCache } from "../programcache"
5
5
  import BufferOffsetManger from "../../util/account/bufferoffsetmanager";
6
6
  import { programCache } from "../rings/distancering/circleflatprogram";
7
7
 
8
- const GLOBE_MIDPOINT_COUNT = 100;
8
+ const GLOBE_MIDPOINT_COUNT = 30;
9
9
  const ITEM_SIZE = 9;
10
10
 
11
11
  const vertexShader = `#version 300 es
@@ -17,7 +17,7 @@ ${mercatorXYToGLPosition}
17
17
  ${cartesian3DToGLPosition}
18
18
 
19
19
  in vec2 start_position;
20
- in vec3 start_poisition3d;
20
+ in vec3 start_position3d;
21
21
  in vec2 end_position;
22
22
  in vec3 end_position3d;
23
23
  in float dash_ratio;
@@ -34,7 +34,12 @@ void main() {
34
34
  vec2 longLat;
35
35
  if (is3D) {
36
36
  interpolation = float(gl_VertexID) / ${GLOBE_MIDPOINT_COUNT - 1}.0;
37
- vec3 cartesian = pointsOnSphereBetween(start_poisition3d, end_position3d, interpolation) * length(end_position3d);
37
+ vec3 cartesian;
38
+ if ( length( start_position3d - end_position3d) < 4.4){
39
+ cartesian = mix( start_position3d, end_position3d, interpolation);
40
+ } else {
41
+ cartesian = pointsOnSphereBetween(start_position3d, end_position3d, interpolation) * length(end_position3d);
42
+ }
38
43
  gl_Position = cartesian3DToGLPosition(cartesian);
39
44
  v_limp = vec2(0.0, 0.0);
40
45
  } else {
@@ -124,11 +129,9 @@ class Logic {
124
129
  this._lastOpacity = opacity;
125
130
  }
126
131
  const drawCount = globe.api_GetCurrentGeometry() === 0 ? GLOBE_MIDPOINT_COUNT : 2;
127
- // gl.disable(gl.DEPTH_TEST);
128
132
  gl.drawArraysInstanced(gl.LINE_STRIP, 0, drawCount, length);
129
133
  gl.bindVertexArray(null);
130
134
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
131
- // gl.enable(gl.DEPTH_TEST);
132
135
  }
133
136
 
134
137
  //
@@ -0,0 +1,315 @@
1
+ import { createProgram, shaderfunctions } from "../../../util";
2
+ import { CameraUniformBlockTotem, CameraUniformBlockString } from "../../totems";
3
+ import { noRegisterGlobeProgramCache, globeProgramCache } from "../../programcache";
4
+ import {
5
+ POLE,
6
+ PI,
7
+ longLatRadToMercator,
8
+ mercatorXYToGLPosition,
9
+ longLatRadToCartesian3D,
10
+ circleLimpFromLongLatRadCenterCartesian3D_accurate,
11
+ circleLimpFromLongLatRadCenterMercatorCompass_accurate,
12
+ circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate,
13
+ cartesian3DToGLPosition
14
+
15
+
16
+ } from "../../../util/shaderfunctions/geometrytransformations";
17
+
18
+
19
+ /**
20
+ * TODO:
21
+ * 1. Triangle face looks at screen. if rotation angle is positive the last vertex must be the faintest.
22
+ *
23
+ */
24
+
25
+ const drawModeMap = Object.freeze({
26
+ LINE_STRIP: 0,
27
+ TRIANGLE_FAN: 1,
28
+ });
29
+
30
+
31
+
32
+ const vertexShaderSource = `#version 300 es
33
+
34
+ ${CameraUniformBlockString}
35
+ ${PI}
36
+ ${longLatRadToMercator}
37
+ ${mercatorXYToGLPosition}
38
+ ${longLatRadToCartesian3D}
39
+ ${circleLimpFromLongLatRadCenterCartesian3D_accurate}
40
+ ${circleLimpFromLongLatRadCenterMercatorCompass_accurate}
41
+ ${circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate}
42
+ ${cartesian3DToGLPosition}
43
+
44
+ uniform float edge_count;
45
+ uniform int draw_mode; // %2 => 0: LINE_STRIP, 1: TRIANGLE_FAN
46
+ uniform float plugin_alpha_multiplier;
47
+ //, lat, startAngle, tailAngle, ...rgba, radius, rgbaMode
48
+ // in vec2 center; // long, lat in radian
49
+ in vec2 center2d;
50
+ in vec3 center3d;
51
+ in float start_angle2d;
52
+ in float tail_angle2d;
53
+
54
+ in float start_angle3d;
55
+ in float tail_angle3d;
56
+
57
+ in vec4 color;
58
+ in float radius; // in meter
59
+ in float color_mode; // 0.0: constant, 1.0: fading, 2.0: hide
60
+ // flat out int vid;
61
+ // flat out float v_phase;
62
+ out vec2 v_pos;
63
+ out vec4 v_color;
64
+ // flat out float v_angle;
65
+
66
+ void main() {
67
+ // vid = gl_VertexID;
68
+ if (color_mode == 2.0 || radius == 0.0) { return; }
69
+ float start_angle, tail_angle;
70
+ if (is3D) {
71
+ start_angle = start_angle3d;
72
+ tail_angle = tail_angle3d;
73
+ } else {
74
+ start_angle = start_angle2d;
75
+ tail_angle = tail_angle2d;
76
+ }
77
+ float color_mode_ = color_mode;
78
+ if ( draw_mode == 0 && color_mode == 1.0) {color_mode_ = 0.0;}
79
+ float vertexID = float(gl_VertexID);
80
+ float radius_ = radius;
81
+ float alpha = plugin_alpha_multiplier;
82
+ if (draw_mode == 1) { // TRIANGLE_FAN
83
+ if (gl_VertexID == 0) {
84
+ radius_ = 0.0;
85
+ if ( color_mode == 1.0 ) { alpha = 0.0; }
86
+ }
87
+ vertexID -= 1.0;
88
+ }
89
+ float phase = ( vertexID / (edge_count - 1.0) );
90
+ // v_angle = tail_angle;
91
+
92
+ if ( color_mode_ == 1.0 ) {
93
+ if ( tail_angle < 0.0 ) {
94
+ v_color = vec4( color.rgb , color.a * ( 1.0 - phase ) * alpha );
95
+ } else {
96
+ v_color = vec4( color.rgb , color.a * phase * alpha );
97
+ }
98
+ } else {
99
+ v_color = vec4( color.rgb , color.a * alpha );
100
+ }
101
+ if ( color_mode == 0.0 && draw_mode == 1 ) {
102
+ v_color.a /= 2.0;
103
+ }
104
+ float angle;
105
+ if ( tail_angle > 0.0 ) {
106
+ angle = tail_angle * (-phase + 1.0) + start_angle;
107
+ } else {
108
+ angle = tail_angle * phase + start_angle;
109
+ }
110
+ if (is3D) {
111
+ vec3 pos = circleLimpFromLongLatRadCenterCartesian3D_accurate(center3d, radius_, angle);
112
+ v_pos = vec2(0.0, 0.0);
113
+ gl_Position = cartesian3DToGLPosition(pos);
114
+ }
115
+ else {
116
+ vec2 pos2 = circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate(center2d, radius_, angle);
117
+ v_pos = pos2;
118
+ gl_Position = mercatorXYToGLPosition(pos2);
119
+ }
120
+
121
+ gl_PointSize = 10.0;
122
+ }`;
123
+
124
+
125
+ const fragmentShaderSource = `#version 300 es` + POLE + PI + `
126
+ precision highp float;
127
+ // flat in int vid;
128
+ in vec4 v_color;
129
+ in vec2 v_pos;
130
+ // flat in float v_phase;
131
+ // in float v_angle;
132
+ out vec4 outColor;
133
+ void main() {
134
+ // if( vid % 2 == 0 ) { discard; }
135
+ // if ( mod(v_angle, PI / 36.0 ) < (PI / 72.0)) { discard; }
136
+ // if ( mod(v_angle * v_phase, PI / 90.0 ) < (PI / 180.0)) { discard; }
137
+ if ( v_pos.x < -POLE || v_pos.x > POLE || v_pos.y < -POLE || v_pos.y > POLE ) { discard; }
138
+ outColor = v_color;
139
+ }`;
140
+
141
+ export const ITEM_SIZE = 10;
142
+
143
+ export class Logic {
144
+
145
+ constructor(globe) {
146
+ this.globe = globe;
147
+ this.gl = globe.gl;
148
+ this._lastMode = 0;
149
+ this._lastEdgeCount = 64;
150
+ this._lastAlphaMultiplier = 1.0;
151
+
152
+ this.program = createProgram(this.gl, vertexShaderSource, fragmentShaderSource);
153
+ const { gl, program } = this;
154
+ { // set attributes locations
155
+ gl.bindAttribLocation(program, 0, 'center2d');
156
+ gl.bindAttribLocation(program, 1, 'center3d')
157
+ gl.bindAttribLocation(program, 2, 'start_angle2d');
158
+ gl.bindAttribLocation(program, 3, 'tail_angle2d');
159
+ gl.bindAttribLocation(program, 4, 'start_angle3d');
160
+ gl.bindAttribLocation(program, 5, 'tail_angle3d');
161
+ gl.bindAttribLocation(program, 6, 'color');
162
+ gl.bindAttribLocation(program, 7, 'radius');
163
+ gl.bindAttribLocation(program, 8, 'color_mode');
164
+ // vao
165
+ // instanced draw read 1
166
+ }
167
+ { // Uniforms
168
+ this._edgeCountLocation = gl.getUniformLocation(program, 'edge_count');
169
+ this._draw_modeLocation = gl.getUniformLocation(program, 'draw_mode');
170
+ this._plugin_alpha_multiplierLocation = gl.getUniformLocation(program, 'plugin_alpha_multiplier');
171
+ const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
172
+ gl.useProgram(program);
173
+ gl.uniform1i(this._draw_modeLocation, this._lastMode);
174
+ gl.uniform1f(this._edgeCountLocation, this._lastEdgeCount);
175
+ gl.uniform1f(this._plugin_alpha_multiplierLocation, 1.0);
176
+
177
+ this.cameraBlockBindingPoint = 0;
178
+ this.cameraBlockTotem = globeProgramCache.getProgram(globe, CameraUniformBlockTotem);
179
+ const cameraBlockIndex = gl.getUniformBlockIndex(program, "CameraUniformBlock");
180
+ gl.uniformBlockBinding(program, cameraBlockIndex, this.cameraBlockBindingPoint);
181
+
182
+ gl.useProgram(currentProgram);
183
+ }
184
+
185
+ }
186
+
187
+
188
+
189
+ draw(length, vao, edgeCount, alphaMultiplier, drawMode) {
190
+ const { gl, program, cameraBlockTotem, cameraBlockBindingPoint } = this
191
+
192
+ // gl.disable(gl.DEPTH_TEST);
193
+ gl.useProgram(program);
194
+ if (drawMode !== this._lastMode) {
195
+ gl.uniform1i(this._draw_modeLocation, drawModeMap[drawMode]);
196
+ this._lastMode = drawMode;
197
+ }
198
+ if (edgeCount !== this._lastEdgeCount) {
199
+ gl.uniform1f(this._edgeCountLocation, edgeCount);
200
+ this._lastEdgeCount = edgeCount;
201
+ }
202
+ if (alphaMultiplier !== this._lastAlphaMultiplier) {
203
+ gl.uniform1f(this._plugin_alpha_multiplierLocation, alphaMultiplier);
204
+ this._lastAlphaMultiplier = alphaMultiplier;
205
+ }
206
+ const overdraw = drawModeMap[drawMode];
207
+ cameraBlockTotem.bind(cameraBlockBindingPoint);
208
+ gl.bindVertexArray(vao);
209
+ gl.drawArraysInstanced(gl[drawMode], 0, edgeCount + overdraw, length);
210
+ cameraBlockTotem.unbind(cameraBlockBindingPoint);
211
+ gl.bindVertexArray(null);
212
+ // gl.enable(gl.DEPTH_TEST);
213
+ }
214
+
215
+
216
+ free() {
217
+ noRegisterGlobeProgramCache.releaseProgram(this.globe, CameraUniformBlockTotem);
218
+ this.gl.deleteProgram(this.program);
219
+ this.program = null;
220
+ }
221
+
222
+
223
+ /**
224
+ * in vec2 center; // long, lat in radian
225
+ in float start_angle; // the start of partial circle from bearing point
226
+ in float tail_angle; // the rotation of the partial circle
227
+ in vec4 color;
228
+ in float radius; // in meter
229
+ in float color_mode; // 0.0: constant, 1.0: fading, 2.0: hide
230
+ */
231
+
232
+ createVAO(center2dObj, center3dObj, startAngle2DObj, tailAngle2DObj, startAngle3DObj, tailAngle3DObj, colorObj, radiusObj, colorModeObj) {
233
+
234
+ const { gl } = this;
235
+ const vao = gl.createVertexArray();
236
+ gl.bindVertexArray(vao);
237
+
238
+ {
239
+ const { buffer, stride, offset } = center2dObj;
240
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
241
+ gl.enableVertexAttribArray(0);
242
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, stride, offset);
243
+ gl.vertexAttribDivisor(0, 1);
244
+ }
245
+
246
+ {
247
+ const { buffer, stride, offset } = center3dObj;
248
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
249
+ gl.enableVertexAttribArray(1);
250
+ gl.vertexAttribPointer(1, 3, gl.FLOAT, false, stride, offset);
251
+ gl.vertexAttribDivisor(1, 1);
252
+ }
253
+
254
+ {
255
+ const { buffer, stride, offset } = startAngle2DObj;
256
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
257
+ gl.enableVertexAttribArray(2);
258
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, stride, offset);
259
+ gl.vertexAttribDivisor(2, 1);
260
+ }
261
+ {
262
+ const { buffer, stride, offset } = tailAngle2DObj;
263
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
264
+ gl.enableVertexAttribArray(3);
265
+ gl.vertexAttribPointer(3, 1, gl.FLOAT, false, stride, offset);
266
+ gl.vertexAttribDivisor(3, 1);
267
+ }
268
+ {
269
+ const { buffer, stride, offset } = startAngle3DObj;
270
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
271
+ gl.enableVertexAttribArray(4);
272
+ gl.vertexAttribPointer(4, 1, gl.FLOAT, false, stride, offset);
273
+ gl.vertexAttribDivisor(4, 1);
274
+ }
275
+ {
276
+ const { buffer, stride, offset } = tailAngle3DObj;
277
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
278
+ gl.enableVertexAttribArray(5);
279
+ gl.vertexAttribPointer(5, 1, gl.FLOAT, false, stride, offset);
280
+ gl.vertexAttribDivisor(5, 1);
281
+ }
282
+ {
283
+ const { buffer, stride, offset } = colorObj;
284
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
285
+ gl.enableVertexAttribArray(6);
286
+ gl.vertexAttribPointer(6, 4, gl.FLOAT, false, stride, offset);
287
+ gl.vertexAttribDivisor(6, 1);
288
+ }
289
+ {
290
+ const { buffer, stride, offset } = radiusObj;
291
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
292
+ gl.enableVertexAttribArray(7);
293
+ gl.vertexAttribPointer(7, 1, gl.FLOAT, false, stride, offset);
294
+ gl.vertexAttribDivisor(7, 1);
295
+ }
296
+ {
297
+ const { buffer, stride, offset } = colorModeObj;
298
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
299
+ gl.enableVertexAttribArray(8);
300
+ gl.vertexAttribPointer(8, 1, gl.FLOAT, false, stride, offset);
301
+ gl.vertexAttribDivisor(8, 1);
302
+ }
303
+ gl.bindVertexArray(null);
304
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
305
+ return vao;
306
+ }
307
+
308
+
309
+
310
+ }
311
+
312
+ export const pieceOfPieProgramCache = Object.freeze({
313
+ get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, Logic),
314
+ release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, Logic)
315
+ });
package/util/check/get.js CHANGED
@@ -4,7 +4,7 @@ export const mapGetOrThrow = (errorNote) => {
4
4
  const result = [];
5
5
  for (let i = 0; i < ids.length; i++) {
6
6
  const e = mapInstance.get(ids[i]);
7
- if (e === undefined) throw new Error(errorNote + ":" + ids[i]);
7
+ if (e === undefined) throw new Error(errorNote + " " + ids[i]);
8
8
  result.push(e);
9
9
  }
10
10
  return result;
@@ -134,10 +134,11 @@ vec2 circleLimpFromLongLatRadCenterMercatorRealDistance(vec2 center, float radiu
134
134
 
135
135
  float delta_long = atan(sin(ang) * sin_r * cos(center.y), cos_r - sin(center.y) * sin_lat);
136
136
  float longi = center.x + delta_long;
137
+
137
138
 
138
139
  return vec2(
139
140
  R * longi,
140
- R * log(tan(PI / 4.0 + lat / 2.0))
141
+ R * log(tan(PI / 4.0 + lat / 2.0))
141
142
  );
142
143
  }`;
143
144
 
@@ -343,10 +344,10 @@ vec2 circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate(vec2 mercato
343
344
 
344
345
  float delta_long = atan(sin(ang) * sin_r * cos(center.y), cos_r - sin(center.y) * sin_lat);
345
346
  float longi = center.x + delta_long;
346
-
347
+ float y = mix(-80.5, 80.5, abs(lat + PI / 2.0));
347
348
  return vec2(
348
349
  R * longi,
349
- R * log(tan(PI / 4.0 + lat / 2.0))
350
+ R * log(tan(PI / 4.0 + lat / 2.0)) - y
350
351
  );
351
352
  }`;
352
353