@pirireis/webglobeplugins 0.1.10 → 0.3.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.
@@ -0,0 +1,256 @@
1
+
2
+
3
+ /**
4
+ * OffsetManager
5
+ * 1) Capacity
6
+ * 2) Offset account
7
+ * 3) Command Buffers in its regisration list.
8
+ *
9
+ * How insertBulk works:
10
+ * 0) autoExtendBuffers..
11
+ * 1) assign offset to all keys if not already assigned.
12
+ * 2) send item list to each buffer manager and let them do their job.
13
+ * This cannot work. BufferManager does not know the which data to insert.
14
+ * Solutions:
15
+ * 1) selectMethod: insertBulk(items, offsets, selectMethod)
16
+ * selectMethod(item) => itemToBlock(item)
17
+ * 2) att1manager.insertBulk(items.map(item => this.att1ItemToBlock(item)), offsets)
18
+ * Idea about future:
19
+ * insert first tombstone.length items one by one.
20
+ * insert the rest in a big float32array. IT CAN BE DONE
21
+ * 3) DrawRender
22
+ *
23
+ * How autoExtendBuffers works:
24
+ * 1) if incoming items length is greater then space left in buffer, calculate new capacity and extend all buffers.
25
+ *
26
+ *
27
+
28
+ */
29
+
30
+
31
+
32
+ /**
33
+ * Scratchpad
34
+ *
35
+ * plugin insertBulk(items){
36
+ * this.offsetManager.autoExtendBuffers(items.length);
37
+ * this.offsetManager.assignOffsets(items); // read item.keys and assign offsets to them.
38
+ * this.attrib1BufferManager.insertBulk(items.map(item => this.attrib1Block(item)), );
39
+ * this.attrib2BufferManager.insertBulk();
40
+ * if (this.attrib3isInNeed) this.attrib3BufferManager.insertBulk(items);
41
+ * this.globe.DrawRender();
42
+ * }
43
+ *
44
+ * useTheCaseThatRequiresAttrib3(){
45
+ * // generate items from other buffers if possible.
46
+ * }
47
+ *
48
+ *
49
+ * assignOffsets(items){
50
+ * for (const item of items){
51
+ * const offset = this.offsetManager.getOffset(item.key) || this.offsetManager.nextOffset();
52
+ * item.__offset__ = offset;
53
+ *
54
+ * allBuffers = [attrib1BufferManager, attrib2BufferManager, attrib3BufferManager]
55
+ * // // not single responsibility ..
56
+ * defrag(allBuffers){
57
+ * for (const bufferManager of allBuffers){
58
+ * bufferManager.defrag(this.offsetManager.offsetMap);
59
+ * }
60
+ * this.offsetManager._defrag();
61
+ * }
62
+ *
63
+ */
64
+
65
+
66
+ /**
67
+ *
68
+ * attrib1BufferManager.insertBulk( items) {
69
+ * gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
70
+ * for (const item of items) {
71
+ * const block = this.itemToBlock(item); // this changes based on inserted data structure and expected block structure.
72
+ * gl.bufferSubData(gl.ARRAY_BUFFER, item.__offset__, block);
73
+ * }
74
+ * gl.bindBuffer(gl.ARRAY_BUFFER, null);
75
+ * }
76
+ *
77
+ * deleteBulk(offsets){
78
+ * gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
79
+ * for (const offset of offsets) {
80
+ * gl.bufferSubData(gl.ARRAY_BUFFER, offset, emptyBlock);
81
+ * }
82
+ * gl.bindBuffer(gl.ARRAY_BUFFER, null);
83
+ * }
84
+ *
85
+ *
86
+ * //
87
+ * defrag(offsetMap){
88
+ * const newArray = new Float32Array(itemCount * itemSize);
89
+ * const bufferData = this._getBufferData();
90
+ * let newOffSet = 0;
91
+ * for (const [key, offSet] of offsetMap) {
92
+ * const bufferOffset = offset;
93
+ * newArray.set(bufferData.slice(bufferOffset, bufferOffset + itemSize), newOffSet);
94
+ newOffset += itemSize * 4;
95
+ }
96
+ *
97
+ * gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
98
+ *
99
+ * }
100
+ *
101
+ * ----------------
102
+
103
+ */
104
+
105
+ export class BufferOrchestrator {
106
+
107
+ constructor({ capacity = 10 } = {}) {
108
+ this._capacity = capacity;
109
+ this.offsetMap = new Map();
110
+ this.tombstoneOffsets = [];
111
+ this._length = 0;
112
+ }
113
+
114
+
115
+ resetWithCapacity(bufferManagersMap, capacity = null) {
116
+ this._capacity = capacity !== null ? capacity : this._capacity;
117
+ for (const [key, { bufferManager }] of bufferManagersMap) {
118
+ bufferManager.resetWithCapacity(this._capacity);
119
+ }
120
+ this.offsetMap.clear();
121
+ this.tombstoneOffsets = [];
122
+ this._length = 0;
123
+ }
124
+
125
+ insertBulk(items, bufferManagersMap) {
126
+ this.autoExtendBuffers(items.length, bufferManagersMap);
127
+ const { offsetMap } = this;
128
+ const offsets = [];
129
+ for (const item of items) {
130
+ const offset = offsetMap.get(item.key) || this.nextOffset();
131
+ offsetMap.set(item.key, offset);
132
+ offsets.push(offset);
133
+ }
134
+ for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
135
+ bufferManager.insertBulk(items.map(adaptor), offsets);
136
+ }
137
+ }
138
+
139
+
140
+ // doesnot assign offset to the new items.
141
+ updateBulk(items, bufferManagersMap, bufferKeys) {
142
+ const { offsetMap } = this;
143
+ const offsets = [];
144
+ for (const item of items) {
145
+ const offset = offsetMap.get(item.key);
146
+ offsets.push(offset);
147
+ }
148
+ if (bufferKeys) {
149
+ for (const key of bufferKeys) {
150
+ const { bufferManager, adaptor } = bufferManagersMap.get(key);
151
+ bufferManager.insertBulk(items.map(adaptor), offsets);
152
+ }
153
+ } else {
154
+ for (const [key, { bufferManager, adaptor }] of bufferManagersMap) {
155
+ bufferManager.insertBulk(items.map(adaptor), offsets);
156
+ }
157
+ }
158
+
159
+ }
160
+
161
+
162
+ deleteBulk(keys, bufferManagersMap) {
163
+ const offsets = [];
164
+ for (const key of keys) {
165
+ const offset = this.getOffset(key);
166
+ if (offset !== undefined) {
167
+ offsets.push(offset);
168
+ this.offsetMap.delete(key);
169
+ this.tombstoneOffsets.push(offset);
170
+ }
171
+ }
172
+ for (const [key, { bufferManager }] of bufferManagersMap) {
173
+ bufferManager.deleteBulk(offsets);
174
+ }
175
+ console.log("deleteBulk after item size", this.offsetMap.size);
176
+ }
177
+
178
+
179
+
180
+ getOffset(key) {
181
+ return this.offsetMap.get(key);
182
+ }
183
+
184
+ nextOffset() {
185
+ if (this.tombstoneOffsets.length > 0) {
186
+ const offset = this.tombstoneOffsets.pop();
187
+ return offset;
188
+ }
189
+ if (this._length < this._capacity) {
190
+ return this._length++;
191
+ }
192
+ return false;
193
+ }
194
+
195
+
196
+ autoExtendBuffers(itemsLength, bufferManagersMap) {
197
+ if (itemsLength <= this.emptySpace) return;
198
+ const newCapacity = this.length + itemsLength;
199
+ console.log("autoExtendBuffers", "item L", itemsLength, "E space", this.emptySpace, "cap", this.capacity, "length", this.length, 'new Cap', newCapacity);
200
+ for (const [key, { bufferManager }] of bufferManagersMap) {
201
+ console.log("length", this.length, "newCapacity", newCapacity);
202
+ bufferManager.extendBuffer(this.length, newCapacity);
203
+ }
204
+ this._capacity = newCapacity;
205
+ }
206
+
207
+
208
+ defrag(bufferManagers, bufferKeys) { // TODO defrag and leave some empty space
209
+ const offsetMap = this.offsetMap;
210
+ console.log("defrag size", offsetMap.size, "cap", this.capacity, "length", this.length);
211
+ if (bufferKeys) {
212
+ for (const key of bufferKeys) {
213
+ const offset = offsetMap.get(key);
214
+ if (offset !== undefined) {
215
+ for (const [key, { bufferManager }] of bufferManagers) {
216
+ bufferManager.defrag([offset], this.length, offsetMap.size);
217
+ }
218
+ }
219
+ }
220
+ } else {
221
+ for (const [key, { bufferManager }] of bufferManagers) {
222
+ bufferManager.defrag(offsetMap.values(), this.length, offsetMap.size);
223
+ }
224
+ }
225
+ this._defrag();
226
+ this._length = this._capacity = offsetMap.size;
227
+ this.tombstoneOffsets = [];
228
+ }
229
+
230
+
231
+
232
+ _defrag() {
233
+ const newOffsetMap = new Map();
234
+ let newOffset = 0;
235
+ for (const [key, offset] of this.offsetMap) {
236
+ console.log("defrag", key, offset, newOffset);
237
+ newOffsetMap.set(key, newOffset++);
238
+ }
239
+ this.offsetMap = newOffsetMap
240
+ }
241
+
242
+ get length() {
243
+ return this._length;
244
+ }
245
+
246
+ get emptySpace() {
247
+ return this._capacity - this.offsetMap.size;
248
+ }
249
+
250
+ get capacity() {
251
+ return this._capacity;
252
+ }
253
+ }
254
+
255
+
256
+
@@ -0,0 +1,4 @@
1
+ import { BufferOrchestrator } from "./buffer-orchestrator";
2
+ import { BufferManager } from "./buffer-manager";
3
+
4
+ export { BufferOrchestrator, BufferManager };
@@ -0,0 +1,9 @@
1
+ export const vaoAttributeLoader = (gl, buffer, position, length, stride, offset, divisor = null) => {
2
+ gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
3
+ gl.enableVertexAttribArray(position);
4
+ gl.vertexAttribPointer(position, length, gl.FLOAT, false, stride, offset);
5
+ if (divisor !== null) {
6
+ gl.vertexAttribDivisor(position, divisor);
7
+ }
8
+
9
+ }
@@ -11,7 +11,7 @@ export const POLE = `
11
11
 
12
12
  export const R = `
