@pirireis/webglobeplugins 0.6.17 → 0.6.19
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/bearing-line/plugin-flat-old.js +500 -0
- package/bearing-line/plugin.js +189 -71
- package/bearing-line/pluginOLD.js +430 -0
- package/circle-line-chain/plugin.js +60 -8
- package/circle-line-chain/plugin_newer_old.js +406 -0
- package/package.json +1 -1
- package/pin/pin-point-totem.js +77 -0
- package/programs/line-on-globe/circle-accurate-3d.js +185 -0
- package/programs/line-on-globe/circle-accurate-flat.js +200 -0
- package/programs/line-on-globe/circle-accurate.js +3 -1
- package/programs/line-on-globe/naive-accurate.js +8 -5
- package/programs/rings/partial-ring/piece-of-pie.js +315 -0
- package/util/check/get.js +1 -1
- package/util/jshelpers/data-filler.js +19 -0
- package/util/shaderfunctions/geometrytransformations.js +9 -3
- package/write-text/context-text3.js +4 -0
|
@@ -0,0 +1,430 @@
|
|
|
1
|
+
import { programCache as ringProgramCache } from '../partialrings/program';
|
|
2
|
+
import { LineOnGlobeCache } from '../programs/line-on-globe/naive';
|
|
3
|
+
import { CircleCache } from '../programs/line-on-globe/circle';
|
|
4
|
+
import { BufferOrchestrator, BufferManager } from '../util/account';
|
|
5
|
+
import { AngledLineProgramCache } from '../programs/line-on-globe/angled-line';
|
|
6
|
+
import { mapGetOrThrow } from "../util/check/get";
|
|
7
|
+
import { ContextTextWriter } from '../write-text/context-text'
|
|
8
|
+
export const RINGPARTIAL_DRAW_MODE = Object.freeze({
|
|
9
|
+
LINE_STRIP: "LINE_STRIP",
|
|
10
|
+
TRIANGLE_FAN: "TRIANGLE_FAN",
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const constraintFloat = (x, lowerBound, upperBound) => {
|
|
14
|
+
if (typeof x !== "number") throw new Error("type must be numberic")
|
|
15
|
+
if (lowerBound > x || x > upperBound) throw new Error(`input must be between ${lowerBound} - ${upperBound}`)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @typedef {Object}textContextInjection
|
|
23
|
+
* @property {string} id
|
|
24
|
+
* @property {function} coordsAdaptor
|
|
25
|
+
* @property {function} textAdaptor
|
|
26
|
+
* @property {ContextTextWriter} writer
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
export default class Plugin {
|
|
31
|
+
/**
|
|
32
|
+
*
|
|
33
|
+
* @param {*} id
|
|
34
|
+
* @param {Map<[K ,{writer:ContextTextWriter, coordsAdaptor, textAdaptor}]} textContextInjectionMap import { ContextTextWriter } from '@pirireis/webglobeplugins/write-text/context-text';
|
|
35
|
+
*
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
constructor(id, { opacity = 1, textContextInjectionMap = new Map(), drawVRM = true, drawBearingLine = true, drawAngleRing = true, drawText = true } = {}) {
|
|
39
|
+
this.id = id;
|
|
40
|
+
this._opacity = opacity;
|
|
41
|
+
this.bufferOrchestrator = new BufferOrchestrator({ capacity: 10 });
|
|
42
|
+
this._checkTextContextInjectionMap(textContextInjectionMap);
|
|
43
|
+
this._textContextInjectionMap = textContextInjectionMap;
|
|
44
|
+
this.drawVRM = drawVRM;
|
|
45
|
+
this.drawBearingLine = drawBearingLine;
|
|
46
|
+
this.drawAngleRing = drawAngleRing;
|
|
47
|
+
this.drawText = drawText;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
setDoDrawVRM(bool) {
|
|
51
|
+
if (bool === this.drawVRM) return;
|
|
52
|
+
this.drawVRM = bool;
|
|
53
|
+
this.globe.DrawRender();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
setDoDrawText(bool) {
|
|
57
|
+
if (bool === this.drawText) return;
|
|
58
|
+
this.drawText = bool;
|
|
59
|
+
this.globe.DrawRender();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
setDoDrawText(bool) {
|
|
63
|
+
if (bool === this.drawText) return;
|
|
64
|
+
this.drawText = bool;
|
|
65
|
+
this.globe.DrawRender();
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
_checkTextContextInjectionMap(textContextInjectionMap) {
|
|
69
|
+
if (!(textContextInjectionMap instanceof Map)) throw new TypeError("textContextInjectionMap is not instance of Map");
|
|
70
|
+
textContextInjectionMap.forEach((v) => {
|
|
71
|
+
if (typeof v !== 'object') throw new TypeError("textContextInjectionMap format is wrong");
|
|
72
|
+
if (typeof v.coordsAdaptor !== 'function') throw new TypeError("textContextInjectionMap coordsAdaptor format is wrong");
|
|
73
|
+
if (typeof v.textAdaptor !== 'function') throw new TypeError("textContextInjectionMap textAdaptor format is wrong");
|
|
74
|
+
if (!(v.writer instanceof ContextTextWriter)) throw new TypeError("textContextInjectionMap writer is not instance of ContextTextWriter");
|
|
75
|
+
})
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
setDoDrawAngleRing(bool) {
|
|
79
|
+
if (bool === this.drawAngleRing) return;
|
|
80
|
+
this.drawAngleRing = bool;
|
|
81
|
+
this.globe.DrawRender();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
settextContextInjectionMap(textContextInjectionMap, data = null) {
|
|
86
|
+
this._textContextInjectionMap = textContextInjectionMap;
|
|
87
|
+
this._textContextInjectionMap.forEach(({ writer }) => writer.clear());
|
|
88
|
+
if (data) {
|
|
89
|
+
for (const item of data) {
|
|
90
|
+
this._insertTexts(item);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
setOpacity(opacity) {
|
|
97
|
+
constraintFloat(opacity, 0, 1);
|
|
98
|
+
this._opacity = opacity;
|
|
99
|
+
this._textContextInjectionMap.forEach(({ writer }) => writer.setOpacity(opacity));
|
|
100
|
+
this.globe.DrawRender();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
init(globe, gl) {
|
|
107
|
+
this.gl = gl;
|
|
108
|
+
this.globe = globe;
|
|
109
|
+
this.lineProgram = LineOnGlobeCache.get(globe);
|
|
110
|
+
this.ringProgram = ringProgramCache.get(globe);
|
|
111
|
+
this.angledLineProgram = AngledLineProgramCache.get(globe);
|
|
112
|
+
this.circleProgram = CircleCache.get(globe);
|
|
113
|
+
// this.angleTextContext = new ContextTextWriter(globe);
|
|
114
|
+
// this.distanceTextContext = new ContextTextWriter(globe);
|
|
115
|
+
{
|
|
116
|
+
// createBuffers
|
|
117
|
+
const bufferType = "DYNAMIC_DRAW";
|
|
118
|
+
const initialCapacity = this.bufferOrchestrator.capacity;
|
|
119
|
+
this.bufferManagersCompMap = new Map(
|
|
120
|
+
[
|
|
121
|
+
["centerCoords", {
|
|
122
|
+
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
123
|
+
'adaptor': (item) => new Float32Array([item.long, item.lat]),
|
|
124
|
+
}],
|
|
125
|
+
["targetCoords", {
|
|
126
|
+
'bufferManager': new BufferManager(gl, 2, { bufferType, initialCapacity }),
|
|
127
|
+
'adaptor': (item) => new Float32Array([item.endLong, item.endLat])
|
|
128
|
+
}],
|
|
129
|
+
["startAngle", {
|
|
130
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
131
|
+
'adaptor': (item) => new Float32Array([item.startAngle])
|
|
132
|
+
}],
|
|
133
|
+
["tailAngle", {
|
|
134
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
135
|
+
'adaptor': (item) => new Float32Array([item.tailAngle])
|
|
136
|
+
}],
|
|
137
|
+
["rgba", {
|
|
138
|
+
'bufferManager': new BufferManager(gl, 4, { bufferType, initialCapacity }),
|
|
139
|
+
'adaptor': (item) => new Float32Array(item.rgba)
|
|
140
|
+
}],
|
|
141
|
+
["radius", {
|
|
142
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
143
|
+
'adaptor': (item) => new Float32Array([item.radius])
|
|
144
|
+
}],
|
|
145
|
+
["rgbaMode", {
|
|
146
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
147
|
+
'adaptor': (item) => new Float32Array([item.rgbaMode])
|
|
148
|
+
}],
|
|
149
|
+
["dashRatio", {
|
|
150
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
151
|
+
'adaptor': (item) => new Float32Array([item.dashRatio])
|
|
152
|
+
}],
|
|
153
|
+
["bearingAngle", {
|
|
154
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
155
|
+
'adaptor': (item) => new Float32Array([item.bearingAngle])
|
|
156
|
+
}],
|
|
157
|
+
["bigRadius", {
|
|
158
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
159
|
+
'adaptor': (item) => new Float32Array([item.bigRadius])
|
|
160
|
+
}],
|
|
161
|
+
["dashOpacity", {
|
|
162
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
163
|
+
'adaptor': (item) => new Float32Array([item.dashOpacity])
|
|
164
|
+
}],
|
|
165
|
+
["circleDashAngle", {
|
|
166
|
+
'bufferManager': new BufferManager(gl, 1, { bufferType, initialCapacity }),
|
|
167
|
+
'adaptor': (item) => new Float32Array([item.circleDashAngle / 360])
|
|
168
|
+
}]
|
|
169
|
+
]
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
const obj = function (bufferManagerComp) {
|
|
175
|
+
return { 'buffer': bufferManagerComp.bufferManager.buffer, 'stride': 0, 'offset': 0 }
|
|
176
|
+
};
|
|
177
|
+
|
|
178
|
+
this.lineVao = this.lineProgram.createVAO(
|
|
179
|
+
...['centerCoords', 'targetCoords', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
180
|
+
this.ringVao = this.ringProgram.createVAO(
|
|
181
|
+
...['centerCoords', 'startAngle', 'tailAngle', 'rgba', 'radius', 'rgbaMode'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
182
|
+
{
|
|
183
|
+
const angledLineBuffers = ["centerCoords", "bearingAngle", "bigRadius", "rgba", "dashRatio"].map(key => obj(this.bufferManagersCompMap.get(key)));
|
|
184
|
+
// dashOpacity is same as rgba.a to eleminate effect of dashOpacity.
|
|
185
|
+
const colorBuffer = this.bufferManagersCompMap.get("rgba");
|
|
186
|
+
angledLineBuffers.push(
|
|
187
|
+
{ 'buffer': colorBuffer.bufferManager.buffer, 'stride': 16, 'offset': 12 },
|
|
188
|
+
)
|
|
189
|
+
this.angledLineVao = this.angledLineProgram.createVAO(...angledLineBuffers);
|
|
190
|
+
}
|
|
191
|
+
// centerObj, startAngleObj, radiusObj, colorObj, dashRatioObj, dashOpacityObj
|
|
192
|
+
this.circleVao = this.circleProgram.createVAO(
|
|
193
|
+
...["centerCoords", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
draw3D() {
|
|
199
|
+
const { gl } = this;
|
|
200
|
+
this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
|
|
201
|
+
gl.disable(gl.DEPTH_TEST);
|
|
202
|
+
if (this.drawAngleRing) {
|
|
203
|
+
this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity * 0.8, RINGPARTIAL_DRAW_MODE.TRIANGLE_FAN);
|
|
204
|
+
this.ringProgram.draw(this.bufferOrchestrator.length, this.ringVao, 360, this._opacity, RINGPARTIAL_DRAW_MODE.LINE_STRIP);
|
|
205
|
+
}
|
|
206
|
+
if (this.drawBearingLine) {
|
|
207
|
+
this.angledLineProgram.draw(this.angledLineVao, this.bufferOrchestrator.length, this._opacity * 0.8);
|
|
208
|
+
}
|
|
209
|
+
if (this.drawVRM) {
|
|
210
|
+
this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
|
|
211
|
+
}
|
|
212
|
+
if (this.drawText) {
|
|
213
|
+
this._textContextInjectionMap.forEach((e) => { e.writer.draw(); });
|
|
214
|
+
}
|
|
215
|
+
gl.enable(gl.DEPTH_TEST);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @typedef {{key, long, lat, endLong, endLat, bearingAngle, radius, rgba:[4numbers], rgbaMode, bigRadius, dashRatio, dashOpacity, circleDashAngle}} item
|
|
221
|
+
* @property {string} key
|
|
222
|
+
* @property {number} long
|
|
223
|
+
* @property {number} lat
|
|
224
|
+
* @property {number} endLong
|
|
225
|
+
* @property {number} endLat
|
|
226
|
+
* @property {number} bearingAngle 0-360
|
|
227
|
+
* @property {number} radius angle ring radius
|
|
228
|
+
* @property {Array<4numbers>} rgba [r,g,b,a]
|
|
229
|
+
* @property {number} rgbaMode 0 constant, 1 fading, 2 hides angle ring
|
|
230
|
+
* @property {number} bigRadius undefined means it will be calculated from long, lat, endLong, endLat
|
|
231
|
+
* @property {number} dashRatio 0-1
|
|
232
|
+
* @property {number} dashOpacity 0-1
|
|
233
|
+
* @property {number} circleDashAngle 0-360
|
|
234
|
+
* @param {Array<item>} items
|
|
235
|
+
* @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
|
|
236
|
+
*/
|
|
237
|
+
insertBulk(items, textWriterInjectionSubSetIDs = []) {
|
|
238
|
+
const { globe, bufferOrchestrator, bufferManagersCompMap } = this;// angleTextContext, distanceTextContext,
|
|
239
|
+
const textWriterInjectionSubSets = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
|
|
240
|
+
const data = []
|
|
241
|
+
for (let item of items) {
|
|
242
|
+
this._insertTexts(item, textWriterInjectionSubSets);
|
|
243
|
+
data.push(this.__insertAdaptor(item));
|
|
244
|
+
}
|
|
245
|
+
bufferOrchestrator.insertBulk(data, bufferManagersCompMap);
|
|
246
|
+
this._textContextInjectionMap.forEach((v) => {
|
|
247
|
+
const { writer } = v;
|
|
248
|
+
writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
|
|
249
|
+
})
|
|
250
|
+
globe.DrawRender();
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
deleteBulk(keys) {
|
|
257
|
+
this.bufferOrchestrator.deleteBulk(keys, this.bufferManagersCompMap, ["radius", "centerCoords", "targetCoords", "rgba"]);
|
|
258
|
+
this._deleteTexts(keys);
|
|
259
|
+
this.globe.DrawRender();
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
defrag() {
|
|
264
|
+
this.bufferOrchestrator.defrag(this.bufferManagersCompMap);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
*
|
|
269
|
+
* @param {Array<{key, long, lat, endLong, endLat, bearingAngle}>} items
|
|
270
|
+
* @param {Array<string>} textWriterInjectionSubSetIDs | textContextInjectionMap keys to be used for writing text.
|
|
271
|
+
*/
|
|
272
|
+
updateCoordinatesBulk(items, textWriterInjectionSubSetIDs = []) { //TODO
|
|
273
|
+
const injectionsSubSet = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);;
|
|
274
|
+
const { globe, bufferOrchestrator, bufferManagersCompMap, } = this;
|
|
275
|
+
const data = []
|
|
276
|
+
for (let item of items) {
|
|
277
|
+
this._insertTexts(item, injectionsSubSet);
|
|
278
|
+
data.push(this.__updateCoordsAdaptor(item));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
bufferOrchestrator.updateBulk(data, bufferManagersCompMap, ["centerCoords", "targetCoords", "startAngle", "tailAngle", "bearingAngle", "bigRadius", "radius"]);
|
|
282
|
+
globe.DrawRender();
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
/**
|
|
287
|
+
*
|
|
288
|
+
* @param {*} items some colums EXCEPT positional ones
|
|
289
|
+
* @param {string} propertyIDs
|
|
290
|
+
* @param {string} textWriterInjectionSubSetIDs
|
|
291
|
+
* Do NOT send empty data if property ID of this data is entered or NaN is loaded to the buffer, resulting in an unwanted behaviour.
|
|
292
|
+
*/
|
|
293
|
+
updatePartial(items, propertyIDs = [], textWriterInjectionSubSetIDs = []) { // textWriterInjectionSubSetIDs = []
|
|
294
|
+
if (propertyIDs.length === 0) console.warn("updatePartial is called with no target propertyIDs");
|
|
295
|
+
const { _textContextInjectionMap, bufferOrchestrator, bufferManagersCompMap } = this;
|
|
296
|
+
const writers = textWriterGetOrThrow(this._textContextInjectionMap, textWriterInjectionSubSetIDs);
|
|
297
|
+
for (let item of items) { this._insertTexts(item, writers) }
|
|
298
|
+
bufferOrchestrator.updateBulk(items, bufferManagersCompMap, propertyIDs);
|
|
299
|
+
// patch to update text opacity
|
|
300
|
+
for (const property of propertyIDs) {
|
|
301
|
+
if (property === "rgba") {
|
|
302
|
+
_textContextInjectionMap.forEach((v) => {
|
|
303
|
+
const { writer } = v;
|
|
304
|
+
writer.updateOpacityBulk(items, (e) => e.key, (e) => e.rgba[3]);
|
|
305
|
+
})
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
this.globe.DrawRender();
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
|
|
312
|
+
__insertAdaptor(item) {
|
|
313
|
+
const lat = radian(item.lat)
|
|
314
|
+
const long = radian(item.long)
|
|
315
|
+
const endLat = radian(item.endLat)
|
|
316
|
+
const endLong = radian(item.endLong)
|
|
317
|
+
const rgba = item.rgba !== undefined ? item.rgba : [0, 0, 0, 0];
|
|
318
|
+
const rgbaMode = item.rgbaMode !== undefined ? item.rgbaMode : 0;
|
|
319
|
+
const dashRatio = item.dashRatio !== undefined ? item.dashRatio : 1.0;
|
|
320
|
+
const dashOpacity = item.dashOpacity !== undefined ? item.dashOpacity : 0.9;
|
|
321
|
+
const circleDashAngle = item.circleDashAngle !== undefined ? item.circleDashAngle : 360;
|
|
322
|
+
const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
|
|
323
|
+
const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
|
|
324
|
+
const startAngle = calculateStartAngle(long, lat, endLong, endLat);
|
|
325
|
+
const bearingAngle = radian(item.bearingAngle - 90);
|
|
326
|
+
let tailAngle = bearingAngle - startAngle;
|
|
327
|
+
if (tailAngle > 0) {
|
|
328
|
+
tailAngle -= Math.PI * 2;
|
|
329
|
+
}
|
|
330
|
+
return {
|
|
331
|
+
key: item.key,
|
|
332
|
+
lat,
|
|
333
|
+
long,
|
|
334
|
+
endLat,
|
|
335
|
+
endLong,
|
|
336
|
+
bearingAngle,
|
|
337
|
+
radius,
|
|
338
|
+
bigRadius,
|
|
339
|
+
startAngle,
|
|
340
|
+
tailAngle,
|
|
341
|
+
rgba,
|
|
342
|
+
dashRatio,
|
|
343
|
+
dashOpacity,
|
|
344
|
+
circleDashAngle,
|
|
345
|
+
rgbaMode
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
__updateCoordsAdaptor(item) {
|
|
350
|
+
const lat = radian(item.lat)
|
|
351
|
+
const long = radian(item.long)
|
|
352
|
+
const endLat = radian(item.endLat)
|
|
353
|
+
const endLong = radian(item.endLong)
|
|
354
|
+
const bigRadius = item.bigRadius !== undefined ? item.bigRadius : this.globe.Math.GetDist3D(item.long, item.lat, item.endLong, item.endLat);
|
|
355
|
+
const radius = item.radius !== undefined ? item.radius : bigRadius * 0.2;
|
|
356
|
+
const startAngle = calculateStartAngle(long, lat, endLong, endLat);
|
|
357
|
+
const bearingAngle = radian(item.bearingAngle - 90);
|
|
358
|
+
let tailAngle = bearingAngle - startAngle;
|
|
359
|
+
if (tailAngle > 0) {
|
|
360
|
+
tailAngle -= Math.PI * 2;
|
|
361
|
+
}
|
|
362
|
+
return {
|
|
363
|
+
key: item.key,
|
|
364
|
+
lat,
|
|
365
|
+
long,
|
|
366
|
+
endLat,
|
|
367
|
+
endLong,
|
|
368
|
+
bearingAngle,
|
|
369
|
+
radius,
|
|
370
|
+
bigRadius,
|
|
371
|
+
startAngle,
|
|
372
|
+
tailAngle,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
//TODO free
|
|
378
|
+
free() {
|
|
379
|
+
if (this.isFreed) return;
|
|
380
|
+
this.bufferManagersCompMap.forEach(({ bufferManager, adaptor }) => {
|
|
381
|
+
bufferManager.free();
|
|
382
|
+
});
|
|
383
|
+
LineOnGlobeCache.release(this.globe);
|
|
384
|
+
ringProgramCache.release(this.globe);
|
|
385
|
+
CircleCache.release(this.globe);
|
|
386
|
+
AngledLineProgramCache.release(this.globe);
|
|
387
|
+
this.isFreed = true;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
_insertTexts(item, textWriterInjectionSubSet) {
|
|
394
|
+
//TODO This method can be more performant if it works horizontally, tabular
|
|
395
|
+
textWriterInjectionSubSet.forEach((v) => {
|
|
396
|
+
const { coordsAdaptor, textAdaptor, writer } = v
|
|
397
|
+
const { lat, long } = coordsAdaptor(item);
|
|
398
|
+
const text = textAdaptor(item);
|
|
399
|
+
writer.insertText(item.key, lat, long, text);
|
|
400
|
+
});
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
_deleteTexts(keys) {
|
|
405
|
+
this._textContextInjectionMap.forEach((e) => {
|
|
406
|
+
e.writer.deleteTextBulk(keys);
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
|
|
415
|
+
const radian = (degree) => degree * Math.PI / 180;
|
|
416
|
+
|
|
417
|
+
const integralSec = (angle) => {
|
|
418
|
+
return Math.log(Math.tan(angle / 2 + Math.PI / 4));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const textWriterGetOrThrow = mapGetOrThrow("BearingLine textContextInjection id does not exist in map")
|
|
422
|
+
|
|
423
|
+
const calculateStartAngle = (long, lat, endLong, endLat) => {
|
|
424
|
+
const dLat = (integralSec(endLat) - integralSec(lat)); // Because lines are strectes toward poles.
|
|
425
|
+
const dLong = endLong - long;
|
|
426
|
+
|
|
427
|
+
let angle = -Math.atan2(dLat, dLong);
|
|
428
|
+
return angle;
|
|
429
|
+
}
|
|
430
|
+
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { LineOnGlobeCache } from '../programs/line-on-globe/naive-accurate';
|
|
2
|
-
import { CircleCache } from '../programs/line-on-globe/circle-accurate';
|
|
2
|
+
import { CircleCache, EDGE_COUNT as EDGE_COUNT_2D_CIRCLE, centerCoords2dflatDataCreator } from '../programs/line-on-globe/circle-accurate-flat';
|
|
3
|
+
import { CircleCache as Circle3DCache } from '../programs/line-on-globe/circle-accurate-3d';
|
|
3
4
|
import { LineToTheOriginCache } from "../programs/line-on-globe/to-the-origin"
|
|
4
5
|
import { BufferOrchestrator, BufferManager } from "../util/account";
|
|
5
6
|
import { ChainListMap } from "./chain-list-map";
|
|
6
7
|
import { mapGetOrThrow } from "../util/check/get";
|
|
7
8
|
import { keyMethod } from "./util";
|
|
9
|
+
import { populateFloat32Array } from "../util/jshelpers/data-filler";
|
|
8
10
|
import { ContextTextWriter3 } from '../write-text/context-text3';
|
|
9
11
|
// TODO: Add update buffer and update text mehods on add, delete, update methods
|
|
10
12
|
|
|
@@ -76,7 +78,9 @@ export class CircleLineChainPlugin {
|
|
|
76
78
|
_initOrchestrations() {
|
|
77
79
|
const { gl, globe } = this;
|
|
78
80
|
this.lineProgram = LineOnGlobeCache.get(globe);
|
|
79
|
-
this.
|
|
81
|
+
this.circleProgram2d = CircleCache.get(globe);
|
|
82
|
+
this.circle3DProgram = Circle3DCache.get(globe);
|
|
83
|
+
|
|
80
84
|
this.lineToTheOriginProgram = LineToTheOriginCache.get(globe);
|
|
81
85
|
{
|
|
82
86
|
// createBuffers
|
|
@@ -133,7 +137,32 @@ export class CircleLineChainPlugin {
|
|
|
133
137
|
if (item.circleProperties?.rgba) return new Float32Array(item.circleProperties.rgba);
|
|
134
138
|
return new Float32Array(item.chainProperties.rgba);
|
|
135
139
|
}
|
|
136
|
-
}]
|
|
140
|
+
}],
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
// Mercator buffers
|
|
144
|
+
["circleDashAngleMercator", {
|
|
145
|
+
'bufferManager': new BufferManager(gl, 1 * EDGE_COUNT_2D_CIRCLE, { bufferType, initialCapacity }),
|
|
146
|
+
'adaptor': (item) => {
|
|
147
|
+
if (item.circleProperties?.circleDashAngle) return new Float32Array([item.circleProperties.circleDashAngle / 360]);
|
|
148
|
+
return new populateFloat32Array.fillFloat32Array(EDGE_COUNT_2D_CIRCLE, item.chainProperties.circleDashAngle / 360);
|
|
149
|
+
}
|
|
150
|
+
}],
|
|
151
|
+
["rgbaCircleMercator", {
|
|
152
|
+
"bufferManager": new BufferManager(gl, 4 * EDGE_COUNT_2D_CIRCLE, { bufferType, initialCapacity }),
|
|
153
|
+
"adaptor": (item) => {
|
|
154
|
+
if (item.circleProperties?.rgba) return populateFloat32Array.fillWithListData(EDGE_COUNT_2D_CIRCLE, item.circleProperties.rgba);
|
|
155
|
+
return populateFloat32Array.fillWithListData(EDGE_COUNT_2D_CIRCLE, item.chainProperties.rgba);
|
|
156
|
+
}
|
|
157
|
+
}],
|
|
158
|
+
["dashOpacityMercator", {
|
|
159
|
+
'bufferManager': new BufferManager(gl, 1 * EDGE_COUNT_2D_CIRCLE, { bufferType, initialCapacity }),
|
|
160
|
+
'adaptor': (item) => populateFloat32Array.fillFloat32Array(EDGE_COUNT_2D_CIRCLE, item.chainProperties.dashOpacity)
|
|
161
|
+
}],
|
|
162
|
+
["centerCoords2dMercator", {
|
|
163
|
+
'bufferManager': new BufferManager(gl, 2 * EDGE_COUNT_2D_CIRCLE, { bufferType, initialCapacity }),
|
|
164
|
+
'adaptor': (item) => item.centerCoords2dflat,
|
|
165
|
+
}],
|
|
137
166
|
]
|
|
138
167
|
);
|
|
139
168
|
// (startPotisionBufferObj, endPositionBufferObj, dashRatioBufferObj, colorBufferObj)
|
|
@@ -142,10 +171,14 @@ export class CircleLineChainPlugin {
|
|
|
142
171
|
};
|
|
143
172
|
this.lineVao = this.lineProgram.createVAO(
|
|
144
173
|
...['centerCoords2d', 'centerCoords3d', 'targetCoords2d', 'targetCoords3d', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
145
|
-
this.
|
|
146
|
-
...["
|
|
174
|
+
this.circleVao2d = this.circleProgram2d.createVAO(
|
|
175
|
+
...["centerCoords2dMercator", "rgbaCircleMercator", "circleDashAngleMercator", "dashOpacityMercator"].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
147
176
|
this.toOriginVao = this.lineToTheOriginProgram.createVAO(
|
|
148
177
|
...["targetCoords3d", "rgba"].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
178
|
+
this.circle3DVao = this.circle3DProgram.createVAO(
|
|
179
|
+
...["centerCoords3d", "bigRadius", "rgbaCircle", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key)))
|
|
180
|
+
);
|
|
181
|
+
|
|
149
182
|
}
|
|
150
183
|
|
|
151
184
|
}
|
|
@@ -338,13 +371,16 @@ export class CircleLineChainPlugin {
|
|
|
338
371
|
const { globe } = this;
|
|
339
372
|
// this.lineVao = this.lineProgram.createVAO(
|
|
340
373
|
// ...['centerCoords', 'targetCoords', 'dashRatio', 'dashOpacity', 'rgba'].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
341
|
-
// this.
|
|
374
|
+
// this.circleVao2d = this.circleProgram2d.createVAO(
|
|
342
375
|
// ...["centerCoords", "bigRadius", "rgba", "circleDashAngle", "dashOpacity"].map(key => obj(this.bufferManagersCompMap.get(key))));
|
|
343
376
|
// }
|
|
344
377
|
|
|
345
378
|
const radiusM = radiusMethod(globe);
|
|
346
379
|
const callback = (v, i, array, chainProperties) => {
|
|
347
380
|
if (i == array.length - 1) return null;
|
|
381
|
+
|
|
382
|
+
const centerCoords2dflat = centerCoords2dflatDataCreator(globe, v.long, v.lat, array[i + 1].long, array[i + 1].lat);
|
|
383
|
+
|
|
348
384
|
return {
|
|
349
385
|
chainProperties: chainProperties,
|
|
350
386
|
bigRadius: radiusM(v, i, array),
|
|
@@ -354,7 +390,9 @@ export class CircleLineChainPlugin {
|
|
|
354
390
|
lat: v.lat,
|
|
355
391
|
lineProperties: v.lineProperties,
|
|
356
392
|
circleProperties: v.circleProperties,
|
|
393
|
+
centerCoords2dflat,
|
|
357
394
|
key: v.__identity__
|
|
395
|
+
|
|
358
396
|
}
|
|
359
397
|
}
|
|
360
398
|
const bulkData = [];
|
|
@@ -381,8 +419,15 @@ export class CircleLineChainPlugin {
|
|
|
381
419
|
})
|
|
382
420
|
LineOnGlobeCache.release(this.globe);
|
|
383
421
|
CircleCache.release(this.globe);
|
|
422
|
+
Circle3DCache.release(this.globe);
|
|
423
|
+
LineToTheOriginCache.release(this.globe);
|
|
424
|
+
this._textContextWriterInjectionMap.forEach((writer) => writer.free());
|
|
425
|
+
const { gl } = this;
|
|
426
|
+
gl.deleteVertexArray(this.lineVao);
|
|
427
|
+
gl.deleteVertexArray(this.circleVao2d);
|
|
428
|
+
gl.deleteVertexArray(this.toOriginVao);
|
|
384
429
|
this.lineProgram = null;
|
|
385
|
-
this.
|
|
430
|
+
this.circleProgram2d = null;
|
|
386
431
|
this.isFreed = true;
|
|
387
432
|
}
|
|
388
433
|
|
|
@@ -390,9 +435,16 @@ export class CircleLineChainPlugin {
|
|
|
390
435
|
const { gl, globe } = this;
|
|
391
436
|
gl.disable(gl.DEPTH_TEST);
|
|
392
437
|
this.lineProgram.draw(this.lineVao, this.bufferOrchestrator.length, this._opacity);
|
|
393
|
-
if (this._drawCircleOn) this.circleProgram.draw(this.circleVao, this.bufferOrchestrator.length, this._opacity);
|
|
394
438
|
this._textContextWriterInjectionMap.forEach((writer) => writer.draw());
|
|
395
439
|
this.lineToTheOriginProgram.draw(this.toOriginVao, this.bufferOrchestrator.length, this._opacity);
|
|
440
|
+
const is3D = globe.api_GetCurrentGeometry() === 0;
|
|
441
|
+
if (this._drawCircleOn) {
|
|
442
|
+
if (is3D) {
|
|
443
|
+
this.circle3DProgram.draw(this.circle3DVao, this.bufferOrchestrator.length, this._opacity);
|
|
444
|
+
} else {
|
|
445
|
+
this.circleProgram2d.draw(this.circleVao2d, this.bufferOrchestrator.length, this._opacity);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
396
448
|
gl.enable(gl.DEPTH_TEST);
|
|
397
449
|
}
|
|
398
450
|
}
|