@pirireis/webglobeplugins 0.15.2-3.alpha → 0.15.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 (45) hide show
  1. package/Math/arc-generate-points copy.js +366 -0
  2. package/Math/arc.js +2 -1
  3. package/Math/circle-cdf-points.js +170 -1
  4. package/Math/circle.js +25 -0
  5. package/Math/globe-util/horizon-plane.js +112 -0
  6. package/Math/methods.js +2 -2
  7. package/Math/vec3.js +2 -6
  8. package/altitude-locator/draw-subset-obj.js +16 -0
  9. package/altitude-locator/plugin.js +1 -1
  10. package/bearing-line/plugin.js +2 -3
  11. package/package.json +1 -1
  12. package/point-tracks/plugin.js +22 -82
  13. package/programs/line-on-globe/lines-color-instanced-flat.js +1 -0
  14. package/programs/line-on-globe/linestrip/linestrip.js +28 -2
  15. package/programs/line-on-globe/paddings/paddings.js +1 -0
  16. package/programs/point-on-globe/element-globe-surface-glow.js +1 -0
  17. package/programs/rings/partial-ring/piece-of-pie copy.js +286 -0
  18. package/programs/totems/camerauniformblock.js +0 -7
  19. package/programs/totems/canvas-webglobe-info.js +9 -9
  20. package/range-tools-on-terrain/bearing-line/adapters.js +5 -8
  21. package/range-tools-on-terrain/bearing-line/plugin.js +20 -95
  22. package/range-tools-on-terrain/circle-line-chain/adapters.js +8 -15
  23. package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +12 -16
  24. package/range-tools-on-terrain/circle-line-chain/plugin.js +11 -67
  25. package/range-tools-on-terrain/range-ring/adapters.js +6 -74
  26. package/range-tools-on-terrain/range-ring/plugin.js +7 -222
  27. package/range-tools-on-terrain/range-ring/types.js +1 -9
  28. package/semiplugins/lightweight/line-plugin.js +47 -65
  29. package/semiplugins/lightweight/piece-of-pie-plugin.js +18 -44
  30. package/semiplugins/shape-on-terrain/arc-plugin.js +100 -197
  31. package/semiplugins/shape-on-terrain/circle-plugin.js +90 -209
  32. package/semiplugins/shape-on-terrain/derived/padding-plugin.js +101 -0
  33. package/semiplugins/shape-on-terrain/one-degree-padding.js +85 -0
  34. package/util/account/single-attribute-buffer-management/buffer-manager.js +0 -10
  35. package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +8 -145
  36. package/util/account/single-attribute-buffer-management/object-store.js +0 -7
  37. package/util/build-strategy/static-dynamic.js +1 -11
  38. package/util/check/typecheck.js +0 -12
  39. package/util/geometry/index.js +1 -2
  40. package/programs/totems/globe-changes.js +0 -59
  41. package/semiplugins/interface.js +0 -1
  42. package/semiplugins/shape-on-terrain/padding-1-degree.js +0 -538
  43. package/util/account/single-attribute-buffer-management/buffer-orchestrator1.js +0 -159
  44. package/util/frame-counter-trigger.js +0 -84
  45. package/write-text/context-text4.js +0 -140
@@ -9,7 +9,6 @@ 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";
13
12
  const ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL = 8;
14
13
  const CIRCLE_POINTS_COUNT_HALF = 65; // Half of the points plus one for the reflection
15
14
  const CIRCLE_POINTS_COUNT = CIRCLE_POINTS_COUNT_HALF * 2 - 1; // Number of points to approximate the circle
