@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
@@ -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
- bufferManagerMap = new Map();
62
+ bufferManagersMap = new Map();
62
63
  bufferOrchestrator = new BufferOrchestrator();
63
64
  circleMap = new Map();
64
65
  _cameraUniformBlock = null;
65
- _isFree = false;
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
- _styleOptions = {
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
- constructor(id, styleOptions = {}) {
79
+ _textDataPreAdaptor = undefined;
80
+ constructor(id, styleOptions = null) {
77
81
  this.id = id;
78
- this._styleOptions = { ...this._styleOptions, ...styleOptions };
79
- this._styleOptions.defaultColor = new Float32Array(this._styleOptions.defaultColor);
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.bufferManagerMap.set("position3d", {
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._styleOptions.defaultHeightFromGroundIn3D } = item;
95
- const result = globe3Dcoordinates(globe, height)(longLatArr, { paddingCount: 1, paddingValue: NaN });
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.bufferManagerMap.set("position2d", {
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._styleOptions.variativeColorsOn) {
108
- this.bufferManagerMap.set("color", {
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._styleOptions.defaultColor, i * 4);
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.bufferManagerMap.get("position3d")?.bufferManager.buffer), createBufferAndReadInfo(this.bufferManagerMap.get("position2d")?.bufferManager.buffer), this._styleOptions.variativeColorsOn ?
126
- createBufferAndReadInfo(this.bufferManagerMap.get("color")?.bufferManager.buffer) : null);
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._isFree)
158
+ if (this._freed)
132
159
  return;
133
160
  if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
134
- !this.bufferManagerMap || !this._vao || !this._circleUBOHandler) {
161
+ !this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
135
162
  throw new Error("Plugin not initialized properly");
136
163
  }
137
- //
138
- const fillStaticKeys = [];
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
- fillStaticKeys.push(circleInput.key);
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.__buildStaticCircles(fillStaticKeys);
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._isFree)
217
+ if (this._freed)
156
218
  return;
157
219
  if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
158
- !this.bufferManagerMap || !this._vao || !this._circleUBOHandler) {
220
+ !this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
159
221
  throw new Error("Plugin not initialized properly");
160
222
  }
161
- this.bufferOrchestrator.deleteBulk(keys, this.bufferManagerMap);
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,39 +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;
240
+ if (drawRender) {
241
+ this.globe.DrawRender();
242
+ }
243
+ }
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) {
259
+ if (!this.globe || !this.gl) {
260
+ console.warn("Globe or WebGL context is not initialized.");
261
+ return;
262
+ }
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);
178
292
  this.globe.DrawRender();
179
293
  }
180
294
  // IMPLICIT METHODS
181
- _buildCircles() {
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) {
182
308
  // @ts-ignore
183
309
  this._staticDynamicStrategy?.updateState();
184
310
  const state = this._staticDynamicStrategy?.getState();
185
- if (state === StaticDynamicState.TO_STATIC) {
186
- this.__buildStaticCircles();
311
+ if (state === StaticDynamicState.DYNAMIC) {
312
+ this.__buildDynamicCircles(subSetIDs);
187
313
  }
188
- else if (state === StaticDynamicState.DYNAMIC) {
189
- this.__buildCircles();
314
+ else if (subSetIDs || state === StaticDynamicState.TO_STATIC) {
315
+ this.__buildStaticCircles(subSetIDs);
190
316
  }
191
317
  }
192
- __buildCircles() {
193
- const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagerMap, circleMap } = this;
318
+ __buildDynamicCircles(subSetIDs = null) {
319
+ const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
194
320
  if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
195
- !bufferOrchestrator || !bufferManagerMap || !circleMap)
321
+ !bufferOrchestrator || !bufferManagersMap || !circleMap)
196
322
  throw new Error("Plugin not initialized properly");
197
323
  // unoptimized.. resets all circles.
198
- // bufferOrchestrator.resetWithCapacity(bufferManagerMap, circleMap.size);
324
+ // bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
199
325
  // Prepare the data for the buffers
200
326
  const data = [{
201
327
  key: "",
202
328
  longLatArr: [],
203
- height: null
329
+ height: null,
330
+ msl: null
204
331
  }];
205
332
  const lookAtPosition = _cameraUniformBlock.getLookAtVector();
206
333
  const cameraPosition = _cameraUniformBlock.getNormalizedCameraVector();
@@ -209,8 +336,16 @@ export class CircleOnTerrainPlugin {
209
336
  vec3.normalize(cameraPosition, cameraPosition);
210
337
  const currentLOD = globe.api_GetCurrentLODWithDecimal();
211
338
  const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
212
- for (const [key, circle] of this.circleMap.entries()) {
213
- const [{ radius, center, height = null }, circleForAzimuthCalc] = circle;
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);
214
349
  const closestAzimuthAngle = CircleMethods.closestAzimuthAngle(circleForAzimuthCalc, cameraPosition);
215
350
  const stregthLevel = defineStregthLevel(currentLOD, radius);
216
351
  if (stregthLevel < 0) {
@@ -222,69 +357,61 @@ export class CircleOnTerrainPlugin {
222
357
  data[0].key = key;
223
358
  data[0].longLatArr = circlePointsLongLat;
224
359
  data[0].height = height;
360
+ data[0].msl = msl;
225
361
  // Add to buffer orchestrator
226
- this.bufferOrchestrator.insertBulk(data, bufferManagerMap, ["position3d", "position2d"]);
362
+ this.bufferOrchestrator.insertBulk(data, bufferManagersMap, [
363
+ this.globe?.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d",
364
+ ]);
227
365
  }
228
366
  }
229
367
  // this will be used to build static circles, which are not affected by camera position or LOD.
230
368
  // LOD < 8 or something
231
369
  __buildStaticCircles(subSetIDs = null) {
232
- const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagerMap, circleMap } = this;
370
+ const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
233
371
  if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
234
- !bufferOrchestrator || !bufferManagerMap || !circleMap)
372
+ !bufferOrchestrator || !bufferManagersMap || !circleMap)
235
373
  throw new Error("Plugin not initialized properly");
