@pirireis/webglobeplugins 0.15.0-alpha → 0.15.2-3.alpha

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.
Files changed (47) hide show
  1. package/Math/arc.js +1 -2
  2. package/Math/circle-cdf-points.js +1 -170
  3. package/Math/circle.js +0 -25
  4. package/Math/methods.js +2 -2
  5. package/Math/vec3.js +6 -2
  6. package/altitude-locator/plugin.js +1 -1
  7. package/bearing-line/plugin.js +3 -2
  8. package/package.json +1 -1
  9. package/point-tracks/plugin.js +82 -22
  10. package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
  11. package/programs/line-on-globe/linestrip/linestrip.js +2 -30
  12. package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
  13. package/programs/rings/partial-ring/piece-of-pie.js +55 -89
  14. package/programs/totems/camerauniformblock.js +7 -0
  15. package/programs/totems/canvas-webglobe-info.js +9 -9
  16. package/programs/totems/globe-changes.js +59 -0
  17. package/range-tools-on-terrain/bearing-line/adapters.js +8 -5
  18. package/range-tools-on-terrain/bearing-line/plugin.js +115 -18
  19. package/range-tools-on-terrain/circle-line-chain/adapters.js +15 -8
  20. package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +35 -13
  21. package/range-tools-on-terrain/circle-line-chain/plugin.js +94 -16
  22. package/range-tools-on-terrain/range-ring/adapters.js +74 -6
  23. package/range-tools-on-terrain/range-ring/plugin.js +222 -7
  24. package/range-tools-on-terrain/range-ring/types.js +9 -1
  25. package/semiplugins/interface.js +1 -0
  26. package/semiplugins/lightweight/line-plugin.js +72 -45
  27. package/semiplugins/lightweight/piece-of-pie-plugin.js +50 -25
  28. package/semiplugins/shape-on-terrain/arc-plugin.js +204 -98
  29. package/semiplugins/shape-on-terrain/circle-plugin.js +215 -88
  30. package/semiplugins/shape-on-terrain/padding-1-degree.js +538 -0
  31. package/util/account/single-attribute-buffer-management/buffer-manager.js +10 -0
  32. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +145 -8
  33. package/util/account/single-attribute-buffer-management/buffer-orchestrator1.js +159 -0
  34. package/util/account/single-attribute-buffer-management/object-store.js +7 -0
  35. package/util/build-strategy/static-dynamic.js +11 -1
  36. package/util/check/typecheck.js +12 -0
  37. package/util/frame-counter-trigger.js +84 -0
  38. package/util/geometry/index.js +2 -1
  39. package/util/webglobjectbuilders.js +2 -2
  40. package/write-text/context-text4.js +140 -0
  41. package/Math/arc-generate-points copy.js +0 -366
  42. package/Math/globe-util/horizon-plane.js +0 -112
  43. package/altitude-locator/draw-subset-obj.js +0 -16
  44. package/programs/line-on-globe/paddings/paddings.js +0 -1
  45. package/programs/rings/partial-ring/piece-of-pie copy.js +0 -286
  46. package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
  47. package/semiplugins/shape-on-terrain/one-degree-padding.js +0 -85
@@ -1,6 +1,18 @@
1
1
  import { CircleOnTerrainPlugin } from "../../semiplugins/shape-on-terrain/circle-plugin";
2
2
  import { ArcOnTerrainPlugin } from "../../semiplugins/shape-on-terrain/arc-plugin";
3
- import { LinePlugin } from "../../semiplugins/lightweight/line-plugin";
3
+ import { Padding1DegreePlugin } from '../../semiplugins/shape-on-terrain/padding-1-degree';
4
+ import { padding1DegreeInputAdapter, rangeRingToArcInputAdapter, rangeRingToCircleInputAdapter, allCircleKeysAdapter, allArcKeysAdapter, createColorRatios } from "./adapters";
5
+ export var ENUM_HIDE;
6
+ (function (ENUM_HIDE) {
7
+ ENUM_HIDE[ENUM_HIDE["SHOW"] = 0] = "SHOW";
8
+ ENUM_HIDE[ENUM_HIDE["HIDE"] = 1] = "HIDE";
9
+ ENUM_HIDE[ENUM_HIDE["HIDE_1_DEGREE_PADDINGS"] = 2] = "HIDE_1_DEGREE_PADDINGS";
10
+ })(ENUM_HIDE || (ENUM_HIDE = {}));
11
+ export var ENUM_TEXT_HIDE;
12
+ (function (ENUM_TEXT_HIDE) {
13
+ ENUM_TEXT_HIDE[ENUM_TEXT_HIDE["SHOW"] = 0] = "SHOW";
14
+ ENUM_TEXT_HIDE[ENUM_TEXT_HIDE["HIDE"] = 1] = "HIDE";
15
+ })(ENUM_TEXT_HIDE || (ENUM_TEXT_HIDE = {}));
4
16
  // @ts-ignore
