@pirireis/webglobeplugins 0.17.0 → 1.0.2

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.
Files changed (274) hide show
  1. package/Math/{angle-calculation.js → angle-calculation.ts} +18 -14
  2. package/Math/{arc-cdf-points.js → arc-cdf-points.ts} +329 -272
  3. package/Math/{arc-generate-points-exponantial.js → arc-generate-points-exponantial.ts} +299 -254
  4. package/Math/{arc.js → arc.ts} +421 -292
  5. package/Math/bounds/line-bbox.js +225 -186
  6. package/Math/{circle-cdf-points.js → circle-cdf-points.ts} +143 -78
  7. package/Math/{circle.js → circle.ts} +49 -33
  8. package/Math/{constants.js → constants.ts} +12 -4
  9. package/Math/contour/{quadtreecontours.js → quadtreecontours.ts} +371 -300
  10. package/Math/contour/quadtreecontours1.js +336 -298
  11. package/Math/{finite-line-2d.js → finite-line-2d.ts} +68 -58
  12. package/Math/haversine.ts +33 -0
  13. package/Math/index.js +0 -1
  14. package/Math/juction/{arc-plane.js → arc-plane.ts} +203 -143
  15. package/Math/juction/{line-sphere.js → line-sphere.ts} +32 -22
  16. package/Math/juction/{plane-plane.js → plane-plane.ts} +62 -53
  17. package/Math/{line.js → line.ts} +84 -52
  18. package/Math/matrix4.ts +0 -0
  19. package/Math/mesh/mapbox-delaunay.d.ts +74 -0
  20. package/Math/{methods.js → methods.ts} +182 -107
  21. package/Math/{plane.js → plane.ts} +92 -56
  22. package/Math/{quaternion.js → quaternion.ts} +128 -106
  23. package/Math/roadmap.md +10 -0
  24. package/Math/templete-shapes/{grid-visually-equal.js → grid-visually-equal.ts} +118 -65
  25. package/Math/tessellation/constants.ts +1 -0
  26. package/Math/tessellation/methods.ts +79 -0
  27. package/Math/tessellation/nearest-value-padding.ts +147 -0
  28. package/Math/tessellation/roadmap.md +48 -0
  29. package/Math/tessellation/spherical-triangle-area.ts +127 -0
  30. package/Math/tessellation/tile-merger.ts +578 -0
  31. package/Math/tessellation/triangle-tessellation.ts +533 -0
  32. package/Math/tessellation/types.ts +1 -0
  33. package/Math/types.ts +68 -0
  34. package/Math/utils.js +3 -2
  35. package/Math/{vec3.js → vec3.ts} +227 -151
  36. package/Math/xyz-tile.ts +26 -0
  37. package/algorithms/search-binary.js +14 -16
  38. package/altitude-locator/adaptors.js +0 -1
  39. package/altitude-locator/keymethod.js +0 -1
  40. package/altitude-locator/plugin.js +445 -345
  41. package/altitude-locator/types.js +26 -21
  42. package/compass-rose/compass-rose-padding-flat.js +274 -230
  43. package/compass-rose/{compass-text-writer.js → compass-text-writer.ts} +210 -155
  44. package/compass-rose/index.js +3 -3
  45. package/{constants.js → constants.ts} +8 -6
  46. package/heatwave/datamanager.js +168 -149
  47. package/heatwave/heatwave.js +261 -206
  48. package/heatwave/index.js +5 -5
  49. package/heatwave/isobar.js +340 -303
  50. package/heatwave/{texture-point-sampler.js → texture-point-sampler.ts} +220 -187
  51. package/investigation-tools/draw/tiles/adapters.ts +133 -0
  52. package/investigation-tools/draw/tiles/tiles.ts +162 -0
  53. package/jest.config.js +6 -7
  54. package/package.json +1 -1
  55. package/pin/pin-object-array1.js +381 -300
  56. package/pin/pin-point-totem1.js +77 -60
  57. package/programs/arrowfield/arrow-field.js +89 -60
  58. package/programs/arrowfield/logic.js +173 -141
  59. package/programs/data2legend/density-to-legend.js +86 -68
  60. package/programs/data2legend/point-to-density-texture.js +84 -67
  61. package/programs/float2legendwithratio/index.js +3 -2
  62. package/programs/float2legendwithratio/logic.js +144 -118
  63. package/programs/float2legendwithratio/object.js +141 -104
  64. package/programs/helpers/blender.js +73 -58
  65. package/programs/helpers/{fadeaway.js → fadeaway.ts} +73 -55
  66. package/programs/index.js +19 -20
  67. package/programs/line-on-globe/circle-accurate-3d.js +112 -85
  68. package/programs/line-on-globe/circle-accurate-flat.js +200 -148
  69. package/programs/line-on-globe/degree-padding-around-circle-3d.js +134 -102
  70. package/programs/line-on-globe/index.js +0 -1
  71. package/programs/line-on-globe/lines-color-instanced-flat.js +99 -80
  72. package/programs/line-on-globe/linestrip/data.ts +29 -0
  73. package/programs/line-on-globe/linestrip/{linestrip.js → linestrip.ts} +152 -93
  74. package/programs/line-on-globe/{naive-accurate-flexible.js → naive-accurate-flexible.ts} +175 -126
  75. package/programs/line-on-globe/util.js +8 -5
  76. package/programs/picking/pickable-polygon-renderer.js +129 -98
  77. package/programs/picking/pickable-renderer.js +130 -98
  78. package/programs/point-on-globe/element-globe-surface-glow.js +122 -93
  79. package/programs/point-on-globe/element-point-glow.js +114 -80
  80. package/programs/point-on-globe/square-pixel-point.js +139 -120
  81. package/programs/polygon-on-globe/roadmap.md +8 -0
  82. package/programs/polygon-on-globe/texture-dem-triangles.ts +290 -0
  83. package/programs/{programcache.js → programcache.ts} +134 -126
  84. package/programs/rings/index.js +1 -1
  85. package/programs/rings/partial-ring/{piece-of-pie.js → piece-of-pie.ts} +222 -152
  86. package/programs/totems/camera-totem-attactment-interface.ts +4 -0
  87. package/programs/totems/{camerauniformblock.js → camerauniformblock.ts} +326 -230
  88. package/programs/totems/{canvas-webglobe-info.js → canvas-webglobe-info.ts} +147 -132
  89. package/programs/totems/dem-textures-manager.ts +368 -0
  90. package/programs/totems/{globe-changes.js → globe-changes.ts} +79 -59
  91. package/programs/totems/gpu-selection-uniform-block.js +127 -99
  92. package/programs/totems/{index.js → index.ts} +2 -2
  93. package/programs/two-d/pixel-padding-for-compass.js +101 -87
  94. package/programs/util.js +19 -14
  95. package/programs/vectorfields/logics/{constants.js → constants.ts} +5 -4
  96. package/programs/vectorfields/logics/drawrectangleparticles.ts +182 -0
  97. package/programs/vectorfields/logics/index.js +4 -2
  98. package/programs/vectorfields/logics/particle-ubo.ts +23 -0
  99. package/programs/vectorfields/logics/{pixelbased.js → pixelbased.ts} +119 -84
  100. package/programs/vectorfields/logics/ubo.js +57 -51
  101. package/programs/vectorfields/{pingpongbuffermanager.js → pingpongbuffermanager.ts} +113 -73
  102. package/publish.bat +62 -0
  103. package/range-tools-on-terrain/bearing-line/{adapters.js → adapters.ts} +154 -114
  104. package/range-tools-on-terrain/bearing-line/{plugin.js → plugin.ts} +569 -457
  105. package/range-tools-on-terrain/bearing-line/types.ts +65 -0
  106. package/range-tools-on-terrain/circle-line-chain/{adapters.js → adapters.ts} +104 -85
  107. package/range-tools-on-terrain/circle-line-chain/{chain-list-map.js → chain-list-map.ts} +446 -382
  108. package/range-tools-on-terrain/circle-line-chain/{plugin.js → plugin.ts} +607 -464
  109. package/range-tools-on-terrain/circle-line-chain/types.ts +43 -0
  110. package/range-tools-on-terrain/range-ring/{adapters.js → adapters.ts} +114 -93
  111. package/range-tools-on-terrain/range-ring/{enum.js → enum.ts} +2 -2
  112. package/range-tools-on-terrain/range-ring/{plugin.js → plugin.ts} +444 -377
  113. package/range-tools-on-terrain/range-ring/rangeringangletext.ts +396 -0
  114. package/range-tools-on-terrain/range-ring/types.ts +30 -0
  115. package/semiplugins/interface.ts +14 -0
  116. package/semiplugins/lightweight/{line-plugin.js → line-plugin.ts} +342 -221
  117. package/semiplugins/lightweight/{piece-of-pie-plugin.js → piece-of-pie-plugin.ts} +275 -200
  118. package/semiplugins/shape-on-terrain/{arc-plugin.js → arc-plugin.ts} +616 -472
  119. package/semiplugins/shape-on-terrain/{circle-plugin.js → circle-plugin.ts} +588 -444
  120. package/semiplugins/shape-on-terrain/goal.md +12 -0
  121. package/semiplugins/shape-on-terrain/{padding-1-degree.js → padding-1-degree.ts} +713 -539
  122. package/semiplugins/shape-on-terrain/terrain-polygon/adapters.ts +69 -0
  123. package/semiplugins/shape-on-terrain/terrain-polygon/data/cache-shortcuts.md +20 -0
  124. package/semiplugins/shape-on-terrain/terrain-polygon/data/cache.ts +149 -0
  125. package/semiplugins/shape-on-terrain/terrain-polygon/data/index-polygon-map.ts +58 -0
  126. package/semiplugins/shape-on-terrain/terrain-polygon/data/manager.ts +4 -0
  127. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.js +196 -0
  128. package/semiplugins/shape-on-terrain/terrain-polygon/data/master-worker.ts +209 -0
  129. package/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.ts +144 -0
  130. package/semiplugins/shape-on-terrain/terrain-polygon/data/random.ts +165 -0
  131. package/semiplugins/shape-on-terrain/terrain-polygon/data/readme.md +5 -0
  132. package/semiplugins/shape-on-terrain/terrain-polygon/data/types.ts +37 -0
  133. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker-contact.ts +81 -0
  134. package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +146 -0
  135. package/semiplugins/shape-on-terrain/terrain-polygon/notes.md +90 -0
  136. package/semiplugins/shape-on-terrain/terrain-polygon/terrain-polygon.ts +265 -0
  137. package/semiplugins/shape-on-terrain/terrain-polygon/types.ts +69 -0
  138. package/semiplugins/shell/bbox-renderer/index.ts +2 -0
  139. package/semiplugins/shell/bbox-renderer/{logic.js → logic.ts} +273 -249
  140. package/semiplugins/shell/bbox-renderer/object.ts +129 -0
  141. package/semiplugins/type.ts +8 -0
  142. package/semiplugins/utility/{container-plugin.js → container-plugin.ts} +126 -94
  143. package/semiplugins/utility/{object-pass-container-plugin.js → object-pass-container-plugin.ts} +101 -80
  144. package/shaders/fragment-toy/firework.js +1 -1
  145. package/shaders/fragment-toy/singularity.js +5 -2
  146. package/terrain-plugin.mmd +83 -0
  147. package/tests/Math/arc-sampling-test.js +367 -0
  148. package/tests/Math/arc-sampling-test.ts +429 -0
  149. package/tests/Math/arc.test.ts +77 -0
  150. package/tests/Math/junction/arc-limit.test.ts +7 -0
  151. package/tests/Math/junction/arc-plane-points.test.ts +196 -0
  152. package/tests/Math/junction/arc-plane.test.ts +172 -0
  153. package/tests/Math/junction/line-sphere.test.ts +127 -0
  154. package/tests/Math/junction/plane-plane.test.ts +91 -0
  155. package/tests/Math/plane-test.ts +17 -0
  156. package/tests/Math/plane.test.ts +43 -0
  157. package/tests/Math/vec3.test.ts +33 -0
  158. package/tracks/point-heat-map/adaptors/timetracksplugin-format-to-this.js +78 -63
  159. package/tracks/point-heat-map/index.js +0 -1
  160. package/tracks/point-heat-map/plugin-webworker.js +148 -121
  161. package/tracks/point-heat-map/point-to-heat-map-flow.js +150 -121
  162. package/tracks/point-heat-map/readme.md +15 -0
  163. package/tracks/point-tracks/key-methods.js +3 -2
  164. package/tracks/point-tracks/plugin.js +487 -393
  165. package/tracks/timetracks/adaptors-line-strip.js +79 -65
  166. package/tracks/timetracks/plugin-line-strip.js +295 -240
  167. package/tracks/timetracks/program-line-strip.js +495 -411
  168. package/tracks/timetracks/programpoint-line-strip.js +137 -109
  169. package/tracks/timetracks/readme.md +1 -0
  170. package/tsconfig.json +22 -0
  171. package/types/@pirireis/webglobe.d.ts +102 -0
  172. package/types/delaunator.d.ts +40 -0
  173. package/types/earcut.d.ts +11 -0
  174. package/types/rbush.d.ts +57 -0
  175. package/types.ts +319 -0
  176. package/util/account/bufferoffsetmanager.js +209 -176
  177. package/util/account/create-buffermap-orchastration.ts +85 -0
  178. package/util/account/index.js +6 -3
  179. package/util/account/single-attribute-buffer-management/{buffer-manager.js → buffer-manager.ts} +151 -117
  180. package/util/account/single-attribute-buffer-management/{buffer-orchestrator.js → buffer-orchestrator.ts} +238 -212
  181. package/util/account/single-attribute-buffer-management/{buffer-orchestrator1.js → buffer-orchestrator1.ts} +184 -159
  182. package/util/account/single-attribute-buffer-management/{index.js → index.ts} +11 -4
  183. package/util/account/single-attribute-buffer-management/{object-store.js → object-store.ts} +76 -55
  184. package/util/account/single-attribute-buffer-management/types.ts +43 -0
  185. package/util/account/util.js +22 -18
  186. package/util/algorithms/index.js +0 -1
  187. package/util/algorithms/search-binary.js +26 -25
  188. package/util/build-strategy/{static-dynamic.js → static-dynamic.ts} +50 -41
  189. package/util/check/index.js +0 -1
  190. package/util/check/typecheck.ts +74 -0
  191. package/util/{frame-counter-trigger.js → frame-counter-trigger.ts} +99 -84
  192. package/util/geometry/{index.js → index.ts} +155 -121
  193. package/util/gl-util/buffer/{attribute-loader.js → attribute-loader.ts} +84 -62
  194. package/util/gl-util/buffer/{index.js → index.ts} +6 -3
  195. package/util/gl-util/draw-options/{methods.js → methods.ts} +47 -32
  196. package/util/gl-util/uniform-block/{manager.js → manager.ts} +232 -190
  197. package/util/{webglobe/gldefaultstates.js → globe-default-gl-states.ts} +5 -4
  198. package/util/helper-methods.ts +9 -0
  199. package/util/index.js +9 -10
  200. package/util/interpolation/index.js +0 -1
  201. package/util/interpolation/timetrack/index.js +9 -2
  202. package/util/interpolation/timetrack/timetrack-interpolator.js +94 -79
  203. package/util/interpolation/timetrack/web-worker.js +51 -46
  204. package/util/picking/{fence.js → fence.ts} +47 -41
  205. package/util/picking/picker-displayer.ts +226 -0
  206. package/util/programs/draw-from-pixel-coords.js +201 -164
  207. package/util/programs/{draw-texture-on-canvas.js → draw-texture-on-canvas.ts} +92 -67
  208. package/util/programs/supersampletotextures.js +130 -97
  209. package/util/programs/texturetoglobe.js +153 -128
  210. package/util/shaderfunctions/{geometrytransformations.js → geometrytransformations.ts} +169 -41
  211. package/util/shaderfunctions/index.js +2 -2
  212. package/util/shaderfunctions/nodata.js +4 -2
  213. package/util/shaderfunctions/noisefunctions.js +10 -7
  214. package/util/{webglobjectbuilders.js → webglobjectbuilders.ts} +446 -358
  215. package/vectorfield/arrowfield/adaptor.js +11 -11
  216. package/vectorfield/arrowfield/index.js +3 -3
  217. package/vectorfield/arrowfield/plugin.js +128 -83
  218. package/vectorfield/waveparticles/adaptor.js +16 -15
  219. package/vectorfield/waveparticles/index.js +3 -3
  220. package/vectorfield/waveparticles/plugin.ts +506 -0
  221. package/vectorfield/wind/adapters/image-to-fields.ts +74 -0
  222. package/vectorfield/wind/adapters/types.ts +12 -0
  223. package/vectorfield/wind/{imagetovectorfieldandmagnitude.js → imagetovectorfieldandmagnitude.ts} +78 -56
  224. package/vectorfield/wind/index.js +5 -5
  225. package/vectorfield/wind/plugin-persistant copy.ts +461 -0
  226. package/vectorfield/wind/plugin-persistant.ts +483 -0
  227. package/vectorfield/wind/plugin.js +883 -671
  228. package/vectorfield/wind/vectorfieldimage.js +27 -23
  229. package/write-text/{context-text-bulk.js → context-text-bulk.ts} +285 -200
  230. package/write-text/context-text3.ts +252 -0
  231. package/write-text/{context-text4.js → context-text4.ts} +231 -145
  232. package/write-text/context-textDELETE.js +125 -94
  233. package/write-text/objectarraylabels/{index.js → index.ts} +2 -2
  234. package/write-text/objectarraylabels/objectarraylabels.d.ts +72 -0
  235. package/write-text/objectarraylabels/objectarraylabels.js +247 -200
  236. package/Math/matrix4.js +0 -1
  237. package/Math/tessellation/earcut/adapters.js +0 -37
  238. package/Math/tessellation/hybrid-triangle-tessellation-meta.js +0 -123
  239. package/Math/tessellation/methods.js +0 -46
  240. package/Math/tessellation/shred-input.js +0 -18
  241. package/Math/tessellation/tile-merger.js +0 -56
  242. package/Math/tessellation/tiler.js +0 -50
  243. package/Math/tessellation/triangle-tessellation-meta.js +0 -516
  244. package/Math/tessellation/triangle-tessellation.js +0 -14
  245. package/Math/tessellation/types.js +0 -1
  246. package/Math/tessellation/zoom-catch.js +0 -1
  247. package/Math/types.js +0 -1
  248. package/programs/line-on-globe/linestrip/data.js +0 -4
  249. package/programs/polygon-on-globe/partial-tesselation.js +0 -1
  250. package/programs/polygon-on-globe/texture-dem-triangle-test-plugin-triangle.js +0 -204
  251. package/programs/polygon-on-globe/texture-dem-triangle-test-plugin.js +0 -118
  252. package/programs/polygon-on-globe/texture-dem-triangles.js +0 -236
  253. package/programs/vectorfields/logics/drawrectangleparticles.js +0 -112
  254. package/programs/vectorfields/logics/ubo-new.js +0 -25
  255. package/range-tools-on-terrain/bearing-line/types.js +0 -1
  256. package/range-tools-on-terrain/circle-line-chain/types.js +0 -1
  257. package/range-tools-on-terrain/range-ring/rangeringangletext.js +0 -331
  258. package/range-tools-on-terrain/range-ring/types.js +0 -9
  259. package/semiplugins/interface.js +0 -1
  260. package/semiplugins/shape-on-terrain/terrain-cover/texture-dem-cover.js +0 -1
  261. package/semiplugins/shell/bbox-renderer/index.js +0 -2
  262. package/semiplugins/shell/bbox-renderer/object.js +0 -65
  263. package/semiplugins/type.js +0 -1
  264. package/types.js +0 -19
  265. package/util/account/create-buffermap-orchastration.js +0 -39
  266. package/util/account/single-attribute-buffer-management/types.js +0 -1
  267. package/util/check/typecheck.js +0 -66
  268. package/util/gl-util/uniform-block/types.js +0 -1
  269. package/util/picking/picker-displayer.js +0 -134
  270. package/util/webglobe/index.js +0 -2
  271. package/util/webglobe/rasteroverlay.js +0 -76
  272. package/vectorfield/waveparticles/plugin.js +0 -290
  273. package/write-text/attached-text-writer.js +0 -95
  274. package/write-text/context-text3.js +0 -167
