@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
|
@@ -9,6 +9,7 @@ import { globe3Dcoordinates, globe2Dcoordinates } from "../../Math/methods";
|
|
|
9
9
|
import { StaticDynamicStrategy, StaticDynamicState } from "../../util/build-strategy/static-dynamic";
|
|
10
10
|
import { WORLD_RADIUS_3D, WORLD_RADIUS_MERCATOR } from "../../Math/constants";
|
|
11
11
|
import { opacityCheck } from "../../util/check/typecheck";
|
|
12
|
+
import { FrameCounterTrigger } from "../../util/frame-counter-trigger";
|
|
12
13
|
const ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL = 8;
|
|
13
14
|
const CIRCLE_POINTS_COUNT_HALF = 65; // Half of the points plus one for the reflection
|
|
14
15
|
const CIRCLE_POINTS_COUNT = CIRCLE_POINTS_COUNT_HALF * 2 - 1; // Number of points to approximate the circle
|
|
@@ -58,45 +59,47 @@ export class CircleOnTerrainPlugin {
|
|
|
58
59
|
globe = null;
|
|
59
60
|
gl = null;
|
|
60
61
|
lineProgram = null;
|
|
61
|
-
|
|
62
|
+
bufferManagersMap = new Map();
|
|
62
63
|
bufferOrchestrator = new BufferOrchestrator();
|
|
63
64
|
circleMap = new Map();
|
|
64
65
|
_cameraUniformBlock = null;
|
|
65
|
-
|
|
66
|
+
_freed = false;
|
|
66
67
|
_circleUBOHandler = null;
|
|
67
68
|
_opacity = 1;
|
|
68
69
|
_vao = null;
|
|
69
70
|
_dobuild = true; // This is used to trigger the build of circles when the camera position changes.
|
|
71
|
+
_frameCounterTrigger = null;
|
|
70
72
|
_staticDynamicStrategy = null;
|
|
71
|
-
|
|
73
|
+
_options = {
|
|
72
74
|
variativeColorsOn: false,
|
|
73
75
|
defaultColor: [0.1, 0.1, 0.1, 1], // Default color in RGBA format
|
|
74
|
-
defaultHeightFromGroundIn3D: 30.0
|
|
76
|
+
defaultHeightFromGroundIn3D: 30.0,
|
|
77
|
+
isMSL: false
|
|
75
78
|
};
|
|
76
|
-
|
|
79
|
+
_textDataPreAdaptor = undefined;
|
|
80
|
+
constructor(id, styleOptions = null) {
|
|
77
81
|
this.id = id;
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
if (styleOptions) {
|
|
83
|
+
this._options = { ...this._options, ...styleOptions };
|
|
84
|
+
}
|
|
80
85
|
}
|
|
81
86
|
init(globe, gl) {
|
|
82
87
|
this.globe = globe;
|
|
83
88
|
this.gl = gl;
|
|
84
89
|
// Initialize the program cache for line strip rendering.
|
|
85
|
-
this._staticDynamicStrategy = new StaticDynamicStrategy(globe, ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL);
|
|
86
90
|
this.lineProgram = LineStripProgramCache.get(globe);
|
|
87
|
-
// const g3D = globe3Dcoordinates(globe, 30);
|
|
88
91
|
const g2D = globe2Dcoordinates(globe);
|
|
89
92
|
// Initialize with a reasonable initial capacity to prevent buffer size issues
|
|
90
93
|
const initialCapacity = 100; // Start with capacity for 100 circles
|
|
91
|
-
this.
|
|
94
|
+
this.bufferManagersMap.set("position3d", {
|
|
92
95
|
bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 3, { initialCapacity }), // plus 1 is for butting linestrips
|
|
93
96
|
adaptor: (item) => {
|
|
94
|
-
const { longLatArr, height = this.
|
|
95
|
-
const result = globe3Dcoordinates(globe,
|
|
97
|
+
const { longLatArr, height = this._options.defaultHeightFromGroundIn3D, msl = this._options.isMSL } = item;
|
|
98
|
+
const result = globe3Dcoordinates(globe, longLatArr, height, msl, { paddingCount: 1, paddingValue: NaN });
|
|
96
99
|
return result;
|
|
97
100
|
}
|
|
98
101
|
});
|
|
99
|
-
this.
|
|
102
|
+
this.bufferManagersMap.set("position2d", {
|
|
100
103
|
bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 2, { initialCapacity }),
|
|
101
104
|
adaptor: (item) => {
|
|
102
105
|
const { longLatArr } = item;
|
|
@@ -104,8 +107,8 @@ export class CircleOnTerrainPlugin {
|
|
|
104
107
|
return result;
|
|
105
108
|
}
|
|
106
109
|
});
|
|
107
|
-
if (this.
|
|
108
|
-
this.
|
|
110
|
+
if (this._options.variativeColorsOn) {
|
|
111
|
+
this.bufferManagersMap.set("color", {
|
|
109
112
|
bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 4, { initialCapacity }),
|
|
110
113
|
adaptor: (item) => {
|
|
111
114
|
if (item.color) {
|
|
@@ -115,50 +118,109 @@ export class CircleOnTerrainPlugin {
|
|
|
115
118
|
}
|
|
116
119
|
else {
|
|
117
120
|
for (let i = 0; i < CIRCLE_POINTS_COUNT; i++) {
|
|
118
|
-
_colorArray.set(this.
|
|
121
|
+
_colorArray.set(this._options.defaultColor, i * 4);
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
return _colorArray;
|
|
122
125
|
}
|
|
123
126
|
});
|
|
124
127
|
}
|
|
125
|
-
this._vao = this.lineProgram.createVAO(createBufferAndReadInfo(this.
|
|
126
|
-
createBufferAndReadInfo(this.
|
|
128
|
+
this._vao = this.lineProgram.createVAO(createBufferAndReadInfo(this.bufferManagersMap.get("position3d")?.bufferManager.buffer), createBufferAndReadInfo(this.bufferManagersMap.get("position2d")?.bufferManager.buffer), this._options.variativeColorsOn ?
|
|
129
|
+
createBufferAndReadInfo(this.bufferManagersMap.get("color")?.bufferManager.buffer) : null);
|
|
127
130
|
this._circleUBOHandler = this.lineProgram.createUBO();
|
|
131
|
+
this.setDefaultColor(this._options.defaultColor);
|
|
128
132
|
this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
|
|
133
|
+
this._staticDynamicStrategy = new StaticDynamicStrategy(globe, ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL, () => {
|
|
134
|
+
this.__buildStaticCircles();
|
|
135
|
+
});
|
|
136
|
+
this._frameCounterTrigger = new FrameCounterTrigger(globe, 15, 1000, (globeChanges) => {
|
|
137
|
+
if (this._freed)
|
|
138
|
+
return;
|
|
139
|
+
this._buildCircles();
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
increaseSpace(amount) {
|
|
143
|
+
if (this._freed) {
|
|
144
|
+
console.warn("Plugin is freed, cannot increase space");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (this.globe === null) {
|
|
148
|
+
console.warn("Globe is not initialized.");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (typeof amount !== "number" || amount <= 0) {
|
|
152
|
+
console.warn("Invalid amount, must be a positive number");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.bufferOrchestrator.ensureSpace(amount, this.bufferManagersMap);
|
|
129
156
|
}
|
|
130
157
|
insertBulk(circles) {
|
|
131
|
-
if (this.
|
|
158
|
+
if (this._freed)
|
|
132
159
|
return;
|
|
133
160
|
if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
|
|
134
|
-
!this.
|
|
161
|
+
!this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
|
|
135
162
|
throw new Error("Plugin not initialized properly");
|
|
136
163
|
}
|
|
137
|
-
|
|
138
|
-
|
|
164
|
+
const keys = [];
|
|
165
|
+
let newItemCount = 0;
|
|
139
166
|
for (const circleInput of circles) {
|
|
140
167
|
if (!circleInput.key || !circleInput.center || !circleInput.radius) {
|
|
141
168
|
console.warn(`CircleOnTerrainPlugin: Circle input is missing required properties: ${circleInput.radius} or ${circleInput.center} or ${circleInput.key}`);
|
|
142
169
|
continue;
|
|
143
170
|
}
|
|
144
|
-
|
|
171
|
+
if (circleInput.radius <= 0) {
|
|
172
|
+
console.warn(`CircleOnTerrainPlugin: Circle ${circleInput.key} has non-positive radius ${circleInput.radius}. Skipping.`);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
keys.push(circleInput.key);
|
|
176
|
+
if (!this.circleMap.has(circleInput.key)) {
|
|
177
|
+
newItemCount++;
|
|
178
|
+
}
|
|
145
179
|
const circleForAzimuthCalc = CircleMethods.createCircleClosestAzimuthAngleProperties(circleInput);
|
|
146
180
|
this.circleMap.set(circleInput.key, [circleInput, circleForAzimuthCalc]);
|
|
147
|
-
if (this._staticDynamicStrategy?.getState() !== StaticDynamicState.DYNAMIC) {
|
|
148
|
-
fillStaticKeys.push(circleInput.key);
|
|
149
|
-
}
|
|
150
181
|
}
|
|
151
|
-
this.
|
|
182
|
+
this.bufferOrchestrator.ensureSpace(newItemCount, this.bufferManagersMap);
|
|
183
|
+
this._buildCircles(keys);
|
|
184
|
+
if (this._options.variativeColorsOn) {
|
|
185
|
+
this.__fillColor(keys);
|
|
186
|
+
}
|
|
152
187
|
this.globe.DrawRender();
|
|
153
188
|
}
|
|
189
|
+
updateColors(keyColorCouples, drawRender = true) {
|
|
190
|
+
if (this._freed) {
|
|
191
|
+
console.warn("Plugin is freed, cannot increase space");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (this.globe === null) {
|
|
195
|
+
console.warn("Globe is not initialized.");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (this._options.variativeColorsOn === false) {
|
|
199
|
+
console.warn("VariativeColors are not enabled");
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
for (const { key, color } of keyColorCouples) {
|
|
203
|
+
const [circleInput] = this.circleMap.get(key) || [];
|
|
204
|
+
if (circleInput) {
|
|
205
|
+
circleInput.color = color;
|
|
206
|
+
this.__fillColor([key]);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
console.warn(`Circle key ${key} not found in circleMap.`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (drawRender) {
|
|
213
|
+
this.globe.DrawRender();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
154
216
|
deleteBulk(keys) {
|
|
155
|
-
if (this.
|
|
217
|
+
if (this._freed)
|
|
156
218
|
return;
|
|
157
219
|
if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
|
|
158
|
-
!this.
|
|
220
|
+
!this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
|
|
159
221
|
throw new Error("Plugin not initialized properly");
|
|
160
222
|
}
|
|
161
|
-
this.bufferOrchestrator.deleteBulk(keys, this.
|
|
223
|
+
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
|
|
162
224
|
for (const key of keys) {
|
|
163
225
|
if (this.circleMap.has(key)) {
|
|
164
226
|
this.circleMap.delete(key);
|
|
@@ -168,47 +230,104 @@ export class CircleOnTerrainPlugin {
|
|
|
168
230
|
}
|
|
169
231
|
}
|
|
170
232
|
}
|
|
171
|
-
setPluginOpacity(opacity) {
|
|
233
|
+
setPluginOpacity(opacity, drawRender = false) {
|
|
172
234
|
if (!this.globe || !this.gl) {
|
|
173
235
|
console.warn("Globe or WebGL context is not initialized.");
|
|
174
236
|
return;
|
|
175
237
|
}
|
|
176
238
|
opacityCheck(opacity);
|
|
177
239
|
this._opacity = opacity;
|
|
178
|
-
|
|
240
|
+
if (drawRender) {
|
|
241
|
+
this.globe.DrawRender();
|
|
242
|
+
}
|
|
179
243
|
}
|
|
180
|
-
|
|
244
|
+
setElevationMode(mode) {
|
|
245
|
+
switch (mode) {
|
|
246
|
+
case "msl":
|
|
247
|
+
this._options.isMSL = true;
|
|
248
|
+
break;
|
|
249
|
+
case "agl":
|
|
250
|
+
this._options.isMSL = false;
|
|
251
|
+
break;
|
|
252
|
+
default:
|
|
253
|
+
throw new Error(`Unknown elevation mode: ${mode}`);
|
|
254
|
+
}
|
|
255
|
+
this._buildCircles();
|
|
256
|
+
this.globe?.DrawRender();
|
|
257
|
+
}
|
|
258
|
+
setDefaultColor(color, drawRender = false) {
|
|
181
259
|
if (!this.globe || !this.gl) {
|
|
182
260
|
console.warn("Globe or WebGL context is not initialized.");
|
|
183
261
|
return;
|
|
184
262
|
}
|
|
185
263
|
this._circleUBOHandler?.updateSingle("u_color", new Float32Array(color));
|
|
264
|
+
if (drawRender) {
|
|
265
|
+
this.globe.DrawRender();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
updateCoordinates(items) {
|
|
269
|
+
if (this._freed) {
|
|
270
|
+
console.warn("CircleOnTerrainPlugin is freed, cannot update coordinates");
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
if (this.globe === null) {
|
|
274
|
+
console.warn("Globe is not initialized, cannot update coordinates");
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
const updateKeys = [];
|
|
278
|
+
for (const item of items) {
|
|
279
|
+
const { key, center, radius } = item;
|
|
280
|
+
const [circleInput] = this.circleMap.get(key) || [];
|
|
281
|
+
if (circleInput) {
|
|
282
|
+
circleInput.center = center;
|
|
283
|
+
circleInput.radius = radius;
|
|
284
|
+
updateKeys.push(key);
|
|
285
|
+
}
|
|
286
|
+
else {
|
|
287
|
+
console.warn(`Circle key ${key} not found in circleMap.`);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
this._buildCircles(updateKeys);
|
|
186
292
|
this.globe.DrawRender();
|
|
187
293
|
}
|
|
188
294
|
// IMPLICIT METHODS
|
|
189
|
-
|
|
295
|
+
__fillColor(subSetIDs) {
|
|
296
|
+
if (!this._options.variativeColorsOn)
|
|
297
|
+
return;
|
|
298
|
+
const wrapper = [null];
|
|
299
|
+
for (const key of subSetIDs) {
|
|
300
|
+
const [circleInput, circleForAzimuthCalc] = this.circleMap.get(key) || [];
|
|
301
|
+
if (circleInput) {
|
|
302
|
+
wrapper[0] = circleInput;
|
|
303
|
+
this.bufferOrchestrator.insertBulk(wrapper, this.bufferManagersMap, ["color"]);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
_buildCircles(subSetIDs = null) {
|
|
190
308
|
// @ts-ignore
|
|
191
309
|
this._staticDynamicStrategy?.updateState();
|
|
192
310
|
const state = this._staticDynamicStrategy?.getState();
|
|
193
|
-
if (state === StaticDynamicState.
|
|
194
|
-
this.
|
|
311
|
+
if (state === StaticDynamicState.DYNAMIC) {
|
|
312
|
+
this.__buildDynamicCircles(subSetIDs);
|
|
195
313
|
}
|
|
196
|
-
else if (state === StaticDynamicState.
|
|
197
|
-
this.
|
|
314
|
+
else if (subSetIDs || state === StaticDynamicState.TO_STATIC) {
|
|
315
|
+
this.__buildStaticCircles(subSetIDs);
|
|
198
316
|
}
|
|
199
317
|
}
|
|
200
|
-
|
|
201
|
-
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator,
|
|
318
|
+
__buildDynamicCircles(subSetIDs = null) {
|
|
319
|
+
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
|
|
202
320
|
if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
|
|
203
|
-
!bufferOrchestrator || !
|
|
321
|
+
!bufferOrchestrator || !bufferManagersMap || !circleMap)
|
|
204
322
|
throw new Error("Plugin not initialized properly");
|
|
205
323
|
// unoptimized.. resets all circles.
|
|
206
|
-
// bufferOrchestrator.resetWithCapacity(
|
|
324
|
+
// bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
|
|
207
325
|
// Prepare the data for the buffers
|
|
208
326
|
const data = [{
|
|
209
327
|
key: "",
|
|
210
328
|
longLatArr: [],
|
|
211
|
-
height: null
|
|
329
|
+
height: null,
|
|
330
|
+
msl: null
|
|
212
331
|
}];
|
|
213
332
|
const lookAtPosition = _cameraUniformBlock.getLookAtVector();
|
|
214
333
|
const cameraPosition = _cameraUniformBlock.getNormalizedCameraVector();
|
|
@@ -217,8 +336,16 @@ export class CircleOnTerrainPlugin {
|
|
|
217
336
|
vec3.normalize(cameraPosition, cameraPosition);
|
|
218
337
|
const currentLOD = globe.api_GetCurrentLODWithDecimal();
|
|
219
338
|
const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
|
|
220
|
-
|
|
221
|
-
|
|
339
|
+
let keys;
|
|
340
|
+
if (!subSetIDs || subSetIDs.length === 0) {
|
|
341
|
+
keys = Array.from(this.circleMap.keys());
|
|
342
|
+
// bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
keys = subSetIDs;
|
|
346
|
+
}
|
|
347
|
+
for (const key of keys) {
|
|
348
|
+
const [{ radius, center, height = null, msl = null }, circleForAzimuthCalc] = this.circleMap.get(key);
|
|
222
349
|
const closestAzimuthAngle = CircleMethods.closestAzimuthAngle(circleForAzimuthCalc, cameraPosition);
|
|
223
350
|
const stregthLevel = defineStregthLevel(currentLOD, radius);
|
|
224
351
|
if (stregthLevel < 0) {
|
|
@@ -230,69 +357,61 @@ export class CircleOnTerrainPlugin {
|
|
|
230
357
|
data[0].key = key;
|
|
231
358
|
data[0].longLatArr = circlePointsLongLat;
|
|
232
359
|
data[0].height = height;
|
|
360
|
+
data[0].msl = msl;
|
|
233
361
|
// Add to buffer orchestrator
|
|
234
|
-
this.bufferOrchestrator.insertBulk(data,
|
|
362
|
+
this.bufferOrchestrator.insertBulk(data, bufferManagersMap, [
|
|
363
|
+
this.globe?.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d",
|
|
364
|
+
]);
|
|
235
365
|
}
|
|
236
366
|
}
|
|
237
367
|
// this will be used to build static circles, which are not affected by camera position or LOD.
|
|
238
368
|
// LOD < 8 or something
|
|
239
369
|
__buildStaticCircles(subSetIDs = null) {
|
|
240
|
-
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator,
|
|
370
|
+
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
|
|
241
371
|
if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
|
|
242
|
-
!bufferOrchestrator || !
|
|
372
|
+
!bufferOrchestrator || !bufferManagersMap || !circleMap)
|
|
243
373
|
throw new Error("Plugin not initialized properly");
|
|
244
|
-
const
|
|
245
|
-
key: "",
|
|
246
|
-
longLatArr: [],
|
|
247
|
-
height: null,
|
|
248
|
-
color: [1, 1, 1, 1]
|
|
249
|
-
}];
|
|
374
|
+
const datas = [];
|
|
250
375
|
// ensure buffer orchestrotrator have enough capacity
|
|
251
376
|
// all circles are build with even sampling, AttractionLevel = 0
|
|
252
377
|
const templateAngles = AnglesStash[0];
|
|
253
378
|
const zeroRotation = 0;
|
|
379
|
+
let keys;
|
|
254
380
|
if (!subSetIDs || subSetIDs.length === 0) {
|
|
255
|
-
|
|
256
|
-
bufferOrchestrator.resetWithCapacity(
|
|
257
|
-
for (const [key, circle] of this.circleMap.entries()) {
|
|
258
|
-
const [{ radius, center, height = null, color = null }, _] = circle;
|
|
259
|
-
CircleCDF.globeFindPointByPolarHalfCircle(circlePointsLongLat, globe, center[0], center[1], radius, zeroRotation, templateAngles);
|
|
260
|
-
data[0].key = key;
|
|
261
|
-
data[0].longLatArr = circlePointsLongLat;
|
|
262
|
-
data[0].height = height;
|
|
263
|
-
data[0].color = color || this._styleOptions.defaultColor;
|
|
264
|
-
this.bufferOrchestrator.insertBulk(data, bufferManagerMap);
|
|
265
|
-
}
|
|
381
|
+
keys = Array.from(this.circleMap.keys());
|
|
382
|
+
// bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
|
|
266
383
|
}
|
|
267
384
|
else {
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
console.warn(`CircleOnTerrainPlugin: Circle ${key} not found in circleMap.`);
|
|
275
|
-
continue;
|
|
276
|
-
}
|
|
277
|
-
const [{ radius, center, height = null, color = null }, _] = this.circleMap.get(key);
|
|
278
|
-
const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
|
|
279
|
-
CircleCDF.globeFindPointByPolarHalfCircle(circlePointsLongLat, globe, center[0], center[1], radius, zeroRotation, templateAngles);
|
|
280
|
-
data[0].key = key;
|
|
281
|
-
data[0].longLatArr = circlePointsLongLat;
|
|
282
|
-
data[0].height = height;
|
|
283
|
-
data[0].color = color || this._styleOptions.defaultColor;
|
|
284
|
-
this.bufferOrchestrator.insertBulk(data, bufferManagerMap);
|
|
385
|
+
keys = subSetIDs;
|
|
386
|
+
}
|
|
387
|
+
for (let key of keys) {
|
|
388
|
+
if (!this.circleMap.has(key)) {
|
|
389
|
+
console.warn(`CircleOnTerrainPlugin: Circle ${key} not found in circleMap.`);
|
|
390
|
+
continue;
|
|
285
391
|
}
|
|
392
|
+
const [{ radius, center, height = null, color = null, msl = undefined }, _] = this.circleMap.get(key);
|
|
393
|
+
const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
|
|
394
|
+
CircleCDF.globeFindPointByPolarHalfCircle(circlePointsLongLat, globe, center[0], center[1], radius, zeroRotation, templateAngles);
|
|
395
|
+
datas.push({
|
|
396
|
+
key,
|
|
397
|
+
longLatArr: circlePointsLongLat,
|
|
398
|
+
height,
|
|
399
|
+
color: color || this._options.defaultColor,
|
|
400
|
+
msl
|
|
401
|
+
});
|
|
286
402
|
}
|
|
403
|
+
this.bufferOrchestrator.insertBulk(datas, bufferManagersMap, [this.globe?.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d"]);
|
|
287
404
|
}
|
|
288
405
|
// GLOBE API INTERFACE
|
|
289
406
|
draw3D() {
|
|
290
|
-
const {
|
|
291
|
-
if (
|
|
292
|
-
!
|
|
407
|
+
const { _freed, globe, gl, lineProgram, bufferOrchestrator, bufferManagersMap, _vao, _circleUBOHandler } = this;
|
|
408
|
+
if (_freed || !globe || !gl || !lineProgram || !bufferOrchestrator ||
|
|
409
|
+
!bufferManagersMap || !_vao || !_circleUBOHandler) {
|
|
293
410
|
return;
|
|
294
411
|
}
|
|
295
|
-
|
|
412
|
+
// if (globe.api_IsScreenMoving())
|
|
413
|
+
this._frameCounterTrigger?.trigger();
|
|
414
|
+
// this._buildCircles();
|
|
296
415
|
const drawOptions = {
|
|
297
416
|
drawRange: {
|
|
298
417
|
first: 0,
|
|
@@ -304,18 +423,18 @@ export class CircleOnTerrainPlugin {
|
|
|
304
423
|
gl.enable(gl.DEPTH_TEST);
|
|
305
424
|
}
|
|
306
425
|
free() {
|
|
307
|
-
if (this.
|
|
426
|
+
if (this._freed)
|
|
308
427
|
return;
|
|
309
|
-
this.
|
|
428
|
+
this._freed = true;
|
|
310
429
|
if (this.lineProgram) {
|
|
311
430
|
LineStripProgramCache.release(this.lineProgram);
|
|
312
431
|
this.lineProgram = null;
|
|
313
432
|
}
|
|
314
433
|
this.circleMap.clear();
|
|
315
|
-
this.
|
|
434
|
+
this.bufferManagersMap.forEach(({ bufferManager }) => {
|
|
316
435
|
bufferManager.free();
|
|
317
436
|
});
|
|
318
|
-
this.
|
|
437
|
+
this.bufferManagersMap.clear();
|
|
319
438
|
CameraUniformBlockTotemCache.release(this.globe);
|
|
320
439
|
}
|
|
321
440
|
}
|