@pirireis/webglobeplugins 0.0.4 → 0.0.6

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.
package/index.js CHANGED
@@ -3,8 +3,9 @@ import * as waveparticles from "./waveparticles";
3
3
  import * as timetracks from "./timetracks";
4
4
  import * as arrowfield from "./arrowfield";
5
5
  import * as rangerings from "./rangerings";
6
+ import * as partialring from "./partialrings";
6
7
  import * as compassrose from "./compassrose";
7
8
  import * as heatwave from "./heatwave";
8
9
  import * as util from "./util";
9
10
  import * as programs from "./programs";
10
- export { wind, waveparticles, timetracks, rangerings, compassrose, heatwave, util, programs, arrowfield };
11
+ export { wind, waveparticles, timetracks, rangerings, compassrose, heatwave, util, programs, arrowfield, partialring };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pirireis/webglobeplugins",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "main": "index.js",
5
5
  "author": "Toprak Nihat Deniz Ozturk",
6
6
  "license": "MIT"
@@ -0,0 +1,15 @@
1
+ * Pie Statistacal view
2
+ A Unit is a bundle of partial rings.
3
+ Multiple partial rings of different color on the same center.
4
+ Update center updates a bundle
5
+ Updating an the amount of a a ring updates all the rings percentage in the same bundle.
6
+
7
+ An animation can be added
8
+
9
+ * EBM bearing view
10
+
11
+ create a plugin with line and points
12
+
13
+ * Target 1 is a point
14
+ * Target 2 is a point or an angle
15
+
@@ -0,0 +1,3 @@
1
+ import PartialRing, { RINGPARTIAL_ALPHA_MODE, RINGPARTIAL_DRAW_MODE, PART_OFFSET_LOOPUP } from './plugin';
2
+
3
+ export { PartialRing, RINGPARTIAL_ALPHA_MODE, RINGPARTIAL_DRAW_MODE, PART_OFFSET_LOOPUP };
@@ -0,0 +1,174 @@
1
+
2
+
3
+ import BufferOffsetManager from '../util/account/bufferoffsetmanager';
4
+ import { programCache, ITEM_SIZE } from './program';
5
+
6
+
7
+
8
+ const emptyBlock = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
9
+
10
+ export const RINGPARTIAL_DRAW_MODE = Object.freeze({
11
+ LINE_STRIP: "LINE_STRIP",
12
+ TRIANGLE_FAN: "TRIANGLE_FAN",
13
+ });
14
+
15
+ export const RINGPARTIAL_ALPHA_MODE = Object.freeze({
16
+ CONSTANT: 0,
17
+ FADING: 1,
18
+ HIDE: 2,
19
+ });
20
+
21
+
22
+ export const PART_OFFSET_LOOPUP = Object.freeze({
23
+ CENTER: 0,
24
+ START_ANGLE: 2,
25
+ TAIL_ANGLE: 3,
26
+ COLOR: 4,
27
+ RADIUS: 8,
28
+ COLOR_MODE: 9,
29
+ });
30
+
31
+
32
+ export default class {
33
+ constructor(id, { edgeCount = 10, drawMode = RINGPARTIAL_DRAW_MODE.LINE_STRIP, startLod = 3, endLod = 13, alphaMultiplier = 1 } = {}) {
34
+ this.id = id;
35
+ this.edgeCount = edgeCount;
36
+ this.drawMode = drawMode;
37
+ this.startLod = startLod;
38
+ this.endLod = endLod;
39
+ this.alphaMultiplier = alphaMultiplier;
40
+
41
+ }
42
+
43
+ init(globe, gl) {
44
+ this.gl = gl;
45
+ this.globe = globe;
46
+ this.program = programCache.get(globe);
47
+ console.log(this.program);
48
+ const { vao, buffer } = this.program.getVaoBuffer();
49
+ this.vao = vao;
50
+ this.buffer = buffer;
51
+
52
+
53
+ }
54
+
55
+
56
+ draw3D() {
57
+ const LOD = this.globe.api_GetCurrentLOD();
58
+
59
+ if (LOD < this.startLod || LOD > this.endLod) return;
60
+ this.program.draw(
61
+ this.bufferManager,
62
+ this.vao,
63
+ this.edgeCount,
64
+ this.alphaMultiplier,
65
+ this.drawMode,
66
+ )
67
+ }
68
+
69
+ /**
70
+ *
71
+ * @param {RINGPARTIAL_DRAW_MODE} drawMode
72
+ */
73
+ setDrawMode(drawMode) {
74
+ this.drawMode = drawMode;
75
+ }
76
+
77
+ setOpacity(opacity) {
78
+ this.alphaMultiplier = opacity;
79
+ }
80
+
81
+ setStartEndLOD({ startLod = null, endLod = null } = {}) {
82
+ if (startLod !== null) this.startLod = startLod;
83
+ if (endLod !== null) this.endLod = endLod;
84
+ }
85
+
86
+ createBufferMAnager(initialCapacity = 10, extendRatio = 1.2, bufferType = 'DYNAMIC_DRAW') {
87
+ if (!this.bufferManager) { this.bufferManager = new BufferManager(this.globe, this.gl, this.buffer, bufferType, { initialCapacity, extendRatio }); }
88
+ return this.bufferManager;
89
+ }
90
+
91
+ free() {
92
+ programCache.free(this.globe);
93
+ this.bufferManager.free();
94
+ }
95
+ }
96
+
97
+
98
+ class BufferManager extends BufferOffsetManager {
99
+
100
+ constructor(globe, gl, buffer, bufferType, { initialCapacity = 10, extendRatio = 1.2 } = {}) {
101
+ super(10, { capacity: initialCapacity });
102
+ this.globe = globe;
103
+ this.gl = gl;
104
+ this.buffer = buffer;
105
+ this.bufferType = bufferType;
106
+ this.extendRatio = extendRatio;
107
+
108
+
109
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
110
+ console.log(bufferType, gl[bufferType], initialCapacity * ITEM_SIZE * 4);
111
+ gl.bufferData(gl.ARRAY_BUFFER, initialCapacity * ITEM_SIZE * 4, gl[bufferType]);
112
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
113
+ }
114
+
115
+ /**
116
+ *
117
+ * @param { Array<{key, center[2], startAngle, tailAngle, radius, color[4], color_mode }>} rings
118
+ * @returns
119
+ */
120
+ insertRings(rings) {
121
+ if (rings.length === 0) return;
122
+ this._autoExtendBuffer(rings.length);
123
+ const { gl, buffer } = this;
124
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
125
+ for (let { key, center, startAngle, tailAngle, color, radius, colorMode } of rings) {
126
+ let offset = this.getOffset(key);
127
+ if (offset === undefined) {
128
+ offset = this.nextOffset();
129
+ this.setOffset(key, offset);
130
+ }
131
+ const block = new Float32Array([
132
+ ...center, startAngle, tailAngle, ...color, radius, colorMode]);
133
+ console.log(offset, block);
134
+ gl.bufferSubData(gl.ARRAY_BUFFER, offset, block);
135
+ // 2 1 1 1 4 1 = 10
136
+ }
137
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
138
+ this.globe.DrawRender();
139
+ }
140
+
141
+
142
+ /**
143
+ *
144
+ * @param {Array<{key:string, payload:Float32Array}} rings
145
+ * @param {PART_OFFSET_LOOPUP} part | CENTER, START_ANGLE, ROTATION_ANGLE, RADIUS, COLOR, COLOR_MODE
146
+ * @returns
147
+ */
148
+ updatePartial(rings, part) {
149
+ const { gl, buffer } = this;
150
+ this._updatePartial(rings, part, gl, buffer);
151
+ this.globe.DrawRender();
152
+
153
+ }
154
+
155
+
156
+ delete(keys) {
157
+ const { gl, buffer } = this;
158
+ this._removefromBuffer(gl, buffer, keys, emptyBlock);
159
+ this.globe.DrawRender();
160
+ }
161
+
162
+ _autoExtendBuffer(payloadSize) {
163
+ const { gl, buffer, bufferType, extendRatio } = this;
164
+ if (payloadSize <= this.spaceLeft()) return;
165
+ const newCapacity = Math.ceil((payloadSize + this.length) * extendRatio);
166
+ this.extendBuffer(gl, buffer, bufferType, newCapacity);
167
+ }
168
+
169
+
170
+ free() {
171
+ this.gl.deleteBuffer(this.buffer);
172
+ this.buffer = null;
173
+ }
174
+ }
@@ -0,0 +1,246 @@
1
+ import { createProgram, shaderfunctions } from "../util";
2
+ import { CameraUniformBlockTotem, CameraUniformBlockString, noRegisterGlobeProgramCache, globeProgramCache } from "../programs";
3
+
4
+ import {
5
+ POLE,
6
+ PI,
7
+ longLatRadToMercator,
8
+ mercatorXYTo2DPoint,
9
+ longLatRadToCartesian3D,
10
+ circleLimpFromLongLatRadCenterCartesian3D,
11
+ circleLimpFromLongLatRadCenterMercatorCompass,
12
+ cartesian3DToGLPosition
13
+
14
+
15
+ } from "../util/shaderfunctions/geometrytransformations";
16
+
17
+
18
+ /**
19
+ * TODO:
20
+ * 1. Triangle face looks at screen. if rotation angle is positive the last vertex must be the faintest.
21
+ *
22
+ */
23
+
24
+ const drawModeMap = Object.freeze({
25
+ LINE_STRIP: 0,
26
+ TRIANGLE_FAN: 1,
27
+ });
28
+
29
+
30
+
31
+ const vertexShaderSource = `#version 300 es` +
32
+ CameraUniformBlockString +
33
+ PI +
34
+ longLatRadToMercator +
35
+ mercatorXYTo2DPoint +
36
+ longLatRadToCartesian3D +
37
+ circleLimpFromLongLatRadCenterCartesian3D +
38
+ circleLimpFromLongLatRadCenterMercatorCompass +
39
+ cartesian3DToGLPosition + `
40
+
41
+ uniform float edge_count;
42
+ uniform int draw_mode; // %2 => 0: LINE_STRIP, 1: TRIANGLE_FAN
43
+ uniform float plugin_alpha_multiplier;
44
+
45
+ in vec2 center; // long, lat in radian
46
+ in float start_angle; // the start of partial circle from bearing point
47
+ in float tail_angle; // the rotation of the partial circle
48
+ in vec4 color;
49
+ in float radius; // in meter
50
+ in float color_mode; // 0.0: constant, 1.0: fading, 2.0: hide
51
+
52
+ out vec2 v_pos;
53
+ out vec4 v_color;
54
+
55
+
56
+ void main() {
57
+ if (color_mode == 2.0 || radius == 0.0) { return; }
58
+
59
+ float vertexID;
60
+ float radius_ = radius;
61
+ float alpha = plugin_alpha_multiplier;
62
+ if (draw_mode == 1) { // TRIANGLE_FAN
63
+ vertexID = float(gl_VertexID - 1);
64
+ if (gl_VertexID == 0) {
65
+ radius_ = 0.0; vertexID = 0.0;
66
+ if ( color_mode == 1.0 ) { alpha = 0.0; }
67
+ }
68
+ } else { // LINE_STRIP
69
+ vertexID = float(gl_VertexID);
70
+ }
71
+
72
+ float phase = ( vertexID / edge_count);
73
+
74
+ if ( color_mode == 1.0 ) {
75
+ if ( tail_angle > 0.0 ) {
76
+ v_color = vec4( color.rgb , color.a * ( 1.0 - phase ) * alpha );
77
+ } else {
78
+ v_color = vec4( color.rgb , color.a * (phase ) * alpha );
79
+ }
80
+ } else {
81
+ v_color = vec4( color.rgb , color.a * alpha );
82
+ }
83
+
84
+ float angle;
85
+ if ( tail_angle < 0.0 ) {
86
+ angle = tail_angle * (-phase + 1.0) + start_angle;
87
+ } else {
88
+ angle = tail_angle * phase + start_angle;
89
+ }
90
+ if (is3D) {
91
+
92
+ vec3 pos = circleLimpFromLongLatRadCenterCartesian3D(center, radius_, angle);
93
+ v_pos = vec2(0.0, 0.0);
94
+ gl_Position = cartesian3DToGLPosition(pos);
95
+ }
96
+ else {
97
+ vec2 pos = circleLimpFromLongLatRadCenterMercatorCompass(center, radius_, angle);
98
+ v_pos = pos;
99
+ gl_Position = mercatorXYTo2DPoint(pos);
100
+ }
101
+
102
+
103
+ gl_PointSize = 2.0;
104
+ }`;
105
+
106
+
107
+ const fragmentShaderSource = `#version 300 es` + POLE + `
108
+ precision highp float;
109
+
110
+ in vec4 v_color;
111
+ in vec2 v_pos;
112
+ out vec4 outColor;
113
+
114
+ void main() {
115
+ if ( v_pos.x < -POLE || v_pos.x > POLE || v_pos.y < -POLE || v_pos.y > POLE ) { discard; }
116
+ outColor = v_color;
117
+ }`;
118
+
119
+ export const ITEM_SIZE = 10;
120
+
121
+ export class Logic {
122
+
123
+ constructor(globe) {
124
+ this.globe = globe;
125
+ this.gl = globe.gl;
126
+ this._lastMode = 0;
127
+ this._lastEdgeCount = 64;
128
+ this._lastAlphaMultiplier = 1.0;
129
+
130
+ this.program = createProgram(this.gl, vertexShaderSource, fragmentShaderSource);
131
+
132
+ const { gl, program } = this;
133
+ { // set attributes locations
134
+ gl.bindAttribLocation(program, 0, 'center');
135
+ gl.bindAttribLocation(program, 1, 'start_angle');
136
+ gl.bindAttribLocation(program, 2, 'tail_angle');
137
+ gl.bindAttribLocation(program, 3, 'color');
138
+ gl.bindAttribLocation(program, 4, 'radius');
139
+ gl.bindAttribLocation(program, 5, 'color_mode');
140
+ // vao
141
+ // instanced draw read 1
142
+ }
143
+ { // Uniforms
144
+ this._edgeCountLocation = gl.getUniformLocation(program, 'edge_count');
145
+ this._draw_modeLocation = gl.getUniformLocation(program, 'draw_mode');
146
+ this._plugin_alpha_multiplierLocation = gl.getUniformLocation(program, 'plugin_alpha_multiplier');
147
+ const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
148
+ gl.useProgram(program);
149
+ gl.uniform1i(this._draw_modeLocation, this._lastMode);
150
+ gl.uniform1f(this._edgeCountLocation, this._lastEdgeCount);
151
+ gl.uniform1f(this._plugin_alpha_multiplierLocation, 1.0);
152
+
153
+ this.cameraBlockBindingPoint = 0;
154
+ this.cameraBlockTotem = globeProgramCache.getProgram(globe, CameraUniformBlockTotem);
155
+ const cameraBlockIndex = gl.getUniformBlockIndex(program, "CameraUniformBlock");
156
+ gl.uniformBlockBinding(program, cameraBlockIndex, this.cameraBlockBindingPoint);
157
+
158
+ gl.useProgram(currentProgram);
159
+ }
160
+
161
+ }
162
+
163
+
164
+
165
+ draw(bufferManager, vao, edgeCount, alphaMultiplier, drawMode) {
166
+ if (alphaMultiplier === 0) { console.log("no draw"); return };
167
+ const { gl, program, cameraBlockTotem, cameraBlockBindingPoint } = this
168
+
169
+ gl.disable(gl.DEPTH_TEST);
170
+ gl.useProgram(program);
171
+ if (drawMode !== this._lastMode) {
172
+ gl.uniform1i(this._draw_modeLocation, drawModeMap[drawMode]);
173
+ this._lastMode = drawMode;
174
+ }
175
+ if (edgeCount !== this._lastEdgeCount) {
176
+ gl.uniform1f(this._edgeCountLocation, edgeCount);
177
+ this._lastEdgeCount = edgeCount;
178
+ }
179
+ if (alphaMultiplier !== this._lastAlphaMultiplier) {
180
+ gl.uniform1f(this._plugin_alpha_multiplierLocation, alphaMultiplier);
181
+ this._lastAlphaMultiplier = alphaMultiplier;
182
+ }
183
+ const overdraw = drawModeMap[drawMode];
184
+ cameraBlockTotem.bind(cameraBlockBindingPoint);
185
+ gl.bindVertexArray(vao);
186
+ gl.drawArraysInstanced(gl[drawMode], 0, edgeCount + overdraw, bufferManager.length);
187
+ cameraBlockTotem.unbind(cameraBlockBindingPoint);
188
+ gl.bindVertexArray(null);
189
+ gl.enable(gl.DEPTH_TEST);
190
+ }
191
+
192
+
193
+ free() {
194
+ noRegisterGlobeProgramCache.releaseProgram(this.globe, CameraUniformBlockTotem);
195
+ this.gl.deleteProgram(this.program);
196
+ this.program = null;
197
+ }
198
+
199
+
200
+ getVaoBuffer() {
201
+ const { gl } = this;
202
+ const vao = gl.createVertexArray();
203
+ const buffer = gl.createBuffer();
204
+ gl.bindVertexArray(vao);
205
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
206
+
207
+ const stride = ITEM_SIZE * 4;
208
+ let offset = 0;
209
+ gl.enableVertexAttribArray(0);
210
+ gl.vertexAttribPointer(0, 2, gl.FLOAT, false, stride, offset);
211
+ offset += 2 * 4;
212
+ gl.enableVertexAttribArray(1);
213
+ gl.vertexAttribPointer(1, 1, gl.FLOAT, false, stride, offset);
214
+ offset += 1 * 4;
215
+ gl.enableVertexAttribArray(2);
216
+ gl.vertexAttribPointer(2, 1, gl.FLOAT, false, stride, offset);
217
+ offset += 1 * 4;
218
+ gl.enableVertexAttribArray(3);
219
+ gl.vertexAttribPointer(3, 4, gl.FLOAT, false, stride, offset);
220
+ offset += 4 * 4;
221
+ gl.enableVertexAttribArray(4);
222
+ gl.vertexAttribPointer(4, 1, gl.FLOAT, false, stride, offset);
223
+ offset += 1 * 4;
224
+ gl.enableVertexAttribArray(5);
225
+ gl.vertexAttribPointer(5, 1, gl.FLOAT, false, stride, offset);
226
+
227
+ gl.vertexAttribDivisor(0, 1);
228
+ gl.vertexAttribDivisor(1, 1);
229
+ gl.vertexAttribDivisor(2, 1);
230
+ gl.vertexAttribDivisor(3, 1);
231
+ gl.vertexAttribDivisor(4, 1);
232
+ gl.vertexAttribDivisor(5, 1);
233
+ gl.bindVertexArray(null);
234
+ gl.bindBuffer(gl.ARRAY_BUFFER, null);
235
+
236
+ return {
237
+ vao,
238
+ buffer,
239
+ }
240
+ }
241
+ }
242
+
243
+ export const programCache = Object.freeze({
244
+ get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, Logic),
245
+ free: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, Logic)
246
+ });
@@ -61,7 +61,7 @@ void main() {
61
61
  }`;
62
62
 
63
63
  class Logic {
64
- constructor(globe,) {
64
+ constructor(globe) {
65
65
  this.globe = globe;
66
66
  this.gl = globe.gl;
67
67
  this.program = createProgram(this.gl, vertexShader, fragmentShader);
@@ -105,7 +105,7 @@ class Logic {
105
105
  gl.uniform1f(this._circleEdgeCountLocation, circle_edge_count);
106
106
  this._circle_edge_count = circle_edge_count;
107
107
  }
108
- gl.drawArraysInstanced(gl.LINE_LOOP, 0, CIRCLE_EDGE_COUNT, attrBufferManager.length);
108
+ gl.drawArraysInstanced(gl.LINE_LOOP, 0, circle_edge_count, attrBufferManager.length);
109
109
  gl.bindVertexArray(null);
110
110
  cameraBlockTotem.unbind(cameraBlockBindingPoint);
111
111
  }