@pirireis/webglobeplugins 0.2.0 → 0.3.1

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.
@@ -0,0 +1,12 @@
1
+ export function bearingRealAngle(long, lat, endLong, endLat) {
2
+ const rLong = Radians * long;
3
+ const rLat = Radians * lat;
4
+ const rEndLong = Radians * endLong;
5
+ const rEndLat = Radians * endLat;
6
+ const delta_long = rEndLong - rLong;
7
+ const x = Math.sin(delta_long) * Math.cos(rEndLat);
8
+ const y = Math.cos(rLat) * Math.sin(rEndLat) - Math.sin(rLat) * Math.cos(rEndLat) * Math.cos(delta_long);
9
+ let initialBearing = Math.atan2(x, y) / Radians;
10
+ initialBearing = (initialBearing + 360) % 360;
11
+ return initialBearing;
12
+ }
package/Math/index.js ADDED
File without changes
@@ -0,0 +1,2 @@
1
+ import BearingLinePlugin from "./plugin"
2
+ export { BearingLinePlugin };
@@ -1,16 +1,44 @@
1
1
  import { programCache as ringProgramCache } from '../partialrings/program';
2
2
  import { LineOnGlobeCache } from '../programs/line-on-globe/naive';
3
-
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 { ContextTextWriter } from '../write-text/context-text'
4
7
  export const RINGPARTIAL_DRAW_MODE = Object.freeze({
5
8
  LINE_STRIP: "LINE_STRIP",
6
9
  TRIANGLE_FAN: "TRIANGLE_FAN",
7
10
  });
8
11
 