236
- const data = [{
237
- key: "",
238
- longLatArr: [],
239
- height: null,
240
- color: [1, 1, 1, 1]
241
- }];
374
+ const datas = [];
242
375
  // ensure buffer orchestrotrator have enough capacity
243
376
  // all circles are build with even sampling, AttractionLevel = 0
244
377
  const templateAngles = AnglesStash[0];
245
378
  const zeroRotation = 0;
379
+ let keys;
246
380
  if (!subSetIDs || subSetIDs.length === 0) {
247
- const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
248
- bufferOrchestrator.resetWithCapacity(bufferManagerMap, circleMap.size);
249
- for (const [key, circle] of this.circleMap.entries()) {
250
- const [{ radius, center, height = null, color = null }, _] = circle;
251
- CircleCDF.globeFindPointByPolarHalfCircle(circlePointsLongLat, globe, center[0], center[1], radius, zeroRotation, templateAngles);
252
- data[0].key = key;
253
- data[0].longLatArr = circlePointsLongLat;
254
- data[0].height = height;
255
- data[0].color = color || this._styleOptions.defaultColor;
256
- this.bufferOrchestrator.insertBulk(data, bufferManagerMap);
257
- }
381
+ keys = Array.from(this.circleMap.keys());
382
+ // bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
258
383
  }
259
384
  else {
260
- // This does check the size beforehand.
261
- // subset is probably is used to insert a single item or,
262
- // rebuild of existing items which passed from rbushTree or similar indexed search.
263
- // therefore, it is not necessary to check for new items and extend capacity
264
- for (let key of subSetIDs) {
265
- if (!this.circleMap.has(key)) {
266
- console.warn(`CircleOnTerrainPlugin: Circle ${key} not found in circleMap.`);
267
- continue;
268
- }
269
- const [{ radius, center, height = null, color = null }, _] = this.circleMap.get(key);
270
- const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
271
- CircleCDF.globeFindPointByPolarHalfCircle(circlePointsLongLat, globe, center[0], center[1], radius, zeroRotation, templateAngles);
272
- data[0].key = key;
273
- data[0].longLatArr = circlePointsLongLat;
274
- data[0].height = height;
275
- data[0].color = color || this._styleOptions.defaultColor;
276
- 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;
277
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
+ });
278
402
  }
403
+ this.bufferOrchestrator.insertBulk(datas, bufferManagersMap, [this.globe?.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d"]);
279
404
  }
280
405
  // GLOBE API INTERFACE
281
406
  draw3D() {
282
- const { _isFree, globe, gl, lineProgram, bufferOrchestrator, bufferManagerMap, _vao, _circleUBOHandler } = this;
283
- if (_isFree || !globe || !gl || !lineProgram || !bufferOrchestrator ||
284
- !bufferManagerMap || !_vao || !_circleUBOHandler) {
407
+ const { _freed, globe, gl, lineProgram, bufferOrchestrator, bufferManagersMap, _vao, _circleUBOHandler } = this;
408
+ if (_freed || !globe || !gl || !lineProgram || !bufferOrchestrator ||
409
+ !bufferManagersMap || !_vao || !_circleUBOHandler) {
285
410
  return;
286
411
  }
287
- this._buildCircles();
412
+ // if (globe.api_IsScreenMoving())
413
+ this._frameCounterTrigger?.trigger();
414
+ // this._buildCircles();
288
415
  const drawOptions = {
289
416
  drawRange: {
290
417
  first: 0,
@@ -296,18 +423,18 @@ export class CircleOnTerrainPlugin {
296
423
  gl.enable(gl.DEPTH_TEST);
297
424
  }
298
425
  free() {
299
- if (this._isFree)
426
+ if (this._freed)
300
427
  return;
301
- this._isFree = true;
428
+ this._freed = true;
302
429
  if (this.lineProgram) {
303
430
  LineStripProgramCache.release(this.lineProgram);
304
431
  this.lineProgram = null;
305
432
  }
306
433
  this.circleMap.clear();
307
- this.bufferManagerMap.forEach(({ bufferManager }) => {
434
+ this.bufferManagersMap.forEach(({ bufferManager }) => {
308
435
  bufferManager.free();
309
436
  });
310
- this.bufferManagerMap.clear();
437
+ this.bufferManagersMap.clear();
311
438
  CameraUniformBlockTotemCache.release(this.globe);
312
439
  }
313
440
  }