@pirireis/webglobeplugins 0.6.49-a → 0.7.0
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/angle-calculation.js +4 -2
- package/Math/methods.js +197 -0
- package/package.json +1 -1
- package/point-heat-map/adaptors/timetracksplugin-format-to-this.js +78 -0
- package/point-heat-map/index.js +0 -0
- package/point-heat-map/plugin-webworker.js +162 -0
- package/point-heat-map/plugin.js +134 -0
- package/point-heat-map/point-to-heat-map-flow.js +155 -0
- package/point-heat-map/readme.md +15 -0
- package/programs/data2legend/density-to-legend.js +115 -0
- package/programs/data2legend/point-to-density-texture.js +114 -0
- package/programs/line-on-globe/degree-padding-around-circle-3d.js +4 -4
- package/timetracks/adaptors-line-strip.js +1 -1
- package/timetracks/program-line-strip.js +1 -1
- package/timetracks/program.js +1 -1
- package/timetracks/programpoint-line-strip.js +1 -1
- package/timetracks/programpoint.js +1 -1
- package/timetracks/readme.md +1 -0
- package/util/algorithms/index.js +0 -0
- package/util/algorithms/search-binary.js +26 -0
- package/util/interpolation/index.js +0 -0
- package/util/interpolation/timetrack/index.js +0 -0
- package/util/interpolation/timetrack/timetrack-interpolator.js +89 -0
- package/util/interpolation/timetrack/web-worker.js +46 -0
- package/util/programs/draw-texture-on-canvas.js +103 -0
- package/util/programs/texturetoglobe.js +1 -1
- package/util/webglobe/gldefaultstates.js +2 -1
- package/waveparticles/plugin.js +0 -2
- package/wind/index.js +0 -2
- package/wind/plugin.js +1 -1
- package/write-text/context-text3.js +1 -1
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { densityToLegendProgramCache } from "../programs/data2legend/density-to-legend";
|
|
2
|
+
import { pointToDensityTextureCache } from "../programs/data2legend/point-to-density-texture";
|
|
3
|
+
import { textureOnCanvasProgramCache } from "../util/programs/draw-texture-on-canvas";
|
|
4
|
+
import { defaultblendfunction } from "../util/webglobe/gldefaultstates";
|
|
5
|
+
class PointHeatmapFlow {
|
|
6
|
+
|
|
7
|
+
constructor(globe) {
|
|
8
|
+
this.globe = null;
|
|
9
|
+
this.gl = null;
|
|
10
|
+
this.program = null;
|
|
11
|
+
this.densityToLegendProgram = null;
|
|
12
|
+
this.globe = globe;
|
|
13
|
+
this.gl = globe.gl;
|
|
14
|
+
this.pointToDensityProgram = pointToDensityTextureCache.get(globe);
|
|
15
|
+
this.densityToLegendProgram = densityToLegendProgramCache.get(globe);
|
|
16
|
+
this.testTextureProgram = textureOnCanvasProgramCache.get(globe);
|
|
17
|
+
this._lookInfo = globe.api_GetCurrentLookInfo();
|
|
18
|
+
const { gl } = this;
|
|
19
|
+
{
|
|
20
|
+
this.buffer = gl.createBuffer();
|
|
21
|
+
this.vao2D = this.pointToDensityProgram.createVAO(this.buffer, 2);
|
|
22
|
+
this.vao3D = this.pointToDensityProgram.createVAO(this.buffer, 3);
|
|
23
|
+
}
|
|
24
|
+
{ // framebuffer and texture
|
|
25
|
+
this.framebuffer = gl.createFramebuffer();
|
|
26
|
+
this.densityTexture = this._createDensityTexture();
|
|
27
|
+
this._bindTextureToFramebuffer();
|
|
28
|
+
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
_bindTextureToFramebuffer() {
|
|
33
|
+
const { gl, densityTexture, framebuffer } = this;
|
|
34
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
35
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, densityTexture, 0);
|
|
36
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
draw(legendTexture, pointSize, opacity = 1.0) {
|
|
41
|
+
const { gl, globe, framebuffer } = this;
|
|
42
|
+
if (this._drawDensityRequired || this._isVisionChanged()) {
|
|
43
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
|
44
|
+
gl.clearColor(0, 0, 0, 0);
|
|
45
|
+
gl.viewport(
|
|
46
|
+
0, 0,
|
|
47
|
+
Math.floor(globe.api_ScrW()), Math.floor(globe.api_ScrH())
|
|
48
|
+
);
|
|
49
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
50
|
+
this._drawDensity(pointSize);
|
|
51
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
52
|
+
}
|
|
53
|
+
defaultblendfunction(gl);
|
|
54
|
+
gl.viewport(0, 0, 400, 400);
|
|
55
|
+
this.testTextureProgram.draw(legendTexture, 1.0);
|
|
56
|
+
gl.viewport(0, 400, 400, 400);
|
|
57
|
+
this.testTextureProgram.draw(this.densityTexture, 1.0);
|
|
58
|
+
gl.viewport(0, 0, globe.api_ScrW(), globe.api_ScrH());
|
|
59
|
+
this._drawLegend(legendTexture, opacity);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
resize() {
|
|
64
|
+
const { gl, densityTexture } = this;
|
|
65
|
+
gl.deleteTexture(densityTexture);
|
|
66
|
+
this.densityTexture = this._createDensityTexture();
|
|
67
|
+
this._bindTextureToFramebuffer();
|
|
68
|
+
this._drawDensityRequired = true;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
// USER API
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {Float32Array} data
|
|
76
|
+
* @format [x, y, z, height] x,y,z is normalized 3d cartesian coordinates. Height in kilometers. Set 6371.137 for ground level.
|
|
77
|
+
*/
|
|
78
|
+
setData(data) {
|
|
79
|
+
const { gl, buffer } = this;
|
|
80
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
81
|
+
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
|
|
82
|
+
// use program
|
|
83
|
+
this.dataLength = data.length;
|
|
84
|
+
this._drawDensityRequired = true;
|
|
85
|
+
this.globe.DrawRender();
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// implicit Methods
|
|
89
|
+
|
|
90
|
+
_createDensityTexture() {
|
|
91
|
+
const { gl, globe } = this;
|
|
92
|
+
const width = Math.floor(globe.api_ScrW())
|
|
93
|
+
const height = Math.floor(globe.api_ScrH());
|
|
94
|
+
const texture = gl.createTexture();
|
|
95
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
96
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
97
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
98
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
99
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
100
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
101
|
+
return texture;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
_drawDensity(pointSize) {
|
|
106
|
+
const { gl, globe, pointToDensityProgram, vao2D, vao3D, dataLength } = this;
|
|
107
|
+
const is3D = globe.api_GetCurrentGeometry() === 0;
|
|
108
|
+
const vao = is3D ? vao3D : vao2D;
|
|
109
|
+
const length = dataLength / (is3D ? 3 : 2);
|
|
110
|
+
gl.blendEquation(gl.FUNC_ADD);
|
|
111
|
+
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.SRC_ALPHA, gl.ONE);
|
|
112
|
+
pointToDensityProgram.draw(vao, length, pointSize);
|
|
113
|
+
|
|
114
|
+
this._drawDensityRequired = false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
_drawLegend(legendTexture, opacity) {
|
|
119
|
+
const { densityToLegendProgram, densityTexture } = this;
|
|
120
|
+
densityToLegendProgram.draw(densityTexture, legendTexture, opacity);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
_isVisionChanged() {
|
|
125
|
+
const currentLookInfo = this.globe.api_GetCurrentLookInfo();
|
|
126
|
+
const _lookInfo = this._lookInfo;
|
|
127
|
+
if (
|
|
128
|
+
currentLookInfo.CenterLong !== _lookInfo.CenterLong ||
|
|
129
|
+
currentLookInfo.CenterLat !== _lookInfo.CenterLat ||
|
|
130
|
+
currentLookInfo.Distance !== _lookInfo.Distance ||
|
|
131
|
+
currentLookInfo.Tilt !== _lookInfo.Tilt ||
|
|
132
|
+
currentLookInfo.NorthAng !== _lookInfo.NorthAng
|
|
133
|
+
) {
|
|
134
|
+
this._lookInfo = currentLookInfo;
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
free() {
|
|
142
|
+
if (this._isFreed) return;
|
|
143
|
+
this._isFreed = true;
|
|
144
|
+
densityToLegendProgramCache.release(this.globe);
|
|
145
|
+
pointToDensityTextureCache.release(this.globe);
|
|
146
|
+
this.gl.deleteTexture(this.densityTexture);
|
|
147
|
+
this.gl.deleteFramebuffer(this.framebuffer);
|
|
148
|
+
this.gl.deleteBuffer(this.buffer);
|
|
149
|
+
this.gl.deleteVertexArray(this.vao2D);
|
|
150
|
+
this.gl.deleteVertexArray(this.vao3D);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
export { PointHeatmapFlow };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# Content
|
|
2
|
+
|
|
3
|
+
point-heat-map/
|
|
4
|
+
├── plugin.js
|
|
5
|
+
└── point-to-heat-flow.js
|
|
6
|
+
|
|
7
|
+
## plugin.js
|
|
8
|
+
|
|
9
|
+
Contains plugin plugin that calculates data on main thread.
|
|
10
|
+
|
|
11
|
+
## point-to-heat-flow.js
|
|
12
|
+
|
|
13
|
+
Contains a wrapper around point-to-density and density-to-color-ramp programs.
|
|
14
|
+
|
|
15
|
+
The reason behind seperation of program flow and plugin is to explore web-worker version of interpolation and compare it with main thread version.
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createProgram } from "../../util/";
|
|
2
|
+
import { noRegisterGlobeProgramCache } from "../programcache";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
const vs = `#version 300 es
|
|
6
|
+
precision highp float;
|
|
7
|
+
|
|
8
|
+
uniform sampler2D u_density_texture;
|
|
9
|
+
in vec2 a_position;
|
|
10
|
+
|
|
11
|
+
out vec2 v_texcoord;
|
|
12
|
+
|
|
13
|
+
void main() {
|
|
14
|
+
gl_Position = vec4(a_position, 0.0, 1.0);
|
|
15
|
+
v_texcoord = a_position * 0.5 + 0.5;
|
|
16
|
+
}`;
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
const fs = `#version 300 es
|
|
20
|
+
precision highp float;
|
|
21
|
+
|
|
22
|
+
uniform sampler2D u_legend_texture;
|
|
23
|
+
uniform sampler2D u_density_texture;
|
|
24
|
+
|
|
25
|
+
uniform float u_opacity;
|
|
26
|
+
in vec2 v_texcoord;
|
|
27
|
+
out vec4 fragColor;
|
|
28
|
+
|
|
29
|
+
void main() {
|
|
30
|
+
float density = texture(u_density_texture, v_texcoord).r;
|
|
31
|
+
fragColor = texture(u_legend_texture, vec2(density, 0.5));
|
|
32
|
+
fragColor.a *= u_opacity * sqrt(density);
|
|
33
|
+
}`;
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class DensityToLegendProgram {
|
|
39
|
+
constructor(globe) {
|
|
40
|
+
this.globe = globe;
|
|
41
|
+
this.gl = globe.gl;
|
|
42
|
+
this.program = createProgram(globe.gl, vs, fs);
|
|
43
|
+
const { gl, program } = this;
|
|
44
|
+
this.uniforms = {
|
|
45
|
+
densityTexture: gl.getUniformLocation(program, "u_density_texture"),
|
|
46
|
+
legendTexture: gl.getUniformLocation(program, "u_legend_texture"),
|
|
47
|
+
opacity: gl.getUniformLocation(program, "u_opacity"),
|
|
48
|
+
}
|
|
49
|
+
{ // assign attribute locations
|
|
50
|
+
gl.bindAttribLocation(program, 0, "a_position");
|
|
51
|
+
}
|
|
52
|
+
{
|
|
53
|
+
this.vao = gl.createVertexArray();
|
|
54
|
+
const a_positionLocation = gl.getAttribLocation(program, "a_position");
|
|
55
|
+
gl.bindVertexArray(this.vao);
|
|
56
|
+
|
|
57
|
+
const buffer = gl.createBuffer();
|
|
58
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
59
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
60
|
+
-1, -1,
|
|
61
|
+
1, -1,
|
|
62
|
+
1, 1,
|
|
63
|
+
-1, 1,
|
|
64
|
+
]), gl.STATIC_DRAW);
|
|
65
|
+
gl.enableVertexAttribArray(a_positionLocation);
|
|
66
|
+
gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 0, 0);
|
|
67
|
+
gl.bindVertexArray(null);
|
|
68
|
+
// gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
69
|
+
this._buffer = buffer;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
this._lastOpacity = 1;
|
|
74
|
+
const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
75
|
+
gl.useProgram(program);
|
|
76
|
+
gl.uniform1f(this.uniforms.opacity, this._lastOpacity);
|
|
77
|
+
gl.useProgram(currentProgram);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
draw(densityTexture, legendTexture, opacity) {
|
|
83
|
+
const { gl, program, uniforms } = this;
|
|
84
|
+
gl.useProgram(program);
|
|
85
|
+
gl.bindVertexArray(this.vao);
|
|
86
|
+
gl.activeTexture(gl.TEXTURE1);
|
|
87
|
+
gl.bindTexture(gl.TEXTURE_2D, legendTexture);
|
|
88
|
+
gl.uniform1i(uniforms.legendTexture, 1);
|
|
89
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
90
|
+
gl.bindTexture(gl.TEXTURE_2D, densityTexture);
|
|
91
|
+
gl.uniform1i(uniforms.densityTexture, 0);
|
|
92
|
+
if (this._lastOpacity !== opacity) {
|
|
93
|
+
gl.uniform1f(uniforms.opacity, opacity);
|
|
94
|
+
this._lastOpacity = opacity;
|
|
95
|
+
}
|
|
96
|
+
gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
|
|
97
|
+
gl.bindVertexArray(null);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
free() {
|
|
102
|
+
const gl = this.gl;
|
|
103
|
+
gl.deleteVertexArray(this.vao);
|
|
104
|
+
gl.deleteBuffer(this._buffer);
|
|
105
|
+
gl.deleteProgram(this.program);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
const densityToLegendProgramCache = {
|
|
111
|
+
get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, DensityToLegendProgram),
|
|
112
|
+
release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, DensityToLegendProgram)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { densityToLegendProgramCache };
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { createProgram } from "../../util/";
|
|
2
|
+
import { noRegisterGlobeProgramCache } from "../programcache";
|
|
3
|
+
import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totems/camerauniformblock";
|
|
4
|
+
import { mercatorXYToGLPosition, cartesian3DToGLPosition } from "../../util/shaderfunctions/geometrytransformations";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
const vs = `#version 300 es
|
|
8
|
+
precision highp float;
|
|
9
|
+
|
|
10
|
+
${CameraUniformBlockString}
|
|
11
|
+
${mercatorXYToGLPosition}
|
|
12
|
+
${cartesian3DToGLPosition}
|
|
13
|
+
|
|
14
|
+
in vec3 position;
|
|
15
|
+
uniform float pointSize;
|
|
16
|
+
|
|
17
|
+
void main() {
|
|
18
|
+
if (is3D) {
|
|
19
|
+
gl_Position = cartesian3DToGLPosition(position);
|
|
20
|
+
} else {
|
|
21
|
+
gl_Position = mercatorXYToGLPosition(position.xy);
|
|
22
|
+
}
|
|
23
|
+
gl_PointSize = pointSize;
|
|
24
|
+
}
|
|
25
|
+
`;
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
const fs = `#version 300 es
|
|
29
|
+
precision highp float;
|
|
30
|
+
out vec4 fragColor;
|
|
31
|
+
|
|
32
|
+
void main() {
|
|
33
|
+
float r = length(gl_PointCoord - 0.5) * 2.0;
|
|
34
|
+
if (r > 1.0) discard;
|
|
35
|
+
// float density = smoothstep(0.1, 1.0, 1.0 - r);
|
|
36
|
+
fragColor = vec4((15.0/16.0)*sqrt(1.0-sqrt(r)));
|
|
37
|
+
}`;
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
class PointHeatmapProgram {
|
|
42
|
+
|
|
43
|
+
constructor(globe) {
|
|
44
|
+
this.globe = globe;
|
|
45
|
+
this.gl = globe.gl;
|
|
46
|
+
this._isFreed = false;
|
|
47
|
+
this.program = createProgram(globe.gl, vs, fs);
|
|
48
|
+
|
|
49
|
+
const { gl, program } = this;
|
|
50
|
+
this.uniforms = {
|
|
51
|
+
pointSize: gl.getUniformLocation(this.program, "pointSize"),
|
|
52
|
+
}
|
|
53
|
+
{ // assign attribute locations
|
|
54
|
+
gl.bindAttribLocation(program, 0, "position");
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
{ // arrange camera uniform block
|
|
58
|
+
this.cameraBlockBingingPoint = 0;
|
|
59
|
+
this.cameraBlockTotem = CameraUniformBlockTotemCache.get(globe);
|
|
60
|
+
const cameraBlockIndex = gl.getUniformBlockIndex(program, "CameraUniformBlock");
|
|
61
|
+
gl.uniformBlockBinding(program, cameraBlockIndex, this.cameraBlockBingingPoint);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
{ // last values
|
|
65
|
+
this._lastPointSize = 0;
|
|
66
|
+
|
|
67
|
+
const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
68
|
+
gl.useProgram(program);
|
|
69
|
+
gl.uniform1f(this.uniforms.pointSize, this._lastPointSize);
|
|
70
|
+
gl.useProgram(currentProgram);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
createVAO(positionBuffer, vectorSize) {
|
|
76
|
+
const gl = this.gl;
|
|
77
|
+
const vao = gl.createVertexArray();
|
|
78
|
+
gl.bindVertexArray(vao);
|
|
79
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
|
|
80
|
+
gl.enableVertexAttribArray(0);
|
|
81
|
+
gl.vertexAttribPointer(0, vectorSize, gl.FLOAT, false, 0, 0);
|
|
82
|
+
gl.bindVertexArray(null);
|
|
83
|
+
return vao;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
draw(vao, length, pointSize = 5.0) {
|
|
87
|
+
const gl = this.gl;
|
|
88
|
+
gl.useProgram(this.program);
|
|
89
|
+
if (pointSize !== this._lastPointSize) {
|
|
90
|
+
gl.uniform1f(this.uniforms.pointSize, pointSize);
|
|
91
|
+
this._lastPointSize = pointSize;
|
|
92
|
+
}
|
|
93
|
+
gl.bindVertexArray(vao);
|
|
94
|
+
this.cameraBlockTotem.bind(this.cameraBlockBingingPoint);
|
|
95
|
+
gl.drawArrays(gl.POINTS, 0, length);
|
|
96
|
+
this.cameraBlockTotem.unbind(this.cameraBlockBingingPoint);
|
|
97
|
+
gl.bindVertexArray(null);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
free() {
|
|
101
|
+
if (this._isFreed) return;
|
|
102
|
+
const { gl, globe } = this;
|
|
103
|
+
CameraUniformBlockTotemCache.release(globe);
|
|
104
|
+
gl.deleteProgram(this.program);
|
|
105
|
+
this._isFreed = true;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const pointToDensityTextureCache = {
|
|
110
|
+
get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, PointHeatmapProgram),
|
|
111
|
+
release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, PointHeatmapProgram)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export { pointToDensityTextureCache };
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
* center_position is too small or doenst loaded as expected.
|
|
20
20
|
*/
|
|
21
21
|
|
|
22
|
-
const INITIAL_EDGE_COUNT =
|
|
22
|
+
const INITIAL_EDGE_COUNT = 720;
|
|
23
23
|
|
|
24
24
|
const vertexShaderSource = `#version 300 es
|
|
25
25
|
precision highp float;
|
|
@@ -86,7 +86,7 @@ class Logic {
|
|
|
86
86
|
this.gl = globe.gl;
|
|
87
87
|
this._lastOpacity = 1.0;
|
|
88
88
|
this._lastEdgeCount = INITIAL_EDGE_COUNT;
|
|
89
|
-
this._lastStepAngle =
|
|
89
|
+
this._lastStepAngle = 720 / INITIAL_EDGE_COUNT;
|
|
90
90
|
this._lastZAlphaMode = Z_ALPHA_MODE.ON;
|
|
91
91
|
this.program = createProgram(this.gl, vertexShaderSource, fragmentShaderSource);
|
|
92
92
|
|
|
@@ -103,7 +103,7 @@ class Logic {
|
|
|
103
103
|
gl.useProgram(program);
|
|
104
104
|
gl.uniform1f(program.uniforms.opacity, 1.0);
|
|
105
105
|
gl.uniform1f(program.uniforms.edgeCount, INITIAL_EDGE_COUNT * 2);
|
|
106
|
-
gl.uniform1f(program.uniforms.stepAngle, this._lastStepAngle * Math.PI /
|
|
106
|
+
gl.uniform1f(program.uniforms.stepAngle, this._lastStepAngle * Math.PI / 360);
|
|
107
107
|
gl.uniform1i(program.uniforms.zAlphaMode, Z_ALPHA_MODE.ON);
|
|
108
108
|
gl.useProgram(currentProgram);
|
|
109
109
|
}
|
|
@@ -162,7 +162,7 @@ class Logic {
|
|
|
162
162
|
this._lastEdgeCount = edgeCount;
|
|
163
163
|
}
|
|
164
164
|
if (this._lastStepAngle !== stepAngle) {
|
|
165
|
-
gl.uniform1f(program.uniforms.stepAngle, stepAngle * Math.PI /
|
|
165
|
+
gl.uniform1f(program.uniforms.stepAngle, stepAngle * Math.PI / 360);
|
|
166
166
|
this._lastStepAngle = stepAngle;
|
|
167
167
|
}
|
|
168
168
|
if (this._lastZAlphaMode !== zAlphaMode) {
|
|
@@ -69,7 +69,7 @@ function fillSliceOfFloat32ArrayLineStrip(floatArray, offset, coordinates, times
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
function addCuttingPointLineStrip(floatArray, offset) {
|
|
72
|
-
floatArray.set(
|
|
72
|
+
floatArray.set(new Float32Array(9).fill(NaN), offset);
|
|
73
73
|
return offset + 9;
|
|
74
74
|
}
|
|
75
75
|
|
|
@@ -628,7 +628,7 @@ void main() {
|
|
|
628
628
|
gl.uniform3fv(_lineProgram.uTranslate, uTranslate);
|
|
629
629
|
|
|
630
630
|
gl.bindVertexArray(_lineProgram.vao);
|
|
631
|
-
gl.drawArrays(gl.LINE_STRIP, 0, this._totalLength);
|
|
631
|
+
gl.drawArrays(gl.LINE_STRIP, 0, this._totalLength);
|
|
632
632
|
gl.drawBuffers([
|
|
633
633
|
gl.COLOR_ATTACHMENT0,
|
|
634
634
|
gl.NONE
|
package/timetracks/program.js
CHANGED
|
@@ -786,7 +786,7 @@ void main() {
|
|
|
786
786
|
gl.uniform3fv(_lineProgram.uTranslate, uTranslate);
|
|
787
787
|
|
|
788
788
|
gl.bindVertexArray(_lineProgram.vao);
|
|
789
|
-
gl.drawArrays(gl.LINES, 0, this._totalLength);
|
|
789
|
+
gl.drawArrays(gl.LINES, 0, this._totalLength);
|
|
790
790
|
gl.drawBuffers([
|
|
791
791
|
gl.COLOR_ATTACHMENT0,
|
|
792
792
|
gl.NONE
|
|
@@ -78,7 +78,7 @@ export default class {
|
|
|
78
78
|
{
|
|
79
79
|
const { gl, _globalsbuffer } = this;
|
|
80
80
|
gl.bindBuffer(gl.UNIFORM_BUFFER, _globalsbuffer);
|
|
81
|
-
gl.bufferData(gl.UNIFORM_BUFFER, 12, gl.STREAM_DRAW);
|
|
81
|
+
gl.bufferData(gl.UNIFORM_BUFFER, 12, gl.STREAM_DRAW);
|
|
82
82
|
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([0, options.opacity, options.pointSize]));
|
|
83
83
|
gl.bindBufferBase(gl.UNIFORM_BUFFER, this._globalsBlockBindingPoint, _globalsbuffer);
|
|
84
84
|
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
|
|
@@ -71,7 +71,7 @@ export default class {
|
|
|
71
71
|
{
|
|
72
72
|
const { gl, _globalsbuffer } = this;
|
|
73
73
|
gl.bindBuffer(gl.UNIFORM_BUFFER, _globalsbuffer);
|
|
74
|
-
gl.bufferData(gl.UNIFORM_BUFFER, 12, gl.STREAM_DRAW);
|
|
74
|
+
gl.bufferData(gl.UNIFORM_BUFFER, 12, gl.STREAM_DRAW);
|
|
75
75
|
gl.bufferSubData(gl.UNIFORM_BUFFER, 0, new Float32Array([0, options.opacity, options.pointSize]));
|
|
76
76
|
gl.bindBufferBase(gl.UNIFORM_BUFFER, this._globalsBlockBindingPoint, _globalsbuffer);
|
|
77
77
|
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
TODO: delete program, programpoint, maybe adaptors. which are related to the old version of this plugin.
|
|
File without changes
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {Array<number>} ListLike
|
|
3
|
+
* @typedef {number || null} Index
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @param {ListLike} container
|
|
8
|
+
* @param {number} value
|
|
9
|
+
* @returns {Index}
|
|
10
|
+
*/
|
|
11
|
+
const findFirstIndexInRange = (container, value) => {
|
|
12
|
+
let start = 0;
|
|
13
|
+
let end = container.length - 1;
|
|
14
|
+
let mid = 0;
|
|
15
|
+
while (start <= end) {
|
|
16
|
+
mid = Math.floor((start + end) / 2);
|
|
17
|
+
if (container[mid] <= value && value <= container[mid + 1]) return mid;
|
|
18
|
+
if (container[mid] < value) start = mid + 1;
|
|
19
|
+
else end = mid - 1;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export { findFirstIndexInRange };
|
|
26
|
+
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { findFirstIndexInRange } from '../../algorithms/search-binary';
|
|
2
|
+
import {
|
|
3
|
+
sphericalLinearInterpolation_Cartesian3d,
|
|
4
|
+
sphericalLinearInterpolation_Mercator,
|
|
5
|
+
} from '../../../Math/methods';
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {Array<number>} vec3 [x, y, z]
|
|
10
|
+
* @typedef {Array<number>} vec2 [x, y]
|
|
11
|
+
* @typedef {Array<number>} vec4 [x, y, z, w]
|
|
12
|
+
* @typedef {number} fraction a number between 0 and 1
|
|
13
|
+
* @typedef {Array<number>} wgs84 [long, lat]
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const GEOMETRY = Object.freeze({
|
|
17
|
+
CARTESIAN3D: 0,
|
|
18
|
+
MERCATOR: 1,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
class TimeTrackInterpolator {
|
|
22
|
+
/**
|
|
23
|
+
* @typedef Timetrack
|
|
24
|
+
* @property {Array<vec4>}} coordinates [x,y,z, length]
|
|
25
|
+
* @property {Array<Number>} times
|
|
26
|
+
* @param {Array<Timetrack>} timeTracks
|
|
27
|
+
*/
|
|
28
|
+
constructor({ timeTracks, bbox = null, geometry = GEOMETRY.CARTESIAN3D } = {}) {
|
|
29
|
+
this.timeTracks = null;
|
|
30
|
+
this.timeTracksStartTimes = null;
|
|
31
|
+
this.geometry = geometry;
|
|
32
|
+
if (timeTracks) this.setTimetracks(timeTracks);
|
|
33
|
+
if (bbox) this.setBbox(bbox);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
setGeometry(geometry) {
|
|
38
|
+
if (geometry !== GEOMETRY.CARTESIAN3D && geometry !== GEOMETRY.MERCATOR) {
|
|
39
|
+
throw new Error('Invalid geometry');
|
|
40
|
+
}
|
|
41
|
+
this.geometry = geometry;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
setTimetracks(timeTracks) {
|
|
45
|
+
console.log("timetracks:", timeTracks);
|
|
46
|
+
this.timeTracks = timeTracks;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
interpolate(time) {
|
|
51
|
+
const { timeTracks, geometry } = this;
|
|
52
|
+
if (!timeTracks) { return null; }
|
|
53
|
+
const resultArray = [];
|
|
54
|
+
const info = {
|
|
55
|
+
outOfRange: 0,
|
|
56
|
+
processed: 0,
|
|
57
|
+
}
|
|
58
|
+
for (let i = 0; i < timeTracks.length; i++) {
|
|
59
|
+
const { times, coordinates } = timeTracks[i];
|
|
60
|
+
|
|
61
|
+
if (times[times.length - 1] < time) continue;
|
|
62
|
+
info.processed++;
|
|
63
|
+
const timeIndex = findFirstIndexInRange(times, time);
|
|
64
|
+
if (timeIndex === null) { info.outOfRange++; continue; }
|
|
65
|
+
const timeFraction = (time - times[timeIndex]) / (times[timeIndex + 1] - times[timeIndex]);
|
|
66
|
+
const interpolated = (geometry === GEOMETRY.CARTESIAN3D) ?
|
|
67
|
+
sphericalLinearInterpolation_Cartesian3d(coordinates[timeIndex], coordinates[timeIndex + 1], timeFraction) :
|
|
68
|
+
sphericalLinearInterpolation_Mercator(coordinates[timeIndex], coordinates[timeIndex + 1], timeFraction);
|
|
69
|
+
resultArray.push(...interpolated);
|
|
70
|
+
}
|
|
71
|
+
return new Float32Array(resultArray);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
// implicit methods
|
|
76
|
+
|
|
77
|
+
_orderTimeTracks() {
|
|
78
|
+
this.timeTracks.sort((a, b) => a.times[0] - b.times[0]);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
_setStartTimes() {
|
|
82
|
+
this.timeTracksStartTimes = this.timeTracks.map(tt => tt.times[0]);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
export { TimeTrackInterpolator, GEOMETRY };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { TimeTrackInterpolator, GEOMETRY } from './timetrack-interpolator';
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
const interpolator = new TimeTrackInterpolator({ geometry: GEOMETRY.CARTESIAN3D });
|
|
5
|
+
|
|
6
|
+
/* eslint-disable-next-line no-restricted-globals */
|
|
7
|
+
self.onmessage = function (e) {
|
|
8
|
+
|
|
9
|
+
const { geometry = null, timeTracks = null, time = null } = e.data;
|
|
10
|
+
|
|
11
|
+
if (geometry !== null) {
|
|
12
|
+
try {
|
|
13
|
+
interpolator.setGeometry(geometry);
|
|
14
|
+
} catch (error) {
|
|
15
|
+
/* eslint-disable-next-line no-restricted-globals */
|
|
16
|
+
self.postMessage({ error: error.message });
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (timeTracks !== null) {
|
|
22
|
+
try {
|
|
23
|
+
interpolator.setTimetracks(timeTracks);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
/* eslint-disable-next-line no-restricted-globals */
|
|
26
|
+
self.postMessage({ error: error.message });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (time !== null) {
|
|
32
|
+
try {
|
|
33
|
+
const result = interpolator.interpolate(time);
|
|
34
|
+
/* eslint-disable-next-line no-restricted-globals */
|
|
35
|
+
self.postMessage(result, [result.buffer]);
|
|
36
|
+
return;
|
|
37
|
+
} catch (error) {
|
|
38
|
+
/* eslint-disable-next-line no-restricted-globals */
|
|
39
|
+
self.postMessage({ error: error.message });
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/* eslint-disable-next-line no-restricted-globals */
|
|
44
|
+
self.postMessage(true);
|
|
45
|
+
}
|
|
46
|
+
|