@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.
- package/Math/arc.js +1 -2
- package/Math/circle-cdf-points.js +1 -170
- package/Math/circle.js +0 -25
- package/Math/methods.js +2 -2
- package/Math/vec3.js +6 -2
- package/altitude-locator/plugin.js +1 -1
- package/bearing-line/plugin.js +3 -2
- package/package.json +1 -1
- package/point-tracks/plugin.js +82 -22
- package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
- package/programs/line-on-globe/linestrip/linestrip.js +2 -30
- package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
- package/programs/rings/partial-ring/piece-of-pie.js +55 -89
- package/programs/totems/camerauniformblock.js +7 -0
- package/programs/totems/canvas-webglobe-info.js +9 -9
- package/programs/totems/globe-changes.js +59 -0
- package/range-tools-on-terrain/bearing-line/adapters.js +8 -5
- package/range-tools-on-terrain/bearing-line/plugin.js +115 -18
- package/range-tools-on-terrain/circle-line-chain/adapters.js +15 -8
- package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +35 -13
- package/range-tools-on-terrain/circle-line-chain/plugin.js +94 -16
- package/range-tools-on-terrain/range-ring/adapters.js +74 -6
- package/range-tools-on-terrain/range-ring/plugin.js +222 -7
- package/range-tools-on-terrain/range-ring/types.js +9 -1
- package/semiplugins/interface.js +1 -0
- package/semiplugins/lightweight/line-plugin.js +72 -45
- package/semiplugins/lightweight/piece-of-pie-plugin.js +50 -25
- package/semiplugins/shape-on-terrain/arc-plugin.js +204 -98
- package/semiplugins/shape-on-terrain/circle-plugin.js +215 -88
- package/semiplugins/shape-on-terrain/padding-1-degree.js +538 -0
- package/util/account/single-attribute-buffer-management/buffer-manager.js +10 -0
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +145 -8
- package/util/account/single-attribute-buffer-management/buffer-orchestrator1.js +159 -0
- package/util/account/single-attribute-buffer-management/object-store.js +7 -0
- package/util/build-strategy/static-dynamic.js +11 -1
- package/util/check/typecheck.js +12 -0
- package/util/frame-counter-trigger.js +84 -0
- package/util/geometry/index.js +2 -1
- package/util/webglobjectbuilders.js +2 -2
- package/write-text/context-text4.js +140 -0
- package/Math/arc-generate-points copy.js +0 -366
- package/Math/globe-util/horizon-plane.js +0 -112
- package/altitude-locator/draw-subset-obj.js +0 -16
- package/programs/line-on-globe/paddings/paddings.js +0 -1
- package/programs/rings/partial-ring/piece-of-pie copy.js +0 -286
- package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
- 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 {
|
|
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
|
-
|
|
23
|
+
paddingPlugin = null; // TODO: implement padding plugin
|
|
12
24
|
_memory = new Map();
|
|
13
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LineOnGlobeCache } from "../../programs/line-on-globe/naive-accurate-flexible";
|
|
2
|
-
import {
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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 {
|
|
54
|
-
if (!
|
|
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
|
-
|
|
76
|
+
bufferOrchestrator.insertBulk(items, bufferManagersMap);
|
|
58
77
|
this.globe?.DrawRender();
|
|
59
78
|
}
|
|
60
79
|
deleteBulk(keys) {
|
|
61
|
-
const {
|
|
62
|
-
if (!
|
|
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
|
-
|
|
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
|
-
|
|
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 {
|
|
94
|
-
if (!
|
|
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.
|
|
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
|
-
|
|
163
|
+
_fillManagerMap() {
|
|
128
164
|
const globe = this.globe;
|
|
129
165
|
const { flatViewOn, globeViewOn, variativeColorsOn, dashedLineOpacityVariativeOn, dashedLineRatioVariativeOn, bufferType = "DYNAMIC_DRAW" } = this._options;
|
|
130
|
-
const m =
|
|
166
|
+
const m = this.bufferManagersMap;
|
|
167
|
+
const initialCapacity = this._options.initialCapacity;
|
|
131
168
|
if (flatViewOn) {
|
|
132
169
|
m.set("start_position", {
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18
|
+
_uboHandler = null;
|
|
19
19
|
_pluginOptions = {
|
|
20
20
|
bufferType: "STATIC_DRAW",
|
|
21
21
|
initialCapacity: INITIAL_CAPACITY,
|
|
22
|
-
|
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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.
|
|
41
|
-
|
|
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.
|
|
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,
|
|
156
|
-
this.program?.draw(length, this.vao, EDGE_COUNT,
|
|
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.
|
|
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
|
}
|