@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
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { noRegisterGlobeProgramCache } from "../../programcache";
|
|
2
|
+
import { CameraUniformBlockTotemCache } from "../camerauniformblock";
|
|
3
|
+
const epsilon = 0.1;
|
|
4
|
+
export function createSmoothstepOpacityPolicy(minZoom = 4, maxZoom = 12) {
|
|
5
|
+
const denom = maxZoom - minZoom;
|
|
6
|
+
if (!Number.isFinite(denom) || denom === 0) {
|
|
7
|
+
throw new Error("createSmoothstepOpacityPolicy: invalid zoom range");
|
|
8
|
+
}
|
|
9
|
+
const smoothstep = (x) => x * x * (3 - 2 * x);
|
|
10
|
+
return (zoomLevel) => {
|
|
11
|
+
const t = (zoomLevel - minZoom) / denom;
|
|
12
|
+
const c = Math.min(1, Math.max(0, t));
|
|
13
|
+
return 1 - smoothstep(c);
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Hysteresis policy: reduces flicker by using separate enter/exit zooms.
|
|
18
|
+
* Example: fade-in begins at enterStart, but won’t fade-out until exitEnd.
|
|
19
|
+
*/
|
|
20
|
+
export function createHysteresisOpacityPolicy(params) {
|
|
21
|
+
const { enterStart, enterEnd, exitStart, exitEnd } = params;
|
|
22
|
+
if (!(exitEnd <= exitStart && exitStart <= enterStart && enterStart <= enterEnd)) {
|
|
23
|
+
throw new Error("createHysteresisOpacityPolicy: expected exitEnd <= exitStart <= enterStart <= enterEnd");
|
|
24
|
+
}
|
|
25
|
+
const lerp01 = (x, a, b) => {
|
|
26
|
+
if (a === b)
|
|
27
|
+
return x >= b ? 1 : 0;
|
|
28
|
+
const t = (x - a) / (b - a);
|
|
29
|
+
return Math.min(1, Math.max(0, t));
|
|
30
|
+
};
|
|
31
|
+
return (zoomLevel, prevOpacity) => {
|
|
32
|
+
// If we were mostly “off”, only allow rising once we hit the enter band.
|
|
33
|
+
if (prevOpacity <= 0.5) {
|
|
34
|
+
if (zoomLevel <= exitStart)
|
|
35
|
+
return lerp01(zoomLevel, exitEnd, exitStart) * 0; // clamp to 0 band
|
|
36
|
+
if (zoomLevel < enterStart)
|
|
37
|
+
return 0;
|
|
38
|
+
return lerp01(zoomLevel, enterStart, enterEnd);
|
|
39
|
+
}
|
|
40
|
+
// If we were mostly “on”, only allow falling once we hit the exit band.
|
|
41
|
+
if (zoomLevel >= enterStart)
|
|
42
|
+
return lerp01(zoomLevel, enterStart, enterEnd);
|
|
43
|
+
if (zoomLevel > exitStart)
|
|
44
|
+
return 1;
|
|
45
|
+
// decreasing band
|
|
46
|
+
return 1 - lerp01(zoomLevel, exitEnd, exitStart);
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Curve policy: caller supplies any curve f(t) where t is normalized [0..1].
|
|
51
|
+
* This is the most flexible option (e.g., gamma, custom spline, etc.).
|
|
52
|
+
*/
|
|
53
|
+
export function createCurveOpacityPolicy(params) {
|
|
54
|
+
const { minZoom, maxZoom, curve } = params;
|
|
55
|
+
const denom = maxZoom - minZoom;
|
|
56
|
+
if (!Number.isFinite(denom) || denom === 0) {
|
|
57
|
+
throw new Error("createCurveOpacityPolicy: invalid zoom range");
|
|
58
|
+
}
|
|
59
|
+
return (zoomLevel) => {
|
|
60
|
+
const t = (zoomLevel - minZoom) / denom;
|
|
61
|
+
const c = Math.min(1, Math.max(0, t));
|
|
62
|
+
const y = curve(c);
|
|
63
|
+
return Math.min(1, Math.max(0, y));
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
class AdaptiveOpacityAttachment {
|
|
67
|
+
globe;
|
|
68
|
+
cameraUniformBlock;
|
|
69
|
+
lastZoomLevel = -1;
|
|
70
|
+
isChangedFlag = false;
|
|
71
|
+
registry = new Map();
|
|
72
|
+
defaultAdaptiveOpacityPolicy = createSmoothstepOpacityPolicy(5.5, 7);
|
|
73
|
+
constructor(globe) {
|
|
74
|
+
this.globe = globe;
|
|
75
|
+
this.cameraUniformBlock = CameraUniformBlockTotemCache.get(this.globe);
|
|
76
|
+
this.cameraUniformBlock.registerAttachment(this);
|
|
77
|
+
}
|
|
78
|
+
update() {
|
|
79
|
+
const zoomLevel = this.globe.api_GetCurrentLODWithDecimal();
|
|
80
|
+
if (epsilon > Math.abs(this.lastZoomLevel - zoomLevel)) {
|
|
81
|
+
this._setIsChanged(false);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
;
|
|
85
|
+
this._setIsChanged(true);
|
|
86
|
+
this.lastZoomLevel = zoomLevel;
|
|
87
|
+
this.registry.forEach((plugin) => {
|
|
88
|
+
plugin.__adaptiveOpacity_set((plugin.__adaptivePolicy || this.defaultAdaptiveOpacityPolicy)(zoomLevel, plugin.__adaptiveOpacity));
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
registerPlugin(plugin) {
|
|
92
|
+
if (this.registry.has(plugin.id)) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
this.registry.set(plugin.id, plugin);
|
|
96
|
+
plugin.__adaptiveOpacity_set((plugin.__adaptivePolicy ||
|
|
97
|
+
this.defaultAdaptiveOpacityPolicy)(this.lastZoomLevel));
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
unregisterPlugin(plugin) {
|
|
101
|
+
if (!this.registry.has(plugin.id)) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
this.registry.delete(plugin.id);
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
_setIsChanged(value) {
|
|
108
|
+
this.isChangedFlag = value;
|
|
109
|
+
}
|
|
110
|
+
get isChanged() {
|
|
111
|
+
return this.isChangedFlag;
|
|
112
|
+
}
|
|
113
|
+
free() {
|
|
114
|
+
this.cameraUniformBlock.unregisterAttachment(this);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
export const AdaptiveOpacityAttachmentObserver = Object.freeze({
|
|
118
|
+
subscribe: (subscriber) => {
|
|
119
|
+
const attachment = noRegisterGlobeProgramCache.getProgram(subscriber.globe, AdaptiveOpacityAttachment);
|
|
120
|
+
if (!attachment.registerPlugin(subscriber)) {
|
|
121
|
+
noRegisterGlobeProgramCache.releaseProgram(subscriber.globe, AdaptiveOpacityAttachment);
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
unsubscribe: (subscriber) => {
|
|
125
|
+
const attachment = noRegisterGlobeProgramCache.getProgram(subscriber.globe, AdaptiveOpacityAttachment);
|
|
126
|
+
if (attachment.unregisterPlugin(subscriber)) {
|
|
127
|
+
subscriber.__adaptiveOpacity_set(1);
|
|
128
|
+
noRegisterGlobeProgramCache.releaseProgram(subscriber.globe, AdaptiveOpacityAttachment);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
package/{programs/totems → webglobeplugins/programs/totems/attachments}/dem-textures-manager.js
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { mergeMeshes } from "
|
|
2
|
-
import { globeBBoxToXYBBOX } from "
|
|
3
|
-
import { noRegisterGlobeProgramCache } from "
|
|
4
|
-
import { CameraUniformBlockTotemCache } from "
|
|
1
|
+
import { mergeMeshes } from "../../../Math/tessellation/tile-merger";
|
|
2
|
+
import { globeBBoxToXYBBOX } from "../../../Math/methods";
|
|
3
|
+
import { noRegisterGlobeProgramCache } from "../../programcache";
|
|
4
|
+
import { CameraUniformBlockTotemCache } from "../camerauniformblock";
|
|
5
5
|
export const DEM_TEXTURE_BLOCK_STRING = `
|
|
6
6
|
layout(std140) uniform DemTextureUniformBlock {
|
|
7
7
|
vec4 u_demTextureBBOX[6]; // 96 bytes
|
|
@@ -256,10 +256,16 @@ export class DemTextureManager {
|
|
|
256
256
|
export const DemTextureManagerCache = Object.freeze({
|
|
257
257
|
get: (globe) => {
|
|
258
258
|
const result = noRegisterGlobeProgramCache.getProgram(globe, DemTextureManager);
|
|
259
|
-
window.demManager = result;
|
|
259
|
+
// window.demManager = result;
|
|
260
260
|
return result;
|
|
261
261
|
},
|
|
262
262
|
release: (globe) => {
|
|
263
263
|
noRegisterGlobeProgramCache.releaseProgram(globe, DemTextureManager);
|
|
264
264
|
}
|
|
265
265
|
});
|
|
266
|
+
// // declare demManager window global
|
|
267
|
+
// declare global {
|
|
268
|
+
// interface Window {
|
|
269
|
+
// demManager: DemTextureManager;
|
|
270
|
+
// }
|
|
271
|
+
// }
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Toprak Nihat Deniz Ozturk
|
|
3
|
+
*/
|
|
1
4
|
import { createProgram } from "../../../util/webglobjectbuilders";
|
|
2
5
|
import { glProgramCache } from "../../programcache";
|
|
3
6
|
import { ParticleUBO } from "./particle-ubo";
|
|
@@ -9,7 +12,7 @@ precision highp float;
|
|
|
9
12
|
` + ParticleUBO.glslCode() + `
|
|
10
13
|
uniform sampler2D u_vector_field;
|
|
11
14
|
uniform sampler2D u_color_field;
|
|
12
|
-
uniform sampler2D
|
|
15
|
+
uniform sampler2D u_magnitude_field;
|
|
13
16
|
in vec2 in_position;
|
|
14
17
|
out vec4 base_color;
|
|
15
18
|
|
|
@@ -24,35 +27,38 @@ vec2 read_value(const vec2 uv) {
|
|
|
24
27
|
|
|
25
28
|
|
|
26
29
|
vec2 lookup_wind(const vec2 uv) { // gerek kalmayabilir. sampler linear methodu ayni isi yapiyor
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
vec2 bl = read_value(vc + vec2(0, px.y)).rg;
|
|
35
|
-
vec2 br = read_value(vc + px).rg;
|
|
30
|
+
vec2 value =texture(u_vector_field, uv).rg; // lower-res hardware filtering
|
|
31
|
+
// normalize value
|
|
32
|
+
float length = length(value);
|
|
33
|
+
if ( length == 0.0 || value.x == escape_value || value.y == escape_value) {
|
|
34
|
+
return vec2(0.0);
|
|
35
|
+
}
|
|
36
|
+
return value/length;
|
|
36
37
|
|
|
37
|
-
|
|
38
|
+
// vec2 res = vec2(textureSize(u_vector_field, 0));
|
|
39
|
+
// vec2 px = 1.0 / res;
|
|
40
|
+
// vec2 vc = (floor(uv * res)) * px;
|
|
41
|
+
// vec2 f = fract(uv * res);
|
|
42
|
+
// vec2 tl = read_value(vc).rg;
|
|
43
|
+
// vec2 tr = read_value(vc + vec2(px.x, 0)).rg;
|
|
44
|
+
// vec2 bl = read_value(vc + vec2(0, px.y)).rg;
|
|
45
|
+
// vec2 br = read_value(vc + px).rg;
|
|
46
|
+
|
|
47
|
+
// return mix(mix(tl, tr, f.x), mix(bl, br, f.x), f.y);
|
|
38
48
|
}
|
|
39
49
|
|
|
40
50
|
|
|
41
51
|
void main(){
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if ( speed < min_speed_threshold || speed > max_speed_threshold ) {
|
|
52
|
+
if ( use_magnitude_field > 0.5) {
|
|
53
|
+
float magnitude = texture(u_magnitude_field, in_position).r;
|
|
54
|
+
|
|
55
|
+
if ( magnitude < min_magnitude_threshold || magnitude > max_magnitude_threshold ) {
|
|
47
56
|
base_color = vec4(0.0);
|
|
48
57
|
return;
|
|
49
58
|
}
|
|
50
59
|
}
|
|
51
60
|
|
|
52
61
|
vec2 direction_vector = lookup_wind(in_position);
|
|
53
|
-
if (direction_vector.r == 0.0 && direction_vector.g == 0.0) return;
|
|
54
|
-
|
|
55
|
-
|
|
56
62
|
vec2 limp;
|
|
57
63
|
if ( 0 == gl_VertexID) { limp = -tail_wing_base_limp; }
|
|
58
64
|
else if ( 1 == gl_VertexID) { limp = vec2( tail_wing_base_limp.x, -tail_wing_base_limp.y); }
|
|
@@ -65,7 +71,7 @@ void main(){
|
|
|
65
71
|
vec2 pos = in_position * 2.0 - 1.0;
|
|
66
72
|
gl_Position = vec4(pos + limp, 0.0, 1.0);
|
|
67
73
|
|
|
68
|
-
base_color = use_color_field != 0.0 ? texture(u_color_field, in_position).rgba :
|
|
74
|
+
base_color = use_color_field != 0.0 ? texture(u_color_field, in_position).rgba : color;
|
|
69
75
|
}`;
|
|
70
76
|
const fragmentShaderSource = `#version 300 es
|
|
71
77
|
precision highp float;
|
|
@@ -79,15 +85,15 @@ export class DrawRectangleParticleProgram {
|
|
|
79
85
|
program;
|
|
80
86
|
_vector_field_location;
|
|
81
87
|
_color_texture_location;
|
|
82
|
-
|
|
88
|
+
_magnitude_field_location;
|
|
83
89
|
constructor(gl) {
|
|
84
90
|
this.gl = gl;
|
|
85
91
|
// this.decoyBuffer = new DecoyBufferManager(gl);
|
|
86
|
-
const { program, _vector_field_location, _color_texture_location,
|
|
92
|
+
const { program, _vector_field_location, _color_texture_location, _magnitude_field_location } = this._createProgram();
|
|
87
93
|
this.program = program;
|
|
88
94
|
this._vector_field_location = _vector_field_location;
|
|
89
95
|
this._color_texture_location = _color_texture_location;
|
|
90
|
-
this.
|
|
96
|
+
this._magnitude_field_location = _magnitude_field_location;
|
|
91
97
|
}
|
|
92
98
|
_createProgram() {
|
|
93
99
|
const gl = this.gl;
|
|
@@ -100,7 +106,7 @@ export class DrawRectangleParticleProgram {
|
|
|
100
106
|
program,
|
|
101
107
|
_vector_field_location: gl.getUniformLocation(program, 'u_vector_field'),
|
|
102
108
|
_color_texture_location: gl.getUniformLocation(program, 'u_color_field'),
|
|
103
|
-
|
|
109
|
+
_magnitude_field_location: gl.getUniformLocation(program, 'u_magnitude_field')
|
|
104
110
|
};
|
|
105
111
|
}
|
|
106
112
|
/**
|
|
@@ -108,7 +114,7 @@ export class DrawRectangleParticleProgram {
|
|
|
108
114
|
* @param vectorFieldTexture | RG32F texture R: x, G: y
|
|
109
115
|
* @param uboManager | WaveParticalUboManager under ubo.js
|
|
110
116
|
*/
|
|
111
|
-
draw(bufferManager, vectorFieldTexture, uboManager, colorFieldTexture,
|
|
117
|
+
draw(bufferManager, vectorFieldTexture, uboManager, colorFieldTexture, magnitudeFieldTexture) {
|
|
112
118
|
const { gl, program } = this;
|
|
113
119
|
gl.useProgram(program);
|
|
114
120
|
gl.bindVertexArray(bufferManager.getSourceVao());
|
|
@@ -119,10 +125,10 @@ export class DrawRectangleParticleProgram {
|
|
|
119
125
|
gl.uniform1i(this._color_texture_location, 1);
|
|
120
126
|
gl.bindTexture(gl.TEXTURE_2D, colorFieldTexture);
|
|
121
127
|
}
|
|
122
|
-
if (
|
|
128
|
+
if (magnitudeFieldTexture) {
|
|
123
129
|
gl.activeTexture(gl.TEXTURE2);
|
|
124
|
-
gl.uniform1i(this.
|
|
125
|
-
gl.bindTexture(gl.TEXTURE_2D,
|
|
130
|
+
gl.uniform1i(this._magnitude_field_location, 2);
|
|
131
|
+
gl.bindTexture(gl.TEXTURE_2D, magnitudeFieldTexture);
|
|
126
132
|
}
|
|
127
133
|
gl.activeTexture(gl.TEXTURE0);
|
|
128
134
|
gl.uniform1i(this._vector_field_location, 0);
|
|
@@ -1,16 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Author: Toprak Nihat Deniz Ozturk
|
|
3
|
+
*/
|
|
1
4
|
import { UBO_BINDING_POINTS } from "./constants";
|
|
2
5
|
import { UniformBlockManager } from "../../../util/gl-util/uniform-block/manager";
|
|
3
6
|
const INITIAL_UBO_DATA = /*@__PURE__*/ new Float32Array([93.17, 0.2, 1.0, 7.0, 1.0, 1.0, 1.0, 0.05, 2000, 2000, 0]);
|
|
4
7
|
export const ParticleUBO = /*@__PURE__*/ new UniformBlockManager("Seawave_UBO", [
|
|
8
|
+
{ name: "color", type: "vec4", value: new Float32Array([1.0, 1.0, 1.0, 1.0]) },
|
|
5
9
|
{ name: "tail_wing_base_limp", type: "vec2", value: INITIAL_UBO_DATA.slice(2, 4) },
|
|
6
10
|
{ name: "draw_texture_size", type: "vec2", value: INITIAL_UBO_DATA.slice(8, 10) },
|
|
7
11
|
{ name: "random_seed", type: "float", value: INITIAL_UBO_DATA.slice(0, 1) },
|
|
8
12
|
{ name: "range", type: "float", value: INITIAL_UBO_DATA.slice(1, 2) },
|
|
9
13
|
{ name: "escape_value", type: "float", value: INITIAL_UBO_DATA.slice(10, 11) },
|
|
10
14
|
{ name: "drop_rate", type: "float", value: INITIAL_UBO_DATA.slice(7, 8) },
|
|
11
|
-
{ name: "color", type: "vec3", value: INITIAL_UBO_DATA.slice(4, 7) },
|
|
12
15
|
{ name: "use_color_field", type: "float", value: new Float32Array([0]) },
|
|
13
|
-
{ name: "
|
|
14
|
-
{ name: "
|
|
15
|
-
{ name: "
|
|
16
|
+
{ name: "use_magnitude_field", type: "float", value: new Float32Array([0]) },
|
|
17
|
+
{ name: "min_magnitude_threshold", type: "float", value: new Float32Array([0]) },
|
|
18
|
+
{ name: "max_magnitude_threshold", type: "float", value: new Float32Array([10000]) },
|
|
16
19
|
], UBO_BINDING_POINTS.SEAWAVE);
|
|
@@ -45,17 +45,13 @@ vec2 random_position(vec2 st){
|
|
|
45
45
|
|
|
46
46
|
void main(){
|
|
47
47
|
vec2 vec = lookup_wind(in_position).xy;
|
|
48
|
-
if (vec.x == 0.0 && vec.y == 0.0){
|
|
49
|
-
out_position = random_position(in_position);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
48
|
float random_value = random(in_position + random_seed);
|
|
53
|
-
if (random_value < drop_rate){
|
|
49
|
+
if (vec.x == 0.0 && vec.y == 0.0 || random_value < drop_rate) {
|
|
54
50
|
out_position = random_position(in_position);
|
|
55
51
|
return;
|
|
56
52
|
}
|
|
57
|
-
|
|
58
|
-
out_position = in_position + (vec / draw_texture_size) * range *
|
|
53
|
+
|
|
54
|
+
out_position = in_position + (vec / draw_texture_size) * range * tail_wing_base_limp.x;
|
|
59
55
|
}
|
|
60
56
|
`;
|
|
61
57
|
const fragmentShaderSource = `#version 300 es
|
package/{semiplugins → webglobeplugins/semiplugins}/shape-on-terrain/terrain-polygon/data/cache.js
RENAMED
|
@@ -1,20 +1,24 @@
|
|
|
1
1
|
import { createTriangleTessellationMeta } from "../../../../Math/tessellation/triangle-tessellation";
|
|
2
|
-
import { triangulation } from "./polygon-to-triangles";
|
|
2
|
+
import { triangulation, calculateRealEdges } from "./polygon-to-triangles";
|
|
3
3
|
import RBush from "rbush";
|
|
4
4
|
import { RADIAN } from "../../../../Math/methods";
|
|
5
5
|
// TODO: use type instead of any
|
|
6
|
-
function _entry(polygon
|
|
6
|
+
function _entry(polygon) {
|
|
7
7
|
__polygonInputWGS84ToRadian(polygon);
|
|
8
|
-
const trianglesData = triangulation(polygon
|
|
8
|
+
const trianglesData = triangulation(polygon);
|
|
9
9
|
const cacheTriangles = [];
|
|
10
|
+
const realEdges = calculateRealEdges(polygon.geometry, trianglesData.indices);
|
|
10
11
|
for (let i = 0; i < trianglesData.indices.length; i += 3) {
|
|
11
12
|
const idx0 = trianglesData.indices[i] * 2;
|
|
12
13
|
const idx1 = trianglesData.indices[i + 1] * 2;
|
|
13
14
|
const idx2 = trianglesData.indices[i + 2] * 2;
|
|
15
|
+
const idx0RealEdge = realEdges[i];
|
|
16
|
+
const idx1RealEdge = realEdges[i + 1];
|
|
17
|
+
const idx2RealEdge = realEdges[i + 2];
|
|
14
18
|
const v0 = [trianglesData.vertices[idx0], trianglesData.vertices[idx0 + 1]];
|
|
15
19
|
const v1 = [trianglesData.vertices[idx1], trianglesData.vertices[idx1 + 1]];
|
|
16
20
|
const v2 = [trianglesData.vertices[idx2], trianglesData.vertices[idx2 + 1]];
|
|
17
|
-
const tessellationMeta = createTriangleTessellationMeta(v0, v1, v2);
|
|
21
|
+
const tessellationMeta = createTriangleTessellationMeta(v0, v1, v2, idx0RealEdge, idx1RealEdge, idx2RealEdge);
|
|
18
22
|
cacheTriangles.push({
|
|
19
23
|
polygon: polygon,
|
|
20
24
|
offset: i / 3,
|
|
@@ -38,11 +42,9 @@ function __polygonInputWGS84ToRadian(polygon) {
|
|
|
38
42
|
}
|
|
39
43
|
export class Cache {
|
|
40
44
|
cache = new Map();
|
|
41
|
-
kmThreshold;
|
|
42
45
|
rbush = new RBush();
|
|
43
46
|
bboxes = [];
|
|
44
|
-
constructor(
|
|
45
|
-
this.kmThreshold = kmThreshold;
|
|
47
|
+
constructor() {
|
|
46
48
|
}
|
|
47
49
|
clear() {
|
|
48
50
|
this.cache.clear();
|
|
@@ -52,7 +54,7 @@ export class Cache {
|
|
|
52
54
|
if (this.cache.has(key)) {
|
|
53
55
|
this.remove(key);
|
|
54
56
|
}
|
|
55
|
-
const triangles = _entry(polygon
|
|
57
|
+
const triangles = _entry(polygon);
|
|
56
58
|
this.rbush.load(triangles);
|
|
57
59
|
this.cache.set(key, { polygon: polygon, triangles });
|
|
58
60
|
}
|
|
@@ -1,50 +1,74 @@
|
|
|
1
1
|
/// <reference lib="webworker" />
|
|
2
|
+
/* eslint-disable no-restricted-globals */
|
|
3
|
+
import { uint32Escape } from "../../../../Math/tessellation/triangle-tessellation";
|
|
2
4
|
const _workers = [];
|
|
3
5
|
const _workerMap = new Map();
|
|
4
|
-
let _maxWorkers = 4;
|
|
6
|
+
let _maxWorkers = 4;
|
|
5
7
|
let _nextWorkerIndex = 0;
|
|
6
|
-
// Configuration state to pass to new workers or re-broadcast
|
|
7
8
|
let _pickableState;
|
|
9
|
+
let _arcState;
|
|
8
10
|
let _variativeColorsOn;
|
|
9
|
-
//
|
|
11
|
+
// NEW: barrier state for "wait for all outputs of the last dispatched batch"
|
|
12
|
+
let _batchInFlight = false;
|
|
13
|
+
let _batchPending = 0;
|
|
10
14
|
function initWorkers() {
|
|
11
|
-
_maxWorkers = Math.max(1, (navigator.hardwareConcurrency || 4) - 1);
|
|
12
|
-
|
|
15
|
+
_maxWorkers = Math.max(1, ((navigator.hardwareConcurrency - 2) || 4) - 1);
|
|
16
|
+
console.log(`TerrainPolygon: initializing ${_maxWorkers} workers.`);
|
|
17
|
+
for (let i = 0; i < _maxWorkers; i++)
|
|
13
18
|
addWorker();
|
|
14
|
-
}
|
|
15
19
|
}
|
|
16
20
|
function addWorker() {
|
|
21
|
+
// IMPORTANT: use the TS entry so the bundler can build the worker module.
|
|
17
22
|
// @ts-ignore
|
|
18
|
-
const worker = new Worker(new URL("./worker.
|
|
23
|
+
const worker = new Worker(new URL("./worker.ts", import.meta.url), { type: "module" });
|
|
19
24
|
const wrapper = {
|
|
20
25
|
worker,
|
|
21
26
|
inProgress: false,
|
|
22
27
|
insertDeleteQueue: [],
|
|
23
28
|
lastBBOXData: null,
|
|
24
29
|
itemCount: 0,
|
|
25
|
-
lastOutput: null
|
|
30
|
+
lastOutput: null,
|
|
26
31
|
};
|
|
27
32
|
worker.onmessage = (event) => {
|
|
28
33
|
wrapper.inProgress = false;
|
|
29
34
|
wrapper.lastOutput = event.data;
|
|
30
|
-
|
|
35
|
+
// Barrier: only merge/send after all workers dispatched for this batch have finished.
|
|
36
|
+
if (_batchInFlight) {
|
|
37
|
+
_batchPending = Math.max(0, _batchPending - 1);
|
|
38
|
+
if (_batchPending === 0) {
|
|
39
|
+
_batchInFlight = false;
|
|
40
|
+
mergeAndSendResults();
|
|
41
|
+
// Start next batch (if anything queued while we were waiting)
|
|
42
|
+
triggerAllWorkers();
|
|
43
|
+
}
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
// Fallback (should rarely happen): if not in a batch, allow immediate draining.
|
|
31
47
|
sendToSubWorker(wrapper);
|
|
32
48
|
};
|
|
33
|
-
// Initialize sub-worker with current global state
|
|
34
49
|
worker.postMessage({
|
|
35
50
|
pickableState: _pickableState,
|
|
36
51
|
variativeColorsOn: _variativeColorsOn,
|
|
52
|
+
arcState: _arcState,
|
|
37
53
|
insertDeleteQueue: [],
|
|
38
54
|
bboxes: null,
|
|
39
55
|
});
|
|
40
56
|
_workers.push(wrapper);
|
|
41
57
|
}
|
|
42
58
|
function mergeAndSendResults() {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
// Match the working master-worker.js sentinel/header layout
|
|
60
|
+
const BASE_VEC3S = 9; // 3 vertices * 3
|
|
61
|
+
const BASE_INDICES = 3;
|
|
62
|
+
const BASE_LONGLATS = 6; // 3 vertices * 2
|
|
63
|
+
const BASE_PICKINDICES = 3;
|
|
64
|
+
const BASE_VARIATIVE = _variativeColorsOn ? 12 : 0; // 3 vertices * 4
|
|
65
|
+
const BASE_REAL_EDGE_ARC_INDICES = _arcState ? 1 : 0; // reserve header only when arc mode is enabled
|
|
66
|
+
let totalVec3s = BASE_VEC3S;
|
|
67
|
+
let totalIndices = BASE_INDICES;
|
|
68
|
+
let totalLongLats = BASE_LONGLATS;
|
|
69
|
+
let totalPickIndices = BASE_PICKINDICES;
|
|
70
|
+
let totalVariativeColors = BASE_VARIATIVE;
|
|
71
|
+
let totalRealEdgeArcIndices = BASE_REAL_EDGE_ARC_INDICES;
|
|
48
72
|
const validOutputs = [];
|
|
49
73
|
for (const w of _workers) {
|
|
50
74
|
if (w.lastOutput) {
|
|
@@ -52,6 +76,9 @@ function mergeAndSendResults() {
|
|
|
52
76
|
totalVec3s += w.lastOutput.vec3s.length;
|
|
53
77
|
totalIndices += w.lastOutput.indices.length;
|
|
54
78
|
totalLongLats += w.lastOutput.longLats.length;
|
|
79
|
+
if (_arcState && w.lastOutput.realEdgeArcIndices) {
|
|
80
|
+
totalRealEdgeArcIndices += w.lastOutput.realEdgeArcIndices.length;
|
|
81
|
+
}
|
|
55
82
|
if (w.lastOutput.pickIndices)
|
|
56
83
|
totalPickIndices += w.lastOutput.pickIndices.length;
|
|
57
84
|
if (w.lastOutput.variativeColors)
|
|
@@ -64,21 +91,50 @@ function mergeAndSendResults() {
|
|
|
64
91
|
vec3s: new Float32Array(totalVec3s),
|
|
65
92
|
indices: new Uint32Array(totalIndices),
|
|
66
93
|
longLats: new Float32Array(totalLongLats),
|
|
94
|
+
realEdgeArcIndices: _arcState && totalRealEdgeArcIndices > 0 ? new Uint32Array(totalRealEdgeArcIndices) : null,
|
|
67
95
|
pickIndices: totalPickIndices > 0 ? new Float32Array(totalPickIndices) : null,
|
|
68
|
-
variativeColors: totalVariativeColors > 0 ? new
|
|
96
|
+
variativeColors: totalVariativeColors > 0 ? new Uint8Array(totalVariativeColors) : null,
|
|
69
97
|
};
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
98
|
+
// Sentinel/header (as in master-worker.js)
|
|
99
|
+
merged.vec3s[0] = NaN;
|
|
100
|
+
merged.vec3s[1] = NaN;
|
|
101
|
+
merged.vec3s[2] = NaN;
|
|
102
|
+
// Uint32Array cannot hold NaN; writing NaN becomes 0. Keep the header reserved anyway.
|
|
103
|
+
merged.indices[0] = 0;
|
|
104
|
+
merged.indices[1] = 0;
|
|
105
|
+
merged.indices[2] = 0;
|
|
106
|
+
merged.longLats[0] = NaN;
|
|
107
|
+
merged.longLats[1] = NaN;
|
|
108
|
+
if (_arcState && merged.realEdgeArcIndices) {
|
|
109
|
+
merged.realEdgeArcIndices[0] = 0; // header/sentinel
|
|
110
|
+
}
|
|
111
|
+
if (merged.variativeColors) {
|
|
112
|
+
// Sentinel/header (no-color marker)
|
|
113
|
+
merged.variativeColors[0] = 0;
|
|
114
|
+
merged.variativeColors[1] = 0;
|
|
115
|
+
merged.variativeColors[2] = 0;
|
|
116
|
+
merged.variativeColors[3] = 255;
|
|
117
|
+
}
|
|
118
|
+
let offsetVec3s = BASE_VEC3S;
|
|
119
|
+
let offsetIndices = BASE_INDICES;
|
|
120
|
+
let offsetLongLats = BASE_LONGLATS;
|
|
121
|
+
let offsetPickIndices = BASE_PICKINDICES;
|
|
122
|
+
let offsetVariativeColors = BASE_VARIATIVE;
|
|
123
|
+
let vertexOffset = 3; // reserve 3 vertices
|
|
124
|
+
let arcCounter = BASE_REAL_EDGE_ARC_INDICES;
|
|
76
125
|
for (const out of validOutputs) {
|
|
77
126
|
merged.vec3s.set(out.vec3s, offsetVec3s);
|
|
78
127
|
offsetVec3s += out.vec3s.length;
|
|
79
128
|
for (let i = 0; i < out.indices.length; i++) {
|
|
80
129
|
merged.indices[offsetIndices + i] = out.indices[i] + vertexOffset;
|
|
81
130
|
}
|
|
131
|
+
if (_arcState && merged.realEdgeArcIndices && out.realEdgeArcIndices) {
|
|
132
|
+
for (let i = 0; i < out.realEdgeArcIndices.length; i++) {
|
|
133
|
+
const realEdgeIndice = out.realEdgeArcIndices[i];
|
|
134
|
+
merged.realEdgeArcIndices[arcCounter++] =
|
|
135
|
+
realEdgeIndice === uint32Escape ? uint32Escape : realEdgeIndice + vertexOffset;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
82
138
|
offsetIndices += out.indices.length;
|
|
83
139
|
vertexOffset += out.vec3s.length / 3;
|
|
84
140
|
merged.longLats.set(out.longLats, offsetLongLats);
|
|
@@ -92,51 +148,59 @@ function mergeAndSendResults() {
|
|
|
92
148
|
offsetVariativeColors += out.variativeColors.length;
|
|
93
149
|
}
|
|
94
150
|
}
|
|
95
|
-
// Send merged result to Main Thread
|
|
96
151
|
self.postMessage(merged, [
|
|
97
152
|
merged.vec3s.buffer,
|
|
98
153
|
merged.indices.buffer,
|
|
99
154
|
merged.longLats.buffer,
|
|
100
155
|
...(merged.pickIndices ? [merged.pickIndices.buffer] : []),
|
|
101
|
-
...(merged.variativeColors ? [merged.variativeColors.buffer] : [])
|
|
156
|
+
...(merged.variativeColors ? [merged.variativeColors.buffer] : []),
|
|
157
|
+
...(merged.realEdgeArcIndices ? [merged.realEdgeArcIndices.buffer] : []),
|
|
102
158
|
]);
|
|
103
159
|
}
|
|
104
160
|
function sendToSubWorker(wrapper) {
|
|
105
161
|
if (wrapper.inProgress)
|
|
106
|
-
return;
|
|
162
|
+
return false;
|
|
107
163
|
if (wrapper.insertDeleteQueue.length === 0 && wrapper.lastBBOXData === null)
|
|
108
|
-
return;
|
|
164
|
+
return false;
|
|
109
165
|
wrapper.inProgress = true;
|
|
110
166
|
wrapper.worker.postMessage({
|
|
111
|
-
pickableState: undefined,
|
|
167
|
+
pickableState: undefined,
|
|
112
168
|
variativeColorsOn: undefined,
|
|
169
|
+
arcState: undefined,
|
|
113
170
|
bboxes: wrapper.lastBBOXData,
|
|
114
171
|
insertDeleteQueue: wrapper.insertDeleteQueue,
|
|
115
172
|
});
|
|
116
173
|
wrapper.lastBBOXData = null;
|
|
117
174
|
wrapper.insertDeleteQueue = [];
|
|
175
|
+
return true;
|
|
118
176
|
}
|
|
119
177
|
function triggerAllWorkers() {
|
|
178
|
+
// If a batch is already running, do not start another one.
|
|
179
|
+
if (_batchInFlight)
|
|
180
|
+
return;
|
|
181
|
+
let dispatched = 0;
|
|
120
182
|
for (const w of _workers) {
|
|
121
|
-
sendToSubWorker(w)
|
|
183
|
+
if (sendToSubWorker(w))
|
|
184
|
+
dispatched++;
|
|
185
|
+
}
|
|
186
|
+
// Start barrier only if we actually dispatched work.
|
|
187
|
+
if (dispatched > 0) {
|
|
188
|
+
_batchInFlight = true;
|
|
189
|
+
_batchPending = dispatched;
|
|
122
190
|
}
|
|
123
191
|
}
|
|
124
|
-
// Handle messages from Main Thread
|
|
125
192
|
self.onmessage = (event) => {
|
|
126
|
-
const { bboxes, insertDeleteQueue, pickableState, variativeColorsOn } = event.data;
|
|
127
|
-
// Initialize if not already done
|
|
193
|
+
const { bboxes, insertDeleteQueue, pickableState, variativeColorsOn, arcState } = event.data;
|
|
128
194
|
if (_workers.length === 0) {
|
|
129
195
|
_pickableState = pickableState;
|
|
130
196
|
_variativeColorsOn = variativeColorsOn;
|
|
197
|
+
_arcState = arcState;
|
|
131
198
|
initWorkers();
|
|
132
199
|
}
|
|
133
|
-
// Handle BBOX updates
|
|
134
200
|
if (bboxes) {
|
|
135
|
-
for (const w of _workers)
|
|
201
|
+
for (const w of _workers)
|
|
136
202
|
w.lastBBOXData = bboxes;
|
|
137
|
-
}
|
|
138
203
|
}
|
|
139
|
-
// Handle Insert/Delete
|
|
140
204
|
if (insertDeleteQueue && insertDeleteQueue.length > 0) {
|
|
141
205
|
if (insertDeleteQueue[0] === "__CLEAR_ALL_ITEMS__") {
|
|
142
206
|
_workerMap.clear();
|
|
@@ -148,7 +212,7 @@ self.onmessage = (event) => {
|
|
|
148
212
|
}
|
|
149
213
|
else {
|
|
150
214
|
for (const item of insertDeleteQueue) {
|
|
151
|
-
if (typeof item ===
|
|
215
|
+
if (typeof item === "string") {
|
|
152
216
|
// Delete
|
|
153
217
|
const workerIdx = _workerMap.get(item);
|
|
154
218
|
if (workerIdx !== undefined) {
|
|
@@ -158,7 +222,7 @@ self.onmessage = (event) => {
|
|
|
158
222
|
}
|
|
159
223
|
}
|
|
160
224
|
else {
|
|
161
|
-
// Insert
|
|
225
|
+
// Insert/Update: MUST enqueue the full polygon payload, not just the key
|
|
162
226
|
let workerIdx = _workerMap.get(item.key);
|
|
163
227
|
if (workerIdx === undefined) {
|
|
164
228
|
workerIdx = _nextWorkerIndex;
|
|
@@ -166,12 +230,12 @@ self.onmessage = (event) => {
|
|
|
166
230
|
_workers[workerIdx].itemCount++;
|
|
167
231
|
_nextWorkerIndex = (_nextWorkerIndex + 1) % _workers.length;
|
|
168
232
|
}
|
|
169
|
-
_workers[workerIdx].insertDeleteQueue.push(item
|
|
233
|
+
_workers[workerIdx].insertDeleteQueue.push(item);
|
|
170
234
|
}
|
|
171
235
|
}
|
|
172
236
|
}
|
|
173
237
|
}
|
|
174
|
-
//
|
|
238
|
+
// This now starts a "batch" and waits for all dispatched workers to respond
|
|
239
|
+
// before mergeAndSendResults() is called.
|
|
175
240
|
triggerAllWorkers();
|
|
176
241
|
};
|
|
177
|
-
export {};
|