@pirireis/webglobeplugins 1.0.3 → 1.0.4
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/package.json +2 -2
- package/plugins/alarms/alarmFadeInFadeOutPlugin/AlarmTimeLineFadeInFadeOutPlugin.js +399 -0
- package/{Math → webglobeplugins/Math}/tessellation/triangle-tessellation.js +82 -4
- package/{heatwave → webglobeplugins/heatwave}/isobar.js +3 -0
- package/{programs → webglobeplugins/programs}/polygon-on-globe/texture-dem-triangles.js +17 -4
- package/webglobeplugins/programs/totems/attachments/adaptive-opacity.js +131 -0
- package/{programs/totems → webglobeplugins/programs/totems/attachments}/dem-textures-manager.js +11 -5
- package/{programs → webglobeplugins/programs}/vectorfields/logics/drawrectangleparticles.js +34 -28
- package/{programs → webglobeplugins/programs}/vectorfields/logics/particle-ubo.js +7 -4
- package/{programs → webglobeplugins/programs}/vectorfields/logics/pixelbased.js +3 -7
- package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/cache.js +10 -8
- package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/master-worker.js +104 -40
- package/webglobeplugins/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.js +76 -0
- package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/worker-contact.js +3 -2
- package/webglobeplugins/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +162 -0
- package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/terrain-polygon.js +66 -3
- package/webglobeplugins/semiplugins/shape-on-terrain/terrain-polygon/test-records.js +14 -0
- package/{semiplugins → webglobeplugins/semiplugins}/shell/bbox-renderer/object.js +5 -2
- package/{tracks → webglobeplugins/tracks}/timetracks/program-line-strip.js +2 -0
- package/{util → webglobeplugins/util}/gl-util/buffer/attribute-loader.js +18 -6
- package/{util → webglobeplugins/util}/gl-util/uniform-block/manager.js +13 -4
- package/{vectorfield → webglobeplugins/vectorfield}/waveparticles/plugin.js +77 -37
- package/{vectorfield → webglobeplugins/vectorfield}/wind/adapters/image-to-fields.js +46 -15
- package/{vectorfield → webglobeplugins/vectorfield}/wind/plugin-persistant.js +32 -17
- package/{vectorfield → webglobeplugins/vectorfield}/wind/plugin.js +4 -4
- package/semiplugins/shape-on-terrain/terrain-polygon/data/polygon-to-triangles.js +0 -100
- package/semiplugins/shape-on-terrain/terrain-polygon/data/worker.js +0 -125
- package/vectorfield/wind/plugin-persistant copy.js +0 -364
- package/{Math → webglobeplugins/Math}/angle-calculation.js +0 -0
- package/{Math → webglobeplugins/Math}/arc-cdf-points.js +0 -0
- package/{Math → webglobeplugins/Math}/arc-generate-points-exponantial.js +0 -0
- package/{Math → webglobeplugins/Math}/arc.js +0 -0
- package/{Math → webglobeplugins/Math}/bounds/line-bbox.js +0 -0
- package/{Math → webglobeplugins/Math}/circle-cdf-points.js +0 -0
- package/{Math → webglobeplugins/Math}/circle.js +0 -0
- package/{Math → webglobeplugins/Math}/constants.js +0 -0
- package/{Math → webglobeplugins/Math}/contour/quadtreecontours.js +0 -0
- package/{Math → webglobeplugins/Math}/contour/quadtreecontours1.js +0 -0
- package/{Math → webglobeplugins/Math}/finite-line-2d.js +0 -0
- package/{Math → webglobeplugins/Math}/haversine.js +0 -0
- package/{Math → webglobeplugins/Math}/index.js +0 -0
- package/{Math → webglobeplugins/Math}/juction/arc-plane.js +0 -0
- package/{Math → webglobeplugins/Math}/juction/line-sphere.js +0 -0
- package/{Math → webglobeplugins/Math}/juction/plane-plane.js +0 -0
- package/{Math → webglobeplugins/Math}/line.js +0 -0
- package/{Math → webglobeplugins/Math}/matrix4.js +0 -0
- package/{Math → webglobeplugins/Math}/methods.js +0 -0
- package/{Math → webglobeplugins/Math}/plane.js +0 -0
- package/{Math → webglobeplugins/Math}/quaternion.js +0 -0
- package/{Math → webglobeplugins/Math}/templete-shapes/grid-visually-equal.js +0 -0
- package/{Math → webglobeplugins/Math}/tessellation/constants.js +0 -0
- package/{Math → webglobeplugins/Math}/tessellation/methods.js +0 -0
- package/{Math → webglobeplugins/Math}/tessellation/nearest-value-padding.js +0 -0
- package/{Math → webglobeplugins/Math}/tessellation/spherical-triangle-area.js +0 -0
- package/{Math → webglobeplugins/Math}/tessellation/tile-merger.js +0 -0
- package/{Math → webglobeplugins/Math}/tessellation/types.js +0 -0
- package/{Math → webglobeplugins/Math}/types.js +0 -0
- package/{Math → webglobeplugins/Math}/utils.js +0 -0
- package/{Math → webglobeplugins/Math}/vec3.js +0 -0
- package/{Math → webglobeplugins/Math}/xyz-tile.js +0 -0
- package/{algorithms → webglobeplugins/algorithms}/search-binary.js +0 -0
- package/{altitude-locator → webglobeplugins/altitude-locator}/adaptors.js +0 -0
- package/{altitude-locator → webglobeplugins/altitude-locator}/keymethod.js +0 -0
- package/{altitude-locator → webglobeplugins/altitude-locator}/plugin.js +0 -0
- package/{altitude-locator → webglobeplugins/altitude-locator}/types.js +0 -0
- package/{compass-rose → webglobeplugins/compass-rose}/compass-rose-padding-flat.js +0 -0
- package/{compass-rose → webglobeplugins/compass-rose}/compass-text-writer.js +0 -0
- package/{compass-rose → webglobeplugins/compass-rose}/index.js +0 -0
- package/{constants.js → webglobeplugins/constants.js} +0 -0
- package/{heatwave → webglobeplugins/heatwave}/datamanager.js +0 -0
- package/{heatwave → webglobeplugins/heatwave}/heatwave.js +0 -0
- package/{heatwave → webglobeplugins/heatwave}/index.js +0 -0
- package/{heatwave → webglobeplugins/heatwave}/texture-point-sampler.js +0 -0
- package/{investigation-tools → webglobeplugins/investigation-tools}/draw/tiles/adapters.js +0 -0
- package/{investigation-tools → webglobeplugins/investigation-tools}/draw/tiles/tiles.js +0 -0
- package/{jest.config.js → webglobeplugins/jest.config.js} +0 -0
- package/{pin → webglobeplugins/pin}/pin-object-array1.js +0 -0
- package/{pin → webglobeplugins/pin}/pin-point-totem1.js +0 -0
- package/{programs → webglobeplugins/programs}/arrowfield/arrow-field.js +0 -0
- package/{programs → webglobeplugins/programs}/arrowfield/logic.js +0 -0
- package/{programs → webglobeplugins/programs}/data2legend/density-to-legend.js +0 -0
- package/{programs → webglobeplugins/programs}/data2legend/point-to-density-texture.js +0 -0
- package/{programs → webglobeplugins/programs}/float2legendwithratio/index.js +0 -0
- package/{programs → webglobeplugins/programs}/float2legendwithratio/logic.js +0 -0
- package/{programs → webglobeplugins/programs}/float2legendwithratio/object.js +0 -0
- package/{programs → webglobeplugins/programs}/helpers/blender.js +0 -0
- package/{programs → webglobeplugins/programs}/helpers/fadeaway.js +0 -0
- package/{programs → webglobeplugins/programs}/index.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/circle-accurate-3d.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/circle-accurate-flat.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/degree-padding-around-circle-3d.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/index.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/lines-color-instanced-flat.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/linestrip/data.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/linestrip/linestrip.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/naive-accurate-flexible.js +0 -0
- package/{programs → webglobeplugins/programs}/line-on-globe/util.js +0 -0
- package/{programs → webglobeplugins/programs}/picking/pickable-polygon-renderer.js +0 -0
- package/{programs → webglobeplugins/programs}/picking/pickable-renderer.js +0 -0
- package/{programs → webglobeplugins/programs}/point-on-globe/element-globe-surface-glow.js +0 -0
- package/{programs → webglobeplugins/programs}/point-on-globe/element-point-glow.js +0 -0
- package/{programs → webglobeplugins/programs}/point-on-globe/square-pixel-point.js +0 -0
- package/{programs → webglobeplugins/programs}/programcache.js +0 -0
- package/{programs → webglobeplugins/programs}/rings/index.js +0 -0
- package/{programs → webglobeplugins/programs}/rings/partial-ring/piece-of-pie.js +0 -0
- package/{programs → webglobeplugins/programs}/totems/camera-totem-attactment-interface.js +0 -0
- package/{programs → webglobeplugins/programs}/totems/camerauniformblock.js +0 -0
- package/{programs → webglobeplugins/programs}/totems/canvas-webglobe-info.js +0 -0
- package/{programs → webglobeplugins/programs}/totems/globe-changes.js +0 -0
- package/{programs → webglobeplugins/programs}/totems/gpu-selection-uniform-block.js +0 -0
- package/{programs → webglobeplugins/programs}/totems/index.js +0 -0
- package/{programs → webglobeplugins/programs}/two-d/pixel-padding-for-compass.js +0 -0
- package/{programs → webglobeplugins/programs}/util.js +0 -0
- package/{programs → webglobeplugins/programs}/vectorfields/logics/constants.js +0 -0
- package/{programs → webglobeplugins/programs}/vectorfields/logics/index.js +0 -0
- package/{programs → webglobeplugins/programs}/vectorfields/logics/ubo.js +0 -0
- package/{programs → webglobeplugins/programs}/vectorfields/pingpongbuffermanager.js +0 -0
- package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/bearing-line/adapters.js +0 -0
- package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/bearing-line/plugin.js +1 -1
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/bearing-line/types.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/circle-line-chain/adapters.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/circle-line-chain/chain-list-map.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/circle-line-chain/plugin.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/circle-line-chain/types.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/range-ring/adapters.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/range-ring/enum.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/range-ring/plugin.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/range-ring/rangeringangletext.js +0 -0
- /package/{range-tools-on-terrain → webglobeplugins/range-tools-on-terrain}/range-ring/types.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/interface.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/lightweight/line-plugin.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/lightweight/piece-of-pie-plugin.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/arc-plugin.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/circle-plugin.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/padding-1-degree.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/adapters.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/index-polygon-map.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/manager.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/random.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/types.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/types.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shell/bbox-renderer/index.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/shell/bbox-renderer/logic.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/type.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/utility/container-plugin.js +0 -0
- /package/{semiplugins → webglobeplugins/semiplugins}/utility/object-pass-container-plugin.js +0 -0
- /package/{shaders → webglobeplugins/shaders}/fragment-toy/firework.js +0 -0
- /package/{shaders → webglobeplugins/shaders}/fragment-toy/singularity.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/point-heat-map/adaptors/timetracksplugin-format-to-this.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/point-heat-map/index.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/point-heat-map/plugin-webworker.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/point-heat-map/point-to-heat-map-flow.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/point-tracks/key-methods.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/point-tracks/plugin.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/timetracks/adaptors-line-strip.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/timetracks/plugin-line-strip.js +0 -0
- /package/{tracks → webglobeplugins/tracks}/timetracks/programpoint-line-strip.js +0 -0
- /package/{types.js → webglobeplugins/types.js} +0 -0
- /package/{util → webglobeplugins/util}/account/bufferoffsetmanager.js +0 -0
- /package/{util → webglobeplugins/util}/account/create-buffermap-orchastration.js +0 -0
- /package/{util → webglobeplugins/util}/account/index.js +0 -0
- /package/{util → webglobeplugins/util}/account/single-attribute-buffer-management/buffer-manager.js +0 -0
- /package/{util → webglobeplugins/util}/account/single-attribute-buffer-management/buffer-orchestrator.js +0 -0
- /package/{util → webglobeplugins/util}/account/single-attribute-buffer-management/buffer-orchestrator1.js +0 -0
- /package/{util → webglobeplugins/util}/account/single-attribute-buffer-management/index.js +0 -0
- /package/{util → webglobeplugins/util}/account/single-attribute-buffer-management/object-store.js +0 -0
- /package/{util → webglobeplugins/util}/account/single-attribute-buffer-management/types.js +0 -0
- /package/{util → webglobeplugins/util}/account/util.js +0 -0
- /package/{util → webglobeplugins/util}/algorithms/index.js +0 -0
- /package/{util → webglobeplugins/util}/algorithms/search-binary.js +0 -0
- /package/{util → webglobeplugins/util}/build-strategy/static-dynamic.js +0 -0
- /package/{util → webglobeplugins/util}/check/index.js +0 -0
- /package/{util → webglobeplugins/util}/check/typecheck.js +0 -0
- /package/{util → webglobeplugins/util}/frame-counter-trigger.js +0 -0
- /package/{util → webglobeplugins/util}/geometry/index.js +0 -0
- /package/{util → webglobeplugins/util}/gl-util/buffer/index.js +0 -0
- /package/{util → webglobeplugins/util}/gl-util/draw-options/methods.js +0 -0
- /package/{util → webglobeplugins/util}/globe-default-gl-states.js +0 -0
- /package/{util → webglobeplugins/util}/helper-methods.js +0 -0
- /package/{util → webglobeplugins/util}/index.js +0 -0
- /package/{util → webglobeplugins/util}/interpolation/index.js +0 -0
- /package/{util → webglobeplugins/util}/interpolation/timetrack/index.js +0 -0
- /package/{util → webglobeplugins/util}/interpolation/timetrack/timetrack-interpolator.js +0 -0
- /package/{util → webglobeplugins/util}/interpolation/timetrack/web-worker.js +0 -0
- /package/{util → webglobeplugins/util}/picking/fence.js +0 -0
- /package/{util → webglobeplugins/util}/picking/picker-displayer.js +0 -0
- /package/{util → webglobeplugins/util}/programs/draw-from-pixel-coords.js +0 -0
- /package/{util → webglobeplugins/util}/programs/draw-texture-on-canvas.js +0 -0
- /package/{util → webglobeplugins/util}/programs/supersampletotextures.js +0 -0
- /package/{util/programs/texturetoglobe.js → webglobeplugins/util/programs/texturetoglobe_delete.js} +0 -0
- /package/{util → webglobeplugins/util}/shaderfunctions/geometrytransformations.js +0 -0
- /package/{util → webglobeplugins/util}/shaderfunctions/index.js +0 -0
- /package/{util → webglobeplugins/util}/shaderfunctions/nodata.js +0 -0
- /package/{util → webglobeplugins/util}/shaderfunctions/noisefunctions.js +0 -0
- /package/{util → webglobeplugins/util}/webglobjectbuilders.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/arrowfield/adaptor.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/arrowfield/index.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/arrowfield/plugin.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/waveparticles/adaptor.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/waveparticles/index.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/wind/adapters/types.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/wind/imagetovectorfieldandmagnitude.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/wind/index.js +0 -0
- /package/{vectorfield → webglobeplugins/vectorfield}/wind/vectorfieldimage.js +0 -0
- /package/{write-text → webglobeplugins/write-text}/context-text-bulk.js +0 -0
- /package/{write-text → webglobeplugins/write-text}/context-text3.js +0 -0
- /package/{write-text → webglobeplugins/write-text}/context-text4.js +0 -0
- /package/{write-text → webglobeplugins/write-text}/context-textDELETE.js +0 -0
- /package/{write-text → webglobeplugins/write-text}/objectarraylabels/index.js +0 -0
- /package/{write-text → webglobeplugins/write-text}/objectarraylabels/objectarraylabels.js +0 -0
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Toprak Nihat Deniz Ozturk
|
|
3
|
+
*/
|
|
1
4
|
import { BBOXGlobeShell } from "../../semiplugins/shell/bbox-renderer/index";
|
|
2
5
|
import { defaultblendfunction } from "../../util/globe-default-gl-states";
|
|
3
6
|
import { PingPongBufferManager } from "../../programs/vectorfields/pingpongbuffermanager";
|
|
@@ -5,6 +8,8 @@ import { pixelBasedMoveProgramCache } from "../../programs/vectorfields/logics/p
|
|
|
5
8
|
import { drawRectangleParticlesProgramCache } from "../../programs/vectorfields/logics/drawrectangleparticles";
|
|
6
9
|
import { FadeAwayProgramCache } from "../../programs/helpers/fadeaway";
|
|
7
10
|
import { ParticleUBO } from "../../programs/vectorfields/logics/particle-ubo";
|
|
11
|
+
import { isBoolean } from "../../util/check/typecheck";
|
|
12
|
+
import { AdaptiveOpacityAttachmentObserver, } from "../../programs/totems/attachments/adaptive-opacity";
|
|
8
13
|
/**
|
|
9
14
|
* STEPS:
|
|
10
15
|
* 1. move particle | buffers: read b1 write b2 | swap buffers b1 <-> b2
|
|
@@ -15,7 +20,31 @@ import { ParticleUBO } from "../../programs/vectorfields/logics/particle-ubo";
|
|
|
15
20
|
const MAX_PIXELS_ON_DIMENSION = 2200;
|
|
16
21
|
export default class Plugin {
|
|
17
22
|
id;
|
|
18
|
-
options
|
|
23
|
+
options = {
|
|
24
|
+
tailSize: 1.0,
|
|
25
|
+
wingSize: 7.0,
|
|
26
|
+
dataWidth: 256,
|
|
27
|
+
dataHeight: 256,
|
|
28
|
+
fadeOpacity: 0.83,
|
|
29
|
+
opacity: 0.75,
|
|
30
|
+
speed: 0.6,
|
|
31
|
+
dropRate: 0.007,
|
|
32
|
+
height: 0,
|
|
33
|
+
minLon: -180,
|
|
34
|
+
minLat: -90,
|
|
35
|
+
maxLon: 180,
|
|
36
|
+
maxLat: 90,
|
|
37
|
+
particleCount: 4000,
|
|
38
|
+
flipY: true,
|
|
39
|
+
drawTextureMaxPixelOnDimension: MAX_PIXELS_ON_DIMENSION,
|
|
40
|
+
useColorTexture: false,
|
|
41
|
+
initialColorData: null,
|
|
42
|
+
useSpeedTexture: false,
|
|
43
|
+
initialSpeedTexture: null,
|
|
44
|
+
minSpeedThreshold: 0.0,
|
|
45
|
+
maxSpeedThreshold: 150.9,
|
|
46
|
+
adaptiveOpacityOn: false,
|
|
47
|
+
};
|
|
19
48
|
globe;
|
|
20
49
|
gl;
|
|
21
50
|
moveParticle;
|
|
@@ -37,34 +66,12 @@ export default class Plugin {
|
|
|
37
66
|
_colorFieldTexture = null;
|
|
38
67
|
_initialColorFieldData = null;
|
|
39
68
|
_speedFieldTexture = null;
|
|
69
|
+
_ableToUseSpeedField = false;
|
|
40
70
|
_initialSpeedFieldData = null;
|
|
71
|
+
__adaptiveOpacity = 1;
|
|
41
72
|
constructor(id, options) {
|
|
42
73
|
this.id = id;
|
|
43
|
-
this.options = {
|
|
44
|
-
tailSize: options.tailSize || 1.0,
|
|
45
|
-
wingSize: options.wingSize || 7.0,
|
|
46
|
-
dataWidth: options.dataWidth || 256,
|
|
47
|
-
dataHeight: options.dataHeight || 256,
|
|
48
|
-
fadeOpacity: options.fadeOpacity ?? 0.83,
|
|
49
|
-
opacity: options.opacity ?? 0.75,
|
|
50
|
-
speed: options.speed ?? 0.6,
|
|
51
|
-
dropRate: options.dropRate ?? 0.007,
|
|
52
|
-
height: options.height ?? 0,
|
|
53
|
-
minLon: options.minLon ?? -180,
|
|
54
|
-
minLat: options.minLat ?? -90,
|
|
55
|
-
maxLon: options.maxLon ?? 180,
|
|
56
|
-
maxLat: options.maxLat ?? 90,
|
|
57
|
-
particleCount: options.particleCount ?? 8000,
|
|
58
|
-
flipY: options.flipY ?? true,
|
|
59
|
-
drawTextureMaxPixelOnDimension: options.drawTextureMaxPixelOnDimension ?? MAX_PIXELS_ON_DIMENSION,
|
|
60
|
-
useColorTexture: options.useColorTexture ?? false,
|
|
61
|
-
initialColorData: options.initialColorData ?? null,
|
|
62
|
-
useSpeedTexture: options.useSpeedTexture ?? false,
|
|
63
|
-
initialSpeedTexture: options.initialSpeedTexture ?? null,
|
|
64
|
-
minSpeedThreshold: options.minSpeedThreshold ?? 0.0,
|
|
65
|
-
maxSpeedThreshold: options.maxSpeedThreshold ?? 150.9,
|
|
66
|
-
};
|
|
67
|
-
console.log("WaveParticle options:", this.options);
|
|
74
|
+
this.options = { ...this.options, ...options };
|
|
68
75
|
this._drawTextureResolution = {};
|
|
69
76
|
this._globeshellparameters = {
|
|
70
77
|
minLon: this.options.minLon,
|
|
@@ -83,6 +90,12 @@ export default class Plugin {
|
|
|
83
90
|
init(globe, gl) {
|
|
84
91
|
this.globe = globe;
|
|
85
92
|
this.gl = gl;
|
|
93
|
+
if (gl.getExtension("OES_texture_float_linear")) {
|
|
94
|
+
this._ableToUseSpeedField = true;
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
console.log("unable to use OES_texture_float_linear extension, speed field texture disabled");
|
|
98
|
+
}
|
|
86
99
|
this.moveParticle = pixelBasedMoveProgramCache.getProgram(gl);
|
|
87
100
|
this.drawParticle = drawRectangleParticlesProgramCache.getProgram(gl);
|
|
88
101
|
this.fadeAway = FadeAwayProgramCache.get(gl);
|
|
@@ -91,7 +104,7 @@ export default class Plugin {
|
|
|
91
104
|
this.bufferManager = new PingPongBufferManager(gl, this.options.particleCount, inPositionLocation);
|
|
92
105
|
this._rgVectorFieldTexture = this._createRGTexture();
|
|
93
106
|
this.waveUbo = ParticleUBO.createUBO(gl);
|
|
94
|
-
if (this.options.useColorTexture) {
|
|
107
|
+
if (this.options.useColorTexture && this._ableToUseSpeedField) {
|
|
95
108
|
this.waveUbo.updateSingle("use_color_field", new Float32Array([1]));
|
|
96
109
|
if (this._initialColorFieldData) {
|
|
97
110
|
this.setColorField(this._initialColorFieldData);
|
|
@@ -102,7 +115,7 @@ export default class Plugin {
|
|
|
102
115
|
}
|
|
103
116
|
}
|
|
104
117
|
if (this.options.useSpeedTexture) {
|
|
105
|
-
this.waveUbo.updateSingle("
|
|
118
|
+
this.waveUbo.updateSingle("use_magnitude_field", new Float32Array([1]));
|
|
106
119
|
console.log("use speed texture");
|
|
107
120
|
if (this._initialSpeedFieldData) {
|
|
108
121
|
this.setSpeedField(this._initialSpeedFieldData);
|
|
@@ -121,7 +134,9 @@ export default class Plugin {
|
|
|
121
134
|
this.setDropRate(this.options.dropRate);
|
|
122
135
|
this.setHeight(this.options.height);
|
|
123
136
|
// ensure speed thresholds are applied to UBO on init
|
|
124
|
-
this.
|
|
137
|
+
this.setMinSpeedThreshold(this.options.minSpeedThreshold);
|
|
138
|
+
this.setMaxSpeedThreshold(this.options.maxSpeedThreshold);
|
|
139
|
+
this.setCycleStepCount(3);
|
|
125
140
|
this.____drawIndex = 0;
|
|
126
141
|
}
|
|
127
142
|
draw3D() {
|
|
@@ -197,6 +212,7 @@ export default class Plugin {
|
|
|
197
212
|
gl.deleteTexture(this._speedFieldTexture);
|
|
198
213
|
this._speedFieldTexture = null;
|
|
199
214
|
}
|
|
215
|
+
AdaptiveOpacityAttachmentObserver.unsubscribe(this);
|
|
200
216
|
}
|
|
201
217
|
setParticleCount(value) {
|
|
202
218
|
this.options.particleCount = value;
|
|
@@ -214,7 +230,6 @@ export default class Plugin {
|
|
|
214
230
|
const { gl } = this;
|
|
215
231
|
if (!gl || !this._rgVectorFieldTexture)
|
|
216
232
|
return;
|
|
217
|
-
console.log("flipY:", this.options.flipY);
|
|
218
233
|
gl.bindTexture(gl.TEXTURE_2D, this._rgVectorFieldTexture);
|
|
219
234
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.options.flipY);
|
|
220
235
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RG32F, this.options.dataWidth, this.options.dataHeight, 0, gl.RG, gl.FLOAT, data);
|
|
@@ -255,7 +270,8 @@ export default class Plugin {
|
|
|
255
270
|
console.error("Opacity must be a number between 0 and 1");
|
|
256
271
|
return;
|
|
257
272
|
}
|
|
258
|
-
this.
|
|
273
|
+
this.options.opacity = value;
|
|
274
|
+
this.globeShellWiggle?.setOpacity(value * this.__adaptiveOpacity);
|
|
259
275
|
}
|
|
260
276
|
setParticleDimensions(tail, wing) {
|
|
261
277
|
if (0 < tail && 0 < wing) {
|
|
@@ -293,12 +309,21 @@ export default class Plugin {
|
|
|
293
309
|
gl.bindTexture(gl.TEXTURE_2D, this._colorFieldTexture);
|
|
294
310
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.options.flipY);
|
|
295
311
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.options.dataWidth, this.options.dataHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);
|
|
296
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.
|
|
297
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.
|
|
312
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
313
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
298
314
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
299
315
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
300
316
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
301
317
|
}
|
|
318
|
+
setUseSpeedField(use) {
|
|
319
|
+
isBoolean(use);
|
|
320
|
+
if (!this.waveUbo) {
|
|
321
|
+
console.warn("UBO is not initialized yet.");
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
this.options.useSpeedTexture = use;
|
|
325
|
+
this.waveUbo.updateSingle("use_magnitude_field", new Float32Array([use ? 1 : 0]));
|
|
326
|
+
}
|
|
302
327
|
setSpeedField(data) {
|
|
303
328
|
const { gl } = this;
|
|
304
329
|
if (!gl)
|
|
@@ -318,8 +343,8 @@ export default class Plugin {
|
|
|
318
343
|
gl.bindTexture(gl.TEXTURE_2D, this._speedFieldTexture);
|
|
319
344
|
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, this.options.flipY);
|
|
320
345
|
gl.texImage2D(gl.TEXTURE_2D, 0, gl.R32F, this.options.dataWidth, this.options.dataHeight, 0, gl.RED, gl.FLOAT, data);
|
|
321
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.
|
|
322
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.
|
|
346
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
|
347
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
323
348
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
324
349
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
325
350
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
@@ -329,11 +354,12 @@ export default class Plugin {
|
|
|
329
354
|
*/
|
|
330
355
|
setMinSpeedThreshold(value) {
|
|
331
356
|
this.options.minSpeedThreshold = value;
|
|
332
|
-
this.waveUbo?.updateSingle("
|
|
357
|
+
this.waveUbo?.updateSingle("min_magnitude_threshold", new Float32Array([value]));
|
|
333
358
|
}
|
|
334
359
|
setMaxSpeedThreshold(value) {
|
|
360
|
+
console.log("setMaxSpeedThreshold called with value:", value);
|
|
335
361
|
this.options.maxSpeedThreshold = value;
|
|
336
|
-
this.waveUbo?.updateSingle("
|
|
362
|
+
this.waveUbo?.updateSingle("max_magnitude_threshold", new Float32Array([value]));
|
|
337
363
|
}
|
|
338
364
|
setSpeedThresholds(min, max) {
|
|
339
365
|
this.setMinSpeedThreshold(min);
|
|
@@ -358,6 +384,10 @@ export default class Plugin {
|
|
|
358
384
|
this._rgVectorFieldTexture = this._createRGTexture();
|
|
359
385
|
this.setVectorFieldData(textureData);
|
|
360
386
|
}
|
|
387
|
+
__adaptiveOpacity_set(value) {
|
|
388
|
+
this.__adaptiveOpacity = value;
|
|
389
|
+
this.globeShellWiggle?.setOpacity(this.options.opacity * this.__adaptiveOpacity);
|
|
390
|
+
}
|
|
361
391
|
_drawTextureSizeFromBbox({ minLon, minLat, maxLon, maxLat }) {
|
|
362
392
|
let horizon;
|
|
363
393
|
if (minLon > 0 && maxLon < 0) {
|
|
@@ -409,6 +439,16 @@ export default class Plugin {
|
|
|
409
439
|
gl.bindTexture(gl.TEXTURE_2D, null);
|
|
410
440
|
return texture;
|
|
411
441
|
}
|
|
442
|
+
setAdaptiveOpacityOn(value) {
|
|
443
|
+
isBoolean(value);
|
|
444
|
+
this.options.adaptiveOpacityOn = value;
|
|
445
|
+
if (value) {
|
|
446
|
+
AdaptiveOpacityAttachmentObserver.subscribe(this);
|
|
447
|
+
}
|
|
448
|
+
else {
|
|
449
|
+
AdaptiveOpacityAttachmentObserver.unsubscribe(this);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
412
452
|
_step() {
|
|
413
453
|
this._stepIndex = (this._stepIndex + 1) % this._fullCycleStepCount;
|
|
414
454
|
}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Toprak Nihat Deniz Ozturk
|
|
3
|
+
*/
|
|
1
4
|
export function imageToFields(data, legendData) {
|
|
2
5
|
const { image, uMin, vMin, uMax, vMax } = data;
|
|
3
6
|
const width = image.width;
|
|
@@ -33,27 +36,55 @@ export function imageToFields(data, legendData) {
|
|
|
33
36
|
const r = imageData.data[index];
|
|
34
37
|
const g = imageData.data[index + 1];
|
|
35
38
|
// Map texel [0,255] to actual speed values [uMin,uMax] and [vMin,vMax]
|
|
36
|
-
const uSpeed = uMin + (r / 255) * uDiff;
|
|
37
|
-
const vSpeed = vMin + (g / 255) * vDiff;
|
|
38
|
-
// Normalize to [-1,1] range for vector field
|
|
39
39
|
const u = uMin + (uDiff * r) / 255;
|
|
40
40
|
const v = vMin + (vDiff * g) / 255;
|
|
41
|
+
const speed = Math.sqrt(u * u + v * v);
|
|
42
|
+
speedFieldData[y * width + x] = speed;
|
|
41
43
|
vectorFieldData[(y * width + x) * 2] = u / scaler;
|
|
42
44
|
vectorFieldData[(y * width + x) * 2 + 1] = -v / scaler;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
let
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
45
|
+
// Determine color via linear interpolation between thresholds
|
|
46
|
+
const thresholds = legendData.thresholds;
|
|
47
|
+
const n = Math.min(thresholds.length, parsedColors.length);
|
|
48
|
+
let outR = 0, outG = 0, outB = 0;
|
|
49
|
+
if (n === 0) {
|
|
50
|
+
outR = outG = outB = 0;
|
|
51
|
+
}
|
|
52
|
+
else if (n === 1 || speed <= thresholds[0]) {
|
|
53
|
+
outR = parsedColors[0].r;
|
|
54
|
+
outG = parsedColors[0].g;
|
|
55
|
+
outB = parsedColors[0].b;
|
|
56
|
+
}
|
|
57
|
+
else if (speed >= thresholds[n - 1]) {
|
|
58
|
+
outR = parsedColors[n - 1].r;
|
|
59
|
+
outG = parsedColors[n - 1].g;
|
|
60
|
+
outB = parsedColors[n - 1].b;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
let i = 0;
|
|
64
|
+
for (; i < n - 1; i++) {
|
|
65
|
+
if (speed < thresholds[i + 1])
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
if (i === n - 1) {
|
|
69
|
+
// set to last color
|
|
70
|
+
outR = parsedColors[n - 1].r;
|
|
71
|
+
outG = parsedColors[n - 1].g;
|
|
72
|
+
outB = parsedColors[n - 1].b;
|
|
73
|
+
continue;
|
|
51
74
|
}
|
|
75
|
+
const t0 = thresholds[i];
|
|
76
|
+
const t1 = thresholds[i + 1];
|
|
77
|
+
const denom = t1 - t0 || 1;
|
|
78
|
+
const t = Math.max(0, Math.min(1, (speed - t0) / denom));
|
|
79
|
+
const c0 = parsedColors[i];
|
|
80
|
+
const c1 = parsedColors[i + 1];
|
|
81
|
+
outR = Math.round(c0.r + (c1.r - c0.r) * t);
|
|
82
|
+
outG = Math.round(c0.g + (c1.g - c0.g) * t);
|
|
83
|
+
outB = Math.round(c0.b + (c1.b - c0.b) * t);
|
|
52
84
|
}
|
|
53
|
-
|
|
54
|
-
colorFieldData[index] =
|
|
55
|
-
colorFieldData[index +
|
|
56
|
-
colorFieldData[index + 2] = color.b;
|
|
85
|
+
colorFieldData[index] = outR;
|
|
86
|
+
colorFieldData[index + 1] = outG;
|
|
87
|
+
colorFieldData[index + 2] = outB;
|
|
57
88
|
colorFieldData[index + 3] = 255; // Alpha channel
|
|
58
89
|
}
|
|
59
90
|
}
|
|
@@ -43,6 +43,7 @@ export default class WindPlugin {
|
|
|
43
43
|
_dropRate;
|
|
44
44
|
texturePointSampler;
|
|
45
45
|
texturePointSamplerAngle;
|
|
46
|
+
adaptiveOpacityOn = false;
|
|
46
47
|
/**
|
|
47
48
|
* @param id - Plugin identifier
|
|
48
49
|
* @param windDataMeta - Wind data metadata
|
|
@@ -68,18 +69,19 @@ export default class WindPlugin {
|
|
|
68
69
|
this.windMetadata = windDataMeta;
|
|
69
70
|
this._legendData = options.legendData || windyLegendData;
|
|
70
71
|
this.options = {
|
|
71
|
-
fadeOpacity: options.fadeOpacity ?? 0.
|
|
72
|
-
speedFactor: options.speedFactor ??
|
|
73
|
-
dropRate: options.dropRate ?? 0.
|
|
74
|
-
dropRateBump: options.dropRateBump ?? 0.001,
|
|
72
|
+
fadeOpacity: options.fadeOpacity ?? 0.91,
|
|
73
|
+
speedFactor: options.speedFactor ?? 1,
|
|
74
|
+
dropRate: options.dropRate ?? 0.06,
|
|
75
|
+
// dropRateBump: options.dropRateBump ?? 0.001,
|
|
75
76
|
baseOpacity: options.baseOpacity ?? 1.0,
|
|
76
|
-
wingSize: options.wingSize ??
|
|
77
|
-
tailSize: options.tailSize ??
|
|
77
|
+
wingSize: options.wingSize ?? 2.0,
|
|
78
|
+
tailSize: options.tailSize ?? 10.0,
|
|
78
79
|
minSpeed: options.minSpeed ?? 0.0,
|
|
79
80
|
maxSpeed: options.maxSpeed ?? 1000.0,
|
|
80
81
|
height: options.height ?? 0.0,
|
|
81
82
|
numParticles: options.numParticles ?? 40000,
|
|
82
|
-
legendData: this._legendData
|
|
83
|
+
legendData: this._legendData,
|
|
84
|
+
adaptiveOpacityOn: options.adaptiveOpacityOn ?? false
|
|
83
85
|
};
|
|
84
86
|
this.windData = null;
|
|
85
87
|
this._height = this.options.height;
|
|
@@ -106,7 +108,7 @@ export default class WindPlugin {
|
|
|
106
108
|
maxLat: bbox[3] > 85 ? 85 : bbox[3],
|
|
107
109
|
particleCount: this.options.numParticles,
|
|
108
110
|
flipY: flipY ?? true,
|
|
109
|
-
useColorTexture:
|
|
111
|
+
useColorTexture: true, // TODO: under test.. make it true later
|
|
110
112
|
useSpeedTexture: true,
|
|
111
113
|
minSpeedThreshold: this.options.minSpeed,
|
|
112
114
|
maxSpeedThreshold: this.options.maxSpeed,
|
|
@@ -197,11 +199,17 @@ export default class WindPlugin {
|
|
|
197
199
|
}
|
|
198
200
|
setFlipY(flipY) {
|
|
199
201
|
isBoolean(flipY);
|
|
200
|
-
this.windMetadata.flipY = flipY;
|
|
201
202
|
if (this.particlePlugin && this.windData) {
|
|
203
|
+
this.windMetadata.flipY = flipY;
|
|
202
204
|
this.setWind(this.windData);
|
|
203
205
|
}
|
|
204
206
|
}
|
|
207
|
+
setUseSpeedField(use) {
|
|
208
|
+
if (this.particlePlugin) {
|
|
209
|
+
console.log("use speed field set to ", use);
|
|
210
|
+
this.particlePlugin.setUseSpeedField(use);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
205
213
|
setDrawTextureMaxPixelOnDimension(value) {
|
|
206
214
|
if (this.particlePlugin) {
|
|
207
215
|
this.particlePlugin.setDrawTextureMaxPixelOnDimension(value);
|
|
@@ -220,6 +228,7 @@ export default class WindPlugin {
|
|
|
220
228
|
set minSpeed(value) {
|
|
221
229
|
this.options.minSpeed = value;
|
|
222
230
|
if (this.particlePlugin) {
|
|
231
|
+
console.log("value", value);
|
|
223
232
|
this.particlePlugin.setMinSpeedThreshold(value);
|
|
224
233
|
}
|
|
225
234
|
}
|
|
@@ -262,14 +271,6 @@ export default class WindPlugin {
|
|
|
262
271
|
get dropRate() {
|
|
263
272
|
return this._dropRate;
|
|
264
273
|
}
|
|
265
|
-
set dropRateBump(value) {
|
|
266
|
-
this.options.dropRateBump = value;
|
|
267
|
-
// Note: ParticlePlugin doesn't have dropRateBump parameter
|
|
268
|
-
// This would need to be added to ParticlePlugin if needed
|
|
269
|
-
}
|
|
270
|
-
get dropRateBump() {
|
|
271
|
-
return this.options.dropRateBump;
|
|
272
|
-
}
|
|
273
274
|
set baseOpacity(value) {
|
|
274
275
|
this.options.baseOpacity = value;
|
|
275
276
|
if (this.particlePlugin) {
|
|
@@ -288,6 +289,13 @@ export default class WindPlugin {
|
|
|
288
289
|
get numParticles() {
|
|
289
290
|
return this.options.numParticles;
|
|
290
291
|
}
|
|
292
|
+
set adaptiveOpacity(value) {
|
|
293
|
+
this.adaptiveOpacityOn = value;
|
|
294
|
+
this.particlePlugin.setAdaptiveOpacityOn(value);
|
|
295
|
+
}
|
|
296
|
+
get adaptiveOpacity() {
|
|
297
|
+
return this.adaptiveOpacityOn;
|
|
298
|
+
}
|
|
291
299
|
/**
|
|
292
300
|
* Set wing and tail size for particle arrows
|
|
293
301
|
*/
|
|
@@ -322,6 +330,13 @@ export default class WindPlugin {
|
|
|
322
330
|
// Update metadata
|
|
323
331
|
this.windMetadata.bbox = [bbox.minLon, bbox.minLat, bbox.maxLon, bbox.maxLat];
|
|
324
332
|
}
|
|
333
|
+
setAdaptiveOpacityOn(value) {
|
|
334
|
+
isBoolean(value);
|
|
335
|
+
this.adaptiveOpacityOn = value;
|
|
336
|
+
if (this.particlePlugin) {
|
|
337
|
+
this.particlePlugin.setAdaptiveOpacityOn(value);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
325
340
|
// ===== Texture Point Sampler (for backward compatibility) =====
|
|
326
341
|
/**
|
|
327
342
|
* Get texture point sampler for magnitude or angle
|
|
@@ -504,20 +504,20 @@ export default class WindPlugin {
|
|
|
504
504
|
const windDataMeta = this._windDataMeta;
|
|
505
505
|
const gl = this.gl;
|
|
506
506
|
this.windData = windData;
|
|
507
|
-
this.windTexture = createTexture(gl, gl.
|
|
507
|
+
this.windTexture = createTexture(gl, gl.NEAREST, windData.image);
|
|
508
508
|
const currentProgram = gl.getParameter(gl.CURRENT_PROGRAM);
|
|
509
509
|
gl.useProgram(this.updateProgram.program);
|
|
510
510
|
gl.uniform2f(this.updateProgram.u_wind_res, windDataMeta.width, windDataMeta.height);
|
|
511
511
|
gl.uniform2f(this.updateProgram.u_wind_min, this.windData.uMin, this.windData.vMin);
|
|
512
512
|
gl.uniform2f(this.updateProgram.u_wind_max, this.windData.uMax, this.windData.vMax);
|
|
513
513
|
this.setGeometry();
|
|
514
|
-
console.log("windData bbox", windData.bbox);
|
|
515
514
|
const minXY = this._latLongToPixelXY(windDataMeta.bbox[1], windDataMeta.bbox[0]);
|
|
516
515
|
const maxXY = this._latLongToPixelXY(windDataMeta.bbox[3], windDataMeta.bbox[2]);
|
|
517
516
|
this._loadBoundingBoxData(minXY.x, minXY.y, maxXY.x, maxXY.y);
|
|
518
517
|
gl.useProgram(currentProgram);
|
|
519
518
|
this._setCoorcinatesDataCalculatorData();
|
|
520
|
-
this.resize();
|
|
519
|
+
// this.resize();
|
|
520
|
+
this.globe.DrawRender();
|
|
521
521
|
}
|
|
522
522
|
// Vector field texture is used to calculate the particle movement.
|
|
523
523
|
/**
|
|
@@ -757,7 +757,7 @@ export default class WindPlugin {
|
|
|
757
757
|
alert("Geometry is not supported");
|
|
758
758
|
}
|
|
759
759
|
gl.useProgram(currentProgram);
|
|
760
|
-
this.resize();
|
|
760
|
+
// this.resize();
|
|
761
761
|
}
|
|
762
762
|
_updateParticles() {
|
|
763
763
|
const gl = this.gl;
|
|
@@ -1,100 +0,0 @@
|
|
|
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
|
-
import { haversine } from "../../../../Math/haversine";
|
|
12
|
-
import earcut from "earcut";
|
|
13
|
-
/**
|
|
14
|
-
*
|
|
15
|
-
*/
|
|
16
|
-
function __pointsInBetweenGreateCircle(lat1, lon1, lat2, lon2, unitSphereDistance) {
|
|
17
|
-
const points = [];
|
|
18
|
-
const d1 = haversine(lat1, lon1, lat2, lon2);
|
|
19
|
-
if (d1 <= unitSphereDistance) {
|
|
20
|
-
return null;
|
|
21
|
-
}
|
|
22
|
-
const numSegments = Math.ceil(d1 / unitSphereDistance);
|
|
23
|
-
for (let i = 1; i < numSegments; i++) {
|
|
24
|
-
const f = i / numSegments;
|
|
25
|
-
const A = Math.sin((1 - f) * d1) / Math.sin(d1);
|
|
26
|
-
const B = Math.sin(f * d1) / Math.sin(d1);
|
|
27
|
-
const x = A * Math.cos(lat1) * Math.cos(lon1) + B * Math.cos(lat2) * Math.cos(lon2);
|
|
28
|
-
const y = A * Math.cos(lat1) * Math.sin(lon1) + B * Math.cos(lat2) * Math.sin(lon2);
|
|
29
|
-
const z = A * Math.sin(lat1) + B * Math.sin(lat2);
|
|
30
|
-
const latN = Math.atan2(z, Math.sqrt(x * x + y * y));
|
|
31
|
-
const lonN = Math.atan2(y, x);
|
|
32
|
-
points.push(latN, lonN);
|
|
33
|
-
}
|
|
34
|
-
return points;
|
|
35
|
-
}
|
|
36
|
-
function _dividePolygonEdgeSize(polygon, kmThreshold) {
|
|
37
|
-
const unitSphereDistance = kmThreshold / 6371; // Earth radius in km
|
|
38
|
-
const newGeometries = polygon.geometry.map(geom => {
|
|
39
|
-
const { vertices, holes } = geom;
|
|
40
|
-
const newVertices = [];
|
|
41
|
-
const newHoles = [];
|
|
42
|
-
const processRing = (start, end) => {
|
|
43
|
-
for (let i = start; i < end; i++) {
|
|
44
|
-
const long1 = vertices[2 * i];
|
|
45
|
-
const lat1 = vertices[2 * i + 1];
|
|
46
|
-
const next_i = (i + 1 < end) ? i + 1 : start;
|
|
47
|
-
const long2 = vertices[2 * next_i];
|
|
48
|
-
const lat2 = vertices[2 * next_i + 1];
|
|
49
|
-
newVertices.push(long1, lat1);
|
|
50
|
-
const extraPoints = __pointsInBetweenGreateCircle(lat1, long1, lat2, long2, unitSphereDistance);
|
|
51
|
-
if (extraPoints) {
|
|
52
|
-
newVertices.push(...extraPoints);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
const shellEnd = holes.length > 0 ? holes[0] : vertices.length / 2;
|
|
57
|
-
processRing(0, shellEnd);
|
|
58
|
-
for (let h = 0; h < holes.length; h++) {
|
|
59
|
-
newHoles.push(newVertices.length / 2);
|
|
60
|
-
const holeStart = holes[h];
|
|
61
|
-
const holeEnd = h + 1 < holes.length ? holes[h + 1] : vertices.length / 2;
|
|
62
|
-
processRing(holeStart, holeEnd);
|
|
63
|
-
}
|
|
64
|
-
return { vertices: newVertices, holes: newHoles };
|
|
65
|
-
});
|
|
66
|
-
return {
|
|
67
|
-
...polygon,
|
|
68
|
-
geometry: newGeometries,
|
|
69
|
-
};
|
|
70
|
-
}
|
|
71
|
-
// TODO:
|
|
72
|
-
// divide TrianglesMiddleData edges longer than threshold
|
|
73
|
-
// function _divideTriangleEdges(
|
|
74
|
-
// key: string,
|
|
75
|
-
// vertices: number[],
|
|
76
|
-
// indices: number[],
|
|
77
|
-
// kmThreshold: number // maybe
|
|
78
|
-
// ): TrianglesMiddleData {
|
|
79
|
-
// return { key, vertices, indices };
|
|
80
|
-
// }
|
|
81
|
-
// TODO: NEED TEST
|
|
82
|
-
function triangulation(polygon, kmThreshold) {
|
|
83
|
-
const finalVertices = [];
|
|
84
|
-
const finalIndices = [];
|
|
85
|
-
let vertexIndexOffset = 0;
|
|
86
|
-
for (const geom of polygon.geometry) {
|
|
87
|
-
const indices = earcut(geom.vertices, geom.holes, 2);
|
|
88
|
-
finalVertices.push(...geom.vertices);
|
|
89
|
-
for (const index of indices) {
|
|
90
|
-
finalIndices.push(index + vertexIndexOffset);
|
|
91
|
-
}
|
|
92
|
-
vertexIndexOffset += geom.vertices.length / 2;
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
key: polygon.key,
|
|
96
|
-
vertices: finalVertices,
|
|
97
|
-
indices: finalIndices
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
export { triangulation };
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
/// <reference lib="webworker" />
|
|
2
|
-
import { Cache } from "./cache";
|
|
3
|
-
import { partialTessellation, zoomLevelShowThreshold } from "../../../../Math/tessellation/triangle-tessellation";
|
|
4
|
-
import { IndexAttributeEscapeValue } from "../../../../programs/polygon-on-globe/texture-dem-triangles";
|
|
5
|
-
const cache = new Cache(100); // 100 km threshold
|
|
6
|
-
let _pickableState = false;
|
|
7
|
-
let _variativeColorsOnState = false;
|
|
8
|
-
let showThreshold = 0;
|
|
9
|
-
// eslint-disable-next-line no-restricted-globals
|
|
10
|
-
self.onmessage = (event) => {
|
|
11
|
-
try {
|
|
12
|
-
const { bboxes, insertDeleteQueue, pickableState, variativeColorsOn } = event.data;
|
|
13
|
-
if (variativeColorsOn !== undefined) {
|
|
14
|
-
_variativeColorsOnState = variativeColorsOn;
|
|
15
|
-
}
|
|
16
|
-
if (pickableState !== undefined) {
|
|
17
|
-
_pickableState = pickableState;
|
|
18
|
-
}
|
|
19
|
-
// Process insert/delete queue
|
|
20
|
-
if (insertDeleteQueue[0] === "__CLEAR_ALL_ITEMS__") {
|
|
21
|
-
insertDeleteQueue.shift();
|
|
22
|
-
cache.clear();
|
|
23
|
-
}
|
|
24
|
-
for (const item of insertDeleteQueue) {
|
|
25
|
-
if (typeof item === 'string') {
|
|
26
|
-
cache.remove(item);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
cache.insert(item.key, item);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
// Update bboxes if provided
|
|
33
|
-
if (bboxes) {
|
|
34
|
-
cache.setBBOXes(bboxes);
|
|
35
|
-
showThreshold = zoomLevelShowThreshold(bboxes[0].zoom, 0.03);
|
|
36
|
-
}
|
|
37
|
-
// Search for triangles in view
|
|
38
|
-
const trianglesInView = cache.search();
|
|
39
|
-
// Prepare arrays for merging
|
|
40
|
-
const results = [];
|
|
41
|
-
// Convert bbox to BBoxZoom format for partialTessellation
|
|
42
|
-
const bboxZooms = bboxes ? bboxes.map(b => ({
|
|
43
|
-
bbox: {
|
|
44
|
-
min: [b.minX, b.minY],
|
|
45
|
-
max: [b.maxX, b.maxY]
|
|
46
|
-
},
|
|
47
|
-
zoom: b.zoom
|
|
48
|
-
})) : []; // This will be empty if no bbox, causing issues
|
|
49
|
-
let counter = 0;
|
|
50
|
-
let indexCounter = 0;
|
|
51
|
-
// Process each triangle
|
|
52
|
-
for (const triangle of trianglesInView) {
|
|
53
|
-
if (triangle.tessellationMeta.showThreshold * 0.075 > showThreshold) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const result = (triangle.tessellationMeta.showThreshold < showThreshold) ? partialTessellation(triangle.tessellationMeta, bboxZooms, 5 // innerCuts parameter
|
|
57
|
-
) : triangle.tessellationMeta.shortCut;
|
|
58
|
-
counter += result.vec3s.length;
|
|
59
|
-
indexCounter += result.indices.length;
|
|
60
|
-
if (_pickableState) {
|
|
61
|
-
// TODO: find a better way to fill indeces to final array
|
|
62
|
-
result.pickIndex = triangle.polygon.index;
|
|
63
|
-
}
|
|
64
|
-
if (_variativeColorsOnState) {
|
|
65
|
-
const color = triangle.polygon.color || [IndexAttributeEscapeValue, IndexAttributeEscapeValue, IndexAttributeEscapeValue, IndexAttributeEscapeValue];
|
|
66
|
-
result.variativeColors = color;
|
|
67
|
-
// Update offset for next triangle
|
|
68
|
-
}
|
|
69
|
-
results.push(result);
|
|
70
|
-
}
|
|
71
|
-
// Send results back
|
|
72
|
-
const output = {
|
|
73
|
-
vec3s: new Float32Array(counter),
|
|
74
|
-
longLats: new Float32Array(counter / 3 * 2),
|
|
75
|
-
indices: new Uint32Array(indexCounter),
|
|
76
|
-
};
|
|
77
|
-
if (_pickableState) {
|
|
78
|
-
output.pickIndices = new Float32Array(counter / 3);
|
|
79
|
-
}
|
|
80
|
-
if (_variativeColorsOnState) {
|
|
81
|
-
output.variativeColors = new Float32Array(counter / 3 * 4);
|
|
82
|
-
}
|
|
83
|
-
let currentVertexOffset = 0;
|
|
84
|
-
let indexOffset = 0;
|
|
85
|
-
for (const result of results) {
|
|
86
|
-
output.vec3s.set(result.vec3s, currentVertexOffset);
|
|
87
|
-
output.longLats.set(result.longLats, (currentVertexOffset / 3) * 2);
|
|
88
|
-
output.indices.set(result.indices.map(i => i + currentVertexOffset / 3), indexOffset);
|
|
89
|
-
currentVertexOffset += result.vec3s.length;
|
|
90
|
-
indexOffset += result.indices.length;
|
|
91
|
-
if (_pickableState) {
|
|
92
|
-
const subArray = output.pickIndices.subarray(currentVertexOffset / 3 - result.vec3s.length / 3, currentVertexOffset / 3);
|
|
93
|
-
subArray.fill(result.pickIndex);
|
|
94
|
-
}
|
|
95
|
-
if (_variativeColorsOnState && result.variativeColors) {
|
|
96
|
-
const vertexCount = result.vec3s.length / 3;
|
|
97
|
-
const colorStartIndex = (currentVertexOffset / 3 - vertexCount) * 4;
|
|
98
|
-
for (let i = 0; i < vertexCount; i++) {
|
|
99
|
-
const offset = colorStartIndex + i * 4;
|
|
100
|
-
output.variativeColors[offset] = result.variativeColors[0];
|
|
101
|
-
output.variativeColors[offset + 1] = result.variativeColors[1];
|
|
102
|
-
output.variativeColors[offset + 2] = result.variativeColors[2];
|
|
103
|
-
output.variativeColors[offset + 3] = result.variativeColors[3];
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
const buffers = [
|
|
108
|
-
output.vec3s.buffer,
|
|
109
|
-
output.indices.buffer,
|
|
110
|
-
output.longLats.buffer,
|
|
111
|
-
];
|
|
112
|
-
if (pickableState && output.pickIndices) {
|
|
113
|
-
buffers.push(output.pickIndices.buffer);
|
|
114
|
-
}
|
|
115
|
-
if (_variativeColorsOnState && output.variativeColors) {
|
|
116
|
-
buffers.push(output.variativeColors.buffer);
|
|
117
|
-
}
|
|
118
|
-
// eslint-disable-next-line no-restricted-globals
|
|
119
|
-
self.postMessage(output, buffers);
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
console.error('Error in worker:', error);
|
|
123
|
-
// self.postMessage({ error: error.message || 'Unknown error in worker' });
|
|
124
|
-
}
|
|
125
|
-
};
|