12
+
13
+ /**
14
+ * @typedef {Object}textContextInjection
15
+ * @property {string} id
16
+ * @property {function} coordsAdaptor
17
+ * @property {function} textAdaptor
18
+ * @property {ContextTextWriter} writer
19
+ *
20
+ */
21
+
9
22
  export default class Plugin {
10
23
 
11
- constructor(id, { opacity = 1 } = {}) {
24
+
25
+ constructor(id, { opacity = 1, textContextInjectionMap = new Map() } = {}) {
12
26
  this.id = id;
13
27
  this._opacity = opacity;
28
+ this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
29
+ this._textContextInjectionMap = textContextInjectionMap;
30
+ }
31
+
32
+
33
+ settextContextInjectionMap(textContextInjectionMap, data = null) {
34
+ this._textContextInjectionMap = textContextInjectionMap;
35
+ this._textContextInjectionMap.forEach(({ writer }) => writer.clear());
36
+ if (data) {
37
+ for (const item of data) {
38
+ this._insertTexts(item);
39
+ }
40
+ }
41
+
14
42
  }
15
43
 
16
44
  setOpacity(opacity) {
@@ -23,21 +51,103 @@ export default class Plugin {
23
51
  this.globe = globe;
24
52
  this.lineProgram = LineOnGlobeCache.get(globe);
25
53
  this.ringProgram = ringProgramCache.get(globe);
26
- this.lineBufferManager = this.lineProgram.createBufferManager();
27
- const { bufferManager, vao } = this.ringProgram.getBufferManagerAndVao();
28
- this.ringBufferManager = bufferManager;
29
- this.ringVao = vao;
54
+ this.angledLineProgram = AngledLineProgramCache.get(globe);
55
+ this.circleProgram = CircleCache.get(globe);
56
+ // this.angleTextContext = new ContextTextWriter(globe);
57
+ // this.distanceTextContext = new ContextTextWriter(globe);
58
+ {
59
+ // createBuffers
60
+ const bufferType = "DYNAMIC_DRAW";
61
+ const initialCapacity = this.bufferOrchestrator.capacity;
62
+ this.bufferManagersCompMap = new Map(
63
+ [
64
+ ["centerCoords", {
65
+ 'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
66
+ 'adaptor': (item) => new Float32Array([item.long, item.lat]),
67
+ }],
68
+ ["targetCoords", {
69
+ 'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
70
+ 'adaptor': (item) => new Float32Array([item.endLong, item.endLat])
71
+ }],
72
+ ["startAngle", {
73
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
74
+ 'adaptor': (item) => new Float32Array([item.startAngle])
75
+ }],
76
+ ["tailAngle", {
77
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
78
+ 'adaptor': (item) => new Float32Array([item.tailAngle])
79
+ }],
80
+ ["rgba", {
81
+ 'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
82
+ 'adaptor': (item) => new Float32Array(item.rgba)
83
+ }],
84
+ ["radius", {
85
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
86
+ 'adaptor': (item) => new Float32Array([item.radius])
87
+ }],
88
+ ["rgbaMode", {
89
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
90
+ 'adaptor': (item) => new Float32Array([item.rgbaMode])
91
+ }],
92
+ ["dashRatio", {
93
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
94
+ 'adaptor': (item) => new Float32Array([item.dashRatio])
95
+ }],
96
+ ["bearingAngle", {
97
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
98
+ 'adaptor': (item) => new Float32Array([item.bearingAngle])
99
+ }],
100
+ ["bigRadius", {
101
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
102
+ 'adaptor': (item) => new Float32Array([item.bigRadius])
103
+ }],
104
+ ["dashOpacity", {
105
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
106
+ 'adaptor': (item) => new Float32Array([item.dashOpacity])
107
+ }],
108
+ ["circleDashRatio", {
109
+ 'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
110
+ 'adaptor': (item) => new Float32Array([item.circleDashRatio])
111
+ }]
112
+ ]
113
+ );
114
+ }
115
+
116
+
117
+ const obj = function (bufferManagerComp) {
118
+ return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
119
+ };
120
+
121
+ this.lineVao = this.lineProgram.createVAO(
122
+ ...['centerCoords', 'targetCoords', 'dashRatio', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
123
+ this.ringVao = this.ringProgram.createVAO(
124
+ ...['centerCoords', 'startAngle', 'tailAngle', 'rgba', 'radius', 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
125
+ {
126
+ const angledLineBuffers = ["centerCoords", "bearingAngle", "bigRadius", "rgba", "dashRatio"].map(key => obj(this.bufferManagersCompMap.get(key)));
127
+ // dashOpacity is same as rgba.a to eleminate effect of dashOpacity.
128
+ const colorBuffer = this.bufferManagersCompMap.get("rgba");
129
+ angledLineBuffers.push(
130
+ { 'buffer': colorBuffer.bufferManager.buffer, 'stride': 16, 'offset': 12 },
131
+ )
132
+ this.angledLineVao = this.angledLineProgram.createVAO(...angledLineBuffers);
133
+ }
134
+ // centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
135
+ this.circleVao = this.circleProgram.createVAO(
136
+ ...["centerCoords", "startAngle", "bigRadius", "rgba", "circleDashRatio", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
30
137
  }
31
138
 
32
139
 
140
+
33
141
  draw3D() {
34
- // vao, edgeCount, alphaMultiplier, drawMode,
35
- this.lineProgram.draw(this.lineBufferManager.vao, this.lineBufferManager.length, this._opacity);
36
- //bufferManager, vao, edgeCount, alphaMultiplier, drawMode
37
- this.gl.disable(this.gl.DEPTH_TEST);
38
- this.ringProgram.draw(this.ringBufferManager.length, this.ringVao, 32, this._opacity * 0.9, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
39
- this.ringProgram.draw(this.ringBufferManager.length, this.ringVao, 32, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
40
- this.gl.enable(this.gl.DEPTH_TEST);
142
+ const { gl } = this;
143
+ this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
144
+ gl.disable(gl.DEPTH_TEST);
145
+ this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity * 0.8, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
146
+ this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
147
+ this.angledLineProgram.draw(this.angledLineVao, this.bufferOrchestrator.length, this._opacity * 0.8);
148
+ this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
149
+ this._textContextInjectionMap.forEach((e) => { e.writer.draw(); });
150
+ gl.enable(gl.DEPTH_TEST);
41
151
  }
42
152
 
43
153
 
@@ -46,95 +156,153 @@ export default class Plugin {
46
156
  * @param {Array<{key, long, lat, endLong, endLat, bearingAngle, radius, rgba:[4numbers]}>} items
47
157
  */
48
158
 
49
- insertBulk(items) {
159
+ insertBulk(items, injectionsSubSetIDs = []) {
160
+ const { globe, bufferOrchestrator, bufferManagersCompMap } = this;// angleTextContext, distanceTextContext,
161
+ const injectionsSubSet = injectionsSubSetIDs.map((id) => this._textContextInjectionMap.get(id));
162
+ const data = []
50
163
  for (let item of items) {
51
- const { lat, long, endLat, endLong, radius = null, rgbaMode = null, bearingAngle = 0 } = item;
52
- item.long = radian(long);
53
- item.lat = radian(lat);
54
- item.endLong = radian(endLong);
55
- item.endLat = radian(endLat);
56
- if (radius === null) {
57
- item.radius = 100000;
58
- }
59
- if (rgbaMode === null) {
60
- item.rgbaMode = 0;
61
- }
62
- const startAngle = calculateStartAngle(item.long, item.lat, item.endLong, item.endLat);
63
-
64
- item.startAngle = startAngle;
65
- const shaderBearingAngle = radian(bearingAngle - 90);
66
- item.tailAngle = shaderBearingAngle - startAngle;
164
+ this._insertTexts(item, injectionsSubSet);
165
+ data.push(this.__insertAdaptor(item));
67
166
  }
68
- this.lineBufferManager.insertBulk(items);
69
- this.ringBufferManager.insertBulk(items);
70
- this.globe.DrawRender();
167
+ bufferOrchestrator.insertBulk(data, bufferManagersCompMap);
168
+ globe.DrawRender();
71
169
  }
72
170
 
73
- /**
74
- *
75
- * @param {Array<{key, long, lat, endLong, endLat, bearingAngle, rgba:[4numbers], colorMode}>} items // TIDI
76
- */
77
- updateBulk(items) { //TODO
78
- this.lineBufferManager.updateBulk(items);
79
- for (let item of items) {
80
- const { long, lat, endLong, endLat } = item;
81
- item.long = radian(long);
82
- item.lat = radian(lat);
83
- item.endLong = radian(endLong);
84
- item.endLat = radian(endLat);
85
- const startAngle = calculateStartAngle(item.long, item.lat, item.endLong, item.endLat);
86
- item.startAngle = startAngle;
87
- }
88
- this.ringBufferManager.updateBulk(items);
89
- this.globe.DrawRender();
90
- }
171
+
91
172
 
92
173
 
93
174
  deleteBulk(keys) {
94
- this.lineBufferManager.deleteBulk(keys);
95
- this.ringBufferManager.deleteBulk(keys);
175
+ this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap, ["radius", "centerCoords", "targetCoords", "rgba"]);
176
+
177
+ this._deleteTexts(keys);
96
178
  this.globe.DrawRender();
97
179
  }
98
180
 
99
181
 
100
182
  defrag() {
101
- this.lineBufferManager.defrag();
102
- this.ringBufferManager.defrag();
103
- this.globe.DrawRender();
183
+ this.bufferOrchestrator.defrag(this.bufferManagersCompMap);
184
+ // this.globe.DrawRender();
104
185
  }
105
186
 
106
187
  /**
107
188
  *
108
189
  * @param {Array<{key, long, lat, endLong, endLat, bearing}>} items // TODO
109
190
  */
110
- updateCoordinatesBulk(items) { //TODO
191
+ updateCoordinatesBulk(items, injectionSubSetIDs = []) { //TODO
192
+ const injectionsSubSet = injectionSubSetIDs.map((id) => this._textContextInjectionMap.get(id));
193
+ const { globe, bufferOrchestrator, bufferManagersCompMap, angleTextContext, distanceTextContext } = this;
194
+ const data = []
111
195
  for (let item of items) {
112
- const { long, lat, endLong, endLat, bearingAngle } = item;
113
- item.long = radian(long);
114
- item.lat = radian(lat);
115
- item.endLong = radian(endLong);
116
- item.endLat = radian(endLat);
117
- const startAngle = calculateStartAngle(item.long, item.lat, item.endLong, item.endLat);
118
- item.startAngle = startAngle;
119
- item.tailAngle = radian(bearingAngle - 90) - startAngle;
196
+ this._insertTexts(item, injectionsSubSet);
197
+ data.push(this.__updateCoordsAdaptor(item));
120
198
  }
121
- this.ringBufferManager.updateCenterAndAngleBulk(items);
122
- this.lineBufferManager.updateCoordinatesBulk(items);
123
- this.globe.DrawRender();
199
+
200
+ bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords", "targetCoords", "startAngle", "tailAngle", "bearingAngle", "bigRadius", "radius"]);
201
+ globe.DrawRender();
202
+ }
203
+
204
+
205
+ __insertAdaptor(item) {
206
+ const lat = radian(item.lat)
207
+ const long = radian(item.long)
208
+ const endLat = radian(item.endLat)
209
+ const endLong = radian(item.endLong)
210
+ const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
211
+ const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
212
+ const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
213
+ const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
214
+ const circleDashRatio = item.circleDashAngle !== undefined ? (item.circleDashAngle / 360) : 1.0;
215
+ console.log("cicleDashRati", circleDashRatio);
216
+ const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
217
+ const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
218
+ const startAngle = calculateStartAngle(long, lat, endLong, endLat);
219
+ const bearingAngle = radian(item.bearingAngle - 90);
220
+ let tailAngle = bearingAngle - startAngle;
221
+ if (tailAngle > 0) {
222
+ tailAngle -= Math.PI * 2;
223
+ }
224
+ return {
225
+ key: item.key,
226
+ lat,
227
+ long,
228
+ endLat,
229
+ endLong,
230
+ bearingAngle,
231
+ radius,
232
+ bigRadius,
233
+ startAngle,
234
+ tailAngle,
235
+ rgba,
236
+ dashRatio,
237
+ dashOpacity,
238
+ circleDashRatio,
239
+ rgbaMode
240
+ };
241
+ }
242
+
243
+ __updateCoordsAdaptor(item) {
244
+ const lat = radian(item.lat)
245
+ const long = radian(item.long)
246
+ const endLat = radian(item.endLat)
247
+ const endLong = radian(item.endLong)
248
+
249
+ const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
250
+ const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
251
+ const startAngle = calculateStartAngle(long, lat, endLong, endLat);
252
+ const bearingAngle = radian(item.bearingAngle - 90);
253
+ let tailAngle = bearingAngle - startAngle;
254
+ if (tailAngle > 0) {
255
+ tailAngle -= Math.PI * 2;
256
+ }
257
+ return {
258
+ key: item.key,
259
+ lat,
260
+ long,
261
+ endLat,
262
+ endLong,
263
+ bearingAngle,
264
+ radius,
265
+ bigRadius,
266
+ startAngle,
267
+ tailAngle,
268
+ };
124
269
  }
125
270
 
271
+
126
272
  //TODO free
127
273
  free() {
128
274
  if (this.isFreed) return;
129
- this.lineBufferManager.free();
130
- this.ringBufferManager.free();
131
- LineOnGlobeCache.free(this.globe);
132
- ringProgramCache.free(this.globe);
275
+ this.bufferManagersCompMap.forEach(({ bufferManager, adaptor }) => {
276
+ bufferManager.free();
277
+ });
278
+ LineOnGlobeCache.release(this.globe);
279
+ ringProgramCache.release(this.globe);
280
+ CircleCache.release(this.globe);
281
+ AngledLineProgramCache.release(this.globe);
133
282
  this.isFreed = true;
134
283
  }
284
+
285
+
286
+
287
+ _insertTexts(item, injectionSubSet) {
288
+ injectionSubSet.forEach((v) => {
289
+ const { coordsAdaptor, textAdaptor, writer } = v
290
+ const { lat, long } = coordsAdaptor(item);
291
+ const text = textAdaptor(item);
292
+ writer.insertText(item.key, lat, long, text);
293
+ });
294
+ }
295
+
296
+ _deleteTexts(keys) {
297
+ this._textContextInjectionMap.forEach((e) => {
298
+ e.writer.deleteTextBulk(keys);
299
+ });
300
+ }
301
+
135
302
  }
136
303
 
137
304
 
305
+
138
306
  const radian = (degree) => degree * Math.PI / 180;
139
307
 
140
308
  const integralSec = (angle) => {
@@ -1,3 +1,15 @@
1
- # Two proglems:
1
+ # Two problems:
2
2
  lines are curved to to arrive perpendicular to the longitude lines
3
- patrial rings are not fit to the lines nor the bearing angle
3
+ patrial rings are not fit to the lines nor the bearing angle
4
+
5
+
6
+
7
+ # AngledLine
8
+
9
+ Does not render
10
+ Check:
11
+ [-] VAO
12
+ [-] Attributes are loaded with data
13
+ Assign constants to attributes.
14
+ [x] Uniforms are loaded // program was not used before setting opacity
15
+ [x] Check geometry // Assigning a constant to the geometry made all edges of the line overlap and the line was not visible
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.2.0",
3
+ "version": "0.3.1",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT"
@@ -5,7 +5,7 @@ import {
5
5
  POLE,
6
6
  PI,
7
7
  longLatRadToMercator,
8
- mercatorXYTo2DPoint,
8
+ mercatorXYToGLPosition,
9
9
  longLatRadToCartesian3D,
10
10
  circleLimpFromLongLatRadCenterCartesian3D,
11
11
  circleLimpFromLongLatRadCenterMercatorRealDistance,
@@ -28,15 +28,16 @@ const drawModeMap = Object.freeze({
28
28
 
29
29
 
30
30
 
31
- const vertexShaderSource = `#version 300 es` +
32
- CameraUniformBlockString +
33
- PI +
34
- longLatRadToMercator +
35
- mercatorXYTo2DPoint +
36
- longLatRadToCartesian3D +
37
- circleLimpFromLongLatRadCenterCartesian3D +
38
- circleLimpFromLongLatRadCenterMercatorRealDistance +
39
- cartesian3DToGLPosition + `
31
+ const vertexShaderSource = `#version 300 es
32
+
33
+ ${CameraUniformBlockString}
34
+ ${PI}
35
+ ${longLatRadToMercator}
36
+ ${mercatorXYToGLPosition}
37
+ ${longLatRadToCartesian3D}
38
+ ${circleLimpFromLongLatRadCenterCartesian3D}
39
+ ${circleLimpFromLongLatRadCenterMercatorRealDistance}
40
+ ${cartesian3DToGLPosition}
40
41
 
41
42
  uniform float edge_count;
42
43
  uniform int draw_mode; // %2 => 0: LINE_STRIP, 1: TRIANGLE_FAN
@@ -48,14 +49,17 @@ in float tail_angle; // the rotation of the partial circle
48
49
  in vec4 color;
49
50
  in float radius; // in meter
50
51
  in float color_mode; // 0.0: constant, 1.0: fading, 2.0: hide
51
-
52
+ flat out int vid;
53
+ out float v_phase;
52
54
  out vec2 v_pos;
53
55
  out vec4 v_color;
54
-
56
+ flat out float v_angle;
55
57
 
56
58
  void main() {
59
+ vid = gl_VertexID;
57
60
  if (color_mode == 2.0 || radius == 0.0) { return; }
58
-
61
+ float color_mode_ = color_mode;
62
+ if ( draw_mode == 0 && color_mode == 1.0) {color_mode_ = 0.0;}
59
63
  float vertexID = float(gl_VertexID);
60
64
  float radius_ = radius;
61
65
  float alpha = plugin_alpha_multiplier;
@@ -66,13 +70,15 @@ void main() {
66
70
  }
67
71
  vertexID -= 1.0;
68
72
  }
69
- float phase = ( vertexID / edge_count);
70
-
71
- if ( color_mode == 1.0 ) {
73
+ float phase = ( vertexID / (edge_count - 1.0) );
74
+ v_angle = tail_angle;
75
+
76
+
77
+ if ( color_mode_ == 1.0 ) {
72
78
  if ( tail_angle < 0.0 ) {
73
79
  v_color = vec4( color.rgb , color.a * ( 1.0 - phase ) * alpha );
74
80
  } else {
75
- v_color = vec4( color.rgb , color.a * (phase ) * alpha );
81
+ v_color = vec4( color.rgb , color.a * phase * alpha );
76
82
  }
77
83
  } else {
78
84
  v_color = vec4( color.rgb , color.a * alpha );
@@ -80,7 +86,7 @@ void main() {
80
86
 
81
87
  float angle;
82
88
  if ( tail_angle > 0.0 ) {
83
- angle = tail_angle * (-phase + 1.0 - 1.0 / edge_count) + start_angle;
89
+ angle = tail_angle * (-phase + 1.0) + start_angle;
84
90
  } else {
85
91
  angle = tail_angle * phase + start_angle;
86
92
  }
@@ -94,22 +100,25 @@ void main() {
94
100
 
95
101
  vec2 pos = circleLimpFromLongLatRadCenterMercatorRealDistance(center, radius_, angle);
96
102
  v_pos = pos;
97
- gl_Position = mercatorXYTo2DPoint(pos);
103
+ gl_Position = mercatorXYToGLPosition(pos);
98
104
  }
99
105
 
100
-
101
106
  gl_PointSize = 10.0;
102
107
  }`;
103
108
 
104
109
 
105
- const fragmentShaderSource = `#version 300 es` + POLE + `
110
+ const fragmentShaderSource = `#version 300 es` + POLE + PI + `
106
111
  precision highp float;
107
-
112
+ flat in int vid;
108
113
  in vec4 v_color;
109
114
  in vec2 v_pos;
115
+ flat in float v_phase;
116
+ in float v_angle;
110
117
  out vec4 outColor;
111
-
112
118
  void main() {
119
+ // if( vid % 2 == 0 ) { discard; }
120
+ // if ( mod(v_angle, PI / 36.0 ) < (PI / 72.0)) { discard; }
121
+ // if ( mod(v_angle * v_phase, PI / 90.0 ) < (PI / 180.0)) { discard; }
113
122
  if ( v_pos.x < -POLE || v_pos.x > POLE || v_pos.y < -POLE || v_pos.y > POLE ) { discard; }
114
123
  outColor = v_color;
115
124
  }`;
@@ -163,7 +172,7 @@ export class Logic {
163
172
  draw(length, vao, edgeCount, alphaMultiplier, drawMode) {
164
173
  const { gl, program, cameraBlockTotem, cameraBlockBindingPoint } = this
165
174
 
166
- gl.disable(gl.DEPTH_TEST);
175
+ // gl.disable(gl.DEPTH_TEST);
167
176
  gl.useProgram(program);
168
177
  if (drawMode !== this._lastMode) {
169
178
  gl.uniform1i(this._draw_modeLocation, drawModeMap[drawMode]);
@@ -183,7 +192,7 @@ export class Logic {
183
192
  gl.drawArraysInstanced(gl[drawMode], 0, edgeCount + overdraw, length);
184
193
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
185
194
  gl.bindVertexArray(null);
186
- gl.enable(gl.DEPTH_TEST);
195
+ // gl.enable(gl.DEPTH_TEST);
187
196
  }
188
197
 
189
198
 
@@ -236,6 +245,70 @@ export class Logic {
236
245
  }
237
246
  }
238
247
 
248
+ /**
249
+ * in vec2 center; // long, lat in radian
250
+ in float start_angle; // the start of partial circle from bearing point
251
+ in float tail_angle; // the rotation of the partial circle
252
+ in vec4 color;
253
+ in float radius; // in meter
254
+ in float color_mode; // 0.0: constant, 1.0: fading, 2.0: hide
255
+ */
256
+
257
+ createVAO(centerObj, startAngleObj, tailAngleObj, colorObj, radiusObj, colorModeObj) {
258
+
259
+ const { gl } = this;
260
+ const vao = gl.createVertexArray();
261
+ gl.bindVertexArray(vao);
262
+
263
+ {
264
+ const { buffer, stride, offset } = centerObj;
265
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
266
+ gl.enableVertexAttribArray(0);
267
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, stride, offset);
268
+ gl.vertexAttribDivisor(0, 1);
269
+ }
270
+
271
+ {
272
+ const { buffer, stride, offset } = startAngleObj;
273
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
274
+ gl.enableVertexAttribArray(1);
275
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, stride, offset);
276
+ gl.vertexAttribDivisor(1, 1);
277
+ }
278
+ {
279
+ const { buffer, stride, offset } = tailAngleObj;
280
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
281
+ gl.enableVertexAttribArray(2);
282
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, stride, offset);
283
+ gl.vertexAttribDivisor(2, 1);
284
+ }
285
+ {
286
+ const { buffer, stride, offset } = colorObj;
287
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
288
+ gl.enableVertexAttribArray(3);
289
+ gl.vertexAttribPointer(3, 4, gl.FLOAT, false, stride, offset);
290
+ gl.vertexAttribDivisor(3, 1);
291
+ }
292
+ {
293
+ const { buffer, stride, offset } = radiusObj;
294
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
295
+ gl.enableVertexAttribArray(4);
296
+ gl.vertexAttribPointer(4, 1, gl.FLOAT, false, stride, offset);
297
+ gl.vertexAttribDivisor(4, 1);
298
+ }
299
+ {
300
+ const { buffer, stride, offset } = colorModeObj;
301
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
302
+ gl.enableVertexAttribArray(5);
303
+ gl.vertexAttribPointer(5, 1, gl.FLOAT, false, stride, offset);
304
+ gl.vertexAttribDivisor(5, 1);
305
+ }
306
+ gl.bindVertexArray(null);
307
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
308
+ return vao;
309
+ }
310
+
311
+
239
312
  getBufferManagerAndVao({ capacity = 10, bufferType = "DYNAMIC_DRAW" } = {}) {
240
313
  const { vao, buffer } = this.getVaoBuffer();
241
314
  return {