13
13
  #ifndef R
14
- #define R 6378136.99911
14
+ #define R 6378137.0
15
15
  #endif
16
16
  `;
17
17
 
@@ -23,13 +23,13 @@ export const PI = `
23
23
 
24
24
  export const POLE_BY_PI = `
25
25
  #ifndef POLE_BY_PI
26
- #define POLE_BY_PI 6378136.99911
26
+ #define POLE_BY_PI 6378137.0
27
27
  #endif
28
28
  `;
29
29
 
30
30
  export const R_3D = `
31
31
  #ifndef R_3D
32
- #define R_3D 6378.137699911
32
+ #define R_3D 6378.137
33
33
  #endif
34
34
  `;
35
35
 
@@ -55,9 +55,9 @@ vec2 pixelXYToCartesian2DPoint( vec2 position, vec2 translate, vec2 mapWH, vec2
55
55
  }
56
56
  `;
57
57
 
58
-
59
- export const mercatorXYTo2DPoint = `
60
- vec4 mercatorXYTo2DPoint( vec2 position) { // projection, translate, mapWH, screenWH comes from camera uniform block
58
+ // TODO: rename it to mercatorXYToGLPosition
59
+ export const mercatorXYToGLPosition = `
60
+ vec4 mercatorXYToGLPosition( vec2 position) { // projection, translate, mapWH, screenWH comes from camera uniform block
61
61
  float x = (( position.x - translate.x ) / mapWH.x) * screenWH.x;
62
62
  float y = (1.0 - (position.y - translate.y) / mapWH.y) * screenWH.y;
63
63
  return projection * vec4(x, y, 0.0, 1.0);
@@ -159,3 +159,104 @@ vec2 circleLimpFromLongLatRadCenterMercatorCompass(vec2 center, float radius, fl
159
159
  }`;
160
160
 
161
161
 
162
+ // Function to interpolate between two Cartesian points using spherical interpolation (slerp)
163
+ export const slerp = `
164
+ vec3 slerp(vec3 A, vec3 B, float t) {
165
+ float cosTheta = dot(A, B);
166
+ float theta = acos(clamp(cosTheta, -1.0, 1.0)); // Angle between the points
167
+
168
+ float sinTheta = sin(theta);
169
+
170
+ // Avoid division by zero // many points falls in to this category
171
+ if (sinTheta < 0.00001) {
172
+ return mix(A, B, t); // Linear interpolation as fallback
173
+ }
174
+
175
+ float factorA = sin((1.0 - t) * theta) / sinTheta;
176
+ float factorB = sin(t * theta) / sinTheta;
177
+
178
+ return factorA * A + factorB * B;
179
+ }
180
+ `;
181
+
182
+ // Function to convert Cartesian coordinates back to spherical (latitude, longitude)
183
+ export const cartesianToSpherical = `
184
+ vec2 cartesianToSpherical(vec3 point) {
185
+ float lat = degrees(asin(point.z)); // Latitude
186
+ float lon = degrees(atan(point.y, point.x)); // Longitude
187
+
188
+ return vec2(lat, lon);
189
+ }`;
190
+
191
+ // Main function to calculate an intermediate point
192
+
193
+ export const interpolateGeographicPoint = slerp + cartesianToSpherical + longLatRadToCartesian3D + `
194
+ vec3 interpolateGeographicPoint(vec2 start, vec2 end, float t) {
195
+ vec3 pointA = longLatRadToCartesian3D(start);
196
+ vec3 pointB = longLatRadToCartesian3D(end);
197
+ vec3 interpolatedPoint = slerp(pointA, pointB, t);
198
+ return interpolatedPoint;
199
+ // return cartesianToSpherical(interpolatedPoint);
200
+ }
201
+ `;
202
+
203
+
204
+
205
+ export const angleBetweenTwoPointsRadian = `
206
+ float angleBetweenTwoPointsRadian(vec2 start_, vec2 end_) {
207
+ float start_lat = log( tan( ( 1.0 - start_.y ) * PI / 2.0 ) );
208
+ float end_lat = log( tan( ( 1.0 - end_.y ) * PI / 2.0 ) );
209
+ float angle = atan( (end_lat - start_lat )/ (end_.x - start_.x));
210
+ return angle;
211
+ }
212
+ `
213
+
214
+ export const circleCircumferenceInterPolationOf2PointsRadian = `
215
+ float circleCircumferenceInterPolationOf2PointsRadian(vec2 center, vec2 target, float bearing_angle, float ratio) {
216
+ vec2 t = target - center;
217
+ float mainAngle = atan(t.x, t.y);
218
+ float angle = mainAngle - * ratio;
219
+ return angle;
220
+ }
221
+ `
222
+
223
+ const circumferencePoints = `
224
+ vec2 circumferencePoints(vec2 center, vec2 target, vec2 target2, float phase) {
225
+ // Calculate vectors from center to target and target2
226
+ vec2 v1 = target - center;
227
+ vec2 v2 = target2 - center;
228
+
229
+ // Normalize the vectors to ensure they are on the unit circle
230
+ v1 = normalize(v1);
231
+ v2 = normalize(v2);
232
+
233
+ // Calculate the angle between the vectors
234
+ float angle1 = atan(v1.y, v1.x);
235
+ float angle2 = atan(v2.y, v2.x);
236
+
237
+ // Ensure the angles are continuous (handle wrap-around at 2π)
238
+ if (angle2 < angle1) {
239
+ angle2 += 2.0 * 3.14159265359; // Add 2π to angle2 if it is smaller
240
+ }
241
+
242
+ // Interpolate the angle based on the phase
243
+ float interpolatedAngle = mix(angle1, angle2, phase);
244
+
245
+ // Calculate the new point on the circle
246
+ vec2 result = vec2(cos(interpolatedAngle), sin(interpolatedAngle));
247
+
248
+ // Scale back to the original circle radius and shift to center
249
+ return center + length(target - center) * result;
250
+ }
251
+ `
252
+
253
+
254
+ export const realDistanceOnSphereR1 = `
255
+ float realDistanceOnSphereR1(vec2 longLat1, vec2 longLat2) {
256
+ float dLat = longLat2.y - longLat1.y;
257
+ float dLong = longLat2.x - longLat1.x;
258
+ float a = sin(dLat / 2.0) * sin(dLat / 2.0) + cos(longLat1.y) * cos(longLat2.y) * sin(dLong / 2.0) * sin(dLong / 2.0);
259
+ float c = 2.0 * atan(sqrt(a), sqrt(1.0 - a));
260
+ return c;
261
+ }
262
+ `;
package/wind/plugin.js CHANGED
@@ -696,9 +696,12 @@ export default class WindPlugin {
696
696
 
697
697
  gl.activeTexture(gl.TEXTURE0);
698
698
  if (this._doDraw()) {
699
- gl.disable(gl.DEPTH_TEST);
700
- gl.disable(gl.STENCIL_TEST);
699
+ const depthTest = gl.isEnabled(gl.DEPTH_TEST);
700
+ if (depthTest) gl.disable(gl.DEPTH_TEST);
701
+ // if (gl.disable(gl.STENCIL_TEST); //
701
702
  this._draw();
703
+ if (depthTest) gl.enable(gl.DEPTH_TEST);
704
+
702
705
  }
703
706
 
704
707
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
@@ -862,8 +865,8 @@ export default class WindPlugin {
862
865
 
863
866
  _resetMachineStates() {
864
867
  const { gl, globe } = this;
865
- gl.disable(gl.DEPTH_TEST);
866
- gl.disable(gl.STENCIL_TEST);
868
+ // gl.disable(gl.DEPTH_TEST);
869
+ // gl.disable(gl.STENCIL_TEST);
867
870
  gl.activeTexture(gl.TEXTURE0);
868
871
  gl.viewport(0, 0, globe.api_ScrW(), globe.api_ScrH());
869
872
  }
@@ -0,0 +1,86 @@
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
+ export class ContextTextWriter {
18
+ constructor(globe, { style = null } = {}) {
19
+ this.globe = globe;
20
+ this.itemMap = new Map();
21
+ this.style = style || defaultStyle;
22
+ }
23
+
24
+ setStyle(style) {
25
+ this.style = style;
26
+ }
27
+
28
+
29
+ draw() {
30
+ const { globe, style, itemMap } = this;
31
+ const { textFont, opacity } = style;
32
+ for (const [key, { lat, long, text }] of itemMap) {
33
+ const { x, y } = globe.api_GetScreenPointFromGeo(
34
+ {
35
+ long: long,
36
+ lat: lat,
37
+ z: 0,
38
+ },
39
+ style.zMode === CSZMode.Z_MSL,
40
+ );
41
+
42
+ globe.api_DrawContextTextMultiLine(text, textFont, opacity, { x, y });
43
+ }
44
+ }
45
+
46
+
47
+ insertText(key, lat, long, text) {
48
+ this.itemMap.set(key, { lat, long, text });
49
+ }
50
+
51
+
52
+ updateText(key, text) {
53
+ const item = this.itemMap.get(key);
54
+ item.text = text;
55
+ }
56
+
57
+ updateCoords(key, lat, long) {
58
+ const item = this.itemMap.get(key);
59
+ item.lat = lat; item.long = long;
60
+ }
61
+
62
+
63
+ insertTextBulk(items) {
64
+ for (const item of items) {
65
+ this.itemMap.set(item.key, item);
66
+ }
67
+ }
68
+
69
+ updateTextCoordsBulk(items) {
70
+ for (const { key, lat, long } of items) {
71
+ const item = this.itemMap.get(key);
72
+ item.lat = lat; item.long = long;
73
+ }
74
+ }
75
+
76
+
77
+ deleteTextBulk(keys) {
78
+ for (const key of keys) {
79
+ this.itemMap.delete(key);
80
+ }
81
+ }
82
+
83
+ clear() {
84
+ this.itemMap.clear();
85
+ }
86
+ }
@@ -0,0 +1 @@
1
+ export { ContextTextWriter } from "./context-text";