@pirireis/webglobeplugins 0.1.10 → 0.2.0

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.
File without changes
@@ -0,0 +1,151 @@
1
+ import { programCache as ringProgramCache } from '../partialrings/program';
2
+ import { LineOnGlobeCache } from '../programs/line-on-globe/naive';
3
+
4
+ export const RINGPARTIAL_DRAW_MODE = Object.freeze({
5
+ LINE_STRIP: "LINE_STRIP",
6
+ TRIANGLE_FAN: "TRIANGLE_FAN",
7
+ });
8
+
9
+ export default class Plugin {
10
+
11
+ constructor(id, { opacity = 1 } = {}) {
12
+ this.id = id;
13
+ this._opacity = opacity;
14
+ }
15
+
16
+ setOpacity(opacity) {
17
+ this._opacity = opacity;
18
+ this.globe.DrawRender();
19
+ }
20
+
21
+ init(globe, gl) {
22
+ this.gl = gl;
23
+ this.globe = globe;
24
+ this.lineProgram = LineOnGlobeCache.get(globe);
25
+ 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;
30
+ }
31
+
32
+
33
+ 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);
41
+ }
42
+
43
+
44
+ /**
45
+ *
46
+ * @param {Array<{key, long, lat, endLong, endLat, bearingAngle, radius, rgba:[4numbers]}>} items
47
+ */
48
+
49
+ insertBulk(items) {
50
+ 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;
67
+ }
68
+ this.lineBufferManager.insertBulk(items);
69
+ this.ringBufferManager.insertBulk(items);
70
+ this.globe.DrawRender();
71
+ }
72
+
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
+ }
91
+
92
+
93
+ deleteBulk(keys) {
94
+ this.lineBufferManager.deleteBulk(keys);
95
+ this.ringBufferManager.deleteBulk(keys);
96
+ this.globe.DrawRender();
97
+ }
98
+
99
+
100
+ defrag() {
101
+ this.lineBufferManager.defrag();
102
+ this.ringBufferManager.defrag();
103
+ this.globe.DrawRender();
104
+ }
105
+
106
+ /**
107
+ *
108
+ * @param {Array<{key, long, lat, endLong, endLat, bearing}>} items // TODO
109
+ */
110
+ updateCoordinatesBulk(items) { //TODO
111
+ 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;
120
+ }
121
+ this.ringBufferManager.updateCenterAndAngleBulk(items);
122
+ this.lineBufferManager.updateCoordinatesBulk(items);
123
+ this.globe.DrawRender();
124
+ }
125
+
126
+ //TODO free
127
+ free() {
128
+ if (this.isFreed) return;
129
+ this.lineBufferManager.free();
130
+ this.ringBufferManager.free();
131
+ LineOnGlobeCache.free(this.globe);
132
+ ringProgramCache.free(this.globe);
133
+ this.isFreed = true;
134
+ }
135
+ }
136
+
137
+
138
+ const radian = (degree) => degree * Math.PI / 180;
139
+
140
+ const integralSec = (angle) => {
141
+ return Math.log(Math.tan(angle / 2 + Math.PI / 4));
142
+ }
143
+
144
+ const calculateStartAngle = (long, lat, endLong, endLat) => {
145
+ const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.
146
+ const dLong = endLong - long;
147
+
148
+ let angle = -Math.atan2(dLat, dLong);
149
+ return angle;
150
+ }
151
+
@@ -0,0 +1,3 @@
1
+ # Two proglems:
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.1.10",
3
+ "version": "0.2.0",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT"
@@ -0,0 +1,89 @@
1
+ import BufferOffsetManager from "../util/account/bufferoffsetmanager";
2
+
3
+
4
+
5
+ const ITEM_SIZE = 10;
6
+ export default class BufferManager extends BufferOffsetManager {
7
+ constructor(globe, gl, buffer, { initialCapacity = 10, bufferType = "DYNAMIC_DRAW" } = {}) {
8
+ super(ITEM_SIZE, { capacity: initialCapacity });
9
+ this.globe = globe;
10
+ this.gl = gl;
11
+ this.buffer = buffer;
12
+ this.bufferType = bufferType;
13
+
14
+
15
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
16
+ gl.bufferData(gl.ARRAY_BUFFER, initialCapacity * ITEM_SIZE * 4, gl[bufferType]);
17
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
18
+ }
19
+
20
+ /**
21
+ *
22
+ * @param { Array<{key, long, lat, startAngle, tailAngle, radius, rgba[4], rgbaMode }>} rings
23
+ * @returns
24
+ */
25
+ insertBulk(items) {
26
+ if (items.length === 0) return;
27
+ this.autoExtendBuffer(items.length);
28
+ const { gl, buffer } = this;
29
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
30
+ for (let { key, long, lat, startAngle, tailAngle, rgba, radius, rgbaMode } of items) {
31
+ const offset = this.getOffset(key) | this.nextOffset();
32
+ this.setOffset(key, offset);
33
+ const block = new Float32Array([
34
+ long, lat, startAngle, tailAngle, ...rgba, radius, rgbaMode]);
35
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, block);
36
+ // 2 1 1 1 4 1 = 10
37
+ }
38
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
39
+ this.globe.DrawRender();
40
+ }
41
+
42
+
43
+ /**
44
+ * @param {Array<{key, long, lat, startAngle, tailAngle}>} items
45
+ *
46
+ * */
47
+ updateCenterAndAngleBulk(items) {
48
+ const { gl, buffer } = this;
49
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
50
+ for (let { key, long, lat, startAngle, tailAngle } of items) {
51
+ const offset = this.getOffset(key);
52
+ if (offset === null) {
53
+ console.warn(`key ${key} not found`);
54
+ continue;
55
+ }
56
+ const block = new Float32Array([long, lat, startAngle, tailAngle]);
57
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, block);
58
+ }
59
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
60
+ this.globe.DrawRender();
61
+ }
62
+ /**
63
+ *
64
+ * @param {Array<{key:string, payload:Float32Array}} items
65
+ * @param {PART_OFFSET_LOOPUP} part | long, lat, START_ANGLE, ROTATION_ANGLE, RADIUS, rgba, rgba_MODE
66
+ * @returns
67
+ */
68
+ updatePartial(items, part) {
69
+ const { gl, buffer } = this;
70
+ this._updatePartial(items, part, gl, buffer);
71
+ this.globe.DrawRender();
72
+
73
+ }
74
+
75
+
76
+
77
+ deleteBulk(keys) {
78
+ this._deleteBulk(keys);
79
+ this.globe.DrawRender();
80
+ }
81
+
82
+
83
+
84
+
85
+ free() {
86
+ this.gl.deleteBuffer(this.buffer);
87
+ this.buffer = null;
88
+ }
89
+ }
@@ -1,3 +1,3 @@
1
1
  import PartialRing, { RINGPARTIAL_ALPHA_MODE, RINGPARTIAL_DRAW_MODE, PART_OFFSET_LOOPUP } from './plugin';
