@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.
- package/Math/arc.js +1 -2
- package/Math/circle-cdf-points.js +1 -170
- package/Math/circle.js +0 -25
- package/Math/methods.js +2 -2
- package/Math/vec3.js +6 -2
- package/altitude-locator/plugin.js +1 -1
- package/bearing-line/plugin.js +3 -2
- package/package.json +1 -1
- package/point-tracks/plugin.js +82 -22
- package/programs/line-on-globe/lines-color-instanced-flat.js +0 -1
- package/programs/line-on-globe/linestrip/linestrip.js +2 -30
- package/programs/point-on-globe/element-globe-surface-glow.js +0 -1
- package/programs/rings/partial-ring/piece-of-pie.js +55 -89
- package/programs/totems/camerauniformblock.js +7 -0
- package/programs/totems/canvas-webglobe-info.js +9 -9
- package/programs/totems/globe-changes.js +59 -0
- package/range-tools-on-terrain/bearing-line/adapters.js +8 -5
- package/range-tools-on-terrain/bearing-line/plugin.js +115 -18
- package/range-tools-on-terrain/circle-line-chain/adapters.js +15 -8
- package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +35 -13
- package/range-tools-on-terrain/circle-line-chain/plugin.js +94 -16
- package/range-tools-on-terrain/range-ring/adapters.js +74 -6
- package/range-tools-on-terrain/range-ring/plugin.js +222 -7
- package/range-tools-on-terrain/range-ring/types.js +9 -1
- package/semiplugins/interface.js +1 -0
- package/semiplugins/lightweight/line-plugin.js +72 -45
- package/semiplugins/lightweight/piece-of-pie-plugin.js +50 -25
- package/semiplugins/shape-on-terrain/arc-plugin.js +204 -98
- package/semiplugins/shape-on-terrain/circle-plugin.js +215 -88
- package/semiplugins/shape-on-terrain/padding-1-degree.js +538 -0
- package/util/account/single-attribute-buffer-management/buffer-manager.js +10 -0
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +145 -8
- package/util/account/single-attribute-buffer-management/buffer-orchestrator1.js +159 -0
- package/util/account/single-attribute-buffer-management/object-store.js +7 -0
- package/util/build-strategy/static-dynamic.js +11 -1
- package/util/check/typecheck.js +12 -0
- package/util/frame-counter-trigger.js +84 -0
- package/util/geometry/index.js +2 -1
- package/util/webglobjectbuilders.js +2 -2
- package/write-text/context-text4.js +140 -0
- package/Math/arc-generate-points copy.js +0 -366
- package/Math/globe-util/horizon-plane.js +0 -112
- package/altitude-locator/draw-subset-obj.js +0 -16
- package/programs/line-on-globe/paddings/paddings.js +0 -1
- package/programs/rings/partial-ring/piece-of-pie copy.js +0 -286
- package/semiplugins/shape-on-terrain/derived/padding-plugin.js +0 -101
- package/semiplugins/shape-on-terrain/one-degree-padding.js +0 -85
|
@@ -9,6 +9,7 @@ import { globe3Dcoordinates, globe2Dcoordinates } from "../../Math/methods";
|
|
|
9
9
|
import { StaticDynamicStrategy, StaticDynamicState } from "../../util/build-strategy/static-dynamic";
|
|
10
10
|
import { WORLD_RADIUS_3D, WORLD_RADIUS_MERCATOR } from "../../Math/constants";
|
|
11
11
|
import { opacityCheck } from "../../util/check/typecheck";
|
|
12
|
+
import { FrameCounterTrigger } from "../../util/frame-counter-trigger";
|
|
12
13
|
const ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL = 8;
|
|
13
14
|
const CIRCLE_POINTS_COUNT_HALF = 65; // Half of the points plus one for the reflection
|
|
14
15
|
const CIRCLE_POINTS_COUNT = CIRCLE_POINTS_COUNT_HALF * 2 - 1; // Number of points to approximate the circle
|
|
@@ -58,45 +59,47 @@ export class CircleOnTerrainPlugin {
|
|
|
58
59
|
globe = null;
|
|
59
60
|
gl = null;
|
|
60
61
|
lineProgram = null;
|
|
61
|
-
|
|
62
|
+
bufferManagersMap = new Map();
|
|
62
63
|
bufferOrchestrator = new BufferOrchestrator();
|
|
63
64
|
circleMap = new Map();
|
|
64
65
|
_cameraUniformBlock = null;
|
|
65
|
-
|
|
66
|
+
_freed = false;
|
|
66
67
|
_circleUBOHandler = null;
|
|
67
68
|
_opacity = 1;
|
|
68
69
|
_vao = null;
|
|
69
70
|
_dobuild = true; // This is used to trigger the build of circles when the camera position changes.
|
|
71
|
+
_frameCounterTrigger = null;
|
|
70
72
|
_staticDynamicStrategy = null;
|
|
71
|
-
|
|
73
|
+
_options = {
|
|
72
74
|
variativeColorsOn: false,
|
|
73
75
|
defaultColor: [0.1, 0.1, 0.1, 1], // Default color in RGBA format
|
|
74
|
-
defaultHeightFromGroundIn3D: 30.0
|
|
76
|
+
defaultHeightFromGroundIn3D: 30.0,
|
|
77
|
+
isMSL: false
|
|
75
78
|
};
|
|
76
|
-
|
|
79
|
+
_textDataPreAdaptor = undefined;
|
|
80
|
+
constructor(id, styleOptions = null) {
|
|
77
81
|
this.id = id;
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
if (styleOptions) {
|
|
83
|
+
this._options = { ...this._options, ...styleOptions };
|
|
84
|
+
}
|
|
80
85
|
}
|
|
81
86
|
init(globe, gl) {
|
|
82
87
|
this.globe = globe;
|
|
83
88
|
this.gl = gl;
|
|
84
89
|
// Initialize the program cache for line strip rendering.
|
|
85
|
-
this._staticDynamicStrategy = new StaticDynamicStrategy(globe, ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL);
|
|
86
90
|
this.lineProgram = LineStripProgramCache.get(globe);
|
|
87
|
-
// const g3D = globe3Dcoordinates(globe, 30);
|
|
88
91
|
const g2D = globe2Dcoordinates(globe);
|
|
89
92
|
// Initialize with a reasonable initial capacity to prevent buffer size issues
|
|
90
93
|
const initialCapacity = 100; // Start with capacity for 100 circles
|
|
91
|
-
this.
|
|
94
|
+
this.bufferManagersMap.set("position3d", {
|
|
92
95
|
bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 3, { initialCapacity }), // plus 1 is for butting linestrips
|
|
93
96
|
adaptor: (item) => {
|
|
94
|
-
const { longLatArr, height = this.
|
|
95
|
-
const result = globe3Dcoordinates(globe,
|
|
97
|
+
const { longLatArr, height = this._options.defaultHeightFromGroundIn3D, msl = this._options.isMSL } = item;
|
|
98
|
+
const result = globe3Dcoordinates(globe, longLatArr, height, msl, { paddingCount: 1, paddingValue: NaN });
|
|
96
99
|
return result;
|
|
97
100
|
}
|
|
98
101
|
});
|
|
99
|
-
this.
|
|
102
|
+
this.bufferManagersMap.set("position2d", {
|
|
100
103
|
bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 2, { initialCapacity }),
|
|
101
104
|
adaptor: (item) => {
|
|
102
105
|
const { longLatArr } = item;
|
|
@@ -104,8 +107,8 @@ export class CircleOnTerrainPlugin {
|
|
|
104
107
|
return result;
|
|
105
108
|
}
|
|
106
109
|
});
|
|
107
|
-
if (this.
|
|
108
|
-
this.
|
|
110
|
+
if (this._options.variativeColorsOn) {
|
|
111
|
+
this.bufferManagersMap.set("color", {
|
|
109
112
|
bufferManager: new BufferManager(gl, (CIRCLE_POINTS_COUNT + 1) * 4, { initialCapacity }),
|
|
110
113
|
adaptor: (item) => {
|
|
111
114
|
if (item.color) {
|
|
@@ -115,50 +118,109 @@ export class CircleOnTerrainPlugin {
|
|
|
115
118
|
}
|
|
116
119
|
else {
|
|
117
120
|
for (let i = 0; i < CIRCLE_POINTS_COUNT; i++) {
|
|
118
|
-
_colorArray.set(this.
|
|
121
|
+
_colorArray.set(this._options.defaultColor, i * 4);
|
|
119
122
|
}
|
|
120
123
|
}
|
|
121
124
|
return _colorArray;
|
|
122
125
|
}
|
|
123
126
|
});
|
|
124
127
|
}
|
|
125
|
-
this._vao = this.lineProgram.createVAO(createBufferAndReadInfo(this.
|
|
126
|
-
createBufferAndReadInfo(this.
|
|
128
|
+
this._vao = this.lineProgram.createVAO(createBufferAndReadInfo(this.bufferManagersMap.get("position3d")?.bufferManager.buffer), createBufferAndReadInfo(this.bufferManagersMap.get("position2d")?.bufferManager.buffer), this._options.variativeColorsOn ?
|
|
129
|
+
createBufferAndReadInfo(this.bufferManagersMap.get("color")?.bufferManager.buffer) : null);
|
|
127
130
|
this._circleUBOHandler = this.lineProgram.createUBO();
|
|
131
|
+
this.setDefaultColor(this._options.defaultColor);
|
|
128
132
|
this._cameraUniformBlock = CameraUniformBlockTotemCache.get(globe);
|
|
133
|
+
this._staticDynamicStrategy = new StaticDynamicStrategy(globe, ACTIVATE_DYNAMIC_STRATEGY_AT_LEVEL, () => {
|
|
134
|
+
this.__buildStaticCircles();
|
|
135
|
+
});
|
|
136
|
+
this._frameCounterTrigger = new FrameCounterTrigger(globe, 15, 1000, (globeChanges) => {
|
|
137
|
+
if (this._freed)
|
|
138
|
+
return;
|
|
139
|
+
this._buildCircles();
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
increaseSpace(amount) {
|
|
143
|
+
if (this._freed) {
|
|
144
|
+
console.warn("Plugin is freed, cannot increase space");
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (this.globe === null) {
|
|
148
|
+
console.warn("Globe is not initialized.");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
if (typeof amount !== "number" || amount <= 0) {
|
|
152
|
+
console.warn("Invalid amount, must be a positive number");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
this.bufferOrchestrator.ensureSpace(amount, this.bufferManagersMap);
|
|
129
156
|
}
|
|
130
157
|
insertBulk(circles) {
|
|
131
|
-
if (this.
|
|
158
|
+
if (this._freed)
|
|
132
159
|
return;
|
|
133
160
|
if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
|
|
134
|
-
!this.
|
|
161
|
+
!this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
|
|
135
162
|
throw new Error("Plugin not initialized properly");
|
|
136
163
|
}
|
|
137
|
-
|
|
138
|
-
|
|
164
|
+
const keys = [];
|
|
165
|
+
let newItemCount = 0;
|
|
139
166
|
for (const circleInput of circles) {
|
|
140
167
|
if (!circleInput.key || !circleInput.center || !circleInput.radius) {
|
|
141
168
|
console.warn(`CircleOnTerrainPlugin: Circle input is missing required properties: ${circleInput.radius} or ${circleInput.center} or ${circleInput.key}`);
|
|
142
169
|
continue;
|
|
143
170
|
}
|
|
144
|
-
|
|
171
|
+
if (circleInput.radius <= 0) {
|
|
172
|
+
console.warn(`CircleOnTerrainPlugin: Circle ${circleInput.key} has non-positive radius ${circleInput.radius}. Skipping.`);
|
|
173
|
+
continue;
|
|
174
|
+
}
|
|
175
|
+
keys.push(circleInput.key);
|
|
176
|
+
if (!this.circleMap.has(circleInput.key)) {
|
|
177
|
+
newItemCount++;
|
|
178
|
+
}
|
|
145
179
|
const circleForAzimuthCalc = CircleMethods.createCircleClosestAzimuthAngleProperties(circleInput);
|
|
146
180
|
this.circleMap.set(circleInput.key, [circleInput, circleForAzimuthCalc]);
|
|
147
|
-
if (this._staticDynamicStrategy?.getState() !== StaticDynamicState.DYNAMIC) {
|
|
148
|
-
fillStaticKeys.push(circleInput.key);
|
|
149
|
-
}
|
|
150
181
|
}
|
|
151
|
-
this.
|
|
182
|
+
this.bufferOrchestrator.ensureSpace(newItemCount, this.bufferManagersMap);
|
|
183
|
+
this._buildCircles(keys);
|
|
184
|
+
if (this._options.variativeColorsOn) {
|
|
185
|
+
this.__fillColor(keys);
|
|
186
|
+
}
|
|
152
187
|
this.globe.DrawRender();
|
|
153
188
|
}
|
|
189
|
+
updateColors(keyColorCouples, drawRender = true) {
|
|
190
|
+
if (this._freed) {
|
|
191
|
+
console.warn("Plugin is freed, cannot increase space");
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (this.globe === null) {
|
|
195
|
+
console.warn("Globe is not initialized.");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
if (this._options.variativeColorsOn === false) {
|
|
199
|
+
console.warn("VariativeColors are not enabled");
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
for (const { key, color } of keyColorCouples) {
|
|
203
|
+
const [circleInput] = this.circleMap.get(key) || [];
|
|
204
|
+
if (circleInput) {
|
|
205
|
+
circleInput.color = color;
|
|
206
|
+
this.__fillColor([key]);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
console.warn(`Circle key ${key} not found in circleMap.`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (drawRender) {
|
|
213
|
+
this.globe.DrawRender();
|
|
214
|
+
}
|
|
215
|
+
}
|
|
154
216
|
deleteBulk(keys) {
|
|
155
|
-
if (this.
|
|
217
|
+
if (this._freed)
|
|
156
218
|
return;
|
|
157
219
|
if (!this.globe || !this.gl || !this.lineProgram || !this.bufferOrchestrator ||
|
|
158
|
-
!this.
|
|
220
|
+
!this.bufferManagersMap || !this._vao || !this._circleUBOHandler) {
|
|
159
221
|
throw new Error("Plugin not initialized properly");
|
|
160
222
|
}
|
|
161
|
-
this.bufferOrchestrator.deleteBulk(keys, this.
|
|
223
|
+
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersMap);
|
|
162
224
|
for (const key of keys) {
|
|
163
225
|
if (this.circleMap.has(key)) {
|
|
164
226
|
this.circleMap.delete(key);
|
|
@@ -168,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
|
-
|
|
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.
|
|
186
|
-
this.
|
|
311
|
+
if (state === StaticDynamicState.DYNAMIC) {
|
|
312
|
+
this.__buildDynamicCircles(subSetIDs);
|
|
187
313
|
}
|
|
188
|
-
else if (state === StaticDynamicState.
|
|
189
|
-
this.
|
|
314
|
+
else if (subSetIDs || state === StaticDynamicState.TO_STATIC) {
|
|
315
|
+
this.__buildStaticCircles(subSetIDs);
|
|
190
316
|
}
|
|
191
317
|
}
|
|
192
|
-
|
|
193
|
-
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator,
|
|
318
|
+
__buildDynamicCircles(subSetIDs = null) {
|
|
319
|
+
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
|
|
194
320
|
if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
|
|
195
|
-
!bufferOrchestrator || !
|
|
321
|
+
!bufferOrchestrator || !bufferManagersMap || !circleMap)
|
|
196
322
|
throw new Error("Plugin not initialized properly");
|
|
197
323
|
// unoptimized.. resets all circles.
|
|
198
|
-
// bufferOrchestrator.resetWithCapacity(
|
|
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
|
-
|
|
213
|
-
|
|
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,
|
|
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,
|
|
370
|
+
const { globe, gl, _cameraUniformBlock, lineProgram, bufferOrchestrator, bufferManagersMap, circleMap } = this;
|
|
233
371
|
if (!globe || !gl || !_cameraUniformBlock || !lineProgram ||
|
|
234
|
-
!bufferOrchestrator || !
|
|
372
|
+
!bufferOrchestrator || !bufferManagersMap || !circleMap)
|
|
235
373
|
throw new Error("Plugin not initialized properly");
|
|
236
|
-
const
|
|
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
|
-
|
|
248
|
-
bufferOrchestrator.resetWithCapacity(
|
|
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
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
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 {
|
|
283
|
-
if (
|
|
284
|
-
!
|
|
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
|
-
|
|
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.
|
|
426
|
+
if (this._freed)
|
|
300
427
|
return;
|
|
301
|
-
this.
|
|
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.
|
|
434
|
+
this.bufferManagersMap.forEach(({ bufferManager }) => {
|
|
308
435
|
bufferManager.free();
|
|
309
436
|
});
|
|
310
|
-
this.
|
|
437
|
+
this.bufferManagersMap.clear();
|
|
311
438
|
CameraUniformBlockTotemCache.release(this.globe);
|
|
312
439
|
}
|
|
313
440
|
}
|