@@ -0,0 +1,209 @@
1
+ /// <reference lib="webworker" />
2
+
3
+ import { PolygonInput, WorkerInput, WorkerOutput, BBOXZOOMDATA } from "../types";
4
+
5
+ interface WorkerWrapper {
6
+ worker: Worker;
7
+ inProgress: boolean;
8
+ insertDeleteQueue: (PolygonInput | string)[];
9
+ lastBBOXData: BBOXZOOMDATA | null;
10
+ itemCount: number;
11
+ lastOutput: WorkerOutput | null;
12
+ }
13
+
14
+ const _workers: WorkerWrapper[] = [];
15
+ const _workerMap: Map<string, number> = new Map();
16
+ let _maxWorkers = 4; // Default, updated in init
17
+ let _nextWorkerIndex = 0;
18
+
19
+ // Configuration state to pass to new workers or re-broadcast
20
+ let _pickableState: boolean | undefined;
21
+ let _variativeColorsOn: boolean | undefined;
22
+
23
+ // Initialize workers
24
+ function initWorkers() {
25
+ _maxWorkers = Math.max(1, (navigator.hardwareConcurrency || 4) - 1);
26
+ for (let i = 0; i < _maxWorkers; i++) {
27
+ addWorker();
28
+ }
29
+ }
30
+
31
+ function addWorker() {
32
+ // @ts-ignore
33
+ const worker = new Worker(new URL("./worker.js", import.meta.url), { type: 'module' });
34
+
35
+ const wrapper: WorkerWrapper = {
36
+ worker,
37
+ inProgress: false,
38
+ insertDeleteQueue: [],
39
+ lastBBOXData: null,
40
+ itemCount: 0,
41
+ lastOutput: null
42
+ };
43
+
44
+ worker.onmessage = (event: MessageEvent<WorkerOutput>) => {
45
+ wrapper.inProgress = false;
46
+ wrapper.lastOutput = event.data;
47
+ mergeAndSendResults();
48
+ sendToSubWorker(wrapper);
49
+ };
50
+
51
+ // Initialize sub-worker with current global state
52
+ worker.postMessage({
53
+ pickableState: _pickableState,
54
+ variativeColorsOn: _variativeColorsOn,
55
+ insertDeleteQueue: [],
56
+ bboxes: null,
57
+ });
58
+
59
+ _workers.push(wrapper);
60
+ }
61
+
62
+ function mergeAndSendResults() {
63
+ let totalVec3s = 0;
64
+ let totalIndices = 0;
65
+ let totalLongLats = 0;
66
+ let totalPickIndices = 0;
67
+ let totalVariativeColors = 0;
68
+
69
+ const validOutputs: WorkerOutput[] = [];
70
+
71
+ for (const w of _workers) {
72
+ if (w.lastOutput) {
73
+ validOutputs.push(w.lastOutput);
74
+ totalVec3s += w.lastOutput.vec3s.length;
75
+ totalIndices += w.lastOutput.indices.length;
76
+ totalLongLats += w.lastOutput.longLats.length;
77
+ if (w.lastOutput.pickIndices) totalPickIndices += w.lastOutput.pickIndices.length;
78
+ if (w.lastOutput.variativeColors) totalVariativeColors += w.lastOutput.variativeColors.length;
79
+ }
80
+ }
81
+
82
+ if (validOutputs.length === 0) return;
83
+
84
+ const merged: WorkerOutput = {
85
+ vec3s: new Float32Array(totalVec3s),
86
+ indices: new Uint32Array(totalIndices),
87
+ longLats: new Float32Array(totalLongLats),
88
+ pickIndices: totalPickIndices > 0 ? new Float32Array(totalPickIndices) : null,
89
+ variativeColors: totalVariativeColors > 0 ? new Float32Array(totalVariativeColors) : null
90
+ };
91
+
92
+ let offsetVec3s = 0;
93
+ let offsetIndices = 0;
94
+ let offsetLongLats = 0;
95
+ let offsetPickIndices = 0;
96
+ let offsetVariativeColors = 0;
97
+ let vertexOffset = 0;
98
+
99
+ for (const out of validOutputs) {
100
+ merged.vec3s.set(out.vec3s, offsetVec3s);
101
+ offsetVec3s += out.vec3s.length;
102
+
103
+ for (let i = 0; i < out.indices.length; i++) {
104
+ merged.indices[offsetIndices + i] = out.indices[i] + vertexOffset;
105
+ }
106
+ offsetIndices += out.indices.length;
107
+ vertexOffset += out.vec3s.length / 3;
108
+
109
+ merged.longLats.set(out.longLats, offsetLongLats);
110
+ offsetLongLats += out.longLats.length;
111
+
112
+ if (merged.pickIndices && out.pickIndices) {
113
+ merged.pickIndices.set(out.pickIndices, offsetPickIndices);
114
+ offsetPickIndices += out.pickIndices.length;
115
+ }
116
+
117
+ if (merged.variativeColors && out.variativeColors) {
118
+ merged.variativeColors.set(out.variativeColors, offsetVariativeColors);
119
+ offsetVariativeColors += out.variativeColors.length;
120
+ }
121
+ }
122
+
123
+ // Send merged result to Main Thread
124
+ self.postMessage(merged, [
125
+ merged.vec3s.buffer,
126
+ merged.indices.buffer,
127
+ merged.longLats.buffer,
128
+ ...(merged.pickIndices ? [merged.pickIndices.buffer] : []),
129
+ ...(merged.variativeColors ? [merged.variativeColors.buffer] : [])
130
+ ]);
131
+ }
132
+
133
+ function sendToSubWorker(wrapper: WorkerWrapper) {
134
+ if (wrapper.inProgress) return;
135
+ if (wrapper.insertDeleteQueue.length === 0 && wrapper.lastBBOXData === null) return;
136
+
137
+ wrapper.inProgress = true;
138
+ wrapper.worker.postMessage({
139
+ pickableState: undefined, // State is set on init, only send updates if needed
140
+ variativeColorsOn: undefined,
141
+ bboxes: wrapper.lastBBOXData,
142
+ insertDeleteQueue: wrapper.insertDeleteQueue,
143
+ } as WorkerInput);
144
+
145
+ wrapper.lastBBOXData = null;
146
+ wrapper.insertDeleteQueue = [];
147
+ }
148
+
149
+ function triggerAllWorkers() {
150
+ for (const w of _workers) {
151
+ sendToSubWorker(w);
152
+ }
153
+ }
154
+
155
+ // Handle messages from Main Thread
156
+ self.onmessage = (event: MessageEvent<WorkerInput>) => {
157
+ const { bboxes, insertDeleteQueue, pickableState, variativeColorsOn } = event.data;
158
+
159
+ // Initialize if not already done
160
+ if (_workers.length === 0) {
161
+ _pickableState = pickableState;
162
+ _variativeColorsOn = variativeColorsOn;
163
+ initWorkers();
164
+ }
165
+
166
+ // Handle BBOX updates
167
+ if (bboxes) {
168
+ for (const w of _workers) {
169
+ w.lastBBOXData = bboxes;
170
+ }
171
+ }
172
+
173
+ // Handle Insert/Delete
174
+ if (insertDeleteQueue && insertDeleteQueue.length > 0) {
175
+ if (insertDeleteQueue[0] === "__CLEAR_ALL_ITEMS__") {
176
+ _workerMap.clear();
177
+ for (const w of _workers) {
178
+ w.insertDeleteQueue = ["__CLEAR_ALL_ITEMS__"];
179
+ w.itemCount = 0;
180
+ w.lastOutput = null;
181
+ }
182
+ } else {
183
+ for (const item of insertDeleteQueue) {
184
+ if (typeof item === 'string') {
185
+ // Delete
186
+ const workerIdx = _workerMap.get(item);
187
+ if (workerIdx !== undefined) {
188
+ _workers[workerIdx].insertDeleteQueue.push(item);
189
+ _workers[workerIdx].itemCount--;
190
+ _workerMap.delete(item);
191
+ }
192
+ } else {
193
+ // Insert
194
+ let workerIdx = _workerMap.get(item.key);
195
+ if (workerIdx === undefined) {
196
+ workerIdx = _nextWorkerIndex;
197
+ _workerMap.set(item.key, workerIdx);
198
+ _workers[workerIdx].itemCount++;
199
+ _nextWorkerIndex = (_nextWorkerIndex + 1) % _workers.length;
200
+ }
201
+ _workers[workerIdx].insertDeleteQueue.push(item.key);
202
+ }
203
+ }
204
+ }
205
+ }
206
+
207
+ // Trigger all workers to process the new data
208
+ triggerAllWorkers();
209
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * # Purpose
3
+ * Divide long edges of polygons into smaller segments
4
+ *
5
+ * This algorithm should be called after earcutting / triangulation.
6
+ * Then earcut should run second time to further divide long edges.
7
+ *
8
+ * populate points on a arc between two given points on a sphere
9
+ *
10
+ */
11
+
12
+
13
+ import { Radian } from "../../../../types";
14
+
15
+ import { PolygonPluginInput, TrianglesMiddleData } from "../types";
16
+ import { haversine } from "../../../../Math/haversine";
17
+
18
+
19
+ import earcut from "earcut";
20
+
21
+
22
+ /**
23
+ *
24
+ */
25
+
26
+ function __pointsInBetweenGreateCircle(
27
+ lat1: Radian,
28
+ lon1: Radian,
29
+ lat2: Radian,
30
+ lon2: Radian,
31
+ unitSphereDistance: number
32
+ ): number[] | null {
33
+ const points: number[] = [];
34
+
35
+ const d1 = haversine(lat1, lon1, lat2, lon2);
36
+ if (d1 <= unitSphereDistance) {
37
+ return null;
38
+ }
39
+
40
+ const numSegments = Math.ceil(d1 / unitSphereDistance);
41
+ for (let i = 1; i < numSegments; i++) {
42
+ const f = i / numSegments;
43
+ const A = Math.sin((1 - f) * d1) / Math.sin(d1);
44
+ const B = Math.sin(f * d1) / Math.sin(d1);
45
+ const x = A * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);
46
+ const y = A * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);
47
+ const z = A * Math.sin(lat1) + B * Math.sin(lat2);
48
+ const latN = Math.atan2(z, Math.sqrt(x * x + y * y));
49
+ const lonN = Math.atan2(y, x);
50
+ points.push(latN, lonN);
51
+ }
52
+
53
+ return points;
54
+ }
55
+
56
+
57
+
58
+ function _dividePolygonEdgeSize(
59
+ polygon: PolygonPluginInput,
60
+ kmThreshold: number
61
+ ): PolygonPluginInput {
62
+ const unitSphereDistance = kmThreshold / 6371; // Earth radius in km
63
+
64
+ const newGeometries = polygon.geometry.map(geom => {
65
+ const { vertices, holes } = geom;
66
+ const newVertices: number[] = [];
67
+ const newHoles: number[] = [];
68
+
69
+ const processRing = (start: number, end: number) => {
70
+ for (let i = start; i < end; i++) {
71
+ const long1 = vertices[2 * i];
72
+ const lat1 = vertices[2 * i + 1];
73
+ const next_i = (i + 1 < end) ? i + 1 : start;
74
+ const long2 = vertices[2 * next_i];
75
+ const lat2 = vertices[2 * next_i + 1];
76
+
77
+ newVertices.push(long1, lat1);
78
+ const extraPoints = __pointsInBetweenGreateCircle(
79
+ lat1, long1, lat2, long2, unitSphereDistance
80
+ );
81
+ if (extraPoints) {
82
+ newVertices.push(...extraPoints);
83
+ }
84
+ }
85
+ };
86
+
87
+ const shellEnd = holes.length > 0 ? holes[0] : vertices.length / 2;
88
+ processRing(0, shellEnd);
89
+
90
+ for (let h = 0; h < holes.length; h++) {
91
+ newHoles.push(newVertices.length / 2);
92
+ const holeStart = holes[h];
93
+ const holeEnd = h + 1 < holes.length ? holes[h + 1] : vertices.length / 2;
94
+ processRing(holeStart, holeEnd);
95
+ }
96
+ return { vertices: newVertices, holes: newHoles };
97
+ });
98
+
99
+ return {
100
+ ...polygon,
101
+ geometry: newGeometries,
102
+ };
103
+ }
104
+
105
+ // TODO:
106
+ // divide TrianglesMiddleData edges longer than threshold
107
+ // function _divideTriangleEdges(
108
+ // key: string,
109
+ // vertices: number[],
110
+ // indices: number[],
111
+ // kmThreshold: number // maybe
112
+ // ): TrianglesMiddleData {
113
+ // return { key, vertices, indices };
114
+ // }
115
+
116
+
117
+
118
+ // TODO: NEED TEST
119
+ function triangulation(polygon: PolygonPluginInput, kmThreshold: number): TrianglesMiddleData {
120
+
121
+ const finalVertices: number[] = [];
122
+ const finalIndices: number[] = [];
123
+ let vertexIndexOffset = 0;
124
+
125
+ for (const geom of polygon.geometry) {
126
+ const indices = earcut(geom.vertices, geom.holes, 2);
127
+
128
+ finalVertices.push(...geom.vertices);
129
+
130
+ for (const index of indices) {
131
+ finalIndices.push(index + vertexIndexOffset);
132
+ }
133
+
134
+ vertexIndexOffset += geom.vertices.length / 2;
135
+ }
136
+
137
+ return {
138
+ key: polygon.key,
139
+ vertices: finalVertices,
140
+ indices: finalIndices
141
+ };
142
+ }
143
+
144
+ export { triangulation };
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Generates random polygon data for testing PolygonPluginInput
3
+ */
4
+
5
+ import { GlobeBBox } from "../../../../types";
6
+
7
+ /**
8
+ * Generates a random polygon with optional holes
9
+ * @param {Object} options - Configuration options
10
+ * @param {number} options.minVertices - Minimum number of vertices for the shell (default: 3)
11
+ * @param {number} options.maxVertices - Maximum number of vertices for the shell (default: 8)
12
+ * @param {number} options.holeCount - Number of holes to generate (default: 0)
13
+ * @param {number} options.minLat - Minimum latitude (default: -85)
14
+ * @param {number} options.maxLat - Maximum latitude (default: 85)
15
+ * @param {number} options.minLng - Minimum longitude (default: -180)
16
+ * @param {number} options.maxLng - Maximum longitude (default: 180)
17
+ * @param {number} options.dimensions - Number of dimensions per vertex (default: 2)
18
+ * @returns {Object} PolygonPluginInput object
19
+ */
20
+ function generateRandomPolygon(options: {
21
+ minVertices?: number;
22
+ maxVertices?: number;
23
+ holeCount?: number;
24
+ minLat?: number;
25
+ maxLat?: number;
26
+ minLng?: number;
27
+ maxLng?: number;
28
+ radius?: number;
29
+ dimensions?: number;
30
+ } = {}) {
31
+ const {
32
+ minVertices = 3,
33
+ maxVertices = 8,
34
+ holeCount = 0,
35
+ minLat = -85,
36
+ maxLat = 85,
37
+ minLng = -180,
38
+ maxLng = 180,
39
+ dimensions = 2,
40
+ radius = 4,
41
+ } = options;
42
+
43
+ const key = `polygon_${Date.now()}_${Math.floor(Math.random() * 1000)}_${Math.random()}`;
44
+ const vertices = [];
45
+ const holes = [];
46
+
47
+ // Generate shell vertices
48
+ const shellVertexCount = Math.floor(Math.random() * (maxVertices - minVertices + 1)) + minVertices;
49
+ const centerLng = Math.random() * (maxLng - minLng) + minLng;
50
+ const centerLat = Math.random() * (maxLat - minLat) + minLat;
51
+
52
+ // Generate shell as a rough circle with random variations
53
+ for (let i = 0; i < shellVertexCount; i++) {
54
+ const angle = (i / shellVertexCount) * 2 * Math.PI;
55
+ const radiusVariation = radius * (0.7 + Math.random() * 0.6); // Add variation to radius
56
+ const lng = centerLng + Math.cos(angle) * radiusVariation;
57
+ const lat = centerLat + Math.sin(angle) * radiusVariation;
58
+
59
+ vertices.push(lng, lat);
60
+ if (dimensions > 2) {
61
+ for (let d = 2; d < dimensions; d++) {
62
+ vertices.push(Math.random() * 1000); // Random additional dimensions
63
+ }
64
+ }
65
+ }
66
+
67
+ // Generate holes
68
+ for (let h = 0; h < holeCount; h++) {
69
+ const holeStartIndex = vertices.length / dimensions;
70
+ holes.push(holeStartIndex);
71
+
72
+ const holeVertexCount = Math.floor(Math.random() * 4) + 3; // 3-6 vertices for holes
73
+ const holeRadius = radius * (0.2 + Math.random() * 0.3); // Smaller radius for holes
74
+ const holeCenterLng = centerLng + (Math.random() - 0.5) * radius * 0.8;
75
+ const holeCenterLat = centerLat + (Math.random() - 0.5) * radius * 0.8;
76
+
77
+ for (let i = 0; i < holeVertexCount; i++) {
78
+ const angle = (i / holeVertexCount) * 2 * Math.PI;
79
+ const lng = holeCenterLng + Math.cos(angle) * holeRadius;
80
+ const lat = holeCenterLat + Math.sin(angle) * holeRadius;
81
+
82
+ vertices.push(lng, lat);
83
+ if (dimensions > 2) {
84
+ for (let d = 2; d < dimensions; d++) {
85
+ vertices.push(Math.random() * 1000);
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ return {
92
+ key,
93
+ geometry: [{ vertices, holes }],
94
+ color: [Math.random(), Math.random(), Math.random(), 1.0],
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Generates multiple random polygons
100
+ * @param {number} count - Number of polygons to generate
101
+ * @param {Object} options - Options to pass to generateRandomPolygon
102
+ * @returns {Array} Array of PolygonPluginInput objects
103
+ */
104
+ function generateRandomPolygons(count: number, options = {}) {
105
+ const polygons = [];
106
+ for (let i = 0; i < count; i++) {
107
+ polygons.push(generateRandomPolygon(options));
108
+ }
109
+ return polygons;
110
+ }
111
+
112
+ /**
113
+ * Generates a simple rectangular polygon for basic testing
114
+ * @param {number} lng - Center longitude
115
+ * @param {number} lat - Center latitude
116
+ * @param {number} width - Width in degrees
117
+ * @param {number} height - Height in degrees
118
+ * @returns {Object} PolygonPluginInput object
119
+ */
120
+ function generateRectanglePolygon(lng = 0, lat = 0, width = 2, height = 1) {
121
+ const halfWidth = width / 2;
122
+ const halfHeight = height / 2;
123
+
124
+ return {
125
+ key: `rectangle_${Date.now()}`,
126
+ geometry: [{
127
+ vertices: [
128
+ lng - halfWidth, lat - halfHeight, // Bottom-left
129
+ lng + halfWidth, lat - halfHeight, // Bottom-right
130
+ lng + halfWidth, lat + halfHeight, // Top-right
131
+ lng - halfWidth, lat + halfHeight // Top-left
132
+ ],
133
+ holes: []
134
+ }]
135
+ };
136
+ }
137
+
138
+ function generateRectangleFromBBOX(bbox: GlobeBBox, key: string | null = null) {
139
+ const { ll, ur } = bbox;
140
+ return {
141
+ key: key || `rectangle_${Date.now()}`,
142
+ geometry: [{
143
+ vertices: [
144
+ ll.x, ll.y, // Bottom-left
145
+ ur.x, ll.y, // Bottom-right
146
+ ur.x, ur.y, // Top-right
147
+ ll.x, ur.y // Top-left
148
+ ],
149
+ holes: []
150
+ }]
151
+ };
152
+ }
153
+
154
+ // // Example usage:
155
+ // console.log('Polygon with holes:', generateRandomPolygon({ holeCount: 2 }));
156
+ // console.log('Multiple polygons:', generateRandomPolygons(3));
157
+ // console.log('Rectangle polygon:', generateRectanglePolygon(-74, 40.7, 0.1, 0.05));
158
+
159
+ export {
160
+ generateRandomPolygon,
161
+ generateRandomPolygons,
162
+ generateRectanglePolygon,
163
+ generateRectangleFromBBOX
164
+ };
165
+
@@ -0,0 +1,5 @@
1
+ # TODO:
2
+
3
+ need a glue to manage cache, connect cache to processed data, ready to be consumed by texture-dem-program
4
+
5
+ It should be able to work on web worker.
@@ -0,0 +1,37 @@
1
+ import { Color } from "../../../../types";
2
+ import { TriangleTessellationMeta } from "../../../../Math/tessellation/triangle-tessellation";
3
+ import { PolygonPluginInput } from "../types";
4
+
5
+
6
+
7
+ type CatchedType = {
8
+ polygon: PolygonPluginInput,
9
+ offset: number,
10
+ tessellationMeta: TriangleTessellationMeta,
11
+ minX: number,
12
+ minY: number,
13
+ maxX: number,
14
+ maxY: number,
15
+ };
16
+
17
+
18
+ type CacheTriangle = {
19
+ parentKey: string;
20
+ tessellationMeta: TriangleTessellationMeta;
21
+ }
22
+
23
+
24
+ type Cache = Map<string,
25
+ {
26
+ triangles: CacheTriangle[],
27
+ properties: PolygonProperties
28
+ }>;
29
+
30
+
31
+
32
+ type PolygonProperties = {
33
+ color: Color,
34
+ height: number,
35
+ }
36
+
37
+ export { CacheTriangle, Cache, PolygonProperties, CatchedType };
@@ -0,0 +1,81 @@
1
+ import { PolygonInput, TerrainPolygonOptions } from "../types";
2
+ import { WorkerInput, WorkerOutput, BBOXZOOMDATA } from "../types";
3
+ import { Globe } from "../../../../types";
4
+ import { MergedTilesInfo } from "../../../../Math/tessellation/tile-merger";
5
+ import { DemTextureManager, DemTextureManagerCache } from "../../../../programs/totems/dem-textures-manager";
6
+ import { RADIAN } from "../../../../Math/methods";
7
+
8
+ export class WorkerContact {
9
+ private _masterWorker: Worker;
10
+ private _options: Pick<TerrainPolygonOptions, "pickable" | "variativeColorsOn">;
11
+ private onResult: (result: WorkerOutput) => void;
12
+ private demTextureManager: DemTextureManager = null as any;
13
+
14
+ constructor(globe: Globe, options: Pick<TerrainPolygonOptions, "pickable" | "variativeColorsOn">, onResult: (result: WorkerOutput) => void) {
15
+ this._options = options;
16
+ this.onResult = onResult;
17
+
18
+ // Initialize the Master Worker
19
+ // @ts-ignore
20
+ this._masterWorker = new Worker(new URL("./master-worker.js", import.meta.url), { type: 'module' });
21
+
22
+ this._masterWorker.onmessage = (event: MessageEvent<WorkerOutput>) => {
23
+ this.onResult(event.data);
24
+ }
25
+
26
+ // Initialize Master Worker state
27
+ this._masterWorker.postMessage({
28
+ pickableState: this._options.pickable,
29
+ variativeColorsOn: this._options.variativeColorsOn,
30
+ insertDeleteQueue: [],
31
+ bboxes: null,
32
+ } as WorkerInput);
33
+
34
+ this.demTextureManager = DemTextureManagerCache.get(globe);
35
+ this.demTextureManager.register(this);
36
+ }
37
+
38
+ setMergedTiles(mergedTilesInfo: MergedTilesInfo[]) {
39
+ const bboxesData: BBOXZOOMDATA = new Array(mergedTilesInfo.length);
40
+ for (let i = 0; i < mergedTilesInfo.length; i++) {
41
+ const { bbox, zoom } = mergedTilesInfo[i];
42
+ bboxesData[i] = {
43
+ zoom: zoom,
44
+ minX: bbox.ll.x * RADIAN,
45
+ minY: bbox.ll.y * RADIAN,
46
+ maxX: bbox.ur.x * RADIAN,
47
+ maxY: bbox.ur.y * RADIAN,
48
+ };
49
+ }
50
+
51
+ // Send BBOX updates to Master Worker
52
+ this._masterWorker.postMessage({
53
+ bboxes: bboxesData
54
+ } as Partial<WorkerInput>);
55
+ }
56
+
57
+ free() {
58
+ this.demTextureManager.unregister(this);
59
+ this._masterWorker.terminate();
60
+ }
61
+
62
+ insertBulk(polygons: PolygonInput[]) {
63
+ this._masterWorker.postMessage({
64
+ insertDeleteQueue: polygons
65
+ } as Partial<WorkerInput>);
66
+ }
67
+
68
+ deleteBulk(keys: string[]) {
69
+ this._masterWorker.postMessage({
70
+ insertDeleteQueue: keys
71
+ } as Partial<WorkerInput>);
72
+ }
73
+
74
+ clear() {
75
+ this._masterWorker.postMessage({
76
+ insertDeleteQueue: ["__CLEAR_ALL_ITEMS__"]
77
+ } as Partial<WorkerInput>);
78
+ }
79
+ }
80
+
81
+