@pirireis/webglobeplugins 0.17.1 → 1.0.3
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/haversine.js +22 -0
- package/Math/methods.js +15 -2
- package/Math/tessellation/methods.js +4 -1
- package/Math/tessellation/nearest-value-padding.js +112 -0
- package/Math/tessellation/spherical-triangle-area.js +99 -0
- package/Math/tessellation/tile-merger.js +346 -215
- package/Math/tessellation/triangle-tessellation.js +381 -9
- package/Math/vec3.js +4 -0
- package/Math/xyz-tile.js +18 -0
- package/altitude-locator/plugin.js +1 -2
- package/investigation-tools/draw/tiles/adapters.js +2 -2
- package/investigation-tools/draw/tiles/tiles.js +2 -2
- package/package.json +1 -1
- package/programs/helpers/fadeaway.js +6 -1
- package/programs/point-on-globe/square-pixel-point.js +1 -0
- package/programs/polygon-on-globe/texture-dem-triangles.js +94 -116
- package/programs/totems/camera-totem-attactment-interface.js +1 -0
- package/programs/totems/camerauniformblock.js +33 -22
- package/programs/totems/dem-textures-manager.js +265 -0
- package/programs/vectorfields/logics/drawrectangleparticles.js +51 -18
- package/programs/vectorfields/logics/{ubo-new.js → particle-ubo.js} +5 -14
- package/programs/vectorfields/logics/pixelbased.js +42 -36
- package/programs/vectorfields/pingpongbuffermanager.js +34 -8
- package/semiplugins/shape-on-terrain/terrain-polygon/adapters.js +55 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/cache.js +102 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/index-polygon-map.js +45 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/manager.js +4 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +177 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.js +100 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/random.js +121 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/types.js +1 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/worker-contact.js +63 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +125 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/terrain-polygon.js +219 -0
- package/semiplugins/shape-on-terrain/terrain-polygon/types.js +8 -0
- package/semiplugins/shell/bbox-renderer/logic.js +18 -58
- package/semiplugins/shell/bbox-renderer/object.js +19 -9
- package/tracks/point-heat-map/point-to-heat-map-flow.js +1 -1
- package/tracks/point-tracks/plugin.js +13 -6
- package/tracks/timetracks/program-line-strip.js +1 -1
- package/util/account/single-attribute-buffer-management/buffer-manager.js +5 -3
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +2 -2
- package/util/gl-util/uniform-block/manager.js +20 -10
- package/util/helper-methods.js +8 -0
- package/util/picking/fence.js +4 -2
- package/util/picking/picker-displayer.js +51 -9
- package/util/programs/draw-texture-on-canvas.js +18 -15
- package/util/shaderfunctions/geometrytransformations.js +67 -1
- package/vectorfield/waveparticles/plugin.js +241 -116
- package/vectorfield/wind/adapters/image-to-fields.js +61 -0
- package/vectorfield/wind/adapters/types.js +1 -0
- package/vectorfield/wind/imagetovectorfieldandmagnitude.js +6 -9
- package/vectorfield/wind/plugin-persistant copy.js +364 -0
- package/vectorfield/wind/plugin-persistant.js +375 -0
- package/vectorfield/wind/plugin.js +1 -1
- package/Math/tessellation/earcut/adapters.js +0 -37
- package/Math/tessellation/hybrid-triangle-tessellation-meta.js +0 -123
- package/Math/tessellation/shred-input.js +0 -18
- package/Math/tessellation/tiler.js +0 -50
- package/Math/tessellation/triangle-tessellation-meta.js +0 -523
- package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +0 -328
- package/programs/vectorfields/logics/drawrectangleparticles1.js +0 -112
- package/semiplugins/shape-on-terrain/terrain-cover/texture-dem-cover.js +0 -1
- package/util/gl-util/uniform-block/types.js +0 -1
- package/util/webglobe/index.js +0 -2
- /package/Math/tessellation/{zoom-catch.js → constants.js} +0 -0
- /package/util/{webglobe/gldefaultstates.js → globe-default-gl-states.js} +0 -0
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/// <reference lib="webworker" />
|
|
2
|
+
import { Cache } from "./cache";
|
|
3
|
+
import { partialTessellation, zoomLevelShowThreshold } from "../../../../Math/tessellation/triangle-tessellation";
|
|
4
|
+
import { IndexAttributeEscapeValue } from "../../../../programs/polygon-on-globe/texture-dem-triangles";
|
|
5
|
+
const cache = new Cache(100); // 100 km threshold
|
|
6
|
+
let _pickableState = false;
|
|
7
|
+
let _variativeColorsOnState = false;
|
|
8
|
+
let showThreshold = 0;
|
|
9
|
+
// eslint-disable-next-line no-restricted-globals
|
|
10
|
+
self.onmessage = (event) => {
|
|
11
|
+
try {
|
|
12
|
+
const { bboxes, insertDeleteQueue, pickableState, variativeColorsOn } = event.data;
|
|
13
|
+
if (variativeColorsOn !== undefined) {
|
|
14
|
+
_variativeColorsOnState = variativeColorsOn;
|
|
15
|
+
}
|
|
16
|
+
if (pickableState !== undefined) {
|
|
17
|
+
_pickableState = pickableState;
|
|
18
|
+
}
|
|
19
|
+
// Process insert/delete queue
|
|
20
|
+
if (insertDeleteQueue[0] === "__CLEAR_ALL_ITEMS__") {
|
|
21
|
+
insertDeleteQueue.shift();
|
|
22
|
+
cache.clear();
|
|
23
|
+
}
|
|
24
|
+
for (const item of insertDeleteQueue) {
|
|
25
|
+
if (typeof item === 'string') {
|
|
26
|
+
cache.remove(item);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
cache.insert(item.key, item);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// Update bboxes if provided
|
|
33
|
+
if (bboxes) {
|
|
34
|
+
cache.setBBOXes(bboxes);
|
|
35
|
+
showThreshold = zoomLevelShowThreshold(bboxes[0].zoom, 0.03);
|
|
36
|
+
}
|
|
37
|
+
// Search for triangles in view
|
|
38
|
+
const trianglesInView = cache.search();
|
|
39
|
+
// Prepare arrays for merging
|
|
40
|
+
const results = [];
|
|
41
|
+
// Convert bbox to BBoxZoom format for partialTessellation
|
|
42
|
+
const bboxZooms = bboxes ? bboxes.map(b => ({
|
|
43
|
+
bbox: {
|
|
44
|
+
min: [b.minX, b.minY],
|
|
45
|
+
max: [b.maxX, b.maxY]
|
|
46
|
+
},
|
|
47
|
+
zoom: b.zoom
|
|
48
|
+
})) : []; // This will be empty if no bbox, causing issues
|
|
49
|
+
let counter = 0;
|
|
50
|
+
let indexCounter = 0;
|
|
51
|
+
// Process each triangle
|
|
52
|
+
for (const triangle of trianglesInView) {
|
|
53
|
+
if (triangle.tessellationMeta.showThreshold * 0.075 > showThreshold) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const result = (triangle.tessellationMeta.showThreshold < showThreshold) ? partialTessellation(triangle.tessellationMeta, bboxZooms, 5 // innerCuts parameter
|
|
57
|
+
) : triangle.tessellationMeta.shortCut;
|
|
58
|
+
counter += result.vec3s.length;
|
|
59
|
+
indexCounter += result.indices.length;
|
|
60
|
+
if (_pickableState) {
|
|
61
|
+
// TODO: find a better way to fill indeces to final array
|
|
62
|
+
result.pickIndex = triangle.polygon.index;
|
|
63
|
+
}
|
|
64
|
+
if (_variativeColorsOnState) {
|
|
65
|
+
const color = triangle.polygon.color || [IndexAttributeEscapeValue, IndexAttributeEscapeValue, IndexAttributeEscapeValue, IndexAttributeEscapeValue];
|
|
66
|
+
result.variativeColors = color;
|
|
67
|
+
// Update offset for next triangle
|
|
68
|
+
}
|
|
69
|
+
results.push(result);
|
|
70
|
+
}
|
|
71
|
+
// Send results back
|
|
72
|
+
const output = {
|
|
73
|
+
vec3s: new Float32Array(counter),
|
|
74
|
+
longLats: new Float32Array(counter / 3 * 2),
|
|
75
|
+
indices: new Uint32Array(indexCounter),
|
|
76
|
+
};
|
|
77
|
+
if (_pickableState) {
|
|
78
|
+
output.pickIndices = new Float32Array(counter / 3);
|
|
79
|
+
}
|
|
80
|
+
if (_variativeColorsOnState) {
|
|
81
|
+
output.variativeColors = new Float32Array(counter / 3 * 4);
|
|
82
|
+
}
|
|
83
|
+
let currentVertexOffset = 0;
|
|
84
|
+
let indexOffset = 0;
|
|
85
|
+
for (const result of results) {
|
|
86
|
+
output.vec3s.set(result.vec3s, currentVertexOffset);
|
|
87
|
+
output.longLats.set(result.longLats, (currentVertexOffset / 3) * 2);
|
|
88
|
+
output.indices.set(result.indices.map(i => i + currentVertexOffset / 3), indexOffset);
|
|
89
|
+
currentVertexOffset += result.vec3s.length;
|
|
90
|
+
indexOffset += result.indices.length;
|
|
91
|
+
if (_pickableState) {
|
|
92
|
+
const subArray = output.pickIndices.subarray(currentVertexOffset / 3 - result.vec3s.length / 3, currentVertexOffset / 3);
|
|
93
|
+
subArray.fill(result.pickIndex);
|
|
94
|
+
}
|
|
95
|
+
if (_variativeColorsOnState && result.variativeColors) {
|
|
96
|
+
const vertexCount = result.vec3s.length / 3;
|
|
97
|
+
const colorStartIndex = (currentVertexOffset / 3 - vertexCount) * 4;
|
|
98
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
99
|
+
const offset = colorStartIndex + i * 4;
|
|
100
|
+
output.variativeColors[offset] = result.variativeColors[0];
|
|
101
|
+
output.variativeColors[offset + 1] = result.variativeColors[1];
|
|
102
|
+
output.variativeColors[offset + 2] = result.variativeColors[2];
|
|
103
|
+
output.variativeColors[offset + 3] = result.variativeColors[3];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const buffers = [
|
|
108
|
+
output.vec3s.buffer,
|
|
109
|
+
output.indices.buffer,
|
|
110
|
+
output.longLats.buffer,
|
|
111
|
+
];
|
|
112
|
+
if (pickableState && output.pickIndices) {
|
|
113
|
+
buffers.push(output.pickIndices.buffer);
|
|
114
|
+
}
|
|
115
|
+
if (_variativeColorsOnState && output.variativeColors) {
|
|
116
|
+
buffers.push(output.variativeColors.buffer);
|
|
117
|
+
}
|
|
118
|
+
// eslint-disable-next-line no-restricted-globals
|
|
119
|
+
self.postMessage(output, buffers);
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
console.error('Error in worker:', error);
|
|
123
|
+
// self.postMessage({ error: error.message || 'Unknown error in worker' });
|
|
124
|
+
}
|
|
125
|
+
};
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { WorkerContact } from "./data/worker-contact";
|
|
2
|
+
import { TextureDemTriangles } from "../../../programs/polygon-on-globe/texture-dem-triangles";
|
|
3
|
+
import { noRegisterGlobeProgramCache } from "../../../programs/programcache";
|
|
4
|
+
import { PickerDisplayer } from "../../../util/picking/picker-displayer";
|
|
5
|
+
import { IndexPolygonMap } from "./data/index-polygon-map";
|
|
6
|
+
export class TerrainPolygonSemiPlugin {
|
|
7
|
+
id;
|
|
8
|
+
globe = null;
|
|
9
|
+
_options = {
|
|
10
|
+
pickable: false,
|
|
11
|
+
variativeColorsOn: false,
|
|
12
|
+
defaultColor: [0.5, 0.5, 1, 1],
|
|
13
|
+
pickedColor: [1, 0, 0, 1],
|
|
14
|
+
opacity: 1.0,
|
|
15
|
+
showTesselationPoints: false,
|
|
16
|
+
};
|
|
17
|
+
_workerContact = null;
|
|
18
|
+
_program = null;
|
|
19
|
+
_pickerDisplayer = null;
|
|
20
|
+
_indexPolygonMap = new IndexPolygonMap();
|
|
21
|
+
_lastPickedPolygon = null;
|
|
22
|
+
_elementArrayBuffer = null;
|
|
23
|
+
_vec3Buffer = null;
|
|
24
|
+
_pickIndexBuffer = null;
|
|
25
|
+
_variativeColorBuffer = null;
|
|
26
|
+
_mercatorXYBuffer = null;
|
|
27
|
+
_vao = null;
|
|
28
|
+
_uboHandler = null;
|
|
29
|
+
_drawPointsRangeIndexParams = {
|
|
30
|
+
drawRange: {
|
|
31
|
+
first: 0,
|
|
32
|
+
count: 0,
|
|
33
|
+
},
|
|
34
|
+
drawMode: WebGL2RenderingContext.POINTS,
|
|
35
|
+
elementBufferIndexType: WebGL2RenderingContext.UNSIGNED_INT,
|
|
36
|
+
elementBuffer: WebGLBuffer = null,
|
|
37
|
+
};
|
|
38
|
+
_drawRangeIndexParams = {
|
|
39
|
+
drawRange: {
|
|
40
|
+
first: 0,
|
|
41
|
+
count: 0,
|
|
42
|
+
},
|
|
43
|
+
drawMode: WebGL2RenderingContext.TRIANGLES,
|
|
44
|
+
elementBufferIndexType: WebGL2RenderingContext.UNSIGNED_INT,
|
|
45
|
+
elementBuffer: WebGLBuffer = null,
|
|
46
|
+
};
|
|
47
|
+
constructor(id, options = {}) {
|
|
48
|
+
this.id = id;
|
|
49
|
+
this._options = { ...this._options, ...options };
|
|
50
|
+
}
|
|
51
|
+
;
|
|
52
|
+
init(globe, gl) {
|
|
53
|
+
this.globe = globe;
|
|
54
|
+
this._drawRangeIndexParams.drawMode = globe.gl.TRIANGLES;
|
|
55
|
+
this._drawRangeIndexParams.elementBufferIndexType = globe.gl.UNSIGNED_INT;
|
|
56
|
+
this._program = noRegisterGlobeProgramCache.getProgram(this.globe, TextureDemTriangles);
|
|
57
|
+
this._elementArrayBuffer = gl.createBuffer();
|
|
58
|
+
this._vec3Buffer = gl.createBuffer();
|
|
59
|
+
this._mercatorXYBuffer = gl.createBuffer();
|
|
60
|
+
this._uboHandler = this._program.createUBO();
|
|
61
|
+
this._uboHandler.updateSingle("opacity", new Float32Array([this._options.opacity]));
|
|
62
|
+
this._uboHandler.updateSingle("defaultColor", new Float32Array(this._options.defaultColor));
|
|
63
|
+
if (this._options.pickable) {
|
|
64
|
+
this._pickIndexBuffer = gl.createBuffer();
|
|
65
|
+
this._pickerDisplayer = new PickerDisplayer(this.globe, "R32I");
|
|
66
|
+
this._uboHandler.updateSingle("private_isPickedOn", new Float32Array([1.0]));
|
|
67
|
+
this._uboHandler.updateSingle("pickedColor", new Float32Array(this._options.pickedColor));
|
|
68
|
+
}
|
|
69
|
+
if (this._options.variativeColorsOn) {
|
|
70
|
+
this._variativeColorBuffer = gl.createBuffer();
|
|
71
|
+
}
|
|
72
|
+
this._vao = this._program.createVAO({
|
|
73
|
+
offset: 0,
|
|
74
|
+
stride: 0,
|
|
75
|
+
buffer: this._vec3Buffer
|
|
76
|
+
}, {
|
|
77
|
+
offset: 0,
|
|
78
|
+
stride: 0,
|
|
79
|
+
buffer: this._mercatorXYBuffer
|
|
80
|
+
}, this._options.pickable ? {
|
|
81
|
+
offset: 0,
|
|
82
|
+
stride: 0,
|
|
83
|
+
buffer: this._pickIndexBuffer
|
|
84
|
+
} : undefined, this._options.variativeColorsOn ? {
|
|
85
|
+
offset: 0,
|
|
86
|
+
stride: 0,
|
|
87
|
+
buffer: this._variativeColorBuffer
|
|
88
|
+
} : undefined);
|
|
89
|
+
this._drawRangeIndexParams.elementBuffer = this._elementArrayBuffer;
|
|
90
|
+
this._workerContact = new WorkerContact(this.globe, this._options, (result) => {
|
|
91
|
+
// console.log('TerrainPolygonSemiPlugin received data from worker', result);
|
|
92
|
+
this.setBuffers(result);
|
|
93
|
+
});
|
|
94
|
+
this._drawRangeIndexParams.elementBuffer = this._elementArrayBuffer;
|
|
95
|
+
this._drawPointsRangeIndexParams.elementBuffer = this._elementArrayBuffer;
|
|
96
|
+
}
|
|
97
|
+
insertBulk(polygons) {
|
|
98
|
+
// if (this._indexPolygonMap) {
|
|
99
|
+
polygons = this._indexPolygonMap.insertBulk(polygons);
|
|
100
|
+
// }
|
|
101
|
+
this._workerContact.insertBulk(polygons);
|
|
102
|
+
}
|
|
103
|
+
deleteBulk(keys) {
|
|
104
|
+
this._workerContact.deleteBulk(keys);
|
|
105
|
+
this._indexPolygonMap.deleteBulk(keys);
|
|
106
|
+
}
|
|
107
|
+
setUniform(name, value) {
|
|
108
|
+
// check options have the key name
|
|
109
|
+
if (name.startsWith("private_")) {
|
|
110
|
+
throw new Error(`Cannot set private uniform ${name}`);
|
|
111
|
+
}
|
|
112
|
+
if (this._options.hasOwnProperty(name)) {
|
|
113
|
+
if (this._options[name] === value) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
this._options[name] = value;
|
|
117
|
+
}
|
|
118
|
+
this._uboHandler.updateSingle(name, value);
|
|
119
|
+
this.globe.DrawRender();
|
|
120
|
+
}
|
|
121
|
+
setOpacity(opacity) {
|
|
122
|
+
if (this._options.opacity !== opacity) {
|
|
123
|
+
this._options.opacity = opacity;
|
|
124
|
+
this._uboHandler.updateSingle("opacity", new Float32Array([opacity]));
|
|
125
|
+
this.globe.DrawRender();
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
setBuffers(data) {
|
|
129
|
+
console.log("TerrainPolygonSemiPlugin updating buffers", data.indices.length / 3, "triangles");
|
|
130
|
+
const gl = this.globe.gl;
|
|
131
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this._elementArrayBuffer);
|
|
132
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data.indices, gl.STREAM_DRAW);
|
|
133
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._vec3Buffer);
|
|
134
|
+
gl.bufferData(gl.ARRAY_BUFFER, data.vec3s, gl.STREAM_DRAW);
|
|
135
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._mercatorXYBuffer);
|
|
136
|
+
gl.bufferData(gl.ARRAY_BUFFER, data.longLats, gl.STREAM_DRAW);
|
|
137
|
+
if (this._options.pickable) {
|
|
138
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._pickIndexBuffer);
|
|
139
|
+
gl.bufferData(gl.ARRAY_BUFFER, data.pickIndices, gl.STREAM_DRAW);
|
|
140
|
+
}
|
|
141
|
+
if (this._options.variativeColorsOn) {
|
|
142
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, this._variativeColorBuffer);
|
|
143
|
+
gl.bufferData(gl.ARRAY_BUFFER, data.variativeColors, gl.STREAM_DRAW);
|
|
144
|
+
}
|
|
145
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
146
|
+
this._drawRangeIndexParams.drawRange.count = data.indices.length;
|
|
147
|
+
this._drawPointsRangeIndexParams.drawRange.count = data.indices.length;
|
|
148
|
+
this.globe.DrawRender();
|
|
149
|
+
}
|
|
150
|
+
getPickedPolygon() {
|
|
151
|
+
if (this._options.pickable === false) {
|
|
152
|
+
throw new Error("TerrainPolygonSemiPlugin is not pickable. Set pickable option to true on construction to enable picking.");
|
|
153
|
+
}
|
|
154
|
+
return this._lastPickedPolygon;
|
|
155
|
+
}
|
|
156
|
+
_selfSelect() {
|
|
157
|
+
const { globe, _pickerDisplayer } = this;
|
|
158
|
+
const pos = globe.api_GetMousePos();
|
|
159
|
+
const x = pos.canvasX;
|
|
160
|
+
const y = globe.api_ScrH() - pos.canvasY;
|
|
161
|
+
_pickerDisplayer.pickXY(x, y, 0, (selectedIDsSet) => {
|
|
162
|
+
if (selectedIDsSet.size > 0) {
|
|
163
|
+
const selectedID = Array.from(selectedIDsSet)[0];
|
|
164
|
+
const newPolygon = this._indexPolygonMap.get(selectedID) || null;
|
|
165
|
+
if (newPolygon !== this._lastPickedPolygon) {
|
|
166
|
+
this._lastPickedPolygon = newPolygon;
|
|
167
|
+
globe.DrawRender();
|
|
168
|
+
this._uboHandler.updateSingle("private_pickedIndex", new Float32Array([selectedID]));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
if (this._lastPickedPolygon !== null) {
|
|
173
|
+
this._lastPickedPolygon = null;
|
|
174
|
+
globe.DrawRender();
|
|
175
|
+
this._uboHandler.updateSingle("private_pickedIndex", new Float32Array([-1]));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
clear() {
|
|
181
|
+
this._workerContact.clear();
|
|
182
|
+
this._indexPolygonMap.clear();
|
|
183
|
+
}
|
|
184
|
+
// GLOBE API INTERACTION METHODS
|
|
185
|
+
resize() {
|
|
186
|
+
if (this._options.pickable) {
|
|
187
|
+
this._pickerDisplayer?.resize();
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
draw3D() {
|
|
191
|
+
const gl = this.globe.gl;
|
|
192
|
+
gl.disable(gl.DEPTH_TEST);
|
|
193
|
+
// drawPoints
|
|
194
|
+
if (this._options.showTesselationPoints) {
|
|
195
|
+
this._program.draw(this._vao, this._drawPointsRangeIndexParams, this._uboHandler);
|
|
196
|
+
}
|
|
197
|
+
if (this._pickerDisplayer) {
|
|
198
|
+
this._pickerDisplayer.bindFBO();
|
|
199
|
+
this._pickerDisplayer.clearTextures();
|
|
200
|
+
// gl.enable(gl.DEPTH_TEST);
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
// gl.disable(gl.DEPTH_TEST);
|
|
204
|
+
}
|
|
205
|
+
gl.frontFace(gl.CW);
|
|
206
|
+
this._program.draw(this._vao, this._drawRangeIndexParams, this._uboHandler);
|
|
207
|
+
gl.frontFace(gl.CCW);
|
|
208
|
+
if (this._pickerDisplayer) {
|
|
209
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
210
|
+
this._pickerDisplayer.drawColorTexture();
|
|
211
|
+
this._selfSelect();
|
|
212
|
+
}
|
|
213
|
+
gl.enable(gl.DEPTH_TEST);
|
|
214
|
+
}
|
|
215
|
+
free() {
|
|
216
|
+
this._workerContact.free();
|
|
217
|
+
noRegisterGlobeProgramCache.releaseProgram(this.globe, TextureDemTriangles);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createProgram } from '../../../util/webglobjectbuilders';
|
|
2
2
|
import { noRegisterGlobeProgramCache } from '../../../programs/programcache';
|
|
3
|
-
import { CameraUniformBlockString, CameraUniformBlockTotemCache
|
|
3
|
+
import { CameraUniformBlockString, CameraUniformBlockTotemCache } from "../../../programs/totems/camerauniformblock";
|
|
4
4
|
const UniformBlockBindingPoints = {
|
|
5
5
|
ShellBlock: 0,
|
|
6
6
|
CameraBlock: 1,
|
|
@@ -99,9 +99,20 @@ const fragmentShader = `#version 300 es
|
|
|
99
99
|
outColor = texture(u_texture, v_texture_coordinate);
|
|
100
100
|
outColor.a *= v_opacity;
|
|
101
101
|
}`;
|
|
102
|
-
class BBOXGlobeShellProgram {
|
|
102
|
+
export class BBOXGlobeShellProgram {
|
|
103
|
+
id = "BBOXGlobeShellProgram";
|
|
104
|
+
description;
|
|
105
|
+
gl;
|
|
106
|
+
globe;
|
|
107
|
+
programWrapper;
|
|
108
|
+
cameraBlockTotem;
|
|
109
|
+
_transformArray;
|
|
110
|
+
_xRes;
|
|
111
|
+
_yRes;
|
|
112
|
+
_vao;
|
|
113
|
+
_indexBuffer;
|
|
114
|
+
_drawCount;
|
|
103
115
|
constructor(globe) {
|
|
104
|
-
this.id = "BBOXGlobeShellProgram";
|
|
105
116
|
this.description = "This program implements flyweight pattern for globe." +
|
|
106
117
|
"At globes draw3D call stack, this program should be prior to any program that uses it." +
|
|
107
118
|
"draw3D method of this object only sets Projetion, ModelView and Translate matrices and if the mode is 2D mapWH .";
|
|
@@ -111,8 +122,6 @@ class BBOXGlobeShellProgram {
|
|
|
111
122
|
this.cameraBlockTotem = CameraUniformBlockTotemCache.get(globe);
|
|
112
123
|
this.cameraBlockTotem.assignBindingPoint(this.programWrapper.program, UniformBlockBindingPoints.CameraBlock);
|
|
113
124
|
this._transformArray = new Float32Array(3);
|
|
114
|
-
// this.setGeometry();
|
|
115
|
-
// this.resize();
|
|
116
125
|
this.updateTime(0);
|
|
117
126
|
this.setMesh({ xRes: 64, yRes: 64, eastWestTied: false });
|
|
118
127
|
}
|
|
@@ -128,9 +137,9 @@ class BBOXGlobeShellProgram {
|
|
|
128
137
|
program,
|
|
129
138
|
u_texture: gl.getUniformLocation(program, "u_texture"),
|
|
130
139
|
u_mesh_resolution: gl.getUniformLocation(program, "u_mesh_resolution"),
|
|
140
|
+
u_time: gl.getUniformLocation(program, "u_time")
|
|
131
141
|
};
|
|
132
142
|
}
|
|
133
|
-
// this method implements data part of flyweight pattern
|
|
134
143
|
getShellBlockBufferManager() {
|
|
135
144
|
return new ShellBlockManager(this.gl);
|
|
136
145
|
}
|
|
@@ -141,57 +150,6 @@ class BBOXGlobeShellProgram {
|
|
|
141
150
|
gl.uniform1f(this.programWrapper.u_time, time);
|
|
142
151
|
gl.useProgram(currentProgram);
|
|
143
152
|
}
|
|
144
|
-
// setRotationAndTranslation(uProjectionMatrix, uModelViewMatrix, uTranslate, resetCurrentProgram = false) {
|
|
145
|
-
// const gl = this.gl;
|
|
146
|
-
// let currentProgram = null;
|
|
147
|
-
// if (resetCurrentProgram) { currentProgram = gl.getParameter(gl.CURRENT_PROGRAM) };
|
|
148
|
-
// gl.useProgram(this.programWrapper.program);
|
|
149
|
-
// gl.uniformMatrix4fv(this.programWrapper.projection, false, uProjectionMatrix);
|
|
150
|
-
// gl.uniformMatrix4fv(this.programWrapper.view, false, uModelViewMatrix);
|
|
151
|
-
// this._transformArray.set([uTranslate.x, uTranslate.y, uTranslate.z], 0);
|
|
152
|
-
// gl.uniform3fv(this.programWrapper.translate, this._transformArray);
|
|
153
|
-
// if (resetCurrentProgram) gl.useProgram(currentProgram);
|
|
154
|
-
// }
|
|
155
|
-
// setGeometry() {
|
|
156
|
-
// const { globe, gl } = this;
|
|
157
|
-
// const { is3D, screenWH, program } = this.programWrapper;
|
|
158
|
-
// const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
159
|
-
// const is3D = this.globe.api_GetCurrentGeometry() === 0;
|
|
160
|
-
// gl.useProgram(program);
|
|
161
|
-
// if (globe.api_GetCurrentGeometry() === globe.api_GeometryTypes().FLAT) {
|
|
162
|
-
// gl.uniform2f(screenWH, globe.api_ScrW(), globe.api_ScrH());
|
|
163
|
-
// }
|
|
164
|
-
// gl.uniform1i(is3D, is3D);
|
|
165
|
-
// gl.useProgram(currentProgram);
|
|
166
|
-
// }
|
|
167
|
-
// resize() {
|
|
168
|
-
// const { gl, globe } = this;
|
|
169
|
-
// if (!globe) return;
|
|
170
|
-
// const { program, screenWH } = this.programWrapper;
|
|
171
|
-
// const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
172
|
-
// gl.useProgram(program);
|
|
173
|
-
// if (globe.api_GetCurrentGeometry() === globe.api_GeometryTypes().FLAT) {
|
|
174
|
-
// gl.uniform2f(screenWH, globe.api_ScrW(), globe.api_ScrH());
|
|
175
|
-
// }
|
|
176
|
-
// gl.useProgram(currentProgram);
|
|
177
|
-
// }
|
|
178
|
-
// only sets
|
|
179
|
-
// data does not draw
|
|
180
|
-
// draw3D(csRenderPass) {
|
|
181
|
-
// const { gl, globe } = this;
|
|
182
|
-
// const { program } = this.programWrapper; //view, projection, translate
|
|
183
|
-
// gl.disable(gl.DEPTH_TEST);
|
|
184
|
-
// gl.useProgram(program);
|
|
185
|
-
// // gl.uniformMatrix4fv(projection, false, uProjectionMatrix);
|
|
186
|
-
// // gl.uniformMatrix4fv(view, false, uModelViewMatrix);
|
|
187
|
-
// // // this._transformArray.set([], 0);
|
|
188
|
-
// // gl.uniform3f(translate, uTranslate.x, uTranslate.y, uTranslate.z);
|
|
189
|
-
// if (globe.api_GetCurrentGeometry() === 1) {
|
|
190
|
-
// const { width, height } = globe.api_GetCurrentWorldWH();
|
|
191
|
-
// gl.uniform2fv(this.programWrapper.mapWH, [width, height]);
|
|
192
|
-
// }
|
|
193
|
-
// gl.enable(gl.DEPTH_TEST);
|
|
194
|
-
// }
|
|
195
153
|
draw(texture, shellBlockDataManager, drawLines = false, csRenderPass) {
|
|
196
154
|
const { gl, programWrapper, _vao, _drawCount } = this;
|
|
197
155
|
const { program, u_texture } = programWrapper;
|
|
@@ -277,7 +235,9 @@ class BBOXGlobeShellProgram {
|
|
|
277
235
|
return { _vao };
|
|
278
236
|
}
|
|
279
237
|
}
|
|
280
|
-
class ShellBlockManager {
|
|
238
|
+
export class ShellBlockManager {
|
|
239
|
+
gl;
|
|
240
|
+
buffer;
|
|
281
241
|
constructor(gl) {
|
|
282
242
|
this.gl = gl;
|
|
283
243
|
this.buffer = gl.createBuffer();
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
import { BBOXGlobeShellProgramCache } from './logic';
|
|
2
2
|
export class BBOXGlobeShell {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
gl;
|
|
4
|
+
globe;
|
|
5
|
+
program;
|
|
6
|
+
shellBlockManager;
|
|
7
|
+
update;
|
|
8
|
+
innerTime;
|
|
9
|
+
texture;
|
|
10
|
+
bbox;
|
|
11
|
+
wiggleInKM;
|
|
12
|
+
wiggleSpeed;
|
|
13
|
+
constructor(gl, globe, { minLon = -180, maxLon = 180, minLat = -90, maxLat = 90, height = 0, u_opacity = 1, wiggleInKM = 0, wiggleSpeed = 0, } = {}) {
|
|
6
14
|
this.gl = gl;
|
|
7
15
|
this.globe = globe;
|
|
8
16
|
this.program = BBOXGlobeShellProgramCache.get(globe);
|
|
9
17
|
this.shellBlockManager = this.program.getShellBlockBufferManager();
|
|
10
18
|
this.update = this.shellBlockManager.update.bind(this.shellBlockManager);
|
|
11
19
|
this.innerTime = 0;
|
|
20
|
+
this.wiggleInKM = wiggleInKM;
|
|
21
|
+
this.wiggleSpeed = wiggleSpeed;
|
|
12
22
|
this.setBBox({ minLon, maxLon, minLat, maxLat });
|
|
13
23
|
this.setOpacity(u_opacity);
|
|
14
24
|
this.setHeight(height);
|
|
@@ -34,9 +44,10 @@ export class BBOXGlobeShell {
|
|
|
34
44
|
// y
|
|
35
45
|
const vertOffset = (90 - maxLat) * Math.PI / 180;
|
|
36
46
|
const vertSize = (maxLat - minLat) * Math.PI / 180;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
47
|
+
this.shellBlockManager.update({
|
|
48
|
+
gridSizeRad: [horSize, vertSize],
|
|
49
|
+
gridOffsetRad: [horOffset, vertOffset]
|
|
50
|
+
});
|
|
40
51
|
this.globe.DrawRender();
|
|
41
52
|
}
|
|
42
53
|
setWiggle({ wiggleSpeed = null, wiggleInKM = null }) {
|
|
@@ -47,11 +58,10 @@ export class BBOXGlobeShell {
|
|
|
47
58
|
this.shellBlockManager.update({ wiggleInKM });
|
|
48
59
|
}
|
|
49
60
|
/**
|
|
50
|
-
*
|
|
51
|
-
* @param {*} program modelView, projection, translate, mapWH, scrWH, should be set before calling this function
|
|
61
|
+
* @param csRenderPass - modelView, projection, translate, mapWH, scrWH, should be set before calling this function
|
|
52
62
|
*/
|
|
53
63
|
draw(csRenderPass) {
|
|
54
|
-
this.program.draw(this.texture, this.shellBlockManager, csRenderPass);
|
|
64
|
+
this.program.draw(this.texture, this.shellBlockManager, false, csRenderPass);
|
|
55
65
|
if (this.wiggleInKM > 0 && this.wiggleSpeed > 0) {
|
|
56
66
|
this.innerTime += this.wiggleSpeed;
|
|
57
67
|
this.shellBlockManager.update({ innerTime: this.innerTime });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { densityToLegendProgramCache } from "../../programs/data2legend/density-to-legend";
|
|
2
2
|
import { pointToDensityTextureCache } from "../../programs/data2legend/point-to-density-texture";
|
|
3
3
|
// import { textureOnCanvasProgramCache } from "../../util/programs/draw-texture-on-canvas";
|
|
4
|
-
import { defaultblendfunction } from "../../util/
|
|
4
|
+
import { defaultblendfunction } from "../../util/globe-default-gl-states";
|
|
5
5
|
class PointHeatmapFlow {
|
|
6
6
|
constructor(globe) {
|
|
7
7
|
this.globe = null;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
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
|
-
import { defaultblendfunction } from "../../util/
|
|
4
|
+
import { defaultblendfunction } from "../../util/globe-default-gl-states";
|
|
5
5
|
import { wgs84ToCartesian3d, wgs84ToMercator } from "../../Math/methods";
|
|
6
6
|
const _0vec3 = /* @__PURE__ */ [0, 0, 0];
|
|
7
7
|
/**
|
|
@@ -66,8 +66,14 @@ class PointTracksPlugin {
|
|
|
66
66
|
adaptor: (item) => new Float32Array(wgs84ToMercator(item.long, item.lat))
|
|
67
67
|
}],
|
|
68
68
|
["rgba", {
|
|
69
|
-
bufferManager: new BufferManager(gl, 4, { bufferType, initialCapacity }),
|
|
70
|
-
adaptor: (item) =>
|
|
69
|
+
bufferManager: new BufferManager(gl, 4, { bufferType, initialCapacity, typedArrayConstructor: Float32Array }),
|
|
70
|
+
// adaptor: (item) => new Uint8Array([
|
|
71
|
+
// item.rgba[0] * 255,
|
|
72
|
+
// item.rgba[1] * 255,
|
|
73
|
+
// item.rgba[2] * 255,
|
|
74
|
+
// item.rgba[3] * 255
|
|
75
|
+
// ])
|
|
76
|
+
adaptor: (item) => new Float32Array(item.rgba)
|
|
71
77
|
}],
|
|
72
78
|
["objectStore", {
|
|
73
79
|
bufferManager: new ObjectStore({ initialCapacity }),
|
|
@@ -196,12 +202,13 @@ class PointTracksPlugin {
|
|
|
196
202
|
focusTracks(trackIDs = null) {
|
|
197
203
|
if (!this.globe)
|
|
198
204
|
return;
|
|
199
|
-
if (
|
|
205
|
+
if (trackIDs === null) {
|
|
200
206
|
this._focusParams.on = false;
|
|
201
207
|
this.globe?.DrawRender();
|
|
202
208
|
return;
|
|
203
209
|
}
|
|
204
|
-
this._focusParams.on =
|
|
210
|
+
this._focusParams.on = true;
|
|
211
|
+
this._fillElementBuffer(trackIDs);
|
|
205
212
|
if (!this._focusParams.on) {
|
|
206
213
|
this._turnOffFocus();
|
|
207
214
|
}
|
|
@@ -218,7 +225,7 @@ class PointTracksPlugin {
|
|
|
218
225
|
_bufferOrchestrator.updateBulk(points.map((pointID) => {
|
|
219
226
|
return {
|
|
220
227
|
key: keyMethod(trackID, pointID),
|
|
221
|
-
rgba:
|
|
228
|
+
rgba: rgba
|
|
222
229
|
};
|
|
223
230
|
}), _bufferManagersMap, ["rgba"]);
|
|
224
231
|
this._refillFocus();
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
// import { createProgram, defaultblendfunction, shaderfunctions } from "../../util";
|
|
5
5
|
import { createProgram } from "../../util/webglobjectbuilders";
|
|
6
|
-
import { defaultblendfunction } from "../../util/
|
|
6
|
+
import { defaultblendfunction } from "../../util/globe-default-gl-states";
|
|
7
7
|
import { pixelXYToCartesian2DPoint, pixelXYToCartesian3DPoint, } from "../../util/shaderfunctions";
|
|
8
8
|
export default class TrackGlowLineProgram {
|
|
9
9
|
/**
|
|
@@ -21,13 +21,15 @@ export class BufferManager {
|
|
|
21
21
|
buffer;
|
|
22
22
|
itemSize;
|
|
23
23
|
bufferType;
|
|
24
|
+
typedArrayConstructor;
|
|
24
25
|
isFreed = false;
|
|
25
|
-
constructor(gl, itemSize, { bufferType = "STATIC_DRAW", buffer = null, initialCapacity = 10 } = {}) {
|
|
26
|
+
constructor(gl, itemSize, { bufferType = "STATIC_DRAW", buffer = null, initialCapacity = 10, typedArrayConstructor = Float32Array } = {}) {
|
|
26
27
|
this.gl = gl;
|
|
27
28
|
this.itemSize = itemSize;
|
|
28
29
|
this.bufferType = bufferType;
|
|
29
30
|
this.buffer = buffer === null ? gl.createBuffer() : buffer;
|
|
30
31
|
this.resetWithCapacity(initialCapacity);
|
|
32
|
+
this.typedArrayConstructor = typedArrayConstructor;
|
|
31
33
|
}
|
|
32
34
|
resetWithCapacity(capacity) {
|
|
33
35
|
const { gl, buffer, bufferType, itemSize } = this;
|
|
@@ -60,8 +62,8 @@ export class BufferManager {
|
|
|
60
62
|
}
|
|
61
63
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
62
64
|
}
|
|
63
|
-
insertBlock(items, offset, adapter
|
|
64
|
-
const { gl, buffer, itemSize } = this;
|
|
65
|
+
insertBlock(items, offset, adapter) {
|
|
66
|
+
const { gl, buffer, itemSize, typedArrayConstructor: Constructor } = this;
|
|
65
67
|
const cpuBuffer = new Constructor(itemSize * items.length);
|
|
66
68
|
for (let i = 0; i < items.length; i++) {
|
|
67
69
|
cpuBuffer.set(adapter(items[i]), i * itemSize);
|
|
@@ -83,12 +83,12 @@ export class BufferOrchestrator {
|
|
|
83
83
|
if (bufferManagerComp === undefined)
|
|
84
84
|
throw new Error("insertBulk bufferKey does not exist");
|
|
85
85
|
const { bufferManager, adaptor } = bufferManagerComp;
|
|
86
|
-
bufferManager.insertBlock(blockLoad, offsetStart, adaptor
|
|
86
|
+
bufferManager.insertBlock(blockLoad, offsetStart, adaptor);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
else {
|
|
90
90
|
for (const [, { bufferManager, adaptor }] of bufferManagersMap) {
|
|
91
|
-
bufferManager.insertBlock(blockLoad, offsetStart, adaptor
|
|
91
|
+
bufferManager.insertBlock(blockLoad, offsetStart, adaptor);
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|