2
2
 
3
- export { PartialRing, RINGPARTIAL_ALPHA_MODE, RINGPARTIAL_DRAW_MODE, PART_OFFSET_LOOPUP };
3
+ export { PartialRing, RINGPARTIAL_ALPHA_MODE, RINGPARTIAL_DRAW_MODE, PART_OFFSET_LOOPUP };
@@ -20,12 +20,13 @@ export const RINGPARTIAL_ALPHA_MODE = Object.freeze({
20
20
 
21
21
 
22
22
  export const PART_OFFSET_LOOPUP = Object.freeze({
23
- CENTER: 0,
23
+ LONG: 0,
24
+ LAT: 1,
24
25
  START_ANGLE: 2,
25
26
  TAIL_ANGLE: 3,
26
- COLOR: 4,
27
+ RGBA: 4,
27
28
  RADIUS: 8,
28
- COLOR_MODE: 9,
29
+ RGBA_MODE: 9,
29
30
  });
30
31
 
31
32
 
@@ -47,8 +48,6 @@ export default class {
47
48
  const { vao, buffer } = this.program.getVaoBuffer();
48
49
  this.vao = vao;
49
50
  this.buffer = buffer;
50
-
51
-
52
51
  }
53
52
 
54
53
 
@@ -57,7 +56,7 @@ export default class {
57
56
 
58
57
  if (LOD < this.startLod || LOD > this.endLod) return;
59
58
  this.program.draw(
60
- this.bufferManager,
59
+ this.bufferManager.length,
61
60
  this.vao,
62
61
  this.edgeCount,
63
62
  this.alphaMultiplier,
@@ -82,8 +81,8 @@ export default class {
82
81
  if (endLod !== null) this.endLod = endLod;
83
82
  }
84
83
 
85
- createBufferMAnager(initialCapacity = 10, extendRatio = 1.2, bufferType = 'DYNAMIC_DRAW') {
86
- if (!this.bufferManager) { this.bufferManager = new BufferManager(this.globe, this.gl, this.buffer, bufferType, { initialCapacity, extendRatio }); }
84
+ createBufferMAnager(initialCapacity = 10, bufferType = 'DYNAMIC_DRAW') {
85
+ if (!this.bufferManager) { this.bufferManager = new BufferManager(this.globe, this.gl, this.buffer, { initialCapacity, bufferType, }); }
87
86
  return this.bufferManager;
88
87
  }
89
88
 
@@ -96,13 +95,12 @@ export default class {
96
95
 
97
96
  class BufferManager extends BufferOffsetManager {
98
97
 
99
- constructor(globe, gl, buffer, bufferType, { initialCapacity = 10, extendRatio = 1.2 } = {}) {
100
- super(10, { capacity: initialCapacity });
98
+ constructor(globe, gl, buffer, { initialCapacity = 10, bufferType, } = {}) {
99
+ super(10, { capacity: initialCapacity, bufferType, });
101
100
  this.globe = globe;
102
101
  this.gl = gl;
103
102
  this.buffer = buffer;
104
103
  this.bufferType = bufferType;
105
- this.extendRatio = extendRatio;
106
104
 
107
105
 
108
106
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
@@ -112,22 +110,20 @@ class BufferManager extends BufferOffsetManager {
112
110
 
113
111
  /**
114
112
  *
115
- * @param { Array<{key, center[2], startAngle, tailAngle, radius, color[4], color_mode }>} rings
113
+ * @param { Array<{key, long, lat, startAngle, tailAngle, radius, rgba[4], rgbaMode }>} rings
116
114
  * @returns
117
115
  */
118
- insertRings(rings) {
119
- if (rings.length === 0) return;
120
- this.autoExtendBuffer(rings.length);
116
+ insertBulk(items) {
117
+ if (items.length === 0) return;
118
+ console.log(items)
119
+ this.autoExtendBuffer(items.length);
121
120
  const { gl, buffer } = this;
122
121
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
123
- for (let { key, center, startAngle, tailAngle, color, radius, colorMode } of rings) {
124
- let offset = this.getOffset(key);
125
- if (offset === undefined) {
126
- offset = this.nextOffset();
127
- this.setOffset(key, offset);
128
- }
122
+ for (let { key, long, lat, startAngle, tailAngle, rgba, radius, rgbaMode } of items) {
123
+ const offset = this.getOffset(key) | this.nextOffset();
124
+ this.setOffset(key, offset);
129
125
  const block = new Float32Array([
130
- ...center, startAngle, tailAngle, ...color, radius, colorMode]);
126
+ long, lat, startAngle, tailAngle, ...rgba, radius, rgbaMode]);
131
127
  gl.bufferSubData(gl.ARRAY_BUFFER, offset, block);
132
128
  // 2 1 1 1 4 1 = 10
133
129
  }
@@ -138,13 +134,13 @@ class BufferManager extends BufferOffsetManager {
138
134
 
139
135
  /**
140
136
  *
141
- * @param {Array<{key:string, payload:Float32Array}} rings
142
- * @param {PART_OFFSET_LOOPUP} part | CENTER, START_ANGLE, ROTATION_ANGLE, RADIUS, COLOR, COLOR_MODE
137
+ * @param {Array<{key:string, payload:Float32Array}} items
138
+ * @param {PART_OFFSET_LOOPUP} part | long, lat, START_ANGLE, ROTATION_ANGLE, RADIUS, rgba, rgba_MODE
143
139
  * @returns
144
140
  */
145
- updatePartial(rings, part) {
141
+ updatePartial(items, part) {
146
142
  const { gl, buffer } = this;
147
- this._updatePartial(rings, part, gl, buffer);
143
+ this._updatePartial(items, part, gl, buffer);
148
144
  this.globe.DrawRender();
149
145
 
150
146
  }
@@ -157,8 +153,6 @@ class BufferManager extends BufferOffsetManager {
157
153
  }
158
154
 
159
155
 
160
-
161
-
162
156
  free() {
163
157
  this.gl.deleteBuffer(this.buffer);
164
158
  this.buffer = null;
@@ -1,6 +1,6 @@
1
1
  import { createProgram, shaderfunctions } from "../util";
2
2
  import { CameraUniformBlockTotem, CameraUniformBlockString, noRegisterGlobeProgramCache, globeProgramCache } from "../programs";
3
-
3
+ import BufferManager from "./buffer-manager";
4
4
  import {
5
5
  POLE,
6
6
  PI,
@@ -8,7 +8,7 @@ import {
8
8
  mercatorXYTo2DPoint,
9
9
  longLatRadToCartesian3D,
10
10
  circleLimpFromLongLatRadCenterCartesian3D,
11
- circleLimpFromLongLatRadCenterMercatorCompass,
11
+ circleLimpFromLongLatRadCenterMercatorRealDistance,
12
12
  cartesian3DToGLPosition
13
13
 
14
14
 
@@ -35,13 +35,13 @@ const vertexShaderSource = `#version 300 es` +
35
35
  mercatorXYTo2DPoint +
36
36
  longLatRadToCartesian3D +
37
37
  circleLimpFromLongLatRadCenterCartesian3D +
38
- circleLimpFromLongLatRadCenterMercatorCompass +
38
+ circleLimpFromLongLatRadCenterMercatorRealDistance +
39
39
  cartesian3DToGLPosition + `
40
40
 
41
41
  uniform float edge_count;
42
42
  uniform int draw_mode; // %2 => 0: LINE_STRIP, 1: TRIANGLE_FAN
43
43
  uniform float plugin_alpha_multiplier;
44
-
44
+ //, lat, startAngle, tailAngle, ...rgba, radius, rgbaMode
45
45
  in vec2 center; // long, lat in radian
46
46
  in float start_angle; // the start of partial circle from bearing point
47
47
  in float tail_angle; // the rotation of the partial circle
@@ -56,20 +56,17 @@ out vec4 v_color;
56
56
  void main() {
57
57
  if (color_mode == 2.0 || radius == 0.0) { return; }
58
58
 
59
- float vertexID;
59
+ float vertexID = float(gl_VertexID);
60
60
  float radius_ = radius;
61
61
  float alpha = plugin_alpha_multiplier;
62
62
  if (draw_mode == 1) { // TRIANGLE_FAN
63
- vertexID = float(gl_VertexID - 1);
64
63
  if (gl_VertexID == 0) {
65
- radius_ = 0.0; vertexID = 0.0;
64
+ radius_ = 0.0;
66
65
  if ( color_mode == 1.0 ) { alpha = 0.0; }
67
66
  }
68
- } else { // LINE_STRIP
69
- vertexID = float(gl_VertexID);
67
+ vertexID -= 1.0;
70
68
  }
71
-
72
- float phase = ( vertexID / edge_count);
69
+ float phase = ( vertexID / edge_count);
73
70
 
74
71
  if ( color_mode == 1.0 ) {
75
72
  if ( tail_angle < 0.0 ) {
@@ -83,7 +80,7 @@ void main() {
83
80
 
84
81
  float angle;
85
82
  if ( tail_angle > 0.0 ) {
86
- angle = tail_angle * (-phase + 1.0) + start_angle;
83
+ angle = tail_angle * (-phase + 1.0 - 1.0 / edge_count) + start_angle;
87
84
  } else {
88
85
  angle = tail_angle * phase + start_angle;
89
86
  }
@@ -94,13 +91,14 @@ void main() {
94
91
  gl_Position = cartesian3DToGLPosition(pos);
95
92
  }
96
93
  else {
97
- vec2 pos = circleLimpFromLongLatRadCenterMercatorCompass(center, radius_, angle);
94
+
95
+ vec2 pos = circleLimpFromLongLatRadCenterMercatorRealDistance(center, radius_, angle);
98
96
  v_pos = pos;
99
97
  gl_Position = mercatorXYTo2DPoint(pos);
100
98
  }
101
99
 
102
100
 
103
- gl_PointSize = 2.0;
101
+ gl_PointSize = 10.0;
104
102
  }`;
105
103
 
106
104
 
@@ -162,7 +160,7 @@ export class Logic {
162
160
 
163
161
 
164
162
 
165
- draw(bufferManager, vao, edgeCount, alphaMultiplier, drawMode) {
163
+ draw(length, vao, edgeCount, alphaMultiplier, drawMode) {
166
164
  const { gl, program, cameraBlockTotem, cameraBlockBindingPoint } = this
167
165
 
168
166
  gl.disable(gl.DEPTH_TEST);
@@ -182,7 +180,7 @@ export class Logic {
182
180
  const overdraw = drawModeMap[drawMode];
183
181
  cameraBlockTotem.bind(cameraBlockBindingPoint);
184
182
  gl.bindVertexArray(vao);
185
- gl.drawArraysInstanced(gl[drawMode], 0, edgeCount + overdraw, bufferManager.length);
183
+ gl.drawArraysInstanced(gl[drawMode], 0, edgeCount + overdraw, length);
186
184
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
187
185
  gl.bindVertexArray(null);
188
186
  gl.enable(gl.DEPTH_TEST);
@@ -237,6 +235,14 @@ export class Logic {
237
235
  buffer,
238
236
  }
239
237
  }
238
+
239
+ getBufferManagerAndVao({ capacity = 10, bufferType = "DYNAMIC_DRAW" } = {}) {
240
+ const { vao, buffer } = this.getVaoBuffer();
241
+ return {
242
+ bufferManager: new BufferManager(this.globe, this.gl, buffer, { capacity, bufferType }),
243
+ vao
244
+ };
245
+ }
240
246
  }
241
247
 
242
248
  export const programCache = Object.freeze({
@@ -43,10 +43,12 @@ void main() {
43
43
 
44
44
  const fragmentShader = `#version 300 es
45
45
  precision highp float;
46
+ uniform float opacity;
46
47
  in vec4 v_color;
47
48
  out vec4 color;
48
49
  void main() {
49
50
  color = v_color;
51
+ color.a *= opacity;
50
52
  }
51
53
  `
52
54
 
@@ -57,6 +59,7 @@ class Logic {
57
59
  this.globe = globe;
58
60
  this.gl = globe.gl;
59
61
  this.program = createProgram(this.gl, vertexShader, fragmentShader);
62
+ this._lastOpacity = 1.0;
60
63
  const { gl, program } = this;
61
64
  {
62
65
  // assign attribute locations
@@ -65,6 +68,14 @@ class Logic {
65
68
  gl.bindAttribLocation(program, 2, "color");
66
69
  }
67
70
 
71
+ {
72
+ this._opacityLocation = gl.getUniformLocation(program, "opacity");
73
+ const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
74
+ gl.useProgram(program);
75
+ gl.uniform1f(this._opacityLocation, this._lastOpacity);
76
+ gl.useProgram(currentProgram);
77
+
78
+ }
68
79
 
69
80
  this.cameraBlockBindingPoint = 0;
70
81
  const cameraBlockIndex = this.gl.getUniformBlockIndex(this.program, "CameraUniformBlock");
@@ -75,18 +86,22 @@ class Logic {
75
86
  }
76
87
 
77
88
 
78
- draw(bufferManager) {
89
+ draw(vao, length, opacity) {
79
90
  const { gl, program, globe } = this;
80
91
  gl.useProgram(program);
81
92
  const { cameraBlockTotem, cameraBlockBindingPoint } = this;
82
93
  cameraBlockTotem.bind(cameraBlockBindingPoint);
83
- gl.bindVertexArray(bufferManager.vao);
94
+ gl.bindVertexArray(vao);
95
+ if (opacity !== this._lastOpacity) {
96
+ gl.uniform1f(this._opacityLocation, opacity);
97
+ this._lastOpacity = opacity;
98
+ }
84
99
  const drawCount = globe.api_GetCurrentGeometry() === 0 ? GLOBE_MIDPOINT_COUNT : 2;
85
100
  gl.disable(gl.DEPTH_TEST);
86
- gl.drawArraysInstanced(gl.LINE_STRIP, 0, drawCount, bufferManager.length);
87
- gl.enable(gl.DEPTH_TEST);
101
+ gl.drawArraysInstanced(gl.LINE_STRIP, 0, drawCount, length);
88
102
  gl.bindVertexArray(null);
89
103
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
104
+ gl.enable(gl.DEPTH_TEST);
90
105
  }
91
106
 
92
107
 
@@ -129,18 +144,19 @@ class BufferManager extends BufferOffsetManger {
129
144
 
130
145
  /**
131
146
  *
132
- * @param {Array<{key:string, startLong:number, startLat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
147
+ * @param {Array<{key:string, long:number, lat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
133
148
  */
134
149
  insertBulk(items) {
135
150
  this.autoExtendBuffer(items.length)
136
151
  const { gl, buffer, globe } = this;
137
152
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
138
- for (let { key, startLong, startLat, endLong, endLat, rgba } of items) {
153
+ for (let { key, long, lat, endLong, endLat, rgba } of items) {
154
+
139
155
  const payload = new Float32Array([
140
- Radian * startLong,
141
- Radian * startLat,
142
- Radian * endLong,
143
- Radian * endLat,
156
+ long,
157
+ lat,
158
+ endLong,
159
+ endLat,
144
160
  ...rgba]);
145
161
  const offset = this.getOffset(key) | this.nextOffset();
146
162
  gl.bufferSubData(gl.ARRAY_BUFFER, offset, payload);
@@ -152,17 +168,17 @@ class BufferManager extends BufferOffsetManger {
152
168
 
153
169
  /**
154
170
  *
155
- * @param {Array<{key:string, startLong:number, startLat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
171
+ * @param {Array<{key:string, long:number, lat:number, endLong:number, endLat:number, rgba:[4numbers] }} items
156
172
  */
157
173
  updateBulk(items) {
158
174
  const { gl, buffer, globe } = this;
159
175
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
160
- for (let { key, startLong, startLat, endLong, endLat, rgba } of items) {
176
+ for (let { key, long, lat, endLong, endLat, rgba } of items) {
161
177
  const payload = new Float32Array([
162
- Radian * startLong,
163
- Radian * startLat,
164
- Radian * endLong,
165
- Radian * endLat,
178
+ long,
179
+ lat,
180
+ endLong,
181
+ endLat,
166
182
  ...rgba]);
167
183
  const offset = this.getOffset(key);
168
184
  if (offset !== undefined) {
@@ -177,17 +193,17 @@ class BufferManager extends BufferOffsetManger {
177
193
 
178
194
  /**
179
195
  *
180
- * @param {Array<{key:string, startLong:number, startLat:number, endLong:number, endLat:number }} items
196
+ * @param {Array<{key:string, long:number, lat:number, endLong:number, endLat:number }} items
181
197
  */
182
198
  updateCoordinatesBulk(items) {
183
199
  const { gl, buffer, globe } = this;
184
200
  gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
185
- for (let { key, startLong, startLat, endLong, endLat } of items) {
201
+ for (let { key, long, lat, endLong, endLat } of items) {
186
202
  const payload = new Float32Array([
187
- Radian * startLong,
188
- Radian * startLat,
189
- Radian * endLong,
190
- Radian * endLat]);
203
+ long,
204
+ lat,
205
+ endLong,
206
+ endLat]);
191
207
  const offset = this.getOffset(key);
192
208
  if (offset !== undefined) {
193
209
  gl.bufferSubData(gl.ARRAY_BUFFER, offset, payload);
@@ -195,6 +211,7 @@ class BufferManager extends BufferOffsetManger {
195
211
  console.warn("key not found", key);
196
212
  }
197
213
  }
214
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
198
215
  globe.DrawRender();
199
216
  }
200
217
 
@@ -128,8 +128,8 @@ class Logic {
128
128
  }
129
129
  gl.disable(gl.DEPTH_TEST);
130
130
  gl.drawArraysInstanced(gl.LINES, 0, 2, attrBufferManager.length);
131
- gl.enable(gl.DEPTH_TEST);
132
131
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
132
+ gl.enable(gl.DEPTH_TEST);
133
133
  gl.bindVertexArray(null);
134
134
 
135
135
  }
@@ -59,6 +59,9 @@ export default class {
59
59
  this.circleProgramCache?.releaseProgram(this.globe);
60
60
  this.PaddingProgramCache?.releaseProgram(this.globe);
61
61
  this.PaddingFreeAngleCache?.releaseProgram(this.globe);
62
+ this.gl.deleteVertexArray(this.bufferManager?.vao);
63
+ this.gl.deleteVertexArray(this.paddingBufferManager?.vao);
64
+ this.paddingBufferManager?.free();
62
65
  this.bufferManager?.free();
63
66
  this.textPlugin?.free();
64
67
  this.circleFlatProgram = null;
@@ -75,6 +75,19 @@ export default class {
75
75
  }
76
76
  }
77
77
 
78
+ _deleteBulk(keys) {
79
+ const { gl, buffer } = this;
80
+ const emptyBlock = new Float32Array(this.itemSize).fill(0)
81
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
82
+ for (let key of keys) {
83
+ const offset = this.getOffset(key);
84
+ if (offset !== undefined) {
85
+ this.deleteFromAccount(key);
86
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, emptyBlock);
87
+ }
88
+ }
89
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
90
+ }
78
91
 
79
92
 
80
93
  offsetMapIterator() { // can be used for defraging the real buffer.
@@ -90,7 +103,6 @@ export default class {
90
103
  const itemSize = this.itemSize;
91
104
  const itemCount = this.itemCount;
92
105
  const capacity = (newCapacity && newCapacity > itemCount) ? newCapacity : itemCount;
93
- console.log("defrag", itemCount, capacity);
94
106
 
95
107
  const newArray = new Float32Array(itemCount * itemSize);
96
108
 
@@ -98,7 +110,6 @@ export default class {
98
110
  let newOffSet = 0;
99
111
  const newOffSetMap = new Map();
100
112
  for (const [key, offSet] of this.offSetMap) {
101
- console.log(key, offSet);
102
113
  const itemOffSet = offSet / 4;
103
114
  newArray.set(bufferData.slice(itemOffSet, itemOffSet + itemSize), newOffSet);
104
115
  // this.offSetMap.set(key, newOffSet * 4);
@@ -147,8 +158,8 @@ export default class {
147
158
  */
148
159
  _updatePartial(items, partOffset) {
149
160
  const { gl, buffer } = this;
150
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
151
161
  const partStart = partOffset * 4;
162
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
152
163
  for (let { key, payload } of items) {
153
164
  let offset = this.getOffset(key);
154
165
  if (offset !== undefined) {
@@ -183,9 +194,11 @@ export default class {
183
194
  gl.bindBuffer(gl.ARRAY_BUFFER, null);
184
195
  }
185
196
 
197
+
198
+
199
+
186
200
  free() {
187
201
  this.gl.deleteBuffer(this.buffer);
188
- this.gl.deleteVertexArray(this.vao);
189
202
  this.buffer = null;
190
203
  this.vao = null;
191
204
  this.gl = null;
@@ -159,3 +159,93 @@ vec2 circleLimpFromLongLatRadCenterMercatorCompass(vec2 center, float radius, fl
159
159
  }`;
160
160
 
161
161
 
162
+ // Function to interpolate between two Cartesian points using spherical interpolation (slerp)
163
+ export const slerp = `
164
+ vec3 slerp(vec3 A, vec3 B, float t) {
165
+ float cosTheta = dot(A, B);
166
+ float theta = acos(clamp(cosTheta, -1.0, 1.0)); // Angle between the points
167
+
168
+ float sinTheta = sin(theta);
169
+
170
+ // Avoid division by zero // many points falls in to this category
171
+ if (sinTheta < 0.00001) {
172
+ return mix(A, B, t); // Linear interpolation as fallback
173
+ }
174
+
175
+ float factorA = sin((1.0 - t) * theta) / sinTheta;
176
+ float factorB = sin(t * theta) / sinTheta;
177
+
178
+ return factorA * A + factorB * B;
179
+ }
180
+ `;
181
+
182
+ // Function to convert Cartesian coordinates back to spherical (latitude, longitude)
183
+ export const cartesianToSpherical = `
184
+ vec2 cartesianToSpherical(vec3 point) {
185
+ float lat = degrees(asin(point.z)); // Latitude
186
+ float lon = degrees(atan(point.y, point.x)); // Longitude
187
+
188
+ return vec2(lat, lon);
189
+ }`;
190
+
191
+ // Main function to calculate an intermediate point
192
+
193
+ export const interpolateGeographicPoint = slerp + cartesianToSpherical + longLatRadToCartesian3D + `
194
+ vec3 interpolateGeographicPoint(vec2 start, vec2 end, float t) {
195
+ vec3 pointA = longLatRadToCartesian3D(start);
196
+ vec3 pointB = longLatRadToCartesian3D(end);
197
+ vec3 interpolatedPoint = slerp(pointA, pointB, t);
198
+ return interpolatedPoint;
199
+ // return cartesianToSpherical(interpolatedPoint);
200
+ }
201
+ `;
202
+
203
+
204
+
205
+ export const angleBetweenTwoPointsRadian = `
206
+ float angleBetweenTwoPointsRadian(vec2 start_, vec2 end_) {
207
+ float start_lat = log( tan( ( 1.0 - start_.y ) * PI / 2.0 ) );
208
+ float end_lat = log( tan( ( 1.0 - end_.y ) * PI / 2.0 ) );
209
+ float angle = atan( (end_lat - start_lat )/ (end_.x - start_.x));
210
+ return angle;
211
+ }
212
+ `
213
+
214
+ export const circleCircumferenceInterPolationOf2PointsRadian = `
215
+ float circleCircumferenceInterPolationOf2PointsRadian(vec2 center, vec2 target, float bearing_angle, float ratio) {
216
+ vec2 t = target - center;
217
+ float mainAngle = atan(t.x, t.y);
218
+ float angle = mainAngle - * ratio;
219
+ return angle;
220
+ }
221
+ `
222
+
223
+ export const circumferencePoints = `
224
+ vec2 circumferencePoints(vec2 center, vec2 target, vec2 target2, float phase, float radius) {
225
+ // Calculate vectors from center to target and target2
226
+ vec2 v1 = target - center;
227
+ vec2 v2 = target2 - center;
228
+
229
+ // Normalize the vectors to ensure they are on the unit circle
230
+ v1 = normalize(v1);
231
+ v2 = normalize(v2);
232
+
233
+ // Calculate the angle between the vectors
234
+ float angle1 = atan(v1.y, v1.x);
235
+ float angle2 = atan(v2.y, v2.x);
236
+
237
+ // Ensure the angles are continuous (handle wrap-around at 2π)
238
+ if (angle2 < angle1) {
239
+ angle2 += 2.0 * 3.14159265359; // Add 2π to angle2 if it is smaller
240
+ }
241
+
242
+ // Interpolate the angle based on the phase
243
+ float interpolatedAngle = mix(angle1, angle2, phase);
244
+
245
+ // Calculate the new point on the circle
246
+ vec2 result = vec2(cos(interpolatedAngle), sin(interpolatedAngle));
247
+
248
+ // Scale back to the original circle radius and shift to center
249
+ return center + radius * result;
250
+ }
251
+ `
package/wind/plugin.js CHANGED
@@ -696,9 +696,12 @@ export default class WindPlugin {
696
696
 
697
697
  gl.activeTexture(gl.TEXTURE0);
698
698
  if (this._doDraw()) {
699
- gl.disable(gl.DEPTH_TEST);
700
- gl.disable(gl.STENCIL_TEST);
699
+ const depthTest = gl.isEnabled(gl.DEPTH_TEST);
700
+ if (depthTest) gl.disable(gl.DEPTH_TEST);
701
+ // if (gl.disable(gl.STENCIL_TEST); //
701
702
  this._draw();
703
+ // if (depthTest) gl.enable(gl.DEPTH_TEST); // TODO: stencil
704
+
702
705
  }
703
706
 
704
707
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
@@ -862,8 +865,8 @@ export default class WindPlugin {
862
865
 
863
866
  _resetMachineStates() {
864
867
  const { gl, globe } = this;
865
- gl.disable(gl.DEPTH_TEST);
866
- gl.disable(gl.STENCIL_TEST);
868
+ // gl.disable(gl.DEPTH_TEST);
869
+ // gl.disable(gl.STENCIL_TEST);
867
870
  gl.activeTexture(gl.TEXTURE0);
868
871
  gl.viewport(0, 0, globe.api_ScrW(), globe.api_ScrH());
869
872
  }