@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.
Files changed (46) 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 +76 -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 +65 -47
  27. package/semiplugins/lightweight/piece-of-pie-plugin.js +50 -25
  28. package/semiplugins/shape-on-terrain/arc-plugin.js +197 -100
  29. package/semiplugins/shape-on-terrain/circle-plugin.js +209 -90
  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/write-text/context-text4.js +140 -0
  40. package/Math/arc-generate-points copy.js +0 -366
  41. package/Math/globe-util/horizon-plane.js +0 -112
  42. package/altitude-locator/draw-subset-obj.js +0 -16
  43. package/programs/line-on-globe/paddings/paddings.js +0 -1
  44. package/programs/rings/partial-ring/piece-of-pie copy.js +0 -286
  45. package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
  46. 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,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
- this.globe.DrawRender();
240
+ if (drawRender) {
241
+ this.globe.DrawRender();
242
+ }
179
243
  }
180
- setDefaultColor(color) {
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
- _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) {
190
308
  // @ts-ignore
191
309
  this._staticDynamicStrategy?.updateState();
192
310
  const state = this._staticDynamicStrategy?.getState();
193
- if (state === StaticDynamicState.TO_STATIC) {
194
- this.__buildStaticCircles();
311
+ if (state === StaticDynamicState.DYNAMIC) {
312
+ this.__buildDynamicCircles(subSetIDs);
195
313
  }
196
- else if (state === StaticDynamicState.DYNAMIC) {
197
- this.__buildCircles();
314
+ else if (subSetIDs || state === StaticDynamicState.TO_STATIC) {
315
+ this.__buildStaticCircles(subSetIDs);
198
316
  }
199
317
  }
200
- __buildCircles() {
201
- const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagerMap, circleMap } = this;
318
+ __buildDynamicCircles(subSetIDs = null) {
319
+ const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
202
320
  if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
203
- !bufferOrchestrator || !bufferManagerMap || !circleMap)
321
+ !bufferOrchestrator || !bufferManagersMap || !circleMap)
204
322
  throw new Error("Plugin not initialized properly");
205
323
  // unoptimized.. resets all circles.
206
- // bufferOrchestrator.resetWithCapacity(bufferManagerMap, circleMap.size);
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
- for (const [key, circle] of this.circleMap.entries()) {
221
- 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);
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, bufferManagerMap, ["position3d", "position2d"]);
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, bufferManagerMap, circleMap } = this;
370
+ const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
241
371
  if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
242
- !bufferOrchestrator || !bufferManagerMap || !circleMap)
372
+ !bufferOrchestrator || !bufferManagersMap || !circleMap)
243
373
  throw new Error("Plugin not initialized properly");
244
- const data = [{
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
- const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
256
- bufferOrchestrator.resetWithCapacity(bufferManagerMap, circleMap.size);
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
- // This does check the size beforehand.
269
- // subset is probably is used to insert a single item or,
270
- // rebuild of existing items which passed from rbushTree or similar indexed search.
271
- // therefore, it is not necessary to check for new items and extend capacity
272
- for (let key of subSetIDs) {
273
- if (!this.circleMap.has(key)) {
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 { _isFree, globe, gl, lineProgram, bufferOrchestrator, bufferManagerMap, _vao, _circleUBOHandler } = this;
291
- if (_isFree || !globe || !gl || !lineProgram || !bufferOrchestrator ||
292
- !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) {
293
410
  return;
294
411
  }
295
- this._buildCircles();
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._isFree)
426
+ if (this._freed)
308
427
  return;
309
- this._isFree = true;
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.bufferManagerMap.forEach(({ bufferManager }) => {
434
+ this.bufferManagersMap.forEach(({ bufferManager }) => {
316
435
  bufferManager.free();
317
436
  });
318
- this.bufferManagerMap.clear();
437
+ this.bufferManagersMap.clear();
319
438
  CameraUniformBlockTotemCache.release(this.globe);
320
439
  }
321
440
  }