@@ -59,47 +58,45 @@ export class CircleOnTerrainPlugin {
59
58
  globe = null;
60
59
  gl = null;
61
60
  lineProgram = null;
62
- bufferManagersMap = new Map();
61
+ bufferManagerMap = new Map();
63
62
  bufferOrchestrator = new BufferOrchestrator();
64
63
  circleMap = new Map();
65
64
  _cameraUniformBlock = null;
66
- _freed = false;
65
+ _isFree = false;
67
66
  _circleUBOHandler = null;
68
67
  _opacity = 1;
69
68
  _vao = null;
70
69
  _dobuild = true; // This is used to trigger the build of circles when the camera position changes.
71
- _frameCounterTrigger = null;
72
70
  _staticDynamicStrategy = null;
73
- _options = {
71
+ _styleOptions = {
74
72
  variativeColorsOn: false,
75
73
  defaultColor: [0.1, 0.1, 0.1, 1], // Default color in RGBA format
76
- defaultHeightFromGroundIn3D: 30.0,
77
- isMSL: false
74
+ defaultHeightFromGroundIn3D: 30.0
78
75
  };
79
- _textDataPreAdaptor = undefined;
80
- constructor(id, styleOptions = null) {
76
+ constructor(id, styleOptions = {}) {
81
77
  this.id = id;
82
- if (styleOptions) {
83
- this._options = { ...this._options, ...styleOptions };
84
- }
78
+ this._styleOptions = { ...this._styleOptions, ...styleOptions };
79
+ this._styleOptions.defaultColor = new Float32Array(this._styleOptions.defaultColor);
85
80
  }
86
81
  init(globe, gl) {
87
82
  this.globe = globe;
88
83
  this.gl = gl;
89
84
  // Initialize the program cache for line strip rendering.
85
+ this._staticDynamicStrategy = new StaticDynamicStrategy(globe, ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL);
90
86
  this.lineProgram = LineStripProgramCache.get(globe);
87
+ // const g3D = globe3Dcoordinates(globe, 30);
91
88
  const g2D = globe2Dcoordinates(globe);
92
89
  // Initialize with a reasonable initial capacity to prevent buffer size issues
93
90
  const initialCapacity = 100; // Start with capacity for 100 circles
94
- this.bufferManagersMap.set("position3d", {
91
+ this.bufferManagerMap.set("position3d", {
95
92
  bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 3, { initialCapacity }), // plus 1 is for butting linestrips
96
93
  adaptor: (item) => {
97
- const { longLatArr, height = this._options.defaultHeightFromGroundIn3D, msl = this._options.isMSL } = item;
98
- const result = globe3Dcoordinates(globe, longLatArr, height, msl, { paddingCount: 1, paddingValue: NaN });
94
+ const { longLatArr, height = this._styleOptions.defaultHeightFromGroundIn3D } = item;
95
+ const result = globe3Dcoordinates(globe, height)(longLatArr, { paddingCount: 1, paddingValue: NaN });
99
96
  return result;
100
97
  }
101
98
  });
102
- this.bufferManagersMap.set("position2d", {
99
+ this.bufferManagerMap.set("position2d", {
103
100
  bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 2, { initialCapacity }),
104
101
  adaptor: (item) => {
105
102
  const { longLatArr } = item;
@@ -107,8 +104,8 @@ export class CircleOnTerrainPlugin {
107
104
  return result;
108
105
  }
109
106
  });
110
- if (this._options.variativeColorsOn) {
111
- this.bufferManagersMap.set("color", {
107
+ if (this._styleOptions.variativeColorsOn) {
108
+ this.bufferManagerMap.set("color", {
112
109
  bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 4, { initialCapacity }),
113
110
  adaptor: (item) => {
114
111
  if (item.color) {
@@ -118,109 +115,50 @@ export class CircleOnTerrainPlugin {
118
115
  }
119
116
  else {
120
117
  for (let i = 0; i < CIRCLE_POINTS_COUNT; i++) {
121
- _colorArray.set(this._options.defaultColor, i * 4);
118
+ _colorArray.set(this._styleOptions.defaultColor, i * 4);
122
119
  }
123
120
  }
124
121
  return _colorArray;
125
122
  }
126
123
  });
127
124
  }
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);
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);
130
127
  this._circleUBOHandler = this.lineProgram.createUBO();
131
- this.setDefaultColor(this._options.defaultColor);
132
128
  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);
156
129
  }
157
130
  insertBulk(circles) {
158
- if (this._freed)
131
+ if (this._isFree)
159
132
  return;
160
133
  if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
161
- !this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
134
+ !this.bufferManagerMap || !this._vao || !this._circleUBOHandler) {
162
135
  throw new Error("Plugin not initialized properly");
163
136
  }
164
- const keys = [];
165
- let newItemCount = 0;
137
+ //
138
+ const fillStaticKeys = [];
166
139
  for (const circleInput of circles) {
167
140
  if (!circleInput.key || !circleInput.center || !circleInput.radius) {
168
141
  console.warn(`CircleOnTerrainPlugin: Circle input is missing required properties: ${circleInput.radius} or ${circleInput.center} or ${circleInput.key}`);
169
142
  continue;
170
143
  }
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
- }
144
+ fillStaticKeys.push(circleInput.key);
179
145
  const circleForAzimuthCalc = CircleMethods.createCircleClosestAzimuthAngleProperties(circleInput);
180
146
  this.circleMap.set(circleInput.key, [circleInput, circleForAzimuthCalc]);
181
- }
182
- this.bufferOrchestrator.ensureSpace(newItemCount, this.bufferManagersMap);
183
- this._buildCircles(keys);
184
- if (this._options.variativeColorsOn) {
185
- this.__fillColor(keys);
186
- }
187
- this.globe.DrawRender();
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.`);
147
+ if (this._staticDynamicStrategy?.getState() !== StaticDynamicState.DYNAMIC) {
148
+ fillStaticKeys.push(circleInput.key);
210
149
  }
211
150
  }
212
- if (drawRender) {
213
- this.globe.DrawRender();
214
- }
151
+ this.__buildStaticCircles(fillStaticKeys);
152
+ this.globe.DrawRender();
215
153
  }
216
154
  deleteBulk(keys) {
217
- if (this._freed)
155
+ if (this._isFree)
218
156
  return;
219
157
  if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
220
- !this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
158
+ !this.bufferManagerMap || !this._vao || !this._circleUBOHandler) {
221
159
  throw new Error("Plugin not initialized properly");
222
160
  }
223
- this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
161
+ this.bufferOrchestrator.deleteBulk(keys, this.bufferManagerMap);
224
162
  for (const key of keys) {
225
163
  if (this.circleMap.has(key)) {
226
164
  this.circleMap.delete(key);
@@ -230,104 +168,47 @@ export class CircleOnTerrainPlugin {
230
168
  }
231
169
  }
232
170
  }
233
- setPluginOpacity(opacity, drawRender = false) {
171
+ setPluginOpacity(opacity) {
234
172
  if (!this.globe || !this.gl) {
235
173
  console.warn("Globe or WebGL context is not initialized.");
236
174
  return;
237
175
  }
238
176
  opacityCheck(opacity);
239
177
  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();
178
+ this.globe.DrawRender();
257
179
  }
258
- setDefaultColor(color, drawRender = false) {
180
+ setDefaultColor(color) {
259
181
  if (!this.globe || !this.gl) {
260
182
  console.warn("Globe or WebGL context is not initialized.");
261
183
  return;
262
184
  }
263
185
  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);
292
186
  this.globe.DrawRender();
293
187
  }
294
188
  // IMPLICIT METHODS
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) {
189
+ _buildCircles() {
308
190
  // @ts-ignore
309
191
  this._staticDynamicStrategy?.updateState();
310
192
  const state = this._staticDynamicStrategy?.getState();
311
- if (state === StaticDynamicState.DYNAMIC) {
312
- this.__buildDynamicCircles(subSetIDs);
193
+ if (state === StaticDynamicState.TO_STATIC) {
194
+ this.__buildStaticCircles();
313
195
  }
314
- else if (subSetIDs || state === StaticDynamicState.TO_STATIC) {
315
- this.__buildStaticCircles(subSetIDs);
196
+ else if (state === StaticDynamicState.DYNAMIC) {
197
+ this.__buildCircles();
316
198
  }
317
199
  }
318
- __buildDynamicCircles(subSetIDs = null) {
319
- const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
200
+ __buildCircles() {
201
+ const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagerMap, circleMap } = this;
320
202
  if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
321
- !bufferOrchestrator || !bufferManagersMap || !circleMap)
203
+ !bufferOrchestrator || !bufferManagerMap || !circleMap)
322
204
  throw new Error("Plugin not initialized properly");
323
205
  // unoptimized.. resets all circles.
324
- // bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
206
+ // bufferOrchestrator.resetWithCapacity(bufferManagerMap, circleMap.size);
325
207
  // Prepare the data for the buffers
326
208
  const data = [{
327
209
  key: "",
328
210
  longLatArr: [],
329
- height: null,
330
- msl: null
211
+ height: null
331
212
  }];
332
213
  const lookAtPosition = _cameraUniformBlock.getLookAtVector();
333
214
  const cameraPosition = _cameraUniformBlock.getNormalizedCameraVector();
@@ -336,16 +217,8 @@ export class CircleOnTerrainPlugin {
336
217
  vec3.normalize(cameraPosition, cameraPosition);
337
218
  const currentLOD = globe.api_GetCurrentLODWithDecimal();
338
219
  const circlePointsLongLat = new Float64Array((CIRCLE_POINTS_COUNT) * 2);
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);
220
+ for (const [key, circle] of this.circleMap.entries()) {
221
+ const [{ radius, center, height = null }, circleForAzimuthCalc] = circle;
349
222
  const closestAzimuthAngle = CircleMethods.closestAzimuthAngle(circleForAzimuthCalc, cameraPosition);
350
223
  const stregthLevel = defineStregthLevel(currentLOD, radius);
351
224
  if (stregthLevel < 0) {
@@ -357,61 +230,69 @@ export class CircleOnTerrainPlugin {
357
230
  data[0].key = key;
358
231
  data[0].longLatArr = circlePointsLongLat;
359
232
  data[0].height = height;
360
- data[0].msl = msl;
361
233
  // Add to buffer orchestrator
362
- this.bufferOrchestrator.insertBulk(data, bufferManagersMap, [
363
- this.globe?.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d",
364
- ]);
234
+ this.bufferOrchestrator.insertBulk(data, bufferManagerMap, ["position3d", "position2d"]);
365
235
  }
366
236
  }
367
237
  // this will be used to build static circles, which are not affected by camera position or LOD.
368
238
  // LOD < 8 or something
369
239
  __buildStaticCircles(subSetIDs = null) {
370
- const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
240
+ const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagerMap, circleMap } = this;
371
241
  if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
372
- !bufferOrchestrator || !bufferManagersMap || !circleMap)
242
+ !bufferOrchestrator || !bufferManagerMap || !circleMap)
373
243
  throw new Error("Plugin not initialized properly");
374
- const datas = [];
244
+ const data = [{
245
+ key: "",
246
+ longLatArr: [],
247
+ height: null,
248
+ color: [1, 1, 1, 1]
249
+ }];
375
250
  // ensure buffer orchestrotrator have enough capacity
376
251
  // all circles are build with even sampling, AttractionLevel = 0
377
252
  const templateAngles = AnglesStash[0];
378
253
  const zeroRotation = 0;
379
- let keys;
380
254
  if (!subSetIDs || subSetIDs.length === 0) {
381
- keys = Array.from(this.circleMap.keys());
382
- // bufferOrchestrator.resetWithCapacity(bufferManagersMap, circleMap.size);
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
+ }
383
266
  }
384
267
  else {
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;
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);
391
285
  }
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
- });
402
286
  }
403
- this.bufferOrchestrator.insertBulk(datas, bufferManagersMap, [this.globe?.api_GetCurrentGeometry() === 0 ? "position3d" : "position2d"]);
404
287
  }
405
288
  // GLOBE API INTERFACE
406
289
  draw3D() {
407
- const { _freed, globe, gl, lineProgram, bufferOrchestrator, bufferManagersMap, _vao, _circleUBOHandler } = this;
408
- if (_freed || !globe || !gl || !lineProgram || !bufferOrchestrator ||
409
- !bufferManagersMap || !_vao || !_circleUBOHandler) {
290
+ const { _isFree, globe, gl, lineProgram, bufferOrchestrator, bufferManagerMap, _vao, _circleUBOHandler } = this;
291
+ if (_isFree || !globe || !gl || !lineProgram || !bufferOrchestrator ||
292
+ !bufferManagerMap || !_vao || !_circleUBOHandler) {
410
293
  return;
411
294
  }
412
- // if (globe.api_IsScreenMoving())
413
- this._frameCounterTrigger?.trigger();
414
- // this._buildCircles();
295
+ this._buildCircles();
415
296
  const drawOptions = {
416
297
  drawRange: {
417
298
  first: 0,
@@ -423,18 +304,18 @@ export class CircleOnTerrainPlugin {
423
304
  gl.enable(gl.DEPTH_TEST);
424
305
  }
425
306
  free() {
426
- if (this._freed)
307
+ if (this._isFree)
427
308
  return;
428
- this._freed = true;
309
+ this._isFree = true;
429
310
  if (this.lineProgram) {
430
311
  LineStripProgramCache.release(this.lineProgram);
431
312
  this.lineProgram = null;
432
313
  }
433
314
  this.circleMap.clear();
434
- this.bufferManagersMap.forEach(({ bufferManager }) => {
315
+ this.bufferManagerMap.forEach(({ bufferManager }) => {
435
316
  bufferManager.free();
436
317
  });
437
- this.bufferManagersMap.clear();
318
+ this.bufferManagerMap.clear();
438
319
  CameraUniformBlockTotemCache.release(this.globe);
439
320
  }
440
321
  }
@@ -0,0 +1,101 @@
1
+ import { ArcOnTerrainPlugin } from "../arc-plugin";
2
+ const EDGE_COUNT = 5;
3
+ const paddingKeys = (padding) => {
4
+ const stepCount = padding.coverAngle / padding.stepAngle;
5
+ const keys = new Array(Math.ceil(stepCount));
6
+ for (let i = 0; i < stepCount; i++) {
7
+ keys[i] = padding.key + i;
8
+ }
9
+ if (keys.length > stepCount) {
10
+ keys[keys.length - 1] = padding.key + stepCount;
11
+ }
12
+ return keys;
13
+ };
14
+ const adapterPadding2Arc = (globe, padding) => {
15
+ const stepCount = padding.coverAngle / padding.stepAngle;
16
+ const result = new Array(Math.ceil(stepCount));
17
+ const fill = (i, angle) => {
18
+ const startPoint = globe.Math.FindPointByPolar(padding.center[0], padding.center[1], padding.outerRadius, angle);
19
+ const endPoint = globe.Math.FindPointByPolar(padding.center[0], padding.center[1], padding.innerRadius, angle);
20
+ result[i] = {
21
+ key: padding.key + i,
22
+ start: [startPoint.long, startPoint.lat],
23
+ end: [endPoint.long, endPoint.lat],
24
+ color: padding.color,
25
+ height: padding.height,
26
+ };
27
+ };
28
+ for (let i = 0; i < stepCount; i++) {
29
+ const angle = padding.startAngle + i * padding.stepAngle;
30
+ fill(i, angle);
31
+ }
32
+ if (result.length > stepCount) {
33
+ const i = result.length - 1;
34
+ const angle = padding.startAngle + padding.coverAngle;
35
+ fill(i, angle);
36
+ }
37
+ return result;
38
+ };
39
+ export const chargerAdaptor = (chargerInput, plugin, padding) => {
40
+ };
41
+ export class PaddingPlugin {
42
+ id;
43
+ arcPlugin;
44
+ globe = null;
45
+ _memory = new Map();
46
+ isFreed = false;
47
+ constructor(id, { variativeColorsOn = true, defaultColor = [1, 1, 1, 1], defaultHeightFromGroundIn3D = 30.0, vertexCount = EDGE_COUNT } = {}) {
48
+ this.id = id;
49
+ this.arcPlugin = new ArcOnTerrainPlugin(id, {
50
+ cameraAttractionIsOn: false,
51
+ vertexCount: vertexCount,
52
+ variativeColorsOn: variativeColorsOn,
53
+ defaultColor: defaultColor,
54
+ defaultHeightFromGroundIn3D: defaultHeightFromGroundIn3D,
55
+ });
56
+ }
57
+ insertBulk(items) {
58
+ for (const padding of items) {
59
+ this.__delete(padding.key);
60
+ this._memory.set(padding.key, padding);
61
+ }
62
+ const arcInputs = items.flatMap(padding => adapterPadding2Arc(this.globe, padding));
63
+ this.arcPlugin.insertBulk(arcInputs);
64
+ }
65
+ deleteBulk(keys) {
66
+ const arcKeys = keys.flatMap(key => paddingKeys({ key, center: [0, 0], outerRadius: 0, innerRadius: 0, startAngle: 0, coverAngle: 0, stepAngle: 0, color: [0, 0, 0, 1] }));
67
+ this.arcPlugin.deleteBulk(arcKeys);
68
+ }
69
+ updateColor(key, color) {
70
+ // TODO: get all padding keys and update all of them
71
+ if (!this._memory.has(key)) {
72
+ console.warn(`Padding with key ${key} does not exist.`);
73
+ return;
74
+ }
75
+ const keys = paddingKeys(this._memory.get(key));
76
+ for (let i = 0; i < keys.length; i++) {
77
+ this.arcPlugin.updateColor(keys[i], color);
78
+ }
79
+ }
80
+ __delete(key) {
81
+ const padding = this._memory.get(key);
82
+ if (padding) {
83
+ const keys = paddingKeys(padding);
84
+ this.arcPlugin.deleteBulk(keys);
85
+ this._memory.delete(key);
86
+ }
87
+ }
88
+ init(globe, gl) {
89
+ this.globe = globe;
90
+ this.arcPlugin.init(globe, gl);
91
+ }
92
+ draw3D() {
93
+ this.arcPlugin.draw3D();
94
+ }
95
+ free() {
96
+ if (this.isFreed)
97
+ return;
98
+ this.isFreed = true;
99
+ this.arcPlugin.free();
100
+ }
101
+ }
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ // // One Degree Padding
3
+ // /**
4
+ // * 2d coordinates are loaded ones
5
+ // * 3d coordinates are calculated on the fly.
6
+ // *
7
+ // * 2d paddings are fixed size
8
+ // * 3d paddings gets shortened as lod increases
9
+ // *
10
+ // * color buffer is shared and does not change on unless insert or delete
11
+ // * changing color can be done by re inserting
12
+ // *
13
+ // *
14
+ // *
15
+ // */
16
+ // import { Globe, LongLat, Meter, Color } from '../../types';
17
+ // import { BufferManagersMap } from '../../util/account/single-attribute-buffer-management/types';
18
+ // import { BufferManager } from '../../util/account/single-attribute-buffer-management/buffer-manager';
19
+ // import { BufferOrchestrator } from '../../util/acconut/single-attribute-buffer-management/buffer-orchestrator';
20
+ // import { LineStripProgramCache, LineProgram } from '../../programs/line-on-globe/linestrip/linestrip';
21
+ // import { ProgramInterface } from '../../types';
22
+ // export type OneDegreePaddingInput = {
23
+ // key: string;
24
+ // center: LongLat;
25
+ // outerRadius: Meter;
26
+ // color: Color;
27
+ // };
28
+ // const _float32Array = new Float32Array(360 * 3 * 2).fill(NaN);
29
+ // export class Paddings1Degree implements ProgramInterface {
30
+ // id: string;
31
+ // private globe: Globe | null = null;
32
+ // private bufferOrchestrator: BufferOrchestrator;
33
+ // private bufferManagersMap: BufferManagersMap;
34
+ // private lineProgram: LineProgram | null = null;
35
+ // private _LODCoeffecientForPaddingScale: number = 1;
36
+ // private _PaddingSizeRatio = 0.1; // 0.1 means 10% of the padding size is used for 3d padding
37
+ // private _finalPaddingSizeRatio = 0.1; // this._LODCoefficientForPaddingScale * this._PaddingSizeRatio; // final padding size ratio is the product of LOD coefficient and padding size ratio
38
+ // constructor(id: string, { capacity = 1000 } = {}) {
39
+ // this.id = id;
40
+ // this.bufferOrchestrator = new BufferOrchestrator({ capacity });
41
+ // this.bufferManagersMap = new Map();
42
+ // this.lineProgram = null;
43
+ // }
44
+ // init(globe: Globe): void {
45
+ // this.globe = globe;
46
+ // this.lineProgram = LineStripProgramCache.get(globe);
47
+ // }
48
+ // __updateLODCoefficientForPaddingScale(): void {
49
+ // // TODO: call this ones when lod changes or each frame // maybe only on 3d geometry
50
+ // }
51
+ // __fillBufferManagersMap() {
52
+ // const globe = this.globe as Globe;
53
+ // const gl = globe.gl as WebGL2RenderingContext;
54
+ // this.bufferManagersMap.set("position2d", {
55
+ // bufferManager: new BufferManager(gl,
56
+ // 360 * (2 + 1), // plus 1 to cut
57
+ // { bufferType: "STATIC_DRAW", initialCapacity: 10 }),
58
+ // adaptor: (PaddingInput: OneDegreePaddingInput) => {
59
+ // for (let i = 0; i < 360; i++) {
60
+ // let { long, lat } = globe.Math.FindPointByPolar(
61
+ // PaddingInput.center[0], // center long
62
+ // PaddingInput.center[1], // center lat
63
+ // PaddingInput.outerRadius, // outer radius
64
+ // i, // angle
65
+ // )
66
+ // let corrds = globe.api_GetMercator2DPoint(long, lat);
67
+ // // fill the second coordinate with 0
68
+ // _float32Array[i * 3] = corrds[0];
69
+ // _float32Array[i * 3 + 1] = corrds[1];
70
+ // ({ long, lat } = globe.Math.FindPointByPolar(
71
+ // PaddingInput.center[0], // center long
72
+ // PaddingInput.center[1], // center lat
73
+ // PaddingInput.outerRadius * this._finalPaddingSizeRatio, // inner radius
74
+ // i, // angle
75
+ // ));
76
+ // let innerCorrds = globe.api_GetMercator2DPoint(long, lat);
77
+ // // fill the second coordinate with 0
78
+ // _float32Array[i * 3 + 2] = innerCorrds[0];
79
+ // _float32Array[i * 3 + 3] = innerCorrds[1];
80
+ // }
81
+ // return _float32Array;
82
+ // }
83
+ // });
84
+ // // Other methods like draw, insertBulk, deleteBulk, etc. would go here
85
+ // }
@@ -60,16 +60,6 @@ export class BufferManager {
60
60
  }
61
61
  gl.bindBuffer(gl.ARRAY_BUFFER, null);
62
62
  }
63
- insertBlock(items, offset, adapter, Constructor = Float32Array) {
64
- const { gl, buffer, itemSize } = this;
65
- const cpuBuffer = new Constructor(itemSize * items.length);
66
- for (let i = 0; i < items.length; i++) {
67
- cpuBuffer.set(adapter(items[i]), i * itemSize);
68
- }
69
- gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
70
- gl.bufferSubData(gl.ARRAY_BUFFER, offset * itemSize * 4, cpuBuffer);
71
- gl.bindBuffer(gl.ARRAY_BUFFER, null);
72
- }
73
63
  // TODO: this is broken
74
64
  defrag(offsetValues, occupiedCapacity, newCapacity) {
75
65
  const { gl, buffer, bufferType, itemSize } = this;