@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
package/Math/arc.js
CHANGED
|
@@ -143,8 +143,7 @@ function _populatePointsWithClosestPointInsideArc(out, arc, count, closestPoint)
|
|
|
143
143
|
* @param {Vec3} cameraPosition - The position of the camera.
|
|
144
144
|
* @param {number} quaternionReuseCount - The number of times to apply the same rotation before recalculating. Higher is faster but less accurate.
|
|
145
145
|
*/
|
|
146
|
-
function _distanceSampling(out, count, inArc, cameraPosition = vec3create(0, 0, 0),
|
|
147
|
-
quaternionReuseCount = 1) {
|
|
146
|
+
function _distanceSampling(out, count, inArc, cameraPosition = vec3create(0, 0, 0), quaternionReuseCount = 1) {
|
|
148
147
|
if (count === 0) {
|
|
149
148
|
return;
|
|
150
149
|
}
|
|
@@ -1,168 +1,4 @@
|
|
|
1
1
|
import { RADIANS } from "./methods";
|
|
2
|
-
function createTemplate(intervalCount, strength = 1.0) {
|
|
3
|
-
const out = new Array(intervalCount);
|
|
4
|
-
const TOTAL = 1;
|
|
5
|
-
let cummulative = 0;
|
|
6
|
-
if (strength <= 0) {
|
|
7
|
-
// If strength is 0, distribute evenly.
|
|
8
|
-
const step = TOTAL / (intervalCount - 1);
|
|
9
|
-
for (let i = 0; i < intervalCount; i++) {
|
|
10
|
-
out[i] = cummulative;
|
|
11
|
-
cummulative += step;
|
|
12
|
-
}
|
|
13
|
-
out[intervalCount - 1] = TOTAL; // Ensure the last value is exactly TOTAL
|
|
14
|
-
return out;
|
|
15
|
-
}
|
|
16
|
-
// If strength is greater than 0, bias towards the start.
|
|
17
|
-
const weights = new Array(intervalCount);
|
|
18
|
-
let currentStep = 1;
|
|
19
|
-
let totalWeight = 0;
|
|
20
|
-
// Calculate weights for each interval, decreasing for later intervals.
|
|
21
|
-
for (let i = 0; i < intervalCount; i++) {
|
|
22
|
-
// Using (i + 1) in the denominator gives earlier intervals the highest weight.
|
|
23
|
-
totalWeight += currentStep;
|
|
24
|
-
weights[i] = totalWeight;
|
|
25
|
-
currentStep += strength;
|
|
26
|
-
}
|
|
27
|
-
// Distribute the total angle based on the weights.
|
|
28
|
-
for (let i = 0; i < intervalCount; i++) {
|
|
29
|
-
// Round to the nearest whole number for this interval.
|
|
30
|
-
out[i] = (weights[i] / totalWeight) * TOTAL;
|
|
31
|
-
}
|
|
32
|
-
if (out[intervalCount - 1] !== TOTAL) {
|
|
33
|
-
out[intervalCount - 1] = TOTAL;
|
|
34
|
-
}
|
|
35
|
-
// console.log("createTemplate", "strength", strength, "intervalCount", intervalCount, "out", out);
|
|
36
|
-
return out;
|
|
37
|
-
}
|
|
38
|
-
function interpolation(a, b, t) {
|
|
39
|
-
return a + (b - a) * t;
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Populates the `out` array with values from the `template` array,
|
|
43
|
-
* distributing the surplus length as interpolated values between the template samples.
|
|
44
|
-
*
|
|
45
|
-
* @param out The destination array to be filled. Its length must be >= template.length.
|
|
46
|
-
* @param template An ordered array of numbers to be placed in the `out` array.
|
|
47
|
-
* @param strength A parameter controlling the distribution bias of surplus samples.
|
|
48
|
-
* - strength = 0: Surplus samples are distributed evenly.
|
|
49
|
-
* - strength > 0: Surplus samples are biased towards the start of the template.
|
|
50
|
-
* - Higher values create a stronger bias.
|
|
51
|
-
*/
|
|
52
|
-
function increasePopulation(// TODO: THERE IS A BUG
|
|
53
|
-
out, template, strength = 1.0) {
|
|
54
|
-
const sourceLength = template.length;
|
|
55
|
-
const destinationLength = out.length;
|
|
56
|
-
const outLengthAtStart = out.length;
|
|
57
|
-
// --- Handle Edge Cases ---
|
|
58
|
-
// If the template is empty, there is nothing to interpolate from.
|
|
59
|
-
if (sourceLength === 0) {
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
// If the template has only one value, fill the output array with that value.
|
|
63
|
-
if (sourceLength === 1) {
|
|
64
|
-
out.fill(template[0]);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
// If the destination is not larger than the source, just copy the template values.
|
|
68
|
-
if (destinationLength <= sourceLength) {
|
|
69
|
-
for (let i = 0; i < destinationLength; i++) {
|
|
70
|
-
out[i] = template[i];
|
|
71
|
-
}
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
// --- Main Logic ---
|
|
75
|
-
const surplus = destinationLength - sourceLength;
|
|
76
|
-
const numGaps = sourceLength - 1;
|
|
77
|
-
// This array will hold the number of extra samples to add in each gap.
|
|
78
|
-
const surplusPerGap = new Array(numGaps).fill(0);
|
|
79
|
-
if (surplus > 0) {
|
|
80
|
-
// --- Step 1: Determine the distribution of surplus items ---
|
|
81
|
-
// If strength is 0, distribute surplus items as evenly as possible.
|
|
82
|
-
if (strength <= 0) {
|
|
83
|
-
const baseToAdd = Math.floor(surplus / numGaps);
|
|
84
|
-
const remainder = surplus % numGaps;
|
|
85
|
-
for (let i = 0; i < numGaps; i++) {
|
|
86
|
-
// Distribute the remainder one by one to the first gaps.
|
|
87
|
-
surplusPerGap[i] = baseToAdd + (i < remainder ? 1 : 0);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
else {
|
|
91
|
-
// Biased Distribution: more items in earlier gaps.
|
|
92
|
-
const weights = new Array(numGaps);
|
|
93
|
-
let totalWeight = 0;
|
|
94
|
-
// A. Calculate a weight for each gap. The weight decreases for later gaps.
|
|
95
|
-
// The `strength` parameter makes this decay steeper.
|
|
96
|
-
for (let i = 0; i < numGaps; i++) {
|
|
97
|
-
// Using (i + 1) in the denominator gives earlier gaps (i=0) the highest weight.
|
|
98
|
-
const weight = Math.pow(1 / (i + 1), strength);
|
|
99
|
-
weights[i] = weight;
|
|
100
|
-
totalWeight += weight;
|
|
101
|
-
}
|
|
102
|
-
// B. Distribute the surplus based on the calculated weights.
|
|
103
|
-
// This method ensures the total distributed count equals the surplus.
|
|
104
|
-
let distributedCount = 0;
|
|
105
|
-
for (let i = 0; i < numGaps - 1; i++) {
|
|
106
|
-
const idealCount = (weights[i] / totalWeight) * surplus;
|
|
107
|
-
// Round to the nearest whole number for this gap.
|
|
108
|
-
const countForThisGap = Math.ceil(idealCount);
|
|
109
|
-
surplusPerGap[i] = countForThisGap;
|
|
110
|
-
distributedCount += countForThisGap;
|
|
111
|
-
}
|
|
112
|
-
// Assign the remainder to the last gap to guarantee the sum is correct.
|
|
113
|
-
//surplusPerGap[numGaps - 1] = surplus - distributedCount;
|
|
114
|
-
// add to first
|
|
115
|
-
const leftover = surplus - distributedCount;
|
|
116
|
-
if (leftover > 0) {
|
|
117
|
-
surplusPerGap[0] += leftover; // Add any leftover to the first gap.
|
|
118
|
-
}
|
|
119
|
-
console.log("leftover", leftover, "distributedCount", distributedCount, "surplus", surplus);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
// --- Step 2: Populate the `out` array ---
|
|
123
|
-
let outIndex = 0;
|
|
124
|
-
for (let i = 0; i < surplusPerGap.length; i++) {
|
|
125
|
-
if (typeof surplusPerGap[i] !== "number" || isNaN(surplusPerGap[i]) || !isFinite(surplusPerGap[i])) {
|
|
126
|
-
console.warn("increasePopulation: Invalid surplusPerGap value at index", i, ":", surplusPerGap[i]);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
for (let i = 0; i < sourceLength; i++) {
|
|
130
|
-
// A. Add the original template item.
|
|
131
|
-
out[outIndex++] = template[i];
|
|
132
|
-
// B. If this is not the last template item, fill the gap after it.
|
|
133
|
-
if (i < numGaps) {
|
|
134
|
-
const numToAdd = surplusPerGap[i];
|
|
135
|
-
if (numToAdd <= 0)
|
|
136
|
-
continue;
|
|
137
|
-
const startVal = template[i];
|
|
138
|
-
const endVal = template[i + 1];
|
|
139
|
-
// C. Add the interpolated ("surplus") items for this gap.
|
|
140
|
-
// The total number of intervals in this gap is numToAdd + 1.
|
|
141
|
-
const totalIntervals = numToAdd + 1;
|
|
142
|
-
for (let j = 1; j <= numToAdd; j++) {
|
|
143
|
-
const t = j / totalIntervals; // The interpolation factor (0 < t < 1)
|
|
144
|
-
// Linear interpolation: out = start * (1 - t) + end * t
|
|
145
|
-
const interpolatedValue = startVal * (1 - t) + endVal * t;
|
|
146
|
-
out[outIndex++] = interpolatedValue;
|
|
147
|
-
if (outIndex >= out.length) {
|
|
148
|
-
console.warn("increasePopulation: Output array overflow. Stopping early.");
|
|
149
|
-
console.warn("processeed item ratio:", i, "/", sourceLength);
|
|
150
|
-
let count = numToAdd - j;
|
|
151
|
-
console.log("count", count);
|
|
152
|
-
for (let _i = i; _i < sourceLength; _i++) {
|
|
153
|
-
count += surplusPerGap[_i];
|
|
154
|
-
}
|
|
155
|
-
console.warn("increasePopulation: Not enough space to add", count, "more items.");
|
|
156
|
-
return; // Prevent overflow if the output array is not large enough.
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
// --- Step 3: Ensure the output length is correct ---
|
|
162
|
-
if (outLengthAtStart !== out.length) {
|
|
163
|
-
console.warn("increasePopulation: Output length mismatch. Expected", outLengthAtStart, "but got", out.length);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
2
|
function createCummulativeTemplate(numberOfPoints, strength, denseRatio = 0.5 // Ratio of points to be densely packed at the start.
|
|
167
3
|
) {
|
|
168
4
|
// Handle edge cases for the number of points.
|
|
@@ -239,9 +75,4 @@ function globeFindPointByPolarHalfCircle(out, globe, centerLong, centerLat, radi
|
|
|
239
75
|
offset -= 2;
|
|
240
76
|
}
|
|
241
77
|
}
|
|
242
|
-
export {
|
|
243
|
-
// createTemplate,
|
|
244
|
-
// increasePopulation,
|
|
245
|
-
// interpolation,
|
|
246
|
-
// createCummulativeTemplate,
|
|
247
|
-
createCummulativeTemplateStash, globeFindPointByPolar, globeFindPointByPolarHalfCircle };
|
|
78
|
+
export { createCummulativeTemplateStash, globeFindPointByPolar, globeFindPointByPolarHalfCircle };
|
package/Math/circle.js
CHANGED
|
@@ -29,30 +29,5 @@ function createCircleClosestAzimuthAngleProperties(circle) {
|
|
|
29
29
|
normal: normal,
|
|
30
30
|
northPointProjectedToOriginPlaneNormalized: N,
|
|
31
31
|
};
|
|
32
|
-
// const distance = normal[2]; //dot(normal, [0, 0, 1] as Vec3)
|
|
33
|
-
// const N: Vec3 = [0, 0, 0];
|
|
34
|
-
// if (Math.abs(distance) < 1e-6) {
|
|
35
|
-
// N[0] = -1;
|
|
36
|
-
// N[1] = 0;
|
|
37
|
-
// N[2] = 0;
|
|
38
|
-
// } else {
|
|
39
|
-
// // TODO: add cases for 8 parts of the sphere
|
|
40
|
-
// copy(N, normal);
|
|
41
|
-
// multiplyScalar(N, N, distance);
|
|
42
|
-
// if (N[2] >= 0) {
|
|
43
|
-
// N[0] = -N[0];
|
|
44
|
-
// N[1] = -N[1];
|
|
45
|
-
// N[2] = 1 - N[2];
|
|
46
|
-
// } else {
|
|
47
|
-
// N[2] = -N[2];
|
|
48
|
-
// N[0] = -N[0];
|
|
49
|
-
// N[1] = -N[1];
|
|
50
|
-
// }
|
|
51
|
-
// }
|
|
52
|
-
// normalize(N, N);
|
|
53
|
-
// return {
|
|
54
|
-
// normal: normal,
|
|
55
|
-
// northPointProjectedToOriginPlaneNormalized: N,
|
|
56
|
-
// }
|
|
57
32
|
}
|
|
58
33
|
export { closestAzimuthAngle, createCircleClosestAzimuthAngleProperties };
|
package/Math/methods.js
CHANGED
|
@@ -73,13 +73,13 @@ export const pixelXYLenghtToUnitVectorWithHeight = (pixelXYHeight) => {
|
|
|
73
73
|
const radius = WORLD_RADIUS_3D + pixelXYHeight[2];
|
|
74
74
|
return [...radianToCartesian3d([long, lat]), radius];
|
|
75
75
|
};
|
|
76
|
-
export const globe3Dcoordinates = (globe, height = 0
|
|
76
|
+
export const globe3Dcoordinates = (globe, longlats, height = 0, msl = false, { paddingCount = 0, paddingValue = NaN }) => {
|
|
77
77
|
const len = longlats.length / 2;
|
|
78
78
|
const result = new Float32Array(len * 3 + paddingCount * 3).fill(paddingValue);
|
|
79
79
|
for (let i = 0; i < len; i++) {
|
|
80
80
|
const long = longlats[i * 2];
|
|
81
81
|
const lat = longlats[i * 2 + 1];
|
|
82
|
-
const xyz = globe.api_GetCartesian3DPoint(long, lat, height,
|
|
82
|
+
const xyz = globe.api_GetCartesian3DPoint(long, lat, height, msl);
|
|
83
83
|
result.set(xyz, i * 3);
|
|
84
84
|
}
|
|
85
85
|
return result;
|
package/Math/vec3.js
CHANGED
|
@@ -60,7 +60,11 @@ function length(a) {
|
|
|
60
60
|
function normalize(outVec, inVec) {
|
|
61
61
|
const len = length(inVec);
|
|
62
62
|
if (len === 0) {
|
|
63
|
-
|
|
63
|
+
console.warn('Cannot normalize a zero vector');
|
|
64
|
+
outVec[0] = 0;
|
|
65
|
+
outVec[1] = 0;
|
|
66
|
+
outVec[2] = 0;
|
|
67
|
+
return;
|
|
64
68
|
}
|
|
65
69
|
outVec[0] = inVec[0] / len;
|
|
66
70
|
outVec[1] = inVec[1] / len;
|
|
@@ -81,7 +85,7 @@ function equals(a, b) {
|
|
|
81
85
|
Math.abs(a[2] - b[2]) < EPSILON);
|
|
82
86
|
}
|
|
83
87
|
function fromUnitVectorToLongLat(out, a) {
|
|
84
|
-
const len = length(a);
|
|
88
|
+
const len = length(a);
|
|
85
89
|
if (len === 0) {
|
|
86
90
|
throw new Error('Cannot convert a zero vector to unit vector');
|
|
87
91
|
}
|
|
@@ -335,7 +335,7 @@ class PointGlowLineToEarthPlugin {
|
|
|
335
335
|
});
|
|
336
336
|
}
|
|
337
337
|
_doesChanged() {
|
|
338
|
-
return this.
|
|
338
|
+
return this.globe.api_IsScreenMoving();
|
|
339
339
|
}
|
|
340
340
|
_changed() {
|
|
341
341
|
this._parametersChanged = true;
|
package/bearing-line/plugin.js
CHANGED
|
@@ -397,8 +397,9 @@ export default class BearingLinePlugin {
|
|
|
397
397
|
const drawRange = { first: 0, count: this.bufferOrchestrator.length };
|
|
398
398
|
this.lineProgram.draw(this.lineVao, { drawRange }, this._opacity);
|
|
399
399
|
if (this.drawAngleRing) {
|
|
400
|
-
this.pieceOfPieProgram.
|
|
401
|
-
this.pieceOfPieProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360,
|
|
400
|
+
this.pieceOfPieProgram._defaultFlexibleUBO.updateSingle("u_opacity", this._opacity * 0.8);
|
|
401
|
+
this.pieceOfPieProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
|
|
402
|
+
this.pieceOfPieProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
|
|
402
403
|
}
|
|
403
404
|
if (this.drawBearingLine) {
|
|
404
405
|
// this.lineProgram.draw(this.bearingLineVAO, this.bufferOrchestrator.length, this._opacity );
|
package/package.json
CHANGED
package/point-tracks/plugin.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BufferOrchestrator, BufferManager, ObjectStore } from "../util/account";
|
|
1
|
+
import { BufferOrchestrator, BufferManager, ObjectStore } from "../util/account/index";
|
|
2
2
|
import { PickerDisplayer } from "../util/picking/picker-displayer";
|
|
3
3
|
import { PointOnGlobeProgramCache } from "../programs/point-on-globe/square-pixel-point";
|
|
4
4
|
import { wgs84ToCartesian3d, wgs84ToMercator } from "../Math/methods";
|
|
@@ -14,7 +14,7 @@ const _0vec3 = /* @__PURE__ */ [0, 0, 0];
|
|
|
14
14
|
* @typedef {Array<Point>, rgba, trackID} Track
|
|
15
15
|
*/
|
|
16
16
|
class PointTracksPlugin {
|
|
17
|
-
constructor(id, { pointSize = 2, hoveredPointSize = 4, selectionPointFilling = 4, opacity = 1.0 } = {}) {
|
|
17
|
+
constructor(id, { pointSize = 2, hoveredPointSize = 4, selectionPointFilling = 4, opacity = 1.0, objectStoreExtraParameters = ["long", "lat", "height"], initialCapacity = 1000 } = {}) {
|
|
18
18
|
this.id = id;
|
|
19
19
|
this._isFreed = false;
|
|
20
20
|
this._pointProgram = null;
|
|
@@ -25,15 +25,20 @@ class PointTracksPlugin {
|
|
|
25
25
|
this._selectedID = -1;
|
|
26
26
|
this._selectedObj = null;
|
|
27
27
|
this._tracksToPointsMap = new Map(); // one to many
|
|
28
|
-
this._opacity = opacity;
|
|
28
|
+
this._opacity = opacity ? opacity : 1.0;
|
|
29
29
|
this.program = null;
|
|
30
30
|
this._lastWH = { w: 0, h: 0 };
|
|
31
31
|
this._focusParams = { on: false, length: 0, elementBuffer: null, trackIDs: [] };
|
|
32
32
|
this.pointSizes = {
|
|
33
|
-
pointSize,
|
|
34
|
-
selectionPointFilling,
|
|
35
|
-
hoveredPointSize
|
|
33
|
+
pointSize: pointSize ? pointSize : 2,
|
|
34
|
+
selectionPointFilling: selectionPointFilling ? selectionPointFilling : 4,
|
|
35
|
+
hoveredPointSize: hoveredPointSize ? hoveredPointSize : 4
|
|
36
36
|
};
|
|
37
|
+
this._objectStoreExtraParameters = objectStoreExtraParameters ? objectStoreExtraParameters : [];
|
|
38
|
+
this._objectStoreExtraParametersFiltered = objectStoreExtraParameters.filter(param => {
|
|
39
|
+
return !["long", "lat", "height", "ID", "trackID"].includes(param);
|
|
40
|
+
});
|
|
41
|
+
this._bufferOrchestrator = new BufferOrchestrator({ capacity: initialCapacity ? initialCapacity : 1000 });
|
|
37
42
|
}
|
|
38
43
|
init(globe, gl) {
|
|
39
44
|
this.globe = globe;
|
|
@@ -45,9 +50,8 @@ class PointTracksPlugin {
|
|
|
45
50
|
}
|
|
46
51
|
_initBufferManagers() {
|
|
47
52
|
const { gl } = this;
|
|
48
|
-
const initialCapacity =
|
|
53
|
+
const initialCapacity = this._bufferOrchestrator.capacity;
|
|
49
54
|
const bufferType = "DYNAMIC_DRAW";
|
|
50
|
-
this._bufferOrchestrator = new BufferOrchestrator({ initialCapacity });
|
|
51
55
|
this._bufferManagersMap = new Map([
|
|
52
56
|
["pos3D", {
|
|
53
57
|
bufferManager: new BufferManager(gl, 3, { bufferType, initialCapacity }),
|
|
@@ -67,9 +71,17 @@ class PointTracksPlugin {
|
|
|
67
71
|
["objectStore", {
|
|
68
72
|
bufferManager: new ObjectStore({ initialCapacity }),
|
|
69
73
|
adaptor: (item) => {
|
|
70
|
-
|
|
71
|
-
trackID: item.trackID,
|
|
74
|
+
const result = {
|
|
75
|
+
trackID: item.trackID,
|
|
76
|
+
pointID: item.pointID,
|
|
72
77
|
};
|
|
78
|
+
// Add extra parameters specified in _objectStoreExtraParameters
|
|
79
|
+
this._objectStoreExtraParameters.forEach(param => {
|
|
80
|
+
if (item.hasOwnProperty(param)) {
|
|
81
|
+
result[param] = item[param];
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return result;
|
|
73
85
|
}
|
|
74
86
|
}]
|
|
75
87
|
]);
|
|
@@ -132,8 +144,8 @@ class PointTracksPlugin {
|
|
|
132
144
|
* @returns
|
|
133
145
|
*/
|
|
134
146
|
insertBulk(tracks) {
|
|
135
|
-
this._fillTracksToPointsMap(tracks);
|
|
136
|
-
const flattenedPoints = tracks.map(trackToFlatPoints).flat();
|
|
147
|
+
this._fillTracksToPointsMap(tracks);
|
|
148
|
+
const flattenedPoints = tracks.map(trackToFlatPoints, this._objectStoreExtraParametersFiltered).flat();
|
|
137
149
|
const currentLoad = this._bufferOrchestrator.length;
|
|
138
150
|
if (currentLoad + flattenedPoints.length >= 2147483647) {
|
|
139
151
|
throw new Error("Too many points, Point count cannot exceed 2147483647");
|
|
@@ -155,8 +167,8 @@ class PointTracksPlugin {
|
|
|
155
167
|
* @param {string} trackID
|
|
156
168
|
*/
|
|
157
169
|
deleteTrack(trackID) {
|
|
158
|
-
const
|
|
159
|
-
const points = Array.from(
|
|
170
|
+
const pointList = this._tracksToPointsMap.get(trackID);
|
|
171
|
+
const points = Array.from(pointList);
|
|
160
172
|
const { _bufferOrchestrator, _bufferManagersMap } = this;
|
|
161
173
|
_bufferOrchestrator.deleteBulk(points.map((pointID) => keyMethod(trackID, pointID)), _bufferManagersMap);
|
|
162
174
|
this._tracksToPointsMap.delete(trackID);
|
|
@@ -189,6 +201,23 @@ class PointTracksPlugin {
|
|
|
189
201
|
}
|
|
190
202
|
this.globe.DrawRender();
|
|
191
203
|
}
|
|
204
|
+
updateTrackColor(trackID, rgba) {
|
|
205
|
+
if (!this._tracksToPointsMap.has(trackID)) {
|
|
206
|
+
console.warn(`Track with ID ${trackID} does not exist.`);
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
const pointList = this._tracksToPointsMap.get(trackID);
|
|
210
|
+
const points = Array.from(pointList);
|
|
211
|
+
const { _bufferOrchestrator, _bufferManagersMap } = this;
|
|
212
|
+
_bufferOrchestrator.updateBulk(points.map((pointID) => {
|
|
213
|
+
return {
|
|
214
|
+
key: keyMethod(trackID, pointID),
|
|
215
|
+
rgba: new Float32Array(rgba)
|
|
216
|
+
};
|
|
217
|
+
}), _bufferManagersMap, ["rgba"]);
|
|
218
|
+
this._refillFocus();
|
|
219
|
+
this.globe?.DrawRender();
|
|
220
|
+
}
|
|
192
221
|
// GLOBE API METHODS
|
|
193
222
|
free() {
|
|
194
223
|
if (this._isFreed)
|
|
@@ -201,6 +230,12 @@ class PointTracksPlugin {
|
|
|
201
230
|
}
|
|
202
231
|
draw3D() {
|
|
203
232
|
const { gl, _pointProgram, _pickerDisplayer, _bufferOrchestrator, _vao } = this;
|
|
233
|
+
if (!gl) {
|
|
234
|
+
throw new Error("GL is not loaded, PointTracks Plugin");
|
|
235
|
+
}
|
|
236
|
+
if (this._isFreed) {
|
|
237
|
+
throw new Error("Plugin is unregistered, PointTracks Plugin");
|
|
238
|
+
}
|
|
204
239
|
this.resize();
|
|
205
240
|
_pickerDisplayer.bindFBO();
|
|
206
241
|
_pickerDisplayer.clearTextures();
|
|
@@ -246,7 +281,12 @@ class PointTracksPlugin {
|
|
|
246
281
|
const pointSet = this._tracksToPointsMap.get(trackID);
|
|
247
282
|
for (let p = 0; p < points.length; p++) {
|
|
248
283
|
const pointID = points[p].ID;
|
|
249
|
-
pointSet.
|
|
284
|
+
if (!pointSet.has(pointID)) {
|
|
285
|
+
pointSet.add(pointID);
|
|
286
|
+
}
|
|
287
|
+
else {
|
|
288
|
+
console.warn(`Point with ID ${pointID} already exists in track ${trackID}. Skipping duplicate.`);
|
|
289
|
+
}
|
|
250
290
|
}
|
|
251
291
|
}
|
|
252
292
|
}
|
|
@@ -256,9 +296,21 @@ class PointTracksPlugin {
|
|
|
256
296
|
}
|
|
257
297
|
}
|
|
258
298
|
_deletePointsFromTracksMap(trackID, pointIDs) {
|
|
259
|
-
const
|
|
299
|
+
const trackIDs = this._tracksToPointsMap.get(trackID);
|
|
300
|
+
if (trackIDs === undefined) {
|
|
301
|
+
console.warn(`Track with ID ${trackID} not found.`);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
260
304
|
for (const pointID of pointIDs) {
|
|
261
|
-
|
|
305
|
+
if (!trackIDs.has(pointID)) {
|
|
306
|
+
console.warn(`Point with ID ${pointID} not found in track ${trackID}.`);
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
trackIDs.delete(pointID);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (trackIDs.size === 0) {
|
|
313
|
+
this._tracksToPointsMap.delete(trackID);
|
|
262
314
|
}
|
|
263
315
|
}
|
|
264
316
|
_selfSelect() {
|
|
@@ -282,14 +334,16 @@ class PointTracksPlugin {
|
|
|
282
334
|
const indexes = [];
|
|
283
335
|
const foundTracks = [];
|
|
284
336
|
for (const trackID of trackIDs) {
|
|
285
|
-
const
|
|
286
|
-
if (!
|
|
337
|
+
const pointList = this._tracksToPointsMap.get(trackID);
|
|
338
|
+
if (!pointList)
|
|
287
339
|
continue;
|
|
288
340
|
foundTracks.push(trackID);
|
|
289
|
-
const
|
|
290
|
-
for (const pointID of points) {
|
|
341
|
+
for (const pointID of pointList) {
|
|
291
342
|
const key = keyMethod(trackID, pointID);
|
|
292
343
|
const index = this._bufferOrchestrator.offsetMap.get(key);
|
|
344
|
+
if (index === undefined) {
|
|
345
|
+
throw new Error;
|
|
346
|
+
}
|
|
293
347
|
indexes.push(index);
|
|
294
348
|
length++;
|
|
295
349
|
}
|
|
@@ -306,7 +360,7 @@ class PointTracksPlugin {
|
|
|
306
360
|
return true;
|
|
307
361
|
}
|
|
308
362
|
}
|
|
309
|
-
const trackToFlatPoints = (track) => {
|
|
363
|
+
const trackToFlatPoints = (track, extraParameters) => {
|
|
310
364
|
const trackID = track.trackID;
|
|
311
365
|
const points = track.points;
|
|
312
366
|
const rgba = new Float32Array(track.rgba);
|
|
@@ -321,6 +375,12 @@ const trackToFlatPoints = (track) => {
|
|
|
321
375
|
rgba,
|
|
322
376
|
trackID
|
|
323
377
|
});
|
|
378
|
+
for (let i = 0; i < extraParameters.length; i++) {
|
|
379
|
+
const param = extraParameters[i];
|
|
380
|
+
if (point.hasOwnProperty(param)) {
|
|
381
|
+
flatPoints[flatPoints.length - 1][param] = point[param];
|
|
382
|
+
}
|
|
383
|
+
}
|
|
324
384
|
}
|
|
325
385
|
return flatPoints;
|
|
326
386
|
};
|
|
@@ -8,7 +8,6 @@ import { attributeLoader } from "../../util/gl-util/buffer/attribute-loader";
|
|
|
8
8
|
* This program draws line between points provided from the first and second buffer.
|
|
9
9
|
* draw method gl.drawArraysInstanced( gl.POINTS, 0,2, lineCount);
|
|
10
10
|
* */
|
|
11
|
-
// TODO: find better way to eleminate edge case distance(posA, posB) > 37000000.0
|
|
12
11
|
const vertexShaderSource = `#version 300 es
|
|
13
12
|
precision highp float;
|
|
14
13
|
${CameraUniformBlockString}
|
|
@@ -3,7 +3,6 @@ import { CameraUniformBlockString, CameraUniformBlockTotemCache } from "../../to
|
|
|
3
3
|
import { cartesian3DToGLPosition, mercatorXYToGLPosition, } from "../../../util/shaderfunctions/geometrytransformations";
|
|
4
4
|
import { noRegisterGlobeProgramCache } from "../../programcache";
|
|
5
5
|
import { attributeLoader } from "../../../util/gl-util/buffer/attribute-loader";
|
|
6
|
-
import "../../../util/gl-util/buffer/attribute-loader";
|
|
7
6
|
import { UniformBlockManager } from "../../../util/gl-util/uniform-block/manager";
|
|
8
7
|
import { drawArrays } from "../../../util/gl-util/draw-options/methods";
|
|
9
8
|
const ESCAPE_VALUE = -1;
|
|
@@ -14,8 +13,6 @@ const uniformBindingPoints = {
|
|
|
14
13
|
// const one = new Float32Array([1]);
|
|
15
14
|
const flexibleBlockManager = new UniformBlockManager('FlexibleAttributes', [
|
|
16
15
|
{ name: "u_color", type: "vec4", value: new Float32Array([0.12, 1, 0.1, 1]) },
|
|
17
|
-
// { name: "u_dash_opacity", type: "float", value: one },
|
|
18
|
-
// { name: "u_dash_length", type: "float", value: one },
|
|
19
16
|
], uniformBindingPoints.flexible);
|
|
20
17
|
const vertexShaderSource = `#version 300 es
|
|
21
18
|
precision highp float;
|
|
@@ -31,24 +28,14 @@ uniform float u_opacity;
|
|
|
31
28
|
in vec3 position3d;
|
|
32
29
|
in vec2 position2d;
|
|
33
30
|
in vec4 color;
|
|
34
|
-
// in float dash_length;
|
|
35
|
-
// in float dash_opacity;
|
|
36
|
-
|
|
37
|
-
// out float v_dash_length;
|
|
38
|
-
// out float v_dash_opacity;
|
|
39
31
|
out vec4 v_color;
|
|
40
32
|
|
|
41
33
|
flat out vec3 v_flat_position;
|
|
42
34
|
out vec3 v_position;
|
|
43
35
|
|
|
44
36
|
void main() {
|
|
45
|
-
|
|
46
37
|
v_color = ( color.r == -1.0 ) ? u_color : color;
|
|
47
38
|
v_color.a *= u_opacity;
|
|
48
|
-
|
|
49
|
-
// v_dash_length = ( dash_length == -1.0 ) ? u_dash_length : dash_length;
|
|
50
|
-
// v_dash_opacity = ( dash_opacity == -1.0 ) ? u_dash_opacity : dash_opacity;
|
|
51
|
-
|
|
52
39
|
if ( is3D ) {
|
|
53
40
|
gl_Position = cartesian3DToGLPosition( position3d );
|
|
54
41
|
v_position = position3d;
|
|
@@ -75,18 +62,8 @@ in vec3 v_position;
|
|
|
75
62
|
out vec4 outColor;
|
|
76
63
|
|
|
77
64
|
void main() {
|
|
78
|
-
outColor = v_color;
|
|
79
|
-
return;
|
|
80
|
-
// float dash_length = v_dash_length;
|
|
81
|
-
// float dash_opacity = v_dash_opacity;
|
|
65
|
+
outColor = vec4( v_color.rgb, v_color.a );
|
|
82
66
|
|
|
83
|
-
// if ( dash_length == 0.0 ) {
|
|
84
|
-
outColor = vec4( v_color.rgb, v_color.a );
|
|
85
|
-
// } else {
|
|
86
|
-
// float dist = distance( v_flat_position, v_position );
|
|
87
|
-
// // float alpha = mod( dist , v_dash_length * 2.0 ) / v_dash_length < 1.0 ? 1.0 : v_dash_opacity;
|
|
88
|
-
// outColor = vec4( 1.0, 1.0, 1.0, v_color.a * opacity *alpha);
|
|
89
|
-
// }
|
|
90
67
|
}`;
|
|
91
68
|
export class LineProgram {
|
|
92
69
|
_vaosPublished = [];
|
|
@@ -112,8 +89,6 @@ export class LineProgram {
|
|
|
112
89
|
this.gl.bindAttribLocation(this.program, 0, "position3d");
|
|
113
90
|
this.gl.bindAttribLocation(this.program, 1, "position2d");
|
|
114
91
|
this.gl.bindAttribLocation(this.program, 2, "color");
|
|
115
|
-
// this.gl.bindAttribLocation(this.program, 3, "dash_length");
|
|
116
|
-
// this.gl.bindAttribLocation(this.program, 4, "dash_opacity");
|
|
117
92
|
this.cameraBlockTotem = CameraUniformBlockTotemCache.get(globe);
|
|
118
93
|
this.cameraBlockTotem.assignBindingPoint(this.program, uniformBindingPoints.camera);
|
|
119
94
|
flexibleBlockManager.assignBindingPoint(this.gl, this.program);
|
|
@@ -125,16 +100,13 @@ export class LineProgram {
|
|
|
125
100
|
this._ubosPublished.push(ubo);
|
|
126
101
|
return ubo;
|
|
127
102
|
}
|
|
128
|
-
createVAO(position3D, position2D, color
|
|
129
|
-
) {
|
|
103
|
+
createVAO(position3D, position2D, color) {
|
|
130
104
|
const { gl } = this;
|
|
131
105
|
const vao = gl.createVertexArray();
|
|
132
106
|
gl.bindVertexArray(vao);
|
|
133
107
|
attributeLoader(gl, position3D, 0, 3);
|
|
134
108
|
attributeLoader(gl, position2D, 1, 2);
|
|
135
109
|
attributeLoader(gl, color, 2, 4, { escapeValues: [ESCAPE_VALUE, ESCAPE_VALUE, ESCAPE_VALUE, ESCAPE_VALUE] });
|
|
136
|
-
// attributeLoader(gl, dashLength, 3, 1, { escapeValues: [ESCAPE_VALUE] });
|
|
137
|
-
// attributeLoader(gl, dashOpacity, 4, 1, { escapeValues: [ESCAPE_VALUE] });
|
|
138
110
|
gl.bindVertexArray(null);
|
|
139
111
|
return vao;
|
|
140
112
|
}
|
|
@@ -100,7 +100,6 @@ class Logic {
|
|
|
100
100
|
const vao = gl.createVertexArray();
|
|
101
101
|
const divisor = 1;
|
|
102
102
|
gl.bindVertexArray(vao);
|
|
103
|
-
// TODO constants to escape values
|
|
104
103
|
attributeLoader(gl, pos3DObj, 0, 3, { divisor });
|
|
105
104
|
attributeLoader(gl, radiusObj, 1, 1, { divisor, escapeValues: [-1] });
|
|
106
105
|
attributeLoader(gl, colorObj, 2, 4, { divisor, escapeValues: [-1, -1, -1, -1] });
|