@pirireis/webglobeplugins 0.5.11 → 0.5.12
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/circle-line-chain/chain-list-map.js +2 -2
- package/compass-rose/compass-rose-padding-flat.js +173 -0
- package/package.json +1 -1
- package/programs/totems/camerauniformblock.js +19 -4
- package/programs/two-d/pixel-padding-for-compass.js +36 -23
- package/util/account/bufferoffsetmanager.js +1 -0
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +14 -2
- package/write-text/context-text-2d-offsets.js +149 -0
- package/compass-rose/compass-rose-flat.js +0 -76
|
@@ -101,11 +101,11 @@ export class ChainListMap {
|
|
|
101
101
|
const index = this.getIndexOfNode(chainKey, node.key)
|
|
102
102
|
const chainNode = this._chainMap.get(chainKey)[index];
|
|
103
103
|
if (node.circleProperties) {
|
|
104
|
-
if (chainNode.circleProperties
|
|
104
|
+
if (typeof chainNode.circleProperties !== 'object') chainNode.circleProperties = {}
|
|
105
105
|
node.circleProperties.forEach((value, key, container) => chainNode.circleProperties[key] = value);
|
|
106
106
|
}
|
|
107
107
|
if (node.lineProperties) {
|
|
108
|
-
if (chainNode.lineProperties
|
|
108
|
+
if (typeof chainNode.lineProperties !== 'object') chainNode.lineProperties = {}
|
|
109
109
|
node.lineProperties.forEach((value, key, container) => chainNode.lineProperties[key] = value);
|
|
110
110
|
}
|
|
111
111
|
});
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
import { PixelPaddingForFlatCompassCache } from "../programs/two-d/pixel-padding-for-compass";
|
|
2
|
+
import { BufferManager, BufferOrchestrator } from "../util/account";
|
|
3
|
+
// import { ContextTextWriter2 } from "../write-text/context-text2";
|
|
4
|
+
import { ContextTextWriter2Offsets } from "../write-text/context-text-2d-offsets"
|
|
5
|
+
|
|
6
|
+
export class PixelPaddingCompassPlugin {
|
|
7
|
+
constructor(id, {
|
|
8
|
+
opacity = 1,
|
|
9
|
+
textAngle = null, defaultProperties = {
|
|
10
|
+
rgba: [1, 1, 1, 1],
|
|
11
|
+
pixelRadiusBig: 350,
|
|
12
|
+
pixelRadiusSmall: 270
|
|
13
|
+
}
|
|
14
|
+
} = {}) {
|
|
15
|
+
this.id = id;
|
|
16
|
+
this._textAngle = textAngle;
|
|
17
|
+
this.textWriters = null
|
|
18
|
+
if (textAngle == null) {
|
|
19
|
+
this._createTextWriters();
|
|
20
|
+
}
|
|
21
|
+
this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
|
|
22
|
+
this.compassMap = new CompassMap({ defaultProperties });
|
|
23
|
+
this._opacity = opacity;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
init(globe, gl) {
|
|
27
|
+
this.globe = globe;
|
|
28
|
+
this.gl = gl;
|
|
29
|
+
|
|
30
|
+
this._initOrchestrations()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
insert(key, long, lat, properties = null) {
|
|
34
|
+
this.compassMap.insert(key, long, lat, properties);
|
|
35
|
+
this.globe.DrawRender();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
delete(key) {
|
|
40
|
+
this.compassMap.delete(key);
|
|
41
|
+
this.globe.DrawRender();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
setTextAngle(textAngle) {
|
|
46
|
+
this._textAngle = textAngle;
|
|
47
|
+
this._createTextWriters();
|
|
48
|
+
this.globe.DrawRender();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
setTextStyle(textStyle) {
|
|
52
|
+
this.textWriters?.forEach((writer) => writer.setStyle(textStyle));
|
|
53
|
+
this.globe.DrawRender();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setOpacity(opacity) {
|
|
57
|
+
this._opacity = opacity;
|
|
58
|
+
this.globe.DrawRender();
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
_initOrchestrations() {
|
|
62
|
+
const { gl, globe } = this;
|
|
63
|
+
this.paddingProgram = PixelPaddingForFlatCompassCache.get(globe);
|
|
64
|
+
{
|
|
65
|
+
// createBuffers
|
|
66
|
+
const bufferType = "DYNAMIC_DRAW";
|
|
67
|
+
const initialCapacity = this.bufferOrchestrator.capacity;
|
|
68
|
+
this.bufferManagersCompMap = new Map(
|
|
69
|
+
[
|
|
70
|
+
["screenCoordinates", {
|
|
71
|
+
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
72
|
+
'adaptor': (item) => new Float32Array([item.x, item.y])
|
|
73
|
+
}],
|
|
74
|
+
["pixelRadiusSmall", {
|
|
75
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
76
|
+
'adaptor': (item) => new Float32Array([item.properties.pixelRadiusSmall])
|
|
77
|
+
}],
|
|
78
|
+
["pixelRadiusBig", {
|
|
79
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
80
|
+
'adaptor': (item) => new Float32Array([item.properties.pixelRadiusBig])
|
|
81
|
+
}],
|
|
82
|
+
["rgba", {
|
|
83
|
+
'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
|
|
84
|
+
'adaptor': (item) => new Float32Array(item.properties.rgba)
|
|
85
|
+
}],
|
|
86
|
+
]
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const obj = function (bufferManagerComp) {
|
|
90
|
+
return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
|
|
91
|
+
};
|
|
92
|
+
this.paddingVao = this.paddingProgram.createVAO(
|
|
93
|
+
...['screenCoordinates', 'pixelRadiusSmall', 'pixelRadiusBig', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_createTextWriters() {
|
|
98
|
+
this.writer = new ContextTextWriter2Offsets(this.globe);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Globe API interface methods
|
|
102
|
+
|
|
103
|
+
draw2D() {
|
|
104
|
+
|
|
105
|
+
const { gl, globe, paddingProgram, paddingVao, bufferOrchestrator, bufferManagersCompMap } = this;
|
|
106
|
+
const items = this.compassMap.query(globe);
|
|
107
|
+
if (items.length === 0) return;
|
|
108
|
+
const { x, y, properties } = items[0];
|
|
109
|
+
console.log(x, y, properties);
|
|
110
|
+
bufferOrchestrator.flush();
|
|
111
|
+
bufferOrchestrator.insertBulk(items, bufferManagersCompMap);
|
|
112
|
+
gl.disable(gl.DEPTH_TEST);
|
|
113
|
+
paddingProgram.draw(paddingVao, bufferOrchestrator.length, this._opacity)
|
|
114
|
+
gl.enable(gl.DEPTH_TEST);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
free() {
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
class CompassMap {
|
|
125
|
+
constructor({ defaultProperties = null } = {}) {
|
|
126
|
+
this.coordsMemory = new Map();
|
|
127
|
+
this.propertyMemory = new Map();
|
|
128
|
+
if (defaultProperties !== null) {
|
|
129
|
+
|
|
130
|
+
this.defaultProperties = defaultProperties
|
|
131
|
+
} else {
|
|
132
|
+
|
|
133
|
+
this.defaultProperties = {
|
|
134
|
+
rgba: [1, 1, 1, 1],
|
|
135
|
+
pixelRadiusBig: 350,
|
|
136
|
+
pixelRadiusSmall: 270
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
insert(key, long, lat, properties = null) {
|
|
142
|
+
this.coordsMemory.set(key, [long, lat]);
|
|
143
|
+
if (properties) this.propertyMemory.set(key, properties);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
delete(key) {
|
|
147
|
+
this.coordsMemory.delete(key);
|
|
148
|
+
this.propertyMemory.delete(key);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
query(globe) {
|
|
152
|
+
const { coordsMemory, propertyMemory, defaultProperties } = this;
|
|
153
|
+
const result = [];
|
|
154
|
+
coordsMemory.forEach((v, k, c) => {
|
|
155
|
+
const { x, y } = globe.api_GetScreenPointFromGeo(
|
|
156
|
+
{
|
|
157
|
+
long: v[0],
|
|
158
|
+
lat: v[1],
|
|
159
|
+
z: 0,
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
);
|
|
163
|
+
if (x !== null) {
|
|
164
|
+
const properties = { ...defaultProperties, ...propertyMemory.get(k) };
|
|
165
|
+
result.push({ key: k, x, y, properties })
|
|
166
|
+
}
|
|
167
|
+
})
|
|
168
|
+
return result;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function isOnTheScreen(globe, points) { }
|
|
173
|
+
|
package/package.json
CHANGED
|
@@ -10,10 +10,14 @@ layout(std140) uniform CameraUniformBlock {
|
|
|
10
10
|
vec2 mapWH; // 8 bytes 144
|
|
11
11
|
vec2 screenWH; // 8 bytes 152
|
|
12
12
|
float z_level; // 4 bytes 160 | 164
|
|
13
|
-
|
|
13
|
+
float world_distance; // 4 bytes 164
|
|
14
|
+
float world_tilt; // 4 bytes 168
|
|
15
|
+
float world_north_angle; // 4 bytes 172
|
|
16
|
+
vec2 world_center_radian; // 8 bytes 176 | 184
|
|
17
|
+
}; // 14 lines
|
|
14
18
|
`;
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
const Radian = Math.PI / 180.0;
|
|
17
21
|
|
|
18
22
|
export default class
|
|
19
23
|
|
|
@@ -44,7 +48,7 @@ export default class
|
|
|
44
48
|
const { gl } = this;
|
|
45
49
|
const ubo = gl.createBuffer();
|
|
46
50
|
gl.bindBuffer(gl.UNIFORM_BUFFER, ubo);
|
|
47
|
-
gl.bufferData(gl.UNIFORM_BUFFER,
|
|
51
|
+
gl.bufferData(gl.UNIFORM_BUFFER, 184, gl.STREAM_DRAW);
|
|
48
52
|
gl.bindBufferBase(gl.UNIFORM_BUFFER, 0, ubo);
|
|
49
53
|
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
|
|
50
54
|
return ubo;
|
|
@@ -87,9 +91,20 @@ export default class
|
|
|
87
91
|
gl.bufferSubData(gl.UNIFORM_BUFFER, 144, mapWHFloat32);
|
|
88
92
|
}
|
|
89
93
|
}
|
|
94
|
+
{
|
|
95
|
+
// float world_distance; // 4 bytes 164
|
|
96
|
+
// float world_tilt; // 4 bytes 168
|
|
97
|
+
// float world_north_angle; // 4 bytes 172
|
|
98
|
+
// vec2 world_center_radian; // 8 bytes 180
|
|
99
|
+
const { CenterLong, CenterLat, Distance, Tilt, NorthAng } = globe.api_GetCurrentLookInfo();
|
|
100
|
+
gl.bufferSubData(gl.UNIFORM_BUFFER, 164, new Float32Array([
|
|
101
|
+
Distance, Radian * Tilt, Radian * NorthAng, Radian * CenterLong, Radian * CenterLat
|
|
102
|
+
]));
|
|
103
|
+
|
|
104
|
+
}
|
|
90
105
|
gl.bindBuffer(gl.UNIFORM_BUFFER, null);
|
|
91
|
-
}
|
|
92
106
|
|
|
107
|
+
}
|
|
93
108
|
|
|
94
109
|
getUBO() {
|
|
95
110
|
return this.ubo;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { createProgram } from "../../util";
|
|
2
2
|
import { CameraUniformBlockTotemCache, CameraUniformBlockString } from "../totems";
|
|
3
|
-
import {
|
|
3
|
+
import { noRegisterGlobeProgramCache } from "../programcache";
|
|
4
4
|
const vertexCount = 720;
|
|
5
5
|
const vertexShaderSource = `#version 300 es
|
|
6
6
|
${CameraUniformBlockString}
|
|
7
|
+
|
|
7
8
|
in vec2 screen_coordinate;
|
|
8
9
|
in float pixel_radius_small;
|
|
9
10
|
in float pixel_radius_big;
|
|
@@ -11,10 +12,9 @@ in vec4 rgba;
|
|
|
11
12
|
|
|
12
13
|
out vec4 v_rgba;
|
|
13
14
|
|
|
14
|
-
uniform float world_angle_radiance;
|
|
15
15
|
uniform float plugin_opacity;
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
vec3 coord_opacity(){
|
|
18
18
|
float radius;
|
|
19
19
|
float angle;
|
|
20
20
|
if( gl_VertexID % 2 == 0){
|
|
@@ -24,21 +24,32 @@ vec2 coords(){
|
|
|
24
24
|
radius = (pixel_radius_big + pixel_radius_small) / 2.0;
|
|
25
25
|
}
|
|
26
26
|
angle = (float(gl_VertexID) / (${vertexCount}.0));
|
|
27
|
-
|
|
28
27
|
} else {
|
|
29
28
|
radius = pixel_radius_big;
|
|
30
29
|
angle = (float(gl_VertexID - 1) / (${vertexCount}.0));
|
|
31
30
|
}
|
|
32
|
-
angle
|
|
33
|
-
|
|
31
|
+
float opacity = fract(angle + 0.2475) / 1.5 + 0.25;
|
|
32
|
+
angle = angle * ${Math.PI * 2.0} + world_north_angle;
|
|
33
|
+
|
|
34
|
+
return vec3( screen_coordinate + vec2( cos(angle), sin(angle)) * radius, opacity);
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
vec2 adjust_pos(vec2 pos) {
|
|
38
|
+
return vec2(
|
|
39
|
+
(pos.x / screenWH.x - 0.5) * 2.0,
|
|
40
|
+
(0.5 - pos.y / screenWH.y) * 2.0
|
|
41
|
+
);
|
|
42
|
+
}
|
|
36
43
|
|
|
37
44
|
void main(){
|
|
38
|
-
|
|
39
|
-
gl_Position = vec4(
|
|
45
|
+
vec3 c = coord_opacity();
|
|
46
|
+
gl_Position = vec4( adjust_pos(c.xy), 0.0, 1.0);
|
|
47
|
+
// gl_Position = vec4( 0.0, 0.0, 0.0, 1.0);
|
|
40
48
|
v_rgba = rgba;
|
|
41
49
|
v_rgba.a *= plugin_opacity;
|
|
50
|
+
// float opacity = (float((gl_VertexID + 179) % 720 ) / (${vertexCount}.0)) / 1.5 + 0.5;
|
|
51
|
+
v_rgba.a *= c.z;
|
|
52
|
+
gl_PointSize = 10.0;
|
|
42
53
|
}
|
|
43
54
|
`
|
|
44
55
|
|
|
@@ -60,10 +71,15 @@ class Logic {
|
|
|
60
71
|
this.program = createProgram(this.gl, vertexShaderSource, fragmentShaderSource);
|
|
61
72
|
const { gl, program } = this;
|
|
62
73
|
{ // assign attribute locations
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
// in vec2 screen_coordinate;
|
|
75
|
+
// in float pixel_radius_small;
|
|
76
|
+
// in float pixel_radius_big;
|
|
77
|
+
// in vec4 rgba;
|
|
78
|
+
|
|
79
|
+
gl.bindAttribLocation(program, 0, "screen_coordinate");
|
|
80
|
+
gl.bindAttribLocation(program, 1, "pixel_radius_small");
|
|
81
|
+
gl.bindAttribLocation(program, 2, "pixel_radius_big");
|
|
82
|
+
gl.bindAttribLocation(program, 3, "rgba");
|
|
67
83
|
}
|
|
68
84
|
{
|
|
69
85
|
this._opacityLocation = gl.getUniformLocation(program, "plugin_opacity");
|
|
@@ -86,11 +102,11 @@ class Logic {
|
|
|
86
102
|
if (globe.api_GetCurrentGeometry() === 0) return;
|
|
87
103
|
gl.useProgram(program);
|
|
88
104
|
cameraBlockTotem.bind(cameraBlockBindingPoint);
|
|
89
|
-
gl.bindVertexArray(vao);
|
|
90
105
|
if (opacity !== this._lastOpacity) {
|
|
91
106
|
this._lastOpacity = opacity;
|
|
92
107
|
gl.uniform1f(_opacityLocation, opacity);
|
|
93
108
|
}
|
|
109
|
+
gl.bindVertexArray(vao);
|
|
94
110
|
gl.drawArraysInstanced(gl.LINES, 0, vertexCount, length);
|
|
95
111
|
gl.bindVertexArray(null);
|
|
96
112
|
cameraBlockTotem.unbind(cameraBlockBindingPoint);
|
|
@@ -98,7 +114,6 @@ class Logic {
|
|
|
98
114
|
|
|
99
115
|
createVAO(screenCoordsBufferObj, pixelRadiusSmallBufferObj, pixelRadiusBigBufferObj, rgbaBufferObj) {
|
|
100
116
|
const { gl } = this;
|
|
101
|
-
|
|
102
117
|
const vao = gl.createVertexArray();
|
|
103
118
|
gl.bindVertexArray(vao);
|
|
104
119
|
{
|
|
@@ -111,26 +126,27 @@ class Logic {
|
|
|
111
126
|
{
|
|
112
127
|
const { buffer, stride = 0, offset = 0 } = pixelRadiusSmallBufferObj;
|
|
113
128
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
114
|
-
gl.enableVertexAttribArray(
|
|
129
|
+
gl.enableVertexAttribArray(1);
|
|
115
130
|
gl.vertexAttribPointer(1, 1, gl.FLOAT, false, stride, offset);
|
|
116
131
|
gl.vertexAttribDivisor(1, 1);
|
|
117
132
|
}
|
|
118
133
|
{
|
|
119
134
|
const { buffer, stride = 0, offset = 0 } = pixelRadiusBigBufferObj;
|
|
120
135
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
121
|
-
gl.enableVertexAttribArray(
|
|
136
|
+
gl.enableVertexAttribArray(2);
|
|
122
137
|
gl.vertexAttribPointer(2, 1, gl.FLOAT, false, stride, offset);
|
|
123
138
|
gl.vertexAttribDivisor(2, 1);
|
|
124
139
|
}
|
|
125
140
|
{
|
|
126
141
|
const { buffer, stride = 0, offset = 0 } = rgbaBufferObj;
|
|
127
142
|
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
128
|
-
gl.enableVertexAttribArray(
|
|
143
|
+
gl.enableVertexAttribArray(3);
|
|
129
144
|
gl.vertexAttribPointer(3, 4, gl.FLOAT, false, stride, offset);
|
|
130
145
|
gl.vertexAttribDivisor(3, 1);
|
|
131
146
|
}
|
|
132
147
|
|
|
133
148
|
gl.bindVertexArray(null);
|
|
149
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
134
150
|
return vao;
|
|
135
151
|
|
|
136
152
|
}
|
|
@@ -139,6 +155,7 @@ class Logic {
|
|
|
139
155
|
|
|
140
156
|
|
|
141
157
|
free() {
|
|
158
|
+
const { globe } = this;
|
|
142
159
|
CameraUniformBlockTotemCache.release(globe);
|
|
143
160
|
}
|
|
144
161
|
}
|
|
@@ -146,10 +163,6 @@ class Logic {
|
|
|
146
163
|
|
|
147
164
|
|
|
148
165
|
export const PixelPaddingForFlatCompassCache = Object.freeze({
|
|
149
|
-
get: (globe) =>
|
|
150
|
-
|
|
151
|
-
},
|
|
152
|
-
release: (globe) => {
|
|
153
|
-
globeProgramCache.releaseProgram(globe, Logic)
|
|
154
|
-
}
|
|
166
|
+
get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, Logic),
|
|
167
|
+
release: (globe) => noRegisterGlobeProgramCache.releaseProgram(globe, Logic)
|
|
155
168
|
})
|
|
@@ -147,8 +147,11 @@ export class BufferOrchestrator {
|
|
|
147
147
|
const offsets = [];
|
|
148
148
|
for (const item of items) {
|
|
149
149
|
const offset = offsetMap.get(item.key);
|
|
150
|
-
if (offset !== undefined) {
|
|
151
|
-
|
|
150
|
+
if (offset !== undefined) {
|
|
151
|
+
offsets.push(offset);
|
|
152
|
+
} else {
|
|
153
|
+
throw new Error("updateBulk item Key does not exist");
|
|
154
|
+
}
|
|
152
155
|
}
|
|
153
156
|
if (bufferKeys) {
|
|
154
157
|
for (const key of bufferKeys) {
|
|
@@ -230,6 +233,15 @@ export class BufferOrchestrator {
|
|
|
230
233
|
}
|
|
231
234
|
|
|
232
235
|
|
|
236
|
+
/**
|
|
237
|
+
* Flushes metadata and sets length to 0 without actualize change on buffers
|
|
238
|
+
* This method created for cases in which data is loaded on each frame
|
|
239
|
+
*/
|
|
240
|
+
flush() {
|
|
241
|
+
this._length = 0;
|
|
242
|
+
this.tombstoneOffSet = []
|
|
243
|
+
this.offsetMap.clear();
|
|
244
|
+
}
|
|
233
245
|
|
|
234
246
|
_defrag() {
|
|
235
247
|
const newOffsetMap = new Map();
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { CSZMode } from "@pirireis/webglobe";
|
|
2
|
+
|
|
3
|
+
const defaultStyle = {
|
|
4
|
+
textFont: {
|
|
5
|
+
name: 'Arial',
|
|
6
|
+
textColor: '#FFFFFF', // beyaz
|
|
7
|
+
hollowColor: '#000000', // siyah
|
|
8
|
+
size: 12, // piksel
|
|
9
|
+
hollow: true,
|
|
10
|
+
bold: true,
|
|
11
|
+
italic: false,
|
|
12
|
+
},
|
|
13
|
+
opacity: 1.0,
|
|
14
|
+
zMode: CSZMode.Z_GROUND_PERVERTEX,
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* TODOs:
|
|
19
|
+
* 1) update all if initials change (propably need a context and a callback to iterate over data)
|
|
20
|
+
* 2) expose a mechanic to update text on zoom change
|
|
21
|
+
* 3) extend the mechanic on 2 to other events
|
|
22
|
+
*/
|
|
23
|
+
export class ContextTextWriter2Offsets {
|
|
24
|
+
constructor(globe, { style = null, doDraw = true, textAdaptor = null, coordinatesAdaptor = null, keyAdaptor = null, opacityAdaptor = null, angleAdaptor = null, angleOnSphere = false } = {}) {
|
|
25
|
+
this.globe = globe;
|
|
26
|
+
this.itemMap = new Map();
|
|
27
|
+
this.style = style || defaultStyle;
|
|
28
|
+
this.doDraw = doDraw;
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
this.textAdaptor = textAdaptor;
|
|
32
|
+
this.coordinatesAdaptor = coordinatesAdaptor;
|
|
33
|
+
this.keyAdaptor = keyAdaptor;
|
|
34
|
+
|
|
35
|
+
this.opacityAdaptor = opacityAdaptor ? opacityAdaptor : () => 1;
|
|
36
|
+
this.angleOnSphere = angleOnSphere;
|
|
37
|
+
if (angleAdaptor) {
|
|
38
|
+
this.angleAdaptor = angleAdaptor
|
|
39
|
+
this.angleAdaptorIsOn = true;
|
|
40
|
+
} else {
|
|
41
|
+
this.angleAdaptor = () => null
|
|
42
|
+
this.angleAdaptorIsOn = false
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
setKeyAdaptor(adaptor) {
|
|
47
|
+
this.keyAdaptor = adaptor;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setDoDraw(bool) {
|
|
51
|
+
this.doDraw = bool;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
setStyle(style) {
|
|
55
|
+
this.style = style;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setOpacity(opacity) {
|
|
59
|
+
this.style.opacity = opacity;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
draw() {
|
|
65
|
+
if (!this.doDraw) return;
|
|
66
|
+
const { globe, style, itemMap } = this;
|
|
67
|
+
const { textFont, opacity: opacity_ } = style;
|
|
68
|
+
const is3D = globe.api_GetCurrentGeometry() === 0;
|
|
69
|
+
const angleIsOn = is3D ? (this.angleAdaptorIsOn && this.angleOnSphere) : (this.angleAdaptorIsOn)
|
|
70
|
+
for (const [key, { center, offsets, texts, opacity = null, angle = null }] of itemMap) {
|
|
71
|
+
const o = opacity === null ? opacity_ : opacity * opacity_;
|
|
72
|
+
if (center.x !== null && center.y !== null) {
|
|
73
|
+
offsets.forEach(({ offsetX, offsetY }, i) => {
|
|
74
|
+
const text = texts[i];
|
|
75
|
+
globe.api_DrawContextTextMultiLine(text, textFont, o, { x: center.x + offsetX, y: center.y + offsetY }, angleIsOn, angle);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
updateOpacityOfItem(item, i, container, properties) {
|
|
84
|
+
const opacity = this.opacityAdaptor(item, i, container, properties);
|
|
85
|
+
if (opacity == null) return;
|
|
86
|
+
const key = this.keyAdaptor(item, i, container, properties);
|
|
87
|
+
const data = this.itemMap.get(key)
|
|
88
|
+
data.opacity = opacity;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
updateOpacityContainer(container, properties) {
|
|
92
|
+
container.forEach((v, i, c) => {
|
|
93
|
+
this.updateOpacityOfItem(v, i, c, properties);
|
|
94
|
+
})
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
insertTextBulk(container, properties) {
|
|
99
|
+
container.forEach((v, i, c) => {
|
|
100
|
+
this.insertText(v, i, c, properties);
|
|
101
|
+
})
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
updateTextCoords(item, i, container, properties) {
|
|
105
|
+
const coords = this.coordinatesAdaptor(item, i, container, properties);
|
|
106
|
+
if (coords == null) return;
|
|
107
|
+
const key = this.keyAdaptor(item, i, container, properties);
|
|
108
|
+
const data = this.itemMap.get(key)
|
|
109
|
+
data.angle = this.angleAdaptor(item, i, container, properties);
|
|
110
|
+
data.long = coords.long;
|
|
111
|
+
data.lat = coords.lat;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
updateTextCoordsBulk(container, properties) {
|
|
115
|
+
container.forEach((v, i, c) => {
|
|
116
|
+
this.updateTextCoords(v, i, c, properties)
|
|
117
|
+
})
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
deleteTextBulk(keys) {
|
|
121
|
+
for (const key of keys) {
|
|
122
|
+
this.itemMap.delete(key);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
insertText(item, id, container, properties) {
|
|
128
|
+
const key = this.keyAdaptor(item, id, container, properties)
|
|
129
|
+
const coords = this.coordinatesAdaptor(item, id, container, properties)
|
|
130
|
+
if (coords == null) {
|
|
131
|
+
this.itemMap.delete(key);
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const text = this.textAdaptor(item, id, container, properties)
|
|
135
|
+
if (text == null) {
|
|
136
|
+
this.itemMap.delete(key);
|
|
137
|
+
return
|
|
138
|
+
};
|
|
139
|
+
const opacity = this.opacityAdaptor(item, id, container, properties);
|
|
140
|
+
const angle = this.angleAdaptor(item, id, container, properties);
|
|
141
|
+
this.itemMap.set(key, { long: coords.long, lat: coords.lat, text, opacity, angle });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
clear() {
|
|
145
|
+
this.itemMap.clear();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import { PixelPaddingForFlatCompassCache } from "../programs/two-d/pixel-padding-for-compass";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export class PixelPaddingCompassPlugin {
|
|
6
|
-
constructor(id, { } = {}) {
|
|
7
|
-
this.id = id;
|
|
8
|
-
this.memory = new Map();
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
init(globe, gl) {
|
|
13
|
-
this.globe = globe;
|
|
14
|
-
this.gl = gl;
|
|
15
|
-
|
|
16
|
-
this._initOrchestrations()
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
_initOrchestrations() {
|
|
22
|
-
const { gl, globe } = this;
|
|
23
|
-
this.paddingProgram = PixelPaddingForFlatCompassCache.get(globe);
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
{
|
|
27
|
-
// createBuffers
|
|
28
|
-
const bufferType = "DYNAMIC_DRAW";
|
|
29
|
-
const initialCapacity = this.bufferOrchestrator.capacity;
|
|
30
|
-
this.bufferManagersCompMap = new Map(
|
|
31
|
-
[
|
|
32
|
-
["screenCoordinates", {
|
|
33
|
-
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
34
|
-
'adaptor': (item) => {
|
|
35
|
-
const { x, y } = globe.api_GetScreenPointFromGeo(
|
|
36
|
-
{
|
|
37
|
-
long: item.long,
|
|
38
|
-
lat: item.lat,
|
|
39
|
-
z: 0,
|
|
40
|
-
});
|
|
41
|
-
return new Float32Array([x, y]);
|
|
42
|
-
}
|
|
43
|
-
}],
|
|
44
|
-
["pixelRadiusSmall", {
|
|
45
|
-
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
46
|
-
'adaptor': (item) => new Float32Array([item.pixelRadiusSmall])
|
|
47
|
-
}],
|
|
48
|
-
["pixelRadiusBig", {
|
|
49
|
-
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
50
|
-
'adaptor': (item) => new Float32Array([item.pixelRadiusBig])
|
|
51
|
-
}],
|
|
52
|
-
["rgba", {
|
|
53
|
-
'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
|
|
54
|
-
'adaptor': (item) => {
|
|
55
|
-
if (item.lineProperties?.rgba) return new Float32Array(item.lineProperties.rgba);
|
|
56
|
-
return new Float32Array(item.rgba);
|
|
57
|
-
}
|
|
58
|
-
}],
|
|
59
|
-
|
|
60
|
-
]
|
|
61
|
-
);
|
|
62
|
-
const obj = function (bufferManagerComp) {
|
|
63
|
-
return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
|
|
64
|
-
};
|
|
65
|
-
this.paddingVao = this.paddingProgram.createVAO(
|
|
66
|
-
...['screenCoordinates', 'pixelRadiusSmall', 'pixelRadiusBig', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
function isOnTheScreen(globe, points) { }
|
|
76
|
-
|