5
17
  export class RangeRingPlugin {
6
18
  id;
@@ -8,24 +20,227 @@ export class RangeRingPlugin {
8
20
  gl = null;
9
21
  circlePlugin;
10
22
  arcPlugin;
11
- linePlugin;
23
+ paddingPlugin = null; // TODO: implement padding plugin
12
24
  _memory = new Map();
13
- constructor(id) {
25
+ _freed = false;
26
+ textWritersMap = new Map();
27
+ _semiPluginOptions = {
28
+ circleOnTerrainOptions: {
29
+ variativeColorsOn: false,
30
+ defaultColor: [1, 1, 1, 1],
31
+ defaultHeightFromGroundIn3D: 30,
32
+ },
33
+ arcOnTerrainOptions: {
34
+ flatViewOn: true,
35
+ globeViewOn: true,
36
+ variativeColorsOn: false,
37
+ defaultColor: [1, 1, 1, 1],
38
+ defaultHeightFromGroundIn3D: 0,
39
+ vertexCount: 32,
40
+ cameraAttractionIsOn: true // If true, camera attraction is enabled else evenly distributed arc points are used
41
+ },
42
+ paddingOptions: {
43
+ variativeColorsOn: false,
44
+ defaultColor: [1, 1, 1, 1],
45
+ defaultHeightFromGroundIn3D: 0,
46
+ },
47
+ };
48
+ constructor(id, { textDataPreAdaptor = (center) => center, textWritersMap = new Map(), }) {
14
49
  this.id = id;
15
- this.circlePlugin = new CircleOnTerrainPlugin(this.id + "-circle");
50
+ this.circlePlugin = new CircleOnTerrainPlugin(this.id + "-circle", {
51
+ variativeColorsOn: true,
52
+ });
16
53
  this.arcPlugin = new ArcOnTerrainPlugin(this.id + "-arc", {
17
- vertexCount: 5,
54
+ variativeColorsOn: true,
55
+ vertexCount: 20,
56
+ });
57
+ this.paddingPlugin = new Padding1DegreePlugin(this.id + "-padding", {
58
+ variativeColorsOn: true,
59
+ defaultColor: [1, 1, 1, 1],
60
+ defaultHeightFromGroundIn3D: 0,
18
61
  });
19
- this.linePlugin = new LinePlugin(this.id + "-line");
62
+ if (textWritersMap) {
63
+ this.textWritersMap = textWritersMap;
64
+ }
20
65
  }
21
66
  insertBulk(items) {
67
+ if (this._freed) {
68
+ console.warn("Plugin is freed, cannot insert items");
69
+ return;
70
+ }
71
+ if (this.globe === null || this.gl === null) {
72
+ console.warn("Globe or WebGL context is not initialized, cannot insert items");
73
+ return;
74
+ }
75
+ const visableItems = items.filter(item => item.hide !== ENUM_HIDE.HIDE);
76
+ if (this.paddingPlugin) {
77
+ const paddingInputs = visableItems.map(item => padding1DegreeInputAdapter(item)).flat();
78
+ this.paddingPlugin.insertBulk(paddingInputs);
79
+ }
80
+ const circleInputs = visableItems.filter(item => item.hide === ENUM_HIDE.SHOW).map(rangeRingToCircleInputAdapter).flat();
81
+ this.circlePlugin.insertBulk(circleInputs);
82
+ const arcInputs = visableItems.map((item) => rangeRingToArcInputAdapter(this.globe, item)).flat();
83
+ this.arcPlugin.insertBulk(arcInputs);
84
+ for (const item of items) {
85
+ this._memory.set(item.centerID, item);
86
+ if (item.hide !== ENUM_HIDE.HIDE && item.textHide === ENUM_HIDE.SHOW) {
87
+ this.updateText([item.centerID]);
88
+ }
89
+ }
90
+ }
91
+ removeCenters(centers) {
92
+ if (this._freed) {
93
+ console.warn("Plugin is freed, cannot remove centers");
94
+ return;
95
+ }
96
+ if (this.globe === null || this.gl === null) {
97
+ console.warn("Globe or WebGL context is not initialized, cannot remove centers");
98
+ return;
99
+ }
100
+ for (let i = 0; i < centers.length; i++) {
101
+ const rangeRingInput = this._memory.get(centers[i]);
102
+ if (!rangeRingInput) {
103
+ console.warn(`No data found for centerID: ${centers[i]}`);
104
+ continue;
105
+ }
106
+ const circleKeys = allCircleKeysAdapter(rangeRingInput);
107
+ this.circlePlugin.deleteBulk(circleKeys);
108
+ this.paddingPlugin?.deleteBulk(circleKeys);
109
+ const allArcKeys = allArcKeysAdapter(rangeRingInput);
110
+ this.arcPlugin.deleteBulk(allArcKeys);
111
+ this._memory.delete(centers[i]);
112
+ }
113
+ this.globe.DrawRender();
114
+ }
115
+ updateCenters() {
116
+ }
117
+ updateCentersCoordinate(items) {
118
+ if (this._freed) {
119
+ console.warn("Plugin is freed, cannot update centers coordinates");
120
+ return;
121
+ }
122
+ if (this.globe === null || this.gl === null) {
123
+ console.warn("Globe or WebGL context is not initialized, cannot update centers coordinates");
124
+ return;
125
+ }
126
+ const globe = this.globe;
127
+ for (const item of items) {
128
+ const { centerID, long, lat } = item;
129
+ const rangeRingInput = this._memory.get(centerID);
130
+ if (rangeRingInput) {
131
+ rangeRingInput.long = long;
132
+ rangeRingInput.lat = lat;
133
+ const arcData = rangeRingToArcInputAdapter(globe, rangeRingInput);
134
+ this.arcPlugin.updateCoordinates(arcData);
135
+ const circleData = rangeRingToCircleInputAdapter(rangeRingInput);
136
+ this.circlePlugin.updateCoordinates(circleData);
137
+ this.paddingPlugin?.updateCoordinates(circleData);
138
+ this.updateText([centerID]);
139
+ }
140
+ }
22
141
  }
23
- _build() {
142
+ updateCentersColor(items) {
143
+ if (this._freed) {
144
+ console.warn("Plugin is freed, cannot update centers color");
145
+ return;
146
+ }
147
+ if (this.globe === null || this.gl === null) {
148
+ console.warn("Globe or WebGL context is not initialized, cannot update centers color");
149
+ return;
150
+ }
151
+ // update Colors from memory map
152
+ for (let item of items) {
153
+ const data = this._memory.get(item.centerID);
154
+ if (!data) {
155
+ console.warn(`No data found for centerID: ${item.centerID}`);
156
+ continue;
157
+ }
158
+ data.rgba = item.rgba;
159
+ // update arc Colors
160
+ const arcColors = allArcKeysAdapter(data).map(key => ({ key, color: data.rgba }));
161
+ this.arcPlugin.updateColors(arcColors, false);
162
+ const circleColors = allCircleKeysAdapter(data).map(key => ({ key, color: data.rgba }));
163
+ this.circlePlugin.updateColors(circleColors);
164
+ if (this.paddingPlugin) {
165
+ const colorRatios = createColorRatios(data.rgba, data.stepAngle, 0.5);
166
+ for (const { key } of circleColors) {
167
+ this.paddingPlugin?.updateColorRatios(key, colorRatios, false);
168
+ }
169
+ }
170
+ this.updateText([item.centerID]);
171
+ }
172
+ this.globe.DrawRender();
173
+ }
174
+ updateCentersHide() {
24
175
  }
25
176
  init(globe, gl) {
26
177
  this.globe = globe;
27
178
  this.gl = gl;
179
+ this.circlePlugin.init(globe, gl);
180
+ this.arcPlugin.init(globe, gl);
181
+ this.paddingPlugin?.init(globe, gl);
28
182
  }
29
183
  draw3D() {
184
+ if (this._freed) {
185
+ console.warn("RangeRing Plugin is freed, cannot draw");
186
+ return;
187
+ }
188
+ this.arcPlugin.draw3D();
189
+ this.paddingPlugin?.draw3D();
190
+ this.circlePlugin.draw3D();
191
+ for (const [key, writer] of this.textWritersMap) {
192
+ writer.draw();
193
+ }
194
+ }
195
+ free() {
196
+ if (this._freed) {
197
+ console.warn("RangeRing Plugin is already freed");
198
+ return;
199
+ }
200
+ this._freed = true;
201
+ this.circlePlugin.free();
202
+ this.arcPlugin.free();
203
+ this.paddingPlugin?.free();
204
+ }
205
+ updateText(centerIDs = null) {
206
+ if (this._freed) {
207
+ console.warn("Plugin is freed, cannot update text");
208
+ return;
209
+ }
210
+ if (this.globe === null || this.gl === null) {
211
+ console.warn("Globe or WebGL context is not initialized, cannot update text");
212
+ return;
213
+ }
214
+ const globe = this.globe;
215
+ const textWritersMap = this.textWritersMap;
216
+ let keys = centerIDs ?? this._memory.keys();
217
+ for (const centerID of keys) {
218
+ const rangeRingData = this._memory.get(centerID);
219
+ if (!rangeRingData)
220
+ continue;
221
+ for (const [key, writer] of textWritersMap) {
222
+ writer.insertText(rangeRingData);
223
+ }
224
+ }
225
+ }
226
+ deleteText(centerIDs) {
227
+ if (this._freed) {
228
+ console.warn("Plugin is freed, cannot delete text");
229
+ return;
230
+ }
231
+ if (this.globe === null || this.gl === null) {
232
+ console.warn("Globe or WebGL context is not initialized, cannot delete text");
233
+ return;
234
+ }
235
+ const globe = this.globe;
236
+ const textWritersMap = this.textWritersMap;
237
+ for (const centerID of centerIDs) {
238
+ const rangeRingData = this._memory.get(centerID);
239
+ if (!rangeRingData)
240
+ continue;
241
+ for (const [key, writer] of textWritersMap) {
242
+ writer.deleteText(rangeRingData);
243
+ }
244
+ }
30
245
  }
31
246
  }
@@ -1 +1,9 @@
1
- export {};
1
+ export const ENUM_HIDE = Object.freeze({
2
+ SHOW: 0,
3
+ HIDE: 1,
4
+ HIDE_1_DEGREE_PADDINGS: 2
5
+ });
6
+ export const ENUM_TEXT_HIDE = Object.freeze({
7
+ SHOW: 0,
8
+ HIDE: 1
9
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { LineOnGlobeCache } from "../../programs/line-on-globe/naive-accurate-flexible";
2
- import { BufferMapOrchestrator } from "../../util/account/create-buffermap-orchastration";
2
+ import { BufferOrchestrator } from "../../util/account/single-attribute-buffer-management/buffer-orchestrator";
3
+ import { BufferManager } from "../../util/account/single-attribute-buffer-management/buffer-manager";
3
4
  import { sphereCoord } from "../../util/geometry/index";
4
5
  import { constraintFloat } from "../../util/check/typecheck";
5
6
  export class LinePlugin {
@@ -10,33 +11,36 @@ export class LinePlugin {
10
11
  vao = null;
11
12
  _options;
12
13
  _uboHandler = null;
13
- _bufferOrchestrator = null;
14
+ bufferOrchestrator;
15
+ bufferManagersMap = new Map();
14
16
  _freed = false;
15
- constructor(id, { flatViewOn = true, globeViewOn = true, variativeColorsOn = false, defaultColor = [1, 1, 1, 1], dashedLineOpacityVariativeOn = false, dashedLineRatioVariativeOn = false, bufferType = "DYNAMIC_DRAW", opacity = 1.0 } = {}) {
17
+ constructor(id, { flatViewOn = true, globeViewOn = true, variativeColorsOn = false, defaultColor = [1, 1, 1, 1], dashedLineOpacityVariativeOn = false, dashedLineRatioVariativeOn = false, bufferType = "DYNAMIC_DRAW", opacity = 1.0, initialCapacity = 10 } = {}) {
16
18
  this.id = id;
17
19
  this._options = {
18
- flatViewOn,
19
- globeViewOn,
20
- variativeColorsOn,
21
- defaultColor,
22
- dashedLineOpacityVariativeOn,
23
- dashedLineRatioVariativeOn,
24
- bufferType,
25
- opacity
20
+ flatViewOn: flatViewOn ?? true,
21
+ globeViewOn: globeViewOn ?? true,
22
+ variativeColorsOn: variativeColorsOn ?? false,
23
+ defaultColor: defaultColor ?? [1, 1, 1, 1],
24
+ dashedLineOpacityVariativeOn: dashedLineOpacityVariativeOn ?? false,
25
+ dashedLineRatioVariativeOn: dashedLineRatioVariativeOn ?? false,
26
+ bufferType: bufferType ?? "DYNAMIC_DRAW",
27
+ opacity: opacity ?? 1.0,
28
+ initialCapacity: initialCapacity ?? 10
26
29
  };
30
+ this.bufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity ?? 10 });
27
31
  }
28
32
  init(globe, gl) {
29
33
  this.globe = globe;
30
34
  this.gl = gl;
31
35
  this.program = LineOnGlobeCache.get(globe);
32
36
  this._uboHandler = this.program.createUBO();
33
- this._bufferOrchestrator = new BufferMapOrchestrator(gl, this._createBufferDetailsMap(), 10 // initial capacity
34
- );
37
+ this.setDefaultColor(this._options.defaultColor);
38
+ this._fillManagerMap();
35
39
  this.vao = this.program.createVAO(...this._createSelectBufferNames().map((key) => {
36
40
  if (key === null) {
37
41
  return null;
38
42
  }
39
- const bufferManagerComp = this._bufferOrchestrator?.bufferManagersMap.get(key);
43
+ const bufferManagerComp = this.bufferManagersMap.get(key);
40
44
  if (bufferManagerComp === undefined) {
41
45
  throw new Error(`Buffer key ${key} does not exist in bufferManagersMap`);
42
46
  }
@@ -49,26 +53,43 @@ export class LinePlugin {
49
53
  }));
50
54
  }
51
55
  // PLUGIN INTERFACE METHODS
56
+ increaseSpace(amount) {
57
+ if (this._freed) {
58
+ console.warn("Plugin is freed, cannot increase space");
59
+ return;
60
+ }
61
+ if (this.globe === null) {
62
+ console.warn("Globe is not initialized.");
63
+ return;
64
+ }
65
+ if (typeof amount !== "number" || amount <= 0) {
66
+ console.warn("Invalid amount, must be a positive number");
67
+ return;
68
+ }
69
+ this.bufferOrchestrator.ensureSpace(amount, this.bufferManagersMap);
70
+ }
52
71
  insertBulk(items) {
53
- const { _bufferOrchestrator, globe } = this;
54
- if (!_bufferOrchestrator || !globe) {
72
+ const { bufferOrchestrator, bufferManagersMap, globe } = this;
73
+ if (!bufferOrchestrator || !globe) {
55
74
  throw new Error("Buffer orchestrator or globe is not initialized.");
56
75
  }
57
- _bufferOrchestrator.insertBulk(items);
76
+ bufferOrchestrator.insertBulk(items, bufferManagersMap);
58
77
  this.globe?.DrawRender();
59
78
  }
60
79
  deleteBulk(keys) {
61
- const { _bufferOrchestrator, globe } = this;
62
- if (!_bufferOrchestrator || !globe) {
80
+ const { bufferOrchestrator, bufferManagersMap, globe } = this;
81
+ if (!bufferOrchestrator || !globe) {
63
82
  throw new Error("Buffer orchestrator or globe is not initialized.");
64
83
  }
65
- _bufferOrchestrator.deleteBulk(keys);
84
+ bufferOrchestrator.deleteBulk(keys, bufferManagersMap);
66
85
  this.globe?.DrawRender();
67
86
  }
68
- setPluginOpacity(opacity) {
87
+ setPluginOpacity(opacity, drawRender = false) {
69
88
  constraintFloat(opacity, 0, 1);
70
89
  this._options.opacity = opacity;
71
- this.globe?.DrawRender();
90
+ if (drawRender) {
91
+ this.globe?.DrawRender();
92
+ }
72
93
  }
73
94
  setPluginDashedLineRatio(ratio) {
74
95
  constraintFloat(ratio, 0, 1);
@@ -81,6 +102,20 @@ export class LinePlugin {
81
102
  this._options.defaultColor[3] = opacity; // Update the default color's alpha channel
82
103
  this.globe?.DrawRender();
83
104
  }
105
+ setDefaultColor(color, drawRender = false) {
106
+ if (!this.globe || !this.gl) {
107
+ console.warn("Globe or WebGL context is not initialized.");
108
+ return;
109
+ }
110
+ this._options.defaultColor = color;
111
+ this._uboHandler?.updateSingle("u_color", new Float32Array(color));
112
+ if (drawRender) {
113
+ this.globe.DrawRender();
114
+ }
115
+ }
116
+ updateCoordinates(items) {
117
+ throw new Error("Method not implemented.");
118
+ }
84
119
  // GLOBE INTERACTION METHODS
85
120
  draw3D() {
86
121
  if (this._freed) {
@@ -90,11 +125,10 @@ export class LinePlugin {
90
125
  if (!this.globe || !this.gl || !this.program || !this.vao) {
91
126
  throw new Error("Globe, GL context or program is not initialized.");
92
127
  }
93
- const { _bufferOrchestrator, _options, _uboHandler, vao } = this;
94
- if (!_bufferOrchestrator || !_bufferOrchestrator || !_uboHandler) {
128
+ const { bufferOrchestrator, _options, _uboHandler, vao } = this;
129
+ if (!bufferOrchestrator || !bufferOrchestrator || !_uboHandler) {
95
130
  throw new Error("Buffer orchestrator is not initialized.");
96
131
  }
97
- const { bufferOrchestrator } = _bufferOrchestrator;
98
132
  const { flatViewOn, globeViewOn, opacity } = _options;
99
133
  const drawOptions = {
100
134
  drawRange: {
@@ -118,67 +152,60 @@ export class LinePlugin {
118
152
  if (this._freed)
119
153
  return;
120
154
  // TODO: FILL
121
- this._bufferOrchestrator?.free();
155
+ this.bufferManagersMap.forEach((manager) => {
156
+ manager.bufferManager.free();
157
+ });
122
158
  this._uboHandler?.free();
123
159
  LineOnGlobeCache.release(this.globe);
124
160
  this._freed = true;
125
161
  }
126
162
  // IMPLICIT INTERFACE METHODS
127
- _createBufferDetailsMap() {
163
+ _fillManagerMap() {
128
164
  const globe = this.globe;
129
165
  const { flatViewOn, globeViewOn, variativeColorsOn, dashedLineOpacityVariativeOn, dashedLineRatioVariativeOn, bufferType = "DYNAMIC_DRAW" } = this._options;
130
- const m = new Map();
166
+ const m = this.bufferManagersMap;
167
+ const initialCapacity = this._options.initialCapacity;
131
168
  if (flatViewOn) {
132
169
  m.set("start_position", {
133
- itemSize: 2,
134
- bufferType: bufferType, // TODO: Ask User?
135
- buffer: null,
170
+ bufferManager: new BufferManager(globe.gl, 2, { bufferType, initialCapacity: this._options.initialCapacity }),
136
171
  adaptor: (item) => {
137
172
  const result = new Float32Array(globe.api_GetMercator2DPoint(item.start[0], item.start[1]));
138
173
  return result;
139
174
  }
140
175
  });
141
176
  m.set("end_position", {
142
- itemSize: 2,
143
- bufferType: bufferType,
144
- buffer: null,
177
+ bufferManager: new BufferManager(globe.gl, 2, { bufferType, initialCapacity: this._options.initialCapacity }),
145
178
  adaptor: (item) => new Float32Array(globe.api_GetMercator2DPoint(item.end[0], item.end[1]))
146
179
  });
147
180
  }
148
181
  if (globeViewOn) {
149
182
  m.set("start_position_3d", {
150
- itemSize: 3,
151
- bufferType: bufferType,
183
+ bufferManager: new BufferManager(globe.gl, 3, { bufferType, initialCapacity: this._options.initialCapacity }),
152
184
  adaptor: (item) => sphereCoord(item.start[0], item.start[1], globe, item.start_altitude || 0)
153
185
  });
154
186
  m.set("end_position_3d", {
155
- itemSize: 3,
156
- bufferType: bufferType,
187
+ bufferManager: new BufferManager(globe.gl, 3, { bufferType, initialCapacity: this._options.initialCapacity }),
157
188
  adaptor: (item) => sphereCoord(item.end[0], item.end[1], globe, item.end_altitude || 0)
158
189
  });
159
190
  }
160
191
  if (variativeColorsOn) {
161
192
  m.set("color", {
162
- itemSize: 4,
163
- bufferType: bufferType,
193
+ bufferManager: new BufferManager(globe.gl, 4, { bufferType, initialCapacity: this._options.initialCapacity }),
164
194
  adaptor: (item) => new Float32Array(item.color !== undefined ? item.color : [-1, -1, -1, -1])
165
195
  });
166
196
  }
167
197
  if (dashedLineOpacityVariativeOn) {
168
198
  m.set("dashed_line_opacity", {
169
- itemSize: 1,
170
- bufferType: bufferType,
199
+ bufferManager: new BufferManager(globe.gl, 1, { bufferType, initialCapacity: this._options.initialCapacity }),
171
200
  adaptor: (item) => new Float32Array(item.dashed_line_opacity !== undefined ? [item.dashed_line_opacity] : [-1])
172
201
  });
173
202
  }
174
203
  if (dashedLineRatioVariativeOn) {
175
204
  m.set("dashed_line_ratio", {
176
- itemSize: 1,
177
- bufferType: bufferType,
205
+ bufferManager: new BufferManager(globe.gl, 1, { bufferType, initialCapacity: this._options.initialCapacity }),
178
206
  adaptor: (item) => new Float32Array(item.dashed_line_ratio !== undefined ? [item.dashed_line_ratio] : [-1])
179
207
  });
180
208
  }
181
- return m;
182
209
  }
183
210
  _createSelectBufferNames() {
184
211
  const { flatViewOn, globeViewOn, variativeColorsOn, dashedLineOpacityVariativeOn, dashedLineRatioVariativeOn } = this._options;
@@ -15,17 +15,23 @@ export class PieceOfPiePlugin {
15
15
  bufferManagersMap = null;
16
16
  bufferOrchestrator = new BufferOrchestrator({ capacity: INITIAL_CAPACITY });
17
17
  drawMode = "BOTH";
18
- opacity = 1;
18
+ _uboHandler = null;
19
19
  _pluginOptions = {
20
20
  bufferType: "STATIC_DRAW",
21
21
  initialCapacity: INITIAL_CAPACITY,
22
- defaultAltitude: 0, // Default altitude is ground level
22
+ opacity: 1.0, // Default opacity is 1.0
23
+ defaultHeightFromGroundIn3D: 0, // Default altitude is ground level
24
+ defaultColor: [1, 1, 1, 1], // Default color is white with full opacity
25
+ variativeColorsOn: false, // Default is to not use variative colors
23
26
  };
24
- constructor(id, options = {}) {
27
+ constructor(id, options = null) {
25
28
  this.id = id;
26
- options.bufferType && (this._pluginOptions.bufferType = options.bufferType);
27
- options.initialCapacity && (this._pluginOptions.initialCapacity = options.initialCapacity);
28
- options.defaultAltitude && (this._pluginOptions.defaultAltitude = options.defaultAltitude);
29
+ if (options) {
30
+ this._pluginOptions = {
31
+ ...this._pluginOptions,
32
+ ...options
33
+ };
34
+ }
29
35
  }
30
36
  insertBulk(items) {
31
37
  this.bufferOrchestrator.insertBulk(items, this.bufferManagersMap);
@@ -35,10 +41,12 @@ export class PieceOfPiePlugin {
35
41
  this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
36
42
  this.globe?.DrawRender();
37
43
  }
38
- setPluginOpacity(opacity) {
44
+ setPluginOpacity(opacity, drawRender = true) {
39
45
  opacityCheck(opacity);
40
- this.opacity = opacity;
41
- this.globe?.DrawRender();
46
+ this._uboHandler?.updateSingle("u_opacity", new Float32Array([opacity]));
47
+ if (drawRender) {
48
+ this.globe?.DrawRender();
49
+ }
42
50
  }
43
51
  setDrawMode(drawMode) {
44
52
  if (drawMode !== "TRIANGLE_FAN" && drawMode !== "LINE_STRIP" && drawMode !== "BOTH") {
@@ -47,6 +55,17 @@ export class PieceOfPiePlugin {
47
55
  this.drawMode = drawMode;
48
56
  this.globe?.DrawRender();
49
57
  }
58
+ setDefaultColor(color) {
59
+ if (this._isFreed) {
60
+ console.warn("PieceOfPiePlugin is freed, cannot set default color.");
61
+ return;
62
+ }
63
+ if (!Array.isArray(color) || color.length !== 4) {
64
+ throw new Error("Color must be an array of 4 numbers [R, G, B, A].");
65
+ }
66
+ this._uboHandler?.updateSingle("u_color", new Float32Array(color));
67
+ this.globe?.DrawRender();
68
+ }
50
69
  _createBufferManagersMap() {
51
70
  const { gl, globe, _pluginOptions } = this;
52
71
  const { bufferType, initialCapacity } = _pluginOptions;
@@ -60,7 +79,7 @@ export class PieceOfPiePlugin {
60
79
  }],
61
80
  ["centerCoords3d", {
62
81
  bufferManager: new BufferManager(gl, 3, { bufferType, initialCapacity }),
63
- adaptor: (item) => sphereCoord(item.center[0], item.center[1], globe, (item.altitude ?? this._pluginOptions.defaultAltitude) / 1000)
82
+ adaptor: (item) => sphereCoord(item.center[0], item.center[1], globe, (item.altitude ?? this._pluginOptions.defaultHeightFromGroundIn3D) / 1000)
64
83
  }],
65
84
  ["startAngle2d", {
66
85
  bufferManager: new BufferManager(gl, 1, { bufferType, initialCapacity }),
@@ -102,21 +121,22 @@ export class PieceOfPiePlugin {
102
121
  bufferManager: new BufferManager(gl, 1, { bufferType, initialCapacity }),
103
122
  adaptor: (item) => new Float32Array([item.fillingMode ?? 0])
104
123
  }],
105
- ["rgba", {
106
- bufferManager: new BufferManager(gl, 4, { bufferType, initialCapacity }),
107
- adaptor: (item) => {
108
- if (!item.color || item.color.length === 0) {
109
- return new Float32Array([1, 1, 1, 1]); // Default color if none provided
110
- }
111
- return new Float32Array(item.color);
112
- }
113
- }
114
- ],
115
124
  ["radius", {
116
125
  bufferManager: new BufferManager(gl, 1, { bufferType, initialCapacity }),
117
126
  adaptor: (item) => new Float32Array([item.radius])
118
127
  }],
119
128
  ]);
129
+ if (this._pluginOptions.variativeColorsOn) {
130
+ bufferManagersMap.set("rgba", {
131
+ bufferManager: new BufferManager(gl, 4, { bufferType, initialCapacity }),
132
+ adaptor: (item) => {
133
+ if (!item.color || item.color.length === 0) {
134
+ return new Float32Array([1, 1, 1, 1]); // Default color if none provided
135
+ }
136
+ return new Float32Array(item.color);
137
+ }
138
+ });
139
+ }
120
140
  this.bufferManagersMap = bufferManagersMap;
121
141
  }
122
142
  init(globe, gl) {
@@ -135,6 +155,9 @@ export class PieceOfPiePlugin {
135
155
  'rgba',
136
156
  'radius',
137
157
  'fillingMode'].map((name) => {
158
+ if (!this.bufferManagersMap?.has(name)) {
159
+ return null; // this make vao with default attribute value with no buffer bound to it
160
+ }
138
161
  const buffer = this.bufferManagersMap?.get(name)?.bufferManager.buffer;
139
162
  return {
140
163
  buffer: buffer,
@@ -142,21 +165,23 @@ export class PieceOfPiePlugin {
142
165
  offset: 0,
143
166
  };
144
167
  }));
168
+ this._uboHandler = this.program.createUBO();
169
+ this._uboHandler.updateSingle("u_color", new Float32Array(this._pluginOptions.defaultColor));
170
+ this._uboHandler.updateSingle("u_opacity", new Float32Array([this._pluginOptions.opacity ?? 1.0])); // Default opacity is 1.0
145
171
  }
146
172
  draw3D() {
147
173
  if (!this.gl || !this.program || !this.vao || !this.globe) {
148
- console.warn("PieChartPlugin is not initialized properly.");
174
+ console.warn("PieChartPlugin is not initialized properly Or unregistered from globe.");
149
175
  return;
150
176
  }
151
177
  const length = this.bufferOrchestrator.length;
152
- console.log("Drawing PieChartPlugin with length:", length);
153
178
  this.gl.disable(this.gl.DEPTH_TEST);
154
179
  if (this.drawMode === "BOTH") {
155
- this.program?.draw(length, this.vao, EDGE_COUNT, this.opacity, "LINE_STRIP");
156
- this.program?.draw(length, this.vao, EDGE_COUNT, this.opacity, "TRIANGLE_FAN");
180
+ this.program?.draw(length, this.vao, EDGE_COUNT, "LINE_STRIP", this._uboHandler);
181
+ this.program?.draw(length, this.vao, EDGE_COUNT, "TRIANGLE_FAN", this._uboHandler);
157
182
  }
158
183
  else {
159
- this.program?.draw(length, this.vao, EDGE_COUNT, this.opacity, this.drawMode);
184
+ this.program?.draw(length, this.vao, EDGE_COUNT, this.drawMode, this._uboHandler);
160
185
  }
161
186
  this.gl.enable(this.gl.DEPTH_TEST);
162
187
  }