@pirireis/webglobeplugins 0.15.1-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 +76 -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 +65 -47
- package/semiplugins/lightweight/piece-of-pie-plugin.js +50 -25
- package/semiplugins/shape-on-terrain/arc-plugin.js +197 -100
- package/semiplugins/shape-on-terrain/circle-plugin.js +209 -90
- 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/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,14 +102,19 @@ export class LinePlugin {
|
|
|
81
102
|
this._options.defaultColor[3] = opacity; // Update the default color's alpha channel
|
|
82
103
|
this.globe?.DrawRender();
|
|
83
104
|
}
|
|
84
|
-
setDefaultColor(color) {
|
|
105
|
+
setDefaultColor(color, drawRender = false) {
|
|
85
106
|
if (!this.globe || !this.gl) {
|
|
86
107
|
console.warn("Globe or WebGL context is not initialized.");
|
|
87
108
|
return;
|
|
88
109
|
}
|
|
89
110
|
this._options.defaultColor = color;
|
|
90
111
|
this._uboHandler?.updateSingle("u_color", new Float32Array(color));
|
|
91
|
-
|
|
112
|
+
if (drawRender) {
|
|
113
|
+
this.globe.DrawRender();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
updateCoordinates(items) {
|
|
117
|
+
throw new Error("Method not implemented.");
|
|
92
118
|
}
|
|
93
119
|
// GLOBE INTERACTION METHODS
|
|
94
120
|
draw3D() {
|
|
@@ -99,11 +125,10 @@ export class LinePlugin {
|
|
|
99
125
|
if (!this.globe || !this.gl || !this.program || !this.vao) {
|
|
100
126
|
throw new Error("Globe, GL context or program is not initialized.");
|
|
101
127
|
}
|
|
102
|
-
const {
|
|
103
|
-
if (!
|
|
128
|
+
const { bufferOrchestrator, _options, _uboHandler, vao } = this;
|
|
129
|
+
if (!bufferOrchestrator || !bufferOrchestrator || !_uboHandler) {
|
|
104
130
|
throw new Error("Buffer orchestrator is not initialized.");
|
|
105
131
|
}
|
|
106
|
-
const { bufferOrchestrator } = _bufferOrchestrator;
|
|
107
132
|
const { flatViewOn, globeViewOn, opacity } = _options;
|
|
108
133
|
const drawOptions = {
|
|
109
134
|
drawRange: {
|
|
@@ -127,67 +152,60 @@ export class LinePlugin {
|
|
|
127
152
|
if (this._freed)
|
|
128
153
|
return;
|
|
129
154
|
// TODO: FILL
|
|
130
|
-
this.
|
|
155
|
+
this.bufferManagersMap.forEach((manager) => {
|
|
156
|
+
manager.bufferManager.free();
|
|
157
|
+
});
|
|
131
158
|
this._uboHandler?.free();
|
|
132
159
|
LineOnGlobeCache.release(this.globe);
|
|
133
160
|
this._freed = true;
|
|
134
161
|
}
|
|
135
162
|
// IMPLICIT INTERFACE METHODS
|
|
136
|
-
|
|
163
|
+
_fillManagerMap() {
|
|
137
164
|
const globe = this.globe;
|
|
138
165
|
const { flatViewOn, globeViewOn, variativeColorsOn, dashedLineOpacityVariativeOn, dashedLineRatioVariativeOn, bufferType = "DYNAMIC_DRAW" } = this._options;
|
|
139
|
-
const m =
|
|
166
|
+
const m = this.bufferManagersMap;
|
|
167
|
+
const initialCapacity = this._options.initialCapacity;
|
|
140
168
|
if (flatViewOn) {
|
|
141
169
|
m.set("start_position", {
|
|
142
|
-
|
|
143
|
-
bufferType: bufferType, // TODO: Ask User?
|
|
144
|
-
buffer: null,
|
|
170
|
+
bufferManager: new BufferManager(globe.gl, 2, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
145
171
|
adaptor: (item) => {
|
|
146
172
|
const result = new Float32Array(globe.api_GetMercator2DPoint(item.start[0], item.start[1]));
|
|
147
173
|
return result;
|
|
148
174
|
}
|
|
149
175
|
});
|
|
150
176
|
m.set("end_position", {
|
|
151
|
-
|
|
152
|
-
bufferType: bufferType,
|
|
153
|
-
buffer: null,
|
|
177
|
+
bufferManager: new BufferManager(globe.gl, 2, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
154
178
|
adaptor: (item) => new Float32Array(globe.api_GetMercator2DPoint(item.end[0], item.end[1]))
|
|
155
179
|
});
|
|
156
180
|
}
|
|
157
181
|
if (globeViewOn) {
|
|
158
182
|
m.set("start_position_3d", {
|
|
159
|
-
|
|
160
|
-
bufferType: bufferType,
|
|
183
|
+
bufferManager: new BufferManager(globe.gl, 3, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
161
184
|
adaptor: (item) => sphereCoord(item.start[0], item.start[1], globe, item.start_altitude || 0)
|
|
162
185
|
});
|
|
163
186
|
m.set("end_position_3d", {
|
|
164
|
-
|
|
165
|
-
bufferType: bufferType,
|
|
187
|
+
bufferManager: new BufferManager(globe.gl, 3, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
166
188
|
adaptor: (item) => sphereCoord(item.end[0], item.end[1], globe, item.end_altitude || 0)
|
|
167
189
|
});
|
|
168
190
|
}
|
|
169
191
|
if (variativeColorsOn) {
|
|
170
192
|
m.set("color", {
|
|
171
|
-
|
|
172
|
-
bufferType: bufferType,
|
|
193
|
+
bufferManager: new BufferManager(globe.gl, 4, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
173
194
|
adaptor: (item) => new Float32Array(item.color !== undefined ? item.color : [-1, -1, -1, -1])
|
|
174
195
|
});
|
|
175
196
|
}
|
|
176
197
|
if (dashedLineOpacityVariativeOn) {
|
|
177
198
|
m.set("dashed_line_opacity", {
|
|
178
|
-
|
|
179
|
-
bufferType: bufferType,
|
|
199
|
+
bufferManager: new BufferManager(globe.gl, 1, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
180
200
|
adaptor: (item) => new Float32Array(item.dashed_line_opacity !== undefined ? [item.dashed_line_opacity] : [-1])
|
|
181
201
|
});
|
|
182
202
|
}
|
|
183
203
|
if (dashedLineRatioVariativeOn) {
|
|
184
204
|
m.set("dashed_line_ratio", {
|
|
185
|
-
|
|
186
|
-
bufferType: bufferType,
|
|
205
|
+
bufferManager: new BufferManager(globe.gl, 1, { bufferType, initialCapacity: this._options.initialCapacity }),
|
|
187
206
|
adaptor: (item) => new Float32Array(item.dashed_line_ratio !== undefined ? [item.dashed_line_ratio] : [-1])
|
|
188
207
|
});
|
|
189
208
|
}
|
|
190
|
-
return m;
|
|
191
209
|
}
|
|
192
210
|
_createSelectBufferNames() {
|
|
193
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
|
}
|