@pirireis/webglobeplugins 0.12.0-alpha → 0.14.0-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-cdf-points.js +20 -0
- package/Math/arc-generate-points copy.js +1 -0
- package/Math/arc.js +21 -8
- package/Math/circle-cdf-points.js +0 -2
- package/Math/circle.js +35 -16
- package/Math/templete-shapes/grid-visually-equal.js +66 -0
- package/altitude-locator/plugin.js +3 -2
- package/bearing-line/plugin.js +1 -2
- package/circle-line-chain/plugin.js +4 -7
- package/compass-rose/compass-rose-padding-flat.js +12 -0
- package/package.json +1 -1
- package/programs/line-on-globe/degree-padding-around-circle-3d.js +1 -1
- package/programs/line-on-globe/linestrip/data.js +4 -0
- package/programs/line-on-globe/{linestrip.js → linestrip/linestrip.js} +37 -35
- package/programs/line-on-globe/naive-accurate-flexible.js +23 -16
- package/programs/picking/pickable-renderer.js +1 -2
- package/programs/rings/distancering/circleflatprogram.js +116 -120
- package/programs/rings/distancering/circlepaddingfreeangleprogram.js +1 -1
- package/programs/rings/distancering/circlepaddysharedbuffer.js +368 -354
- package/programs/rings/distancering/index.js +6 -5
- package/programs/rings/distancering/paddyflatprogram.js +127 -136
- package/programs/rings/distancering/paddyflatprogram2d.js +129 -138
- package/programs/rings/distancering/paddyflatprogram3d.js +128 -136
- package/programs/rings/partial-ring/piece-of-pie copy.js +286 -0
- package/programs/rings/partial-ring/piece-of-pie.js +26 -13
- package/programs/totems/camerauniformblock.js +1 -1
- package/programs/totems/index.js +1 -1
- package/programs/vectorfields/logics/pixelbased.js +5 -21
- package/range-tools-on-terrain/bearing-line/adapters.js +111 -0
- package/range-tools-on-terrain/bearing-line/plugin.js +360 -0
- package/range-tools-on-terrain/bearing-line/types.js +1 -0
- package/range-tools-on-terrain/circle-line-chain/adapters.js +83 -0
- package/range-tools-on-terrain/circle-line-chain/chain-list-map.js +351 -0
- package/range-tools-on-terrain/circle-line-chain/plugin.js +389 -0
- package/range-tools-on-terrain/circle-line-chain/types.js +1 -0
- package/range-tools-on-terrain/range-ring/adapters.js +25 -0
- package/range-tools-on-terrain/range-ring/plugin.js +31 -0
- package/range-tools-on-terrain/range-ring/types.js +1 -0
- package/rangerings/plugin.js +7 -11
- package/semiplugins/lightweight/line-plugin.js +195 -0
- package/semiplugins/lightweight/piece-of-pie-plugin.js +175 -0
- package/semiplugins/shape-on-terrain/arc-plugin.js +368 -0
- package/{shape-on-terrain/circle/plugin.js → semiplugins/shape-on-terrain/circle-plugin.js} +129 -68
- package/semiplugins/shape-on-terrain/derived/padding-plugin.js +96 -0
- package/semiplugins/type.js +1 -0
- package/types.js +0 -11
- package/util/account/create-buffermap-orchastration.js +39 -0
- package/util/account/index.js +2 -2
- package/util/account/single-attribute-buffer-management/buffer-manager.js +2 -3
- package/util/account/single-attribute-buffer-management/buffer-orchestrator.js +14 -3
- package/util/build-strategy/static-dynamic.js +1 -1
- package/util/check/typecheck.js +15 -1
- package/util/geometry/index.js +3 -2
- package/util/gl-util/buffer/attribute-loader.js +2 -5
- package/util/gl-util/draw-options/methods.js +4 -5
- package/util/webglobjectbuilders.js +4 -9
- package/write-text/context-text3.js +17 -0
- package/write-text/context-text3old.js +152 -0
- package/programs/line-on-globe/circle-accurate.js +0 -175
- package/programs/line-on-globe/circle.js +0 -164
- package/programs/line-on-globe/to-the-surface.js +0 -109
- package/programs/rings/distancering/shader.js +0 -1
- package/programs/totems/canvas-webglobe-info1.js +0 -106
- package/shape-on-terrain/arc/naive/plugin.js +0 -205
- package/util/check/get.js +0 -14
- package/util/gl-util/buffer/types.js +0 -1
- package/util/gl-util/draw-options/types.js +0 -15
- package/util/webglobjectbuilders1.js +0 -219
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createProgram
|
|
2
|
-
import { CameraUniformBlockTotem, CameraUniformBlockString } from "../../totems";
|
|
1
|
+
import { createProgram } from "../../../util/webglobjectbuilders";
|
|
2
|
+
import { CameraUniformBlockTotem, CameraUniformBlockString } from "../../totems/index";
|
|
3
3
|
import { noRegisterGlobeProgramCache, globeProgramCache } from "../../programcache";
|
|
4
4
|
import { POLE, PI, longLatRadToMercator, mercatorXYToGLPosition, longLatRadToCartesian3D, circleLimpFromLongLatRadCenterCartesian3D_accurate, circleLimpFromLongLatRadCenterMercatorCompass_accurate,
|
|
5
5
|
//circleLimpFromLongLatRadCenterMercatorRealDistanceNew_accurate,
|
|
@@ -40,7 +40,7 @@ in float tail_angle3d;
|
|
|
40
40
|
|
|
41
41
|
in vec4 color;
|
|
42
42
|
in float radius; // in meter
|
|
43
|
-
in float
|
|
43
|
+
in float filling_mode; // 0.0: constant, 1.0: fading, 2.0: hide
|
|
44
44
|
// flat out int vid;
|
|
45
45
|
// flat out float v_phase;
|
|
46
46
|
out vec2 v_pos;
|
|
@@ -49,7 +49,7 @@ out vec4 v_color;
|
|
|
49
49
|
|
|
50
50
|
void main() {
|
|
51
51
|
// vid = gl_VertexID;
|
|
52
|
-
if (
|
|
52
|
+
if (filling_mode == 2.0 || radius == 0.0) { return; }
|
|
53
53
|
float start_angle, tail_angle;
|
|
54
54
|
if (is3D) {
|
|
55
55
|
start_angle = start_angle3d;
|
|
@@ -58,22 +58,22 @@ void main() {
|
|
|
58
58
|
start_angle = start_angle2d;
|
|
59
59
|
tail_angle = tail_angle2d;
|
|
60
60
|
}
|
|
61
|
-
float
|
|
62
|
-
if ( draw_mode == 0 &&
|
|
61
|
+
float filling_mode_ = filling_mode;
|
|
62
|
+
if ( draw_mode == 0 && filling_mode == 1.0) {filling_mode_ = 0.0;}
|
|
63
63
|
float vertexID = float(gl_VertexID);
|
|
64
64
|
float radius_ = radius;
|
|
65
65
|
float alpha = plugin_alpha_multiplier;
|
|
66
66
|
if (draw_mode == 1) { // TRIANGLE_FAN
|
|
67
67
|
if (gl_VertexID == 0) {
|
|
68
68
|
radius_ = 0.0;
|
|
69
|
-
if (
|
|
69
|
+
if ( filling_mode == 1.0 ) { alpha = 0.0; }
|
|
70
70
|
}
|
|
71
71
|
vertexID -= 1.0;
|
|
72
72
|
}
|
|
73
73
|
float phase = ( vertexID / (edge_count - 1.0) );
|
|
74
74
|
// v_angle = tail_angle;
|
|
75
75
|
|
|
76
|
-
if (
|
|
76
|
+
if ( filling_mode_ == 1.0 ) {
|
|
77
77
|
if ( tail_angle < 0.0 ) {
|
|
78
78
|
v_color = vec4( color.rgb , color.a * ( 1.0 - phase ) * alpha );
|
|
79
79
|
} else {
|
|
@@ -82,7 +82,7 @@ void main() {
|
|
|
82
82
|
} else {
|
|
83
83
|
v_color = vec4( color.rgb , color.a * alpha );
|
|
84
84
|
}
|
|
85
|
-
if (
|
|
85
|
+
if ( filling_mode == 0.0 && draw_mode == 1 ) {
|
|
86
86
|
v_color.a /= 2.0;
|
|
87
87
|
}
|
|
88
88
|
float angle;
|
|
@@ -121,6 +121,17 @@ void main() {
|
|
|
121
121
|
}`;
|
|
122
122
|
export const ITEM_SIZE = 10;
|
|
123
123
|
export class Logic {
|
|
124
|
+
globe;
|
|
125
|
+
gl;
|
|
126
|
+
_lastMode;
|
|
127
|
+
_lastEdgeCount;
|
|
128
|
+
_lastAlphaMultiplier;
|
|
129
|
+
program;
|
|
130
|
+
_edgeCountLocation;
|
|
131
|
+
_draw_modeLocation;
|
|
132
|
+
_plugin_alpha_multiplierLocation;
|
|
133
|
+
cameraBlockBindingPoint;
|
|
134
|
+
cameraBlockTotem; // Type this based on your CameraUniformBlockTotem implementation
|
|
124
135
|
constructor(globe) {
|
|
125
136
|
this.globe = globe;
|
|
126
137
|
this.gl = globe.gl;
|
|
@@ -138,7 +149,7 @@ export class Logic {
|
|
|
138
149
|
gl.bindAttribLocation(program, 5, 'tail_angle3d');
|
|
139
150
|
gl.bindAttribLocation(program, 6, 'color');
|
|
140
151
|
gl.bindAttribLocation(program, 7, 'radius');
|
|
141
|
-
gl.bindAttribLocation(program, 8, '
|
|
152
|
+
gl.bindAttribLocation(program, 8, 'filling_mode');
|
|
142
153
|
// vao
|
|
143
154
|
// instanced draw read 1
|
|
144
155
|
}
|
|
@@ -162,9 +173,9 @@ export class Logic {
|
|
|
162
173
|
const { gl, program, cameraBlockTotem, cameraBlockBindingPoint } = this;
|
|
163
174
|
// gl.disable(gl.DEPTH_TEST);
|
|
164
175
|
gl.useProgram(program);
|
|
165
|
-
if (drawMode !== this._lastMode) {
|
|
176
|
+
if (drawModeMap[drawMode] !== this._lastMode) {
|
|
166
177
|
gl.uniform1i(this._draw_modeLocation, drawModeMap[drawMode]);
|
|
167
|
-
this._lastMode = drawMode;
|
|
178
|
+
this._lastMode = drawModeMap[drawMode];
|
|
168
179
|
}
|
|
169
180
|
if (edgeCount !== this._lastEdgeCount) {
|
|
170
181
|
gl.uniform1f(this._edgeCountLocation, edgeCount);
|
|
@@ -193,7 +204,7 @@ export class Logic {
|
|
|
193
204
|
in float tail_angle; // the rotation of the partial circle
|
|
194
205
|
in vec4 color;
|
|
195
206
|
in float radius; // in meter
|
|
196
|
-
in float
|
|
207
|
+
in float filling_mode; // 0.0: constant, 1.0: fading, 2.0: hide
|
|
197
208
|
*/
|
|
198
209
|
createVAO(center2dObj, center3dObj, startAngle2DObj, tailAngle2DObj, startAngle3DObj, tailAngle3DObj, colorObj, radiusObj, colorModeObj) {
|
|
199
210
|
const { gl } = this;
|
|
@@ -266,6 +277,8 @@ export class Logic {
|
|
|
266
277
|
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
267
278
|
return vao;
|
|
268
279
|
}
|
|
280
|
+
createUBO() {
|
|
281
|
+
}
|
|
269
282
|
}
|
|
270
283
|
export const PieceOfPieProgramCache = Object.freeze({
|
|
271
284
|
get: (globe) => noRegisterGlobeProgramCache.getProgram(globe, Logic),
|
package/programs/totems/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import CameraUniformBlockTotem,
|
|
1
|
+
import { CameraUniformBlockTotem, CameraUniformBlockString, CameraUniformBlockTotemCache } from "./camerauniformblock";
|
|
2
2
|
export { CameraUniformBlockTotem, CameraUniformBlockString, CameraUniformBlockTotemCache };
|
|
@@ -34,7 +34,7 @@ vec2 read_value(const vec2 uv) {
|
|
|
34
34
|
return value;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
vec2 lookup_wind(const vec2 uv) {
|
|
37
|
+
vec2 lookup_wind(const vec2 uv) {
|
|
38
38
|
// return texture(vector_field, uv).rg; // lower-res hardware filtering
|
|
39
39
|
vec2 res = vec2(textureSize(vector_field, 0));
|
|
40
40
|
vec2 px = 1.0 / res;
|
|
@@ -49,23 +49,7 @@ vec2 lookup_wind(const vec2 uv) { // gerek kalmayabilir. sampler linear methodu
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
// return texture(vector_field, uv).rg; // lower-res hardware filtering
|
|
54
|
-
vec2 res = vec2(textureSize(vector_field, 0));
|
|
55
|
-
if (res.x == escape_value || res.y == escape_value){ return vec2(0.0);}
|
|
56
|
-
vec2 px = 1.0 / res;
|
|
57
|
-
vec2 vc = (floor(uv * res)) * px;
|
|
58
|
-
vec2 f = fract(uv * res);
|
|
59
|
-
vec2 tl = texture(vector_field, vc).rg;
|
|
60
|
-
vec2 tr = texture(vector_field, vc + vec2(px.x, 0)).rg;
|
|
61
|
-
vec2 bl = texture(vector_field, vc + vec2(0, px.y)).rg;
|
|
62
|
-
vec2 br = texture(vector_field, vc + px).rg;
|
|
63
|
-
if (tl.x == 0.0 && tl.y == 0.0){ return vec2(0.0);}
|
|
64
|
-
if (tr.x == 0.0 && tr.y == 0.0){ return vec2(0.0);}
|
|
65
|
-
if (bl.x == 0.0 && bl.y == 0.0){ return vec2(0.0);}
|
|
66
|
-
if (br.x == 0.0 && br.y == 0.0){ return vec2(0.0);}
|
|
67
|
-
return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);
|
|
68
|
-
}
|
|
52
|
+
|
|
69
53
|
|
|
70
54
|
|
|
71
55
|
vec2 random_position(vec2 st){
|
|
@@ -74,17 +58,17 @@ vec2 random_position(vec2 st){
|
|
|
74
58
|
|
|
75
59
|
|
|
76
60
|
void main(){
|
|
77
|
-
vec2 vec =
|
|
61
|
+
vec2 vec = lookup_wind(in_position).xy;
|
|
78
62
|
if (vec.x == 0.0 && vec.y == 0.0){
|
|
79
63
|
out_position = random_position(in_position);
|
|
80
64
|
return;
|
|
81
65
|
}
|
|
82
66
|
float random_value = random(in_position + random_seed);
|
|
83
|
-
if (random_value < drop_rate){
|
|
67
|
+
if (random_value < drop_rate){
|
|
84
68
|
out_position = random_position(in_position);
|
|
85
69
|
return;
|
|
86
70
|
}
|
|
87
|
-
out_position = in_position
|
|
71
|
+
out_position = in_position + (vec / draw_texture_size) * range;
|
|
88
72
|
}
|
|
89
73
|
`;
|
|
90
74
|
const fragmentShaderSource = `#version 300 es
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
const radian = (degree) => degree * Math.PI / 180;
|
|
2
|
+
const calculateStartAngle = (long, lat, endLong, endLat) => {
|
|
3
|
+
const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.
|
|
4
|
+
const dLong = endLong - long;
|
|
5
|
+
let angle = -Math.atan2(dLat, dLong);
|
|
6
|
+
return angle;
|
|
7
|
+
};
|
|
8
|
+
const integralSec = (angle) => {
|
|
9
|
+
return Math.log(Math.tan(angle / 2 + Math.PI / 4));
|
|
10
|
+
};
|
|
11
|
+
export const flatLinesInputAdapter = (bearingLine) => {
|
|
12
|
+
const { long, lat, endLong, endLat, rgba } = bearingLine;
|
|
13
|
+
return {
|
|
14
|
+
key: bearingLine.key,
|
|
15
|
+
start: [long, lat],
|
|
16
|
+
end: [endLong, endLat],
|
|
17
|
+
color: rgba,
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export const flatLinesBearingInputAdapter = (bearingLine) => {
|
|
21
|
+
const { long, lat, rgba, key, bearingLat = 0, bearingLong = 0 } = bearingLine;
|
|
22
|
+
return {
|
|
23
|
+
key: key,
|
|
24
|
+
start: [long, lat],
|
|
25
|
+
end: [bearingLong, bearingLat],
|
|
26
|
+
color: rgba,
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export const bearingLineToCircleInputAdapter = (globe) => (bearingLine) => {
|
|
30
|
+
const { long, lat, endLong, endLat, rgba, altitude = 0 } = bearingLine;
|
|
31
|
+
if (bearingLine.radius === undefined || bearingLine.radius === null) {
|
|
32
|
+
const radius = globe.Math.GetDist2D(long, lat, endLong, endLat);
|
|
33
|
+
bearingLine.radius = radius;
|
|
34
|
+
}
|
|
35
|
+
return {
|
|
36
|
+
key: bearingLine.key,
|
|
37
|
+
center: [long, lat],
|
|
38
|
+
radius: bearingLine.radius,
|
|
39
|
+
height: altitude,
|
|
40
|
+
color: rgba,
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
export const bearingLineToArcInputAdapter = (bearingLine) => {
|
|
44
|
+
const { long, lat, endLong, endLat, rgba, altitude = 0 } = bearingLine;
|
|
45
|
+
return {
|
|
46
|
+
key: bearingLine.key,
|
|
47
|
+
start: [long, lat],
|
|
48
|
+
end: [endLong, endLat],
|
|
49
|
+
height: altitude,
|
|
50
|
+
color: rgba,
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export const bearingLineToBearingArcInputAdapter = (globe, bearingLine) => {
|
|
54
|
+
const { long, lat, bearingAngle, rgba, altitude = 0, key } = bearingLine;
|
|
55
|
+
if (bearingLine.radius === undefined || bearingLine.radius === null) {
|
|
56
|
+
throw new Error("Bearing line radius is not defined. Please calculate it before converting to ArcInput.");
|
|
57
|
+
}
|
|
58
|
+
const { long: endLong, lat: endLat } = globe.Math.FindPointByPolar(long, lat, bearingLine.radius, bearingAngle);
|
|
59
|
+
bearingLine.bearingLong = endLong;
|
|
60
|
+
bearingLine.bearingLat = endLat;
|
|
61
|
+
return {
|
|
62
|
+
key: key,
|
|
63
|
+
start: [long, lat],
|
|
64
|
+
end: [endLong, endLat],
|
|
65
|
+
height: altitude,
|
|
66
|
+
color: rgba,
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export const bearingLineToPieceOfPieInputAdapter = (globe, item) => {
|
|
70
|
+
const lat = radian(item.lat);
|
|
71
|
+
const long = radian(item.long);
|
|
72
|
+
const endLat = radian(item.endLat);
|
|
73
|
+
const endLong = radian(item.endLong);
|
|
74
|
+
const altitude = (item.altitude ?? 0) / 1000;
|
|
75
|
+
const radius = item.radius ? item.radius * 0.2 : 10;
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
const { long: bearingLong, lat: bearingLat } = globe.Math.FindPointByPolar(item.long, item.lat, item.radius, item.bearingAngle);
|
|
78
|
+
const startAngle2d = calculateStartAngle(long, lat, endLong, endLat);
|
|
79
|
+
const bearingAngle2d = calculateStartAngle(long, lat, radian(bearingLong), radian(bearingLat));
|
|
80
|
+
let tailAngle2d = bearingAngle2d - startAngle2d;
|
|
81
|
+
if (tailAngle2d > 0) {
|
|
82
|
+
tailAngle2d -= Math.PI * 2;
|
|
83
|
+
}
|
|
84
|
+
const bearingAngle = radian(item.bearingAngle - 90);
|
|
85
|
+
const startAngleReal = globe.Math.GetAzimuthAngle(item.long, item.lat, item.endLong, item.endLat); //startAngle2d * 180 / Math.PI;
|
|
86
|
+
const startAngle3d = radian(startAngleReal - 90);
|
|
87
|
+
let tailAngle3d = bearingAngle - startAngle3d;
|
|
88
|
+
if (tailAngle3d > 0) {
|
|
89
|
+
tailAngle3d -= Math.PI * 2;
|
|
90
|
+
}
|
|
91
|
+
return {
|
|
92
|
+
key: item.key,
|
|
93
|
+
center: [item.long, item.lat],
|
|
94
|
+
radius: radius,
|
|
95
|
+
altitude: altitude + 230,
|
|
96
|
+
color: item.rgba,
|
|
97
|
+
startAngle2D: startAngle2d * 180 / Math.PI,
|
|
98
|
+
coverAngle2D: tailAngle2d * 180 / Math.PI,
|
|
99
|
+
startAngle3D: startAngle3d * 180 / Math.PI,
|
|
100
|
+
coverAngle3D: tailAngle3d * 180 / Math.PI,
|
|
101
|
+
fillingMode: item.pieFillingMode ?? 1,
|
|
102
|
+
};
|
|
103
|
+
};
|
|
104
|
+
export const pieceOfPieOpacityAdaptor = (lod, tiltAngle) => {
|
|
105
|
+
const lodThreshold = 7.5;
|
|
106
|
+
const lodFactor = Math.exp(-Math.max(0, lod - lodThreshold));
|
|
107
|
+
tiltAngle += 5;
|
|
108
|
+
const tiltFactor = Math.min(1, 1 / Math.tan(radian(tiltAngle)));
|
|
109
|
+
const opacity = Math.max(Math.min(lodFactor * tiltFactor, 1), 0);
|
|
110
|
+
return opacity < 0.1 ? 0 : opacity; // Ensure opacity is not less than 0.1
|
|
111
|
+
};
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { ContextTextWriter3 } from "../../write-text/context-text3";
|
|
2
|
+
import { flatLinesInputAdapter, flatLinesBearingInputAdapter, bearingLineToCircleInputAdapter, bearingLineToArcInputAdapter, bearingLineToBearingArcInputAdapter, bearingLineToPieceOfPieInputAdapter, pieceOfPieOpacityAdaptor } from "./adapters";
|
|
3
|
+
import { CircleOnTerrainPlugin } from "../../semiplugins/shape-on-terrain/circle-plugin";
|
|
4
|
+
import { PieceOfPiePlugin } from "../../semiplugins/lightweight/piece-of-pie-plugin";
|
|
5
|
+
import { ArcOnTerrainPlugin } from "../../semiplugins/shape-on-terrain/arc-plugin";
|
|
6
|
+
import { LinePlugin } from "../../semiplugins/lightweight/line-plugin";
|
|
7
|
+
export class BearingLinePlugin {
|
|
8
|
+
id;
|
|
9
|
+
globe = null;
|
|
10
|
+
circlePlugin;
|
|
11
|
+
arcPlugin;
|
|
12
|
+
arcPluginBL;
|
|
13
|
+
pieceOfPiePlugin;
|
|
14
|
+
linePlugin;
|
|
15
|
+
linePluginBL;
|
|
16
|
+
_freed = false;
|
|
17
|
+
_opacities = {
|
|
18
|
+
general: 1,
|
|
19
|
+
circle: 1,
|
|
20
|
+
arc: 1,
|
|
21
|
+
pie: 1,
|
|
22
|
+
bearing: 1
|
|
23
|
+
};
|
|
24
|
+
_textWritersMap = new Map();
|
|
25
|
+
_textDataPreAdaptor = (item) => item;
|
|
26
|
+
drawOptions = {
|
|
27
|
+
drawVRM: true,
|
|
28
|
+
drawBearingLine: true,
|
|
29
|
+
drawAngleRing: true,
|
|
30
|
+
drawText: true,
|
|
31
|
+
flatRealLineOn: true, // This is a new option to control flat real line drawing
|
|
32
|
+
flatStraightLineOn: true // This is a new option to control flat straight line drawing
|
|
33
|
+
};
|
|
34
|
+
_memory = new Map();
|
|
35
|
+
constructor(id, { textWritersMap, textDataPreAdaptor, opacities, drawOptions, } = {}) {
|
|
36
|
+
this.id = id;
|
|
37
|
+
if (!(textWritersMap instanceof Map))
|
|
38
|
+
throw new Error("textWritersMap is not an instance of Map");
|
|
39
|
+
textWritersMap.forEach((v) => {
|
|
40
|
+
if (!(v instanceof ContextTextWriter3))
|
|
41
|
+
throw new Error("textWritersMap element is not an instance of ContextTextWriter3");
|
|
42
|
+
});
|
|
43
|
+
this._textWritersMap = textWritersMap || new Map();
|
|
44
|
+
this._textWritersMap.forEach((writer) => writer.setKeyAdaptor((item) => item.key));
|
|
45
|
+
this._textDataPreAdaptor = textDataPreAdaptor || ((item) => item);
|
|
46
|
+
this.circlePlugin = new CircleOnTerrainPlugin(id + "_circle", {
|
|
47
|
+
variativeColorsOn: true,
|
|
48
|
+
});
|
|
49
|
+
this.arcPlugin = new ArcOnTerrainPlugin(id + "_arc", {
|
|
50
|
+
variativeColorsOn: true,
|
|
51
|
+
});
|
|
52
|
+
this.arcPluginBL = new ArcOnTerrainPlugin(id + "_arcBL", {
|
|
53
|
+
variativeColorsOn: true,
|
|
54
|
+
});
|
|
55
|
+
this.pieceOfPiePlugin = new PieceOfPiePlugin(id + "_pieceOfPie", {
|
|
56
|
+
bufferType: "DYNAMIC_DRAW",
|
|
57
|
+
});
|
|
58
|
+
this.linePlugin = new LinePlugin(id + "_line", {
|
|
59
|
+
variativeColorsOn: true,
|
|
60
|
+
bufferType: "DYNAMIC_DRAW",
|
|
61
|
+
});
|
|
62
|
+
this.linePluginBL = new LinePlugin(id + "_lineBL", {
|
|
63
|
+
variativeColorsOn: true,
|
|
64
|
+
bufferType: "DYNAMIC_DRAW",
|
|
65
|
+
});
|
|
66
|
+
if (opacities) {
|
|
67
|
+
this._opacities = {
|
|
68
|
+
...this._opacities,
|
|
69
|
+
...opacities,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (drawOptions) {
|
|
73
|
+
this.drawOptions = {
|
|
74
|
+
...this.drawOptions,
|
|
75
|
+
...drawOptions
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
setDoDrawVRM(drawVRM) {
|
|
80
|
+
if (this._freed) {
|
|
81
|
+
throw new Error("Plugin has been freed, cannot set draw VRM.");
|
|
82
|
+
}
|
|
83
|
+
if (!this.globe) {
|
|
84
|
+
throw new Error("Globe is not set, cannot set draw VRM.");
|
|
85
|
+
}
|
|
86
|
+
this.drawOptions.drawVRM = drawVRM;
|
|
87
|
+
this.globe.DrawRender();
|
|
88
|
+
}
|
|
89
|
+
setDoDrawText(drawText) {
|
|
90
|
+
if (this._freed) {
|
|
91
|
+
throw new Error("Plugin has been freed, cannot set draw text.");
|
|
92
|
+
}
|
|
93
|
+
if (!this.globe) {
|
|
94
|
+
throw new Error("Globe is not set, cannot set draw text.");
|
|
95
|
+
}
|
|
96
|
+
this.drawOptions.drawText = drawText;
|
|
97
|
+
this.globe.DrawRender();
|
|
98
|
+
}
|
|
99
|
+
setDoDrawBearingLine(drawBearingLine) {
|
|
100
|
+
if (this._freed) {
|
|
101
|
+
throw new Error("Plugin has been freed, cannot set draw bearing line.");
|
|
102
|
+
}
|
|
103
|
+
if (!this.globe) {
|
|
104
|
+
throw new Error("Globe is not set, cannot set draw bearing line.");
|
|
105
|
+
}
|
|
106
|
+
this.drawOptions.drawBearingLine = drawBearingLine;
|
|
107
|
+
this.globe.DrawRender();
|
|
108
|
+
}
|
|
109
|
+
setDoDrawAngleRing(drawAngleRing) {
|
|
110
|
+
if (this._freed) {
|
|
111
|
+
throw new Error("Plugin has been freed, cannot set draw angle ring.");
|
|
112
|
+
}
|
|
113
|
+
if (!this.globe) {
|
|
114
|
+
throw new Error("Globe is not set, cannot set draw angle ring.");
|
|
115
|
+
}
|
|
116
|
+
this.drawOptions.drawAngleRing = drawAngleRing;
|
|
117
|
+
this.globe.DrawRender();
|
|
118
|
+
}
|
|
119
|
+
// TODO:
|
|
120
|
+
updatePartial(items, { textWriterIDs } = {}) {
|
|
121
|
+
if (this._freed) {
|
|
122
|
+
throw new Error("Plugin has been freed, cannot update item.");
|
|
123
|
+
}
|
|
124
|
+
if (!this.globe) {
|
|
125
|
+
throw new Error("Globe is not set, cannot update item.");
|
|
126
|
+
}
|
|
127
|
+
const fixedItems = [];
|
|
128
|
+
for (const item of items) {
|
|
129
|
+
if (!this._memory.has(item.key)) {
|
|
130
|
+
throw new Error(`Item with key ${item.key} not found in memory.`);
|
|
131
|
+
}
|
|
132
|
+
fixedItems.push(this.__memorizeItem(item));
|
|
133
|
+
}
|
|
134
|
+
this._build(fixedItems, { textWriterIDs });
|
|
135
|
+
}
|
|
136
|
+
setDrawOptions(drawOptions) {
|
|
137
|
+
if (this._freed) {
|
|
138
|
+
throw new Error("Plugin has been freed, cannot set draw options.");
|
|
139
|
+
}
|
|
140
|
+
if (!this.globe) {
|
|
141
|
+
throw new Error("Globe is not set, cannot set draw options.");
|
|
142
|
+
}
|
|
143
|
+
this.drawOptions = {
|
|
144
|
+
...this.drawOptions,
|
|
145
|
+
...drawOptions
|
|
146
|
+
};
|
|
147
|
+
this.globe.DrawRender();
|
|
148
|
+
}
|
|
149
|
+
updateCoordinatesBulk(items, { textWriterIDs } = {}) {
|
|
150
|
+
if (this._freed) {
|
|
151
|
+
throw new Error("Plugin has been freed, cannot update coordinates.");
|
|
152
|
+
}
|
|
153
|
+
if (!this.globe) {
|
|
154
|
+
throw new Error("Globe is not set, cannot update coordinates.");
|
|
155
|
+
}
|
|
156
|
+
const fixedItems = [];
|
|
157
|
+
for (const item of items) {
|
|
158
|
+
if (!this._memory.has(item.key)) {
|
|
159
|
+
throw new Error(`Item with key ${item.key} not found in memory.`);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
fixedItems.push(this.__memorizeItem(item));
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
this._build(fixedItems, { textWriterIDs });
|
|
166
|
+
}
|
|
167
|
+
setOpacities(opacities) {
|
|
168
|
+
if (this._freed) {
|
|
169
|
+
throw new Error("Plugin has been freed, cannot set opacities.");
|
|
170
|
+
}
|
|
171
|
+
if (!this.globe) {
|
|
172
|
+
throw new Error("Globe is not set, cannot set opacities.");
|
|
173
|
+
}
|
|
174
|
+
this._opacities = {
|
|
175
|
+
...this._opacities,
|
|
176
|
+
...opacities,
|
|
177
|
+
};
|
|
178
|
+
this.globe.DrawRender();
|
|
179
|
+
}
|
|
180
|
+
insertBulk(items, { textWriterIDs } = {}) {
|
|
181
|
+
this._build(items, { textWriterIDs });
|
|
182
|
+
}
|
|
183
|
+
deleteBulk(keys) {
|
|
184
|
+
if (this._freed) {
|
|
185
|
+
throw new Error("Plugin has been freed, cannot delete items.");
|
|
186
|
+
}
|
|
187
|
+
if (!this.globe) {
|
|
188
|
+
throw new Error("Globe is not set, cannot delete items.");
|
|
189
|
+
}
|
|
190
|
+
if (!this.circlePlugin || !this.arcPlugin) {
|
|
191
|
+
throw new Error("Circle and Arc plugins are not initialized.");
|
|
192
|
+
}
|
|
193
|
+
this.circlePlugin.deleteBulk(keys);
|
|
194
|
+
this.arcPlugin.deleteBulk(keys);
|
|
195
|
+
this.arcPluginBL.deleteBulk(keys);
|
|
196
|
+
this.pieceOfPiePlugin.deleteBulk(keys);
|
|
197
|
+
this.linePlugin.deleteBulk(keys);
|
|
198
|
+
this.linePluginBL.deleteBulk(keys);
|
|
199
|
+
this.__deleteTexts(keys);
|
|
200
|
+
this.globe.DrawRender();
|
|
201
|
+
}
|
|
202
|
+
updateText(textWriterIDs, itemKeys = null) {
|
|
203
|
+
if (this._freed) {
|
|
204
|
+
throw new Error("Plugin has been freed, cannot update text.");
|
|
205
|
+
}
|
|
206
|
+
const items = itemKeys ? itemKeys.map(key => this._memory.get(key)).filter(Boolean) : Array.from(this._memory.values());
|
|
207
|
+
this.__insertTexts(items, textWriterIDs);
|
|
208
|
+
}
|
|
209
|
+
_calculateRadiusFromBearingLine(bearingLine) {
|
|
210
|
+
const { long, lat, endLong, endLat } = bearingLine;
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
bearingLine.radius = this.globe.Math.GetDist2D(long, lat, endLong, endLat);
|
|
213
|
+
}
|
|
214
|
+
__deleteTexts(keys) {
|
|
215
|
+
if (this._freed) {
|
|
216
|
+
throw new Error("Plugin has been freed, cannot delete texts.");
|
|
217
|
+
}
|
|
218
|
+
if (!this.globe) {
|
|
219
|
+
throw new Error("Globe is not set, cannot delete texts.");
|
|
220
|
+
}
|
|
221
|
+
for (const textWriter of this._textWritersMap.values()) {
|
|
222
|
+
textWriter.deleteTextBulk(keys);
|
|
223
|
+
}
|
|
224
|
+
keys.forEach(key => {
|
|
225
|
+
this._memory.delete(key);
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
__insertTexts(items, textWriterIDs = []) {
|
|
229
|
+
if (this._freed) {
|
|
230
|
+
throw new Error("Plugin has been freed, cannot insert texts.");
|
|
231
|
+
}
|
|
232
|
+
if (!this.globe) {
|
|
233
|
+
throw new Error("Globe is not set, cannot insert texts.");
|
|
234
|
+
}
|
|
235
|
+
if (textWriterIDs.length === 0) {
|
|
236
|
+
textWriterIDs = Array.from(this._textWritersMap.keys());
|
|
237
|
+
}
|
|
238
|
+
// check textWriterIDs
|
|
239
|
+
for (const textWriterID of textWriterIDs) {
|
|
240
|
+
const textWriter = this._textWritersMap.get(textWriterID);
|
|
241
|
+
if (!textWriter) {
|
|
242
|
+
throw new Error(`Text writer with ID ${textWriterID} not found.`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
for (const textWriterID of textWriterIDs) {
|
|
246
|
+
const textWriter = this._textWritersMap.get(textWriterID);
|
|
247
|
+
if (textWriter) {
|
|
248
|
+
textWriter.insertTextBulk(items.map(x => this._textDataPreAdaptor(x)), textWriterID);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
__memorizeItem(item) {
|
|
253
|
+
const oldItem = this._memory.get(item.key);
|
|
254
|
+
let newItem = oldItem ? { ...oldItem, ...item } : item;
|
|
255
|
+
this._memory.set(item.key, newItem);
|
|
256
|
+
return newItem;
|
|
257
|
+
}
|
|
258
|
+
_build(items, { textWriterIDs } = {}) {
|
|
259
|
+
if (this._freed) {
|
|
260
|
+
throw new Error("Plugin has been freed, cannot update coordinates.");
|
|
261
|
+
}
|
|
262
|
+
if (!this.globe) {
|
|
263
|
+
throw new Error("Globe is not set, cannot update coordinates.");
|
|
264
|
+
}
|
|
265
|
+
if (!this.circlePlugin || !this.arcPlugin) {
|
|
266
|
+
throw new Error("Circle and Arc plugins are not initialized.");
|
|
267
|
+
}
|
|
268
|
+
items.forEach(item => {
|
|
269
|
+
this._calculateRadiusFromBearingLine(item);
|
|
270
|
+
});
|
|
271
|
+
const processedItems = items.map((item) => this.__memorizeItem(item));
|
|
272
|
+
// @ts-ignore
|
|
273
|
+
const circleInputs = processedItems.map(bearingLineToCircleInputAdapter(this.globe));
|
|
274
|
+
this.circlePlugin.insertBulk(circleInputs);
|
|
275
|
+
const arcInputs = processedItems.map(bearingLineToArcInputAdapter);
|
|
276
|
+
this.arcPlugin.insertBulk(arcInputs);
|
|
277
|
+
// @ts-ignore
|
|
278
|
+
const bearingArcInputs = processedItems.map((x) => bearingLineToBearingArcInputAdapter(this.globe, x));
|
|
279
|
+
this.arcPluginBL.insertBulk(bearingArcInputs);
|
|
280
|
+
this.__insertTexts(processedItems, textWriterIDs);
|
|
281
|
+
// @ts-ignore
|
|
282
|
+
const pieceOfPieInputs = processedItems.map((x) => bearingLineToPieceOfPieInputAdapter(this.globe, x));
|
|
283
|
+
this.pieceOfPiePlugin.insertBulk(pieceOfPieInputs);
|
|
284
|
+
// line inputs
|
|
285
|
+
const lineInputs = processedItems.map(flatLinesInputAdapter);
|
|
286
|
+
this.linePlugin.insertBulk(lineInputs);
|
|
287
|
+
const lineInputsBL = processedItems.map(flatLinesBearingInputAdapter);
|
|
288
|
+
this.linePluginBL.insertBulk(lineInputsBL);
|
|
289
|
+
// @ts-ignore
|
|
290
|
+
this.globe.DrawRender();
|
|
291
|
+
}
|
|
292
|
+
// globe API
|
|
293
|
+
init(globe, gl) {
|
|
294
|
+
if (this._freed) {
|
|
295
|
+
throw new Error("Plugin has been freed, cannot initialize.");
|
|
296
|
+
}
|
|
297
|
+
this.globe = globe;
|
|
298
|
+
this.circlePlugin.init(globe, gl);
|
|
299
|
+
this.arcPlugin.init(globe, gl);
|
|
300
|
+
this.arcPluginBL.init(globe, gl);
|
|
301
|
+
this.linePlugin.init(globe, gl);
|
|
302
|
+
this.linePluginBL.init(globe, gl);
|
|
303
|
+
this.pieceOfPiePlugin.init(globe, gl);
|
|
304
|
+
}
|
|
305
|
+
draw3D() {
|
|
306
|
+
if (this._freed) {
|
|
307
|
+
throw new Error("Plugin has been freed, cannot draw.");
|
|
308
|
+
}
|
|
309
|
+
if (!this.globe) {
|
|
310
|
+
throw new Error("Globe is not set, cannot draw.");
|
|
311
|
+
}
|
|
312
|
+
if (!this.circlePlugin || !this.arcPlugin) {
|
|
313
|
+
throw new Error("Circle and Arc plugins are not initialized.");
|
|
314
|
+
}
|
|
315
|
+
if (this.drawOptions.drawVRM) {
|
|
316
|
+
this.circlePlugin.setPluginOpacity(this._opacities.circle ?? this._opacities.general);
|
|
317
|
+
this.circlePlugin.draw3D();
|
|
318
|
+
}
|
|
319
|
+
if (this.drawOptions.drawBearingLine) {
|
|
320
|
+
this.arcPluginBL.setPluginOpacity(this._opacities.arc ?? this._opacities.general);
|
|
321
|
+
this.arcPluginBL.draw3D();
|
|
322
|
+
}
|
|
323
|
+
if (this.drawOptions.drawAngleRing) {
|
|
324
|
+
const currentLOD = this.globe.api_GetCurrentLODWithDecimal();
|
|
325
|
+
const tiltAngle = this.globe.api_GetCurrentLookInfo().Tilt;
|
|
326
|
+
const opacity = pieceOfPieOpacityAdaptor(currentLOD, tiltAngle) * (this._opacities.general ?? 1);
|
|
327
|
+
if (opacity > 0) {
|
|
328
|
+
this.pieceOfPiePlugin.setPluginOpacity(opacity);
|
|
329
|
+
this.pieceOfPiePlugin.draw3D();
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const currentGeometry = this.globe.api_GetCurrentGeometry();
|
|
333
|
+
this.arcPlugin.setPluginOpacity(this._opacities.arc ?? this._opacities.general);
|
|
334
|
+
this.arcPlugin.draw3D();
|
|
335
|
+
if (currentGeometry === 1) {
|
|
336
|
+
this.linePlugin.draw3D();
|
|
337
|
+
this.linePluginBL.draw3D();
|
|
338
|
+
}
|
|
339
|
+
if (this.drawOptions.drawAngleRing) {
|
|
340
|
+
for (const textWriter of this._textWritersMap.values()) {
|
|
341
|
+
textWriter.draw();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
free() {
|
|
346
|
+
if (this._freed) {
|
|
347
|
+
throw new Error("Plugin has already been freed.");
|
|
348
|
+
}
|
|
349
|
+
this._freed = true;
|
|
350
|
+
this.globe = null;
|
|
351
|
+
this._memory.clear();
|
|
352
|
+
this._textWritersMap.clear();
|
|
353
|
+
this.circlePlugin.free();
|
|
354
|
+
this.arcPlugin.free();
|
|
355
|
+
this.arcPluginBL.free();
|
|
356
|
+
this.pieceOfPiePlugin.free();
|
|
357
|
+
this.linePlugin.free();
|
|
358
|
+
this.linePluginBL.free();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|