@pirireis/webglobeplugins 0.15.21-alpha → 0.15.24

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 (33) 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/vec3.js +1 -1
  5. package/altitude-locator/plugin.js +1 -1
  6. package/package.json +1 -1
  7. package/point-tracks/plugin.js +5 -6
  8. package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
  9. package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
  10. package/programs/totems/camerauniformblock.js +7 -0
  11. package/programs/totems/canvas-webglobe-info.js +9 -9
  12. package/programs/totems/globe-changes.js +21 -14
  13. package/range-tools-on-terrain/bearing-line/plugin.js +2 -5
  14. package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +4 -9
  15. package/range-tools-on-terrain/circle-line-chain/plugin.js +4 -2
  16. package/range-tools-on-terrain/range-ring/adapters.js +25 -9
  17. package/range-tools-on-terrain/range-ring/plugin.js +200 -5
  18. package/range-tools-on-terrain/range-ring/types.js +9 -1
  19. package/semiplugins/lightweight/line-plugin.js +33 -15
  20. package/semiplugins/shape-on-terrain/arc-plugin.js +162 -99
  21. package/semiplugins/shape-on-terrain/circle-plugin.js +170 -83
  22. package/semiplugins/shape-on-terrain/padding-1-degree.js +244 -63
  23. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +1 -1
  24. package/util/build-strategy/static-dynamic.js +11 -1
  25. package/util/frame-counter-trigger.js +84 -0
  26. package/wind/imagetovectorfieldandmagnitude.js +23 -0
  27. package/wind/index.js +2 -2
  28. package/wind/plugin.js +30 -9
  29. package/write-text/context-text4.js +140 -0
  30. package/Math/arc-generate-points copy.js +0 -366
  31. package/Math/globe-util/horizon-plane.js +0 -112
  32. package/altitude-locator/draw-subset-obj.js +0 -16
  33. package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
@@ -7,6 +7,7 @@ import { globe3Dcoordinates, globe2Dcoordinates, RADIANS } from "../../Math/meth
7
7
  import { generateArcPoints, evenlySpacedArcPoints } from "../../Math/arc-cdf-points";
8
8
  import { StaticDynamicState, StaticDynamicStrategy } from "../../util/build-strategy/static-dynamic";
9
9
  import { opacityCheck } from "../../util/check/typecheck";
10
+ import { FrameCounterTrigger } from "../../util/frame-counter-trigger";
10
11
  import * as vec3 from "../../Math/vec3";
11
12
  import * as arc from "../../Math/arc";
12
13
  import { CameraUniformBlockTotemCache } from "../../programs/totems/camerauniformblock";
@@ -17,11 +18,16 @@ const _attractionPoint = [0, 0, 0];
17
18
  const _start = [0, 0, 0];
18
19
  const _end = [0, 0, 0];
19
20
  const _0arc = arc.create([1, 0, 0], [0, 1, 0]); // zero arc for intersection tests
21
+ function createArc(start, end) {
22
+ vec3.fromLongLatToUnitVector(_start, [start[0] * RADIANS, start[1] * RADIANS]);
23
+ vec3.fromLongLatToUnitVector(_end, [end[0] * RADIANS, end[1] * RADIANS]);
24
+ return arc.create(_start, _end);
25
+ }
20
26
  export class ArcOnTerrainPlugin {
21
27
  id;
22
28
  program = null;
23
- bufferManagerMap = null;
24
- _bufferOrchestrator = new BufferOrchestrator({ capacity: INITAL_CAPACITY });
29
+ bufferManagersMap = null;
30
+ bufferOrchestrator = new BufferOrchestrator({ capacity: INITAL_CAPACITY });
25
31
  _opacity = 1;
26
32
  _arcUBOHandler = null;
27
33
  _vao = null;
@@ -33,6 +39,7 @@ export class ArcOnTerrainPlugin {
33
39
  _options;
34
40
  _coordinaateBufferKeysForUpdate = [];
35
41
  _freed = false;
42
+ _frameCounterTrigger = null;
36
43
  constructor(id, { globeViewOn = true, // If true, arcs are drawn in 3D globe view
37
44
  flatViewOn = true, // If true, arcs are drawn in 2D flat view
38
45
  variativeColorsOn = false, defaultColor = [0.1, 0.1, 1, 1], // Default color in RGBA format
@@ -54,24 +61,69 @@ export class ArcOnTerrainPlugin {
54
61
  isMSL: isMSL ? true : false
55
62
  };
56
63
  }
64
+ increaseSpace(amount) {
65
+ if (this._freed) {
66
+ console.warn("Plugin is freed, cannot increase space");
67
+ return;
68
+ }
69
+ if (this.globe === null) {
70
+ console.warn("Globe is not initialized.");
71
+ return;
72
+ }
73
+ if (typeof amount !== "number" || amount <= 0) {
74
+ console.warn("Invalid amount, must be a positive number");
75
+ return;
76
+ }
77
+ this.bufferOrchestrator.ensureSpace(amount, this.bufferManagersMap);
78
+ }
57
79
  insertBulk(arcs) {
58
80
  const keys = [];
81
+ let newItemCount = 0;
59
82
  for (let arcInput of arcs) {
60
83
  const { key, start, end } = arcInput;
61
84
  if (this._arcMap.has(key)) {
62
- this._arcMap.delete(key);
85
+ this._arcMap.delete(key); // Remove old arc
86
+ }
87
+ else {
88
+ newItemCount++;
63
89
  }
64
- vec3.fromLongLatToUnitVector(_start, [start[0] * RADIANS, start[1] * RADIANS]);
65
- vec3.fromLongLatToUnitVector(_end, [end[0] * RADIANS, end[1] * RADIANS]);
66
- const _arc = arc.create(_start, _end);
67
- this._arcMap.set(key, [_arc, arcInput]); // height is null for now
90
+ const _arc = createArc(start, end);
91
+ this._arcMap.set(key, [_arc, arcInput]); // Always set new color
68
92
  keys.push(key);
69
93
  }
70
- this.__buildStaticArcs(keys, true);
94
+ this.bufferOrchestrator.ensureSpace(newItemCount, this.bufferManagersMap);
95
+ this._buildArcs(keys);
96
+ if (this._options.variativeColorsOn) {
97
+ this.__fillColors(keys);
98
+ }
99
+ this.globe.DrawRender();
100
+ }
101
+ updateCoordinates(items) {
102
+ if (this._freed) {
103
+ console.warn("Plugin is freed, cannot update coordinates");
104
+ return;
105
+ }
106
+ if (this.globe === null || this.gl === null) {
107
+ console.warn("Globe or WebGL context is not initialized, cannot update coordinates");
108
+ return;
109
+ }
110
+ const updateKeys = [];
111
+ for (const { key, start, end } of items) {
112
+ const arcInput = this._arcMap.get(key);
113
+ if (!arcInput) {
114
+ console.warn(`Arc with key ${key} not found in arcMap.`);
115
+ continue;
116
+ }
117
+ const _arc = createArc(start, end);
118
+ arc.copy(arcInput[0], _arc); // Update the arc in the map
119
+ // Update the arc in the buffer
120
+ updateKeys.push(key);
121
+ }
122
+ this._buildArcs(updateKeys);
71
123
  this.globe.DrawRender();
72
124
  }
73
125
  deleteBulk(keys) {
74
- if (!this._bufferOrchestrator || !this.bufferManagerMap || !this.globe) {
126
+ if (!this.bufferOrchestrator || !this.bufferManagersMap || !this.globe) {
75
127
  console.warn("Buffer orchestrator or buffer manager map is not initialized.");
76
128
  return;
77
129
  }
@@ -83,27 +135,35 @@ export class ArcOnTerrainPlugin {
83
135
  console.warn(`Arc with key ${key} not found in arcMap.`);
84
136
  }
85
137
  }
86
- this._bufferOrchestrator.deleteBulk(keys, this.bufferManagerMap);
138
+ this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
87
139
  this.globe.DrawRender();
88
140
  }
89
- updateColor(key, color) {
141
+ updateColors(keyColorCouples, drawRender = true) {
142
+ if (this._freed) {
143
+ console.warn("Plugin is freed, cannot update color");
144
+ return;
145
+ }
90
146
  if (this._options.variativeColorsOn === false) {
91
147
  console.warn("Variative colors are not enabled in this plugin. Create another instance with variativeColorsOn: true to use this feature.");
92
148
  return;
93
149
  }
94
- const { _bufferOrchestrator, bufferManagerMap } = this;
95
- if (!_bufferOrchestrator || !bufferManagerMap) {
150
+ const { bufferOrchestrator, bufferManagersMap } = this;
151
+ if (!bufferOrchestrator || !bufferManagersMap) {
96
152
  console.warn("Buffer orchestrator or buffer manager map is not initialized.");
97
153
  return;
98
154
  }
99
- const arcInput = this._arcMap.get(key);
100
- if (!arcInput) {
101
- console.warn(`Arc with key ${key} not found in arcMap.`);
102
- return;
155
+ for (const { key, color } of keyColorCouples) {
156
+ const arcInput = this._arcMap.get(key);
157
+ if (!arcInput) {
158
+ console.warn(`Arc with key ${key} not found in arcMap.`);
159
+ return;
160
+ }
161
+ arcInput[1].color = color; // Update the color in the arc map
162
+ bufferOrchestrator.updateBulk([{ key: key, color: color }], bufferManagersMap, ["color"]);
163
+ }
164
+ if (drawRender) {
165
+ this.globe.DrawRender();
103
166
  }
104
- arcInput[1].color = color; // Update the color in the arc map
105
- _bufferOrchestrator.updateBulk([{ key: key, color: color }], bufferManagerMap, ["color"]);
106
- this.globe.DrawRender();
107
167
  }
108
168
  setPluginOpacity(opacity, drawRender = false) {
109
169
  if (!this.globe || !this.gl) {
@@ -152,11 +212,18 @@ export class ArcOnTerrainPlugin {
152
212
  init(globe, gl) {
153
213
  this.globe = globe;
154
214
  this.gl = gl;
215
+ this._frameCounterTrigger = new FrameCounterTrigger(globe, 15, 1000, (globeChanges) => {
216
+ if (this._freed)
217
+ return;
218
+ this.__buildDynamicArcs();
219
+ });
155
220
  this.program = LineStripProgramCache.get(globe);
156
- this._staticDynamicStrategy = new StaticDynamicStrategy(globe, DYNAMIC_STRATEGY_START_LOD); // Initialize static-dynamic strategy with a transition level of 8
221
+ this._staticDynamicStrategy = new StaticDynamicStrategy(globe, DYNAMIC_STRATEGY_START_LOD, () => {
222
+ this.__buildStaticArcs();
223
+ }); // Initialize static-dynamic strategy with a transition level of 8
157
224
  this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
158
- this._fillBufferManagerMap();
159
- this._bufferOrchestrator = new BufferOrchestrator();
225
+ this._fillbufferManagersMap();
226
+ this.bufferOrchestrator = new BufferOrchestrator();
160
227
  this._arcUBOHandler = this.program.createUBO();
161
228
  this._arcUBOHandler.update(new Map([
162
229
  ["u_color", new Float32Array(this._options.defaultColor)],
@@ -170,11 +237,12 @@ export class ArcOnTerrainPlugin {
170
237
  }
171
238
  const globe = this.globe;
172
239
  this._staticDynamicStrategy?.updateState();
173
- if (globe.api_IsScreenMoving()) {
174
- this._buildArcs(); // can be async
175
- }
176
- const { gl, program, _bufferOrchestrator, _vao, _arcUBOHandler, } = this;
177
- if (!gl || !program || !_bufferOrchestrator || !_vao || !_arcUBOHandler) {
240
+ // if (globe.api_IsScreenMoving()) {
241
+ // this._buildArcs(); // can be async
242
+ // }
243
+ this._frameCounterTrigger?.trigger();
244
+ const { gl, program, bufferOrchestrator, _vao, _arcUBOHandler, } = this;
245
+ if (!gl || !program || !bufferOrchestrator || !_vao || !_arcUBOHandler) {
178
246
  console.warn("WebGL context, program, or buffer orchestrator is not initialized.");
179
247
  return;
180
248
  }
@@ -185,28 +253,31 @@ export class ArcOnTerrainPlugin {
185
253
  const drawOptions = {
186
254
  drawRange: {
187
255
  first: 0,
188
- count: _bufferOrchestrator.length * (this._options.vertexCount + 1)
256
+ count: bufferOrchestrator.length * (this._options.vertexCount + 1)
189
257
  },
190
258
  indexes: null
191
259
  };
192
260
  program.draw(_vao, drawOptions, this._opacity, _arcUBOHandler);
193
261
  gl.enable(gl.DEPTH_TEST);
194
262
  }
195
- _buildArcs() {
263
+ _buildArcs(subSetIDs = null) {
196
264
  const state = this._staticDynamicStrategy?.getState();
197
- if (state === StaticDynamicState.TO_STATIC) {
198
- this.__buildStaticArcs();
265
+ if (state === StaticDynamicState.DYNAMIC) {
266
+ this.__buildDynamicArcs(subSetIDs);
199
267
  }
200
- else if (state === StaticDynamicState.DYNAMIC) {
201
- this.__buildArcs();
268
+ else if (subSetIDs || state === StaticDynamicState.TO_STATIC) {
269
+ this.__buildStaticArcs(subSetIDs);
202
270
  }
203
271
  }
204
- __buildStaticArcs(keys = [], calledFromInsert = false) {
205
- const { globe, _arcMap, _cameraUniformBlock, bufferManagerMap, _bufferOrchestrator } = this;
206
- if (!globe || !_cameraUniformBlock || !bufferManagerMap || !_bufferOrchestrator) {
272
+ __buildStaticArcs(subSetIDs = null) {
273
+ const { globe, _arcMap, _cameraUniformBlock, bufferManagersMap, bufferOrchestrator } = this;
274
+ if (!globe || !_cameraUniformBlock || !bufferManagersMap || !bufferOrchestrator) {
207
275
  console.warn("Globe or camera uniform block is not initialized.");
208
276
  return;
209
277
  }
278
+ const bufferKey = [this.globe.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d"];
279
+ if (!this.bufferManagersMap?.has(bufferKey[0]))
280
+ return;
210
281
  const longLat = [0, 0];
211
282
  const _attractionStrength = 0;
212
283
  const longLatArr = new Float32Array(2 * this._options.vertexCount);
@@ -217,60 +288,40 @@ export class ArcOnTerrainPlugin {
217
288
  color: this._options.defaultColor,
218
289
  msl: null
219
290
  }];
220
- if (keys.length == 0) {
221
- for (const [key, [arcInstance, arcInput]] of _arcMap) {
222
- arc.copy(_0arc, arcInstance);
223
- const generatedPoints = evenlySpacedArcPoints(_0arc.p0, _0arc.normal, _0arc.coverAngle, this._options.vertexCount);
224
- for (let i = 0; i < generatedPoints.length; i++) {
225
- const point = generatedPoints[i];
226
- vec3.fromUnitVectorToLongLat(longLat, point);
227
- longLatArr.set([longLat[0] / RADIANS, longLat[1] / RADIANS], i * 2);
228
- }
229
- data[0].key = key;
230
- data[0].height = arcInput.height ?? this._options.defaultHeightFromGroundIn3D;
231
- data[0].color = arcInput.color ?? this._options.defaultColor;
232
- data[0].msl = arcInput.msl ?? null;
233
- if (calledFromInsert) {
234
- this._bufferOrchestrator.insertBulk(data, bufferManagerMap);
235
- }
236
- else {
237
- this._bufferOrchestrator.updateBulk(data, bufferManagerMap, this._coordinaateBufferKeysForUpdate);
238
- }
239
- }
291
+ let keys;
292
+ if (subSetIDs === null) {
293
+ keys = _arcMap.keys();
240
294
  }
241
295
  else {
242
- for (let key of keys) {
243
- if (!_arcMap.has(key)) {
244
- console.warn(`Arc with key ${key} not found in arcMap.`);
245
- continue;
246
- }
247
- const [arcInstance, arcInput] = _arcMap.get(key);
248
- arc.copy(_0arc, arcInstance);
249
- const generatedPoints = evenlySpacedArcPoints(_0arc.p0, _0arc.normal, _0arc.coverAngle, this._options.vertexCount);
250
- for (let i = 0; i < generatedPoints.length; i++) {
251
- const point = generatedPoints[i];
252
- vec3.fromUnitVectorToLongLat(longLat, point);
253
- longLatArr.set([longLat[0] / RADIANS, longLat[1] / RADIANS], i * 2);
254
- }
255
- data[0].key = key;
256
- data[0].height = arcInput.height ?? this._options.defaultHeightFromGroundIn3D;
257
- data[0].color = arcInput.color ?? this._options.defaultColor;
258
- data[0].msl = arcInput.msl ?? null;
259
- if (calledFromInsert) {
260
- this._bufferOrchestrator.insertBulk(data, bufferManagerMap);
261
- }
262
- else {
263
- this._bufferOrchestrator.updateBulk(data, bufferManagerMap, this._coordinaateBufferKeysForUpdate);
264
- }
296
+ keys = subSetIDs;
297
+ }
298
+ for (const key of keys) {
299
+ const [arcInstance, arcInput] = _arcMap.get(key);
300
+ arc.copy(_0arc, arcInstance);
301
+ const generatedPoints = evenlySpacedArcPoints(_0arc.p0, _0arc.normal, _0arc.coverAngle, this._options.vertexCount);
302
+ for (let i = 0; i < generatedPoints.length; i++) {
303
+ const point = generatedPoints[i];
304
+ vec3.fromUnitVectorToLongLat(longLat, point);
305
+ longLatArr.set([longLat[0] / RADIANS, longLat[1] / RADIANS], i * 2);
265
306
  }
307
+ data[0].key = key;
308
+ data[0].height = arcInput.height ?? this._options.defaultHeightFromGroundIn3D;
309
+ data[0].color = arcInput.color ?? this._options.defaultColor;
310
+ data[0].msl = arcInput.msl ?? null;
311
+ this.bufferOrchestrator.insertBulk(data, bufferManagersMap, bufferKey);
266
312
  }
267
313
  }
268
- __buildArcs() {
269
- const { globe, _arcMap, _cameraUniformBlock, bufferManagerMap } = this;
270
- if (!globe || !_cameraUniformBlock || !bufferManagerMap) {
314
+ __buildDynamicArcs(subSetIDs = null) {
315
+ const { globe, _arcMap, _cameraUniformBlock, bufferManagersMap } = this;
316
+ if (!globe || !_cameraUniformBlock || !bufferManagersMap) {
271
317
  console.warn("Globe or camera uniform block is not initialized.");
272
318
  return;
273
319
  }
320
+ const bufferKey = [
321
+ this.globe.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d"
322
+ ];
323
+ if (!this.bufferManagersMap?.has(bufferKey[0]))
324
+ return;
274
325
  const { cameraAttractionIsOn } = this._options;
275
326
  const lookAtPosition = _cameraUniformBlock.getLookAtVector();
276
327
  const cameraPosition = _cameraUniformBlock.getCameraVector();
@@ -288,7 +339,15 @@ export class ArcOnTerrainPlugin {
288
339
  })();
289
340
  const result = [];
290
341
  const longLat = [0, 0];
291
- for (const [key, [arcInstance, arcInput]] of _arcMap) {
342
+ let keys;
343
+ if (subSetIDs === null) {
344
+ keys = _arcMap.keys();
345
+ }
346
+ else {
347
+ keys = subSetIDs;
348
+ }
349
+ for (const key of keys) {
350
+ const [arcInstance, arcInput] = _arcMap.get(key);
292
351
  arc.copy(_0arc, arcInstance);
293
352
  const isOnArc = arc.closestPoint(_attractionPoint, _0arc, cameraPosition);
294
353
  if (!isOnArc) {
@@ -315,15 +374,10 @@ export class ArcOnTerrainPlugin {
315
374
  msl: arcInput.msl ?? null
316
375
  });
317
376
  }
318
- // this._bufferOrchestrator.resetWithCapacity(bufferManagerMap, result.length);
319
- const bufferNames = [];
320
- if (this._options.globeViewOn)
321
- bufferNames.push("position3d");
322
- if (this._options.flatViewOn)
323
- bufferNames.push("position2d");
324
- this._bufferOrchestrator.insertBulk(result, bufferManagerMap, bufferNames);
377
+ // this.bufferOrchestrator.resetWithCapacity(bufferManagersMap, result.length);
378
+ this.bufferOrchestrator.insertBulk(result, bufferManagersMap, bufferKey);
325
379
  }
326
- _fillBufferManagerMap() {
380
+ _fillbufferManagersMap() {
327
381
  const { gl, globe } = this;
328
382
  if (!gl || !globe) {
329
383
  console.warn("WebGL context or globe is not initialized.");
@@ -331,9 +385,9 @@ export class ArcOnTerrainPlugin {
331
385
  }
332
386
  const g2D = globe2Dcoordinates(globe);
333
387
  const { flatViewOn, globeViewOn, variativeColorsOn } = this._options;
334
- this.bufferManagerMap = new Map();
388
+ this.bufferManagersMap = new Map();
335
389
  if (globeViewOn) {
336
- this.bufferManagerMap.set("position3d", {
390
+ this.bufferManagersMap.set("position3d", {
337
391
  bufferManager: new BufferManager(gl, 3 * (this._options.vertexCount + 1), { bufferType: "STREAM_DRAW", initialCapacity: INITAL_CAPACITY }),
338
392
  adaptor: (item) => {
339
393
  const { longLatArr, height = this._options.defaultHeightFromGroundIn3D, msl = this._options.isMSL } = item;
@@ -343,7 +397,7 @@ export class ArcOnTerrainPlugin {
343
397
  });
344
398
  }
345
399
  if (flatViewOn) {
346
- this.bufferManagerMap.set("position2d", {
400
+ this.bufferManagersMap.set("position2d", {
347
401
  bufferManager: new BufferManager(gl, 2 * (this._options.vertexCount + 1), { bufferType: "STREAM_DRAW", initialCapacity: INITAL_CAPACITY }),
348
402
  adaptor: (item) => {
349
403
  const { longLatArr } = item;
@@ -352,8 +406,8 @@ export class ArcOnTerrainPlugin {
352
406
  });
353
407
  }
354
408
  if (this._options.variativeColorsOn) {
355
- const _colorArray = new Float32Array(4 * (this._options.vertexCount + 1));
356
- this.bufferManagerMap.set("color", {
409
+ const _colorArray = new Float32Array(4 * (this._options.vertexCount + 1)); // TODO: this could cause data races or unexpected overwrites.
410
+ this.bufferManagersMap.set("color", {
357
411
  bufferManager: new BufferManager(gl, 4 * (this._options.vertexCount + 1), { bufferType: "STREAM_DRAW", initialCapacity: INITAL_CAPACITY }),
358
412
  adaptor: (item) => {
359
413
  // Calculate color based on radius
@@ -378,7 +432,7 @@ export class ArcOnTerrainPlugin {
378
432
  return null;
379
433
  this._coordinaateBufferKeysForUpdate.push(key);
380
434
  // @ts-ignore
381
- const bufferManager = this.bufferManagerMap.get(key).bufferManager;
435
+ const bufferManager = this.bufferManagersMap.get(key).bufferManager;
382
436
  // @ts-ignore
383
437
  return createBufferAndReadInfo(bufferManager.buffer);
384
438
  });
@@ -388,6 +442,15 @@ export class ArcOnTerrainPlugin {
388
442
  bufferObjects[2] // color
389
443
  );
390
444
  }
445
+ __fillColors(subSetIDs) {
446
+ if (this._options.variativeColorsOn === false)
447
+ return;
448
+ const data = [null];
449
+ for (const id of subSetIDs) {
450
+ data[0] = this._arcMap.get(id)[1];
451
+ this.bufferOrchestrator.insertBulk(data, this.bufferManagersMap, ["color"]);
452
+ }
453
+ }
391
454
  free() {
392
455
  if (this._freed) {
393
456
  console.warn("Plugin already freed");
@@ -398,7 +461,7 @@ export class ArcOnTerrainPlugin {
398
461
  return;
399
462
  }
400
463
  this._arcUBOHandler?.free();
401
- this.bufferManagerMap?.forEach((manager) => {
464
+ this.bufferManagersMap?.forEach((manager) => {
402
465
  manager.bufferManager.free();
403
466
  });
404
467
  CameraUniformBlockTotemCache.release(this.globe);