@ztgkzhaohao/geo-effect-kit 0.1.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/index.d.ts +108 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +427 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BoundingSphere, BillboardGraphics, CallbackPositionProperty, CallbackProperty, Cartesian2, Cartesian3, Cartesian4, CircleGeometry, Color, ColorMaterialProperty, ConstantPositionProperty, ConstantProperty, CustomDataSource, EllipsoidSurfaceAppearance, Event, GeometryInstance, GroundPrimitive, HeadingPitchRoll, HeadingPitchRange, HeightReference, HorizontalOrigin, Material, Math as CesiumMath, PointGraphics, PolylineGlowMaterialProperty, PolygonGeometry, PolygonHierarchy, PostProcessStage, Primitive, Rectangle, Transforms, VerticalOrigin, } from 'cesium';
|
|
1
|
+
import { BoundingSphere, BillboardGraphics, CallbackPositionProperty, CallbackProperty, Cartesian2, Cartesian3, Cartesian4, CircleGeometry, Color, ColorMaterialProperty, ConstantPositionProperty, ConstantProperty, CustomDataSource, EllipsoidSurfaceAppearance, Event, GeometryInstance, GroundPrimitive, HeadingPitchRoll, HeadingPitchRange, HeightReference, HorizontalOrigin, Material, Math as CesiumMath, PointGraphics, PolylineArrowMaterialProperty, PolylineDashMaterialProperty, PolylineGlowMaterialProperty, PolylineOutlineMaterialProperty, PolygonGeometry, PolygonHierarchy, PostProcessStage, Primitive, Rectangle, Transforms, VerticalOrigin, } from 'cesium';
|
|
2
2
|
import { decompressFrames, parseGIF } from 'gifuct-js';
|
|
3
3
|
export const GEO_RADAR_SCAN_MATERIAL_TYPE = 'GeoRadarScanMaterial';
|
|
4
4
|
export const GEO_RIPPLE_SPREAD_MATERIAL_TYPE = 'GeoRippleSpreadMaterial';
|
|
@@ -7,16 +7,42 @@ export const GEO_SCAN_CONE_MATERIAL_TYPE = 'GeoScanConeMaterial';
|
|
|
7
7
|
export const GEO_SHIELD_DOME_MATERIAL_TYPE = 'GeoShieldDomeMaterial';
|
|
8
8
|
export const GEO_TEMPERATURE_FIELD_MATERIAL_TYPE = 'GeoTemperatureFieldMaterial';
|
|
9
9
|
export const GEO_WATER_SURFACE_MATERIAL_TYPE = 'GeoWaterSurfaceMaterial';
|
|
10
|
+
export const GEO_MATERIAL_POLYLINE_MATERIAL_TYPE = 'GeoMaterialPolylineMaterial';
|
|
10
11
|
export const RADAR_SCAN_TYPE_VALUES = ['classic', 'sector', 'pulse', 'grid'];
|
|
11
12
|
export const RIPPLE_SPREAD_TYPE_VALUES = ['water', 'energy', 'soft'];
|
|
12
13
|
export const SCENE_WEATHER_TYPE_VALUES = ['rain', 'snow', 'fog', 'lightning'];
|
|
13
14
|
export const POST_PROCESS_TYPE_VALUES = ['bloom', 'night-vision', 'black-white', 'brightness', 'mosaic', 'depth-of-field'];
|
|
14
15
|
export const POLYLINE_FLOW_TYPE_VALUES = ['dispatch', 'migration', 'attack', 'comet', 'electric'];
|
|
16
|
+
export const MATERIAL_POLYLINE_STYLE_VALUES = [
|
|
17
|
+
'solid',
|
|
18
|
+
'outline',
|
|
19
|
+
'arrow',
|
|
20
|
+
'dash',
|
|
21
|
+
'dual-dash',
|
|
22
|
+
'flow',
|
|
23
|
+
'flow-color',
|
|
24
|
+
'three-dash',
|
|
25
|
+
'cross',
|
|
26
|
+
'navigation',
|
|
27
|
+
];
|
|
28
|
+
export const MATERIAL_POLYLINE_IMAGE_PRESET_VALUES = [
|
|
29
|
+
'pulse',
|
|
30
|
+
'gradual',
|
|
31
|
+
'arrow-blue',
|
|
32
|
+
'rainbow',
|
|
33
|
+
'arrow-repeat',
|
|
34
|
+
'dovetail',
|
|
35
|
+
'yellow-flow',
|
|
36
|
+
'transparent-flow',
|
|
37
|
+
'interval',
|
|
38
|
+
'small-arrow',
|
|
39
|
+
'gradient',
|
|
40
|
+
];
|
|
15
41
|
export const FLY_LINE_MODE_VALUES = ['single-arc', 'hub-spoke', 'bidirectional'];
|
|
16
42
|
export const LIGHT_WALL_TYPE_VALUES = ['security', 'warning', 'data', 'fence', 'pulse'];
|
|
17
43
|
export const SCAN_CONE_TYPE_VALUES = ['searchlight', 'radar', 'camera', 'drone', 'alarm'];
|
|
18
44
|
export const SHIELD_DOME_TYPE_VALUES = ['hex', 'plasma', 'matrix', 'aegis', 'storm'];
|
|
19
|
-
export const WATER_SURFACE_TYPE_VALUES = ['river', 'lake', 'flood'];
|
|
45
|
+
export const WATER_SURFACE_TYPE_VALUES = ['river', 'lake', 'flood', 'flow'];
|
|
20
46
|
export function createRadarScanEffect(viewer, options) {
|
|
21
47
|
return new RadarScanEffect(viewer, options);
|
|
22
48
|
}
|
|
@@ -32,6 +58,9 @@ export function createPostProcessEffect(viewer, options = {}) {
|
|
|
32
58
|
export function createPolylineFlowEffect(viewer, options) {
|
|
33
59
|
return new PolylineFlowEffect(viewer, options);
|
|
34
60
|
}
|
|
61
|
+
export function createMaterialPolylineEffect(viewer, options) {
|
|
62
|
+
return new MaterialPolylineEffect(viewer, options);
|
|
63
|
+
}
|
|
35
64
|
export function createFlyLineEffect(viewer, options) {
|
|
36
65
|
return new FlyLineEffect(viewer, options);
|
|
37
66
|
}
|
|
@@ -125,6 +154,27 @@ export function normalizePolylineFlowOptions(options) {
|
|
|
125
154
|
visible: options.visible ?? true,
|
|
126
155
|
};
|
|
127
156
|
}
|
|
157
|
+
export function normalizeMaterialPolylineOptions(options) {
|
|
158
|
+
const imagePreset = normalizeMaterialPolylineImagePreset(options.imagePreset);
|
|
159
|
+
return {
|
|
160
|
+
positions: normalizePositions(options.positions, false),
|
|
161
|
+
style: normalizeMaterialPolylineStyle(options.style),
|
|
162
|
+
color: options.color ?? '#33f7ff',
|
|
163
|
+
secondaryColor: options.secondaryColor ?? '#ffffff',
|
|
164
|
+
backgroundColor: options.backgroundColor ?? 'rgba(0, 64, 255, 0.35)',
|
|
165
|
+
width: Math.max(1, finiteOr(options.width ?? 8, 8)),
|
|
166
|
+
outlineWidth: Math.max(0, finiteOr(options.outlineWidth ?? 2, 2)),
|
|
167
|
+
speed: clamp(finiteOr(options.speed ?? 1, 1), 0.05, 8),
|
|
168
|
+
repeat: normalizeMaterialPolylineRepeat(options.repeat),
|
|
169
|
+
imagePreset,
|
|
170
|
+
image: options.image ?? getMaterialPolylinePresetImage(imagePreset),
|
|
171
|
+
arcHeight: Math.max(0, finiteOr(options.arcHeight ?? 0, 0)),
|
|
172
|
+
arcSamples: clampInteger(finiteOr(options.arcSamples ?? 48, 48), 2, 128),
|
|
173
|
+
cornerRadius: clamp(finiteOr(options.cornerRadius ?? 0, 0), 0, 0.45),
|
|
174
|
+
clampToGround: options.clampToGround ?? true,
|
|
175
|
+
visible: options.visible ?? true,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
128
178
|
export function normalizeFlyLineOptions(options) {
|
|
129
179
|
return {
|
|
130
180
|
lines: normalizeFlyLineRoutes(options.lines),
|
|
@@ -264,6 +314,14 @@ export function shouldRebuildPolylineFlow(previous, next) {
|
|
|
264
314
|
previous.positions.length !== next.positions.length ||
|
|
265
315
|
!positionsEqual(previous.positions, next.positions));
|
|
266
316
|
}
|
|
317
|
+
export function shouldRebuildMaterialPolyline(previous, next) {
|
|
318
|
+
return (previous.clampToGround !== next.clampToGround ||
|
|
319
|
+
previous.arcHeight !== next.arcHeight ||
|
|
320
|
+
previous.arcSamples !== next.arcSamples ||
|
|
321
|
+
previous.cornerRadius !== next.cornerRadius ||
|
|
322
|
+
previous.positions.length !== next.positions.length ||
|
|
323
|
+
!positionsEqual(previous.positions, next.positions));
|
|
324
|
+
}
|
|
267
325
|
export function shouldRebuildFlyLine(previous, next) {
|
|
268
326
|
return (previous.mode !== next.mode ||
|
|
269
327
|
previous.arcHeight !== next.arcHeight ||
|
|
@@ -285,8 +343,7 @@ export function shouldRebuildLightWall(previous, next) {
|
|
|
285
343
|
export function shouldRebuildScanCone(previous, next) {
|
|
286
344
|
return (previous.radiusMeters !== next.radiusMeters ||
|
|
287
345
|
previous.lengthMeters !== next.lengthMeters ||
|
|
288
|
-
previous.aperture !== next.aperture
|
|
289
|
-
!positionsEqual([previous.center], [next.center]));
|
|
346
|
+
previous.aperture !== next.aperture);
|
|
290
347
|
}
|
|
291
348
|
export function shouldRebuildShieldDome(previous, next) {
|
|
292
349
|
return previous.radiusMeters !== next.radiusMeters || !positionsEqual([previous.center], [next.center]);
|
|
@@ -416,6 +473,53 @@ export function buildRippleSpreadMaterialSource() {
|
|
|
416
473
|
}
|
|
417
474
|
`;
|
|
418
475
|
}
|
|
476
|
+
export function buildMaterialPolylineMaterialSource() {
|
|
477
|
+
return `
|
|
478
|
+
// ${GEO_MATERIAL_POLYLINE_MATERIAL_TYPE}
|
|
479
|
+
czm_material czm_getMaterial(czm_materialInput materialInput)
|
|
480
|
+
{
|
|
481
|
+
czm_material material = czm_getDefaultMaterial(materialInput);
|
|
482
|
+
vec2 st = materialInput.st;
|
|
483
|
+
float time = fract(czm_frameNumber * 0.016667 * speed);
|
|
484
|
+
vec2 uv = vec2(fract(st.s * repeatX - time), fract(st.t * repeatY));
|
|
485
|
+
vec4 textureColor = texture(image, uv);
|
|
486
|
+
float flowEnabled = step(5.5, styleType) * (1.0 - step(6.5, styleType));
|
|
487
|
+
float flowColorEnabled = step(6.5, styleType) * (1.0 - step(7.5, styleType));
|
|
488
|
+
float threeDashEnabled = step(7.5, styleType) * (1.0 - step(8.5, styleType));
|
|
489
|
+
float crossEnabled = step(8.5, styleType) * (1.0 - step(9.5, styleType));
|
|
490
|
+
float navigationEnabled = step(9.5, styleType);
|
|
491
|
+
float dynamicEnabled = max(max(flowEnabled, flowColorEnabled), max(max(threeDashEnabled, crossEnabled), navigationEnabled));
|
|
492
|
+
float centerDistance = abs(st.t - 0.5);
|
|
493
|
+
float centerCore = smoothstep(0.18, 0.0, centerDistance);
|
|
494
|
+
float sideCore = smoothstep(0.08, 0.0, abs(centerDistance - 0.32));
|
|
495
|
+
float dash = smoothstep(0.68, 0.72, fract(st.s * repeatX - time));
|
|
496
|
+
float cross = max(
|
|
497
|
+
smoothstep(0.08, 0.0, centerDistance) * dash,
|
|
498
|
+
smoothstep(0.022, 0.0, abs(fract(st.s * repeatX - time) - 0.5))
|
|
499
|
+
);
|
|
500
|
+
float navCycle = fract(st.s * repeatX - time);
|
|
501
|
+
float navWhite = smoothstep(0.0, 0.08, navCycle) * (1.0 - smoothstep(0.22, 0.32, navCycle));
|
|
502
|
+
float navGreen = smoothstep(0.24, 0.34, navCycle) * (1.0 - smoothstep(0.86, 0.96, navCycle));
|
|
503
|
+
float textureAlpha = textureColor.a;
|
|
504
|
+
vec3 imageColor = textureColor.rgb;
|
|
505
|
+
float imageBrightness = max(max(imageColor.r, imageColor.g), imageColor.b);
|
|
506
|
+
float tintWeight = (1.0 - imageBrightness) * 0.45;
|
|
507
|
+
vec3 flowImageColor = mix(imageColor, imageColor * color.rgb, tintWeight);
|
|
508
|
+
vec3 flowColor = flowImageColor * flowEnabled + mix(color.rgb, secondaryColor.rgb, smoothstep(0.0, 1.0, uv.s)) * flowColorEnabled;
|
|
509
|
+
vec3 threeColor = (color.rgb * centerCore + secondaryColor.rgb * sideCore) * max(centerCore, sideCore) * threeDashEnabled;
|
|
510
|
+
vec3 crossColor = color.rgb * cross * crossEnabled;
|
|
511
|
+
vec3 navColor = (secondaryColor.rgb * navWhite + color.rgb * navGreen) * navigationEnabled;
|
|
512
|
+
vec3 mixed = flowColor + threeColor + crossColor + navColor;
|
|
513
|
+
float flowColorAlpha = smoothstep(0.02, 0.18, fract(uv.s)) * (1.0 - smoothstep(0.58, 0.98, fract(uv.s)));
|
|
514
|
+
float patternAlpha = max(max(textureAlpha * flowEnabled + flowColorAlpha * flowColorEnabled, max(centerCore, sideCore) * threeDashEnabled), max(cross * crossEnabled, max(navWhite, navGreen) * navigationEnabled));
|
|
515
|
+
float backgroundAlpha = backgroundColor.a * dynamicEnabled * (1.0 - patternAlpha) * 0.58;
|
|
516
|
+
material.diffuse = mix(backgroundColor.rgb, mixed, clamp(patternAlpha + 0.1, 0.0, 1.0));
|
|
517
|
+
material.emission = mixed * (0.32 + patternAlpha * 0.84);
|
|
518
|
+
material.alpha = clamp(backgroundAlpha + patternAlpha * color.a, 0.0, 1.0);
|
|
519
|
+
return material;
|
|
520
|
+
}
|
|
521
|
+
`;
|
|
522
|
+
}
|
|
419
523
|
export function buildSceneWeatherPostProcessSource() {
|
|
420
524
|
return `
|
|
421
525
|
uniform sampler2D colorTexture;
|
|
@@ -725,6 +829,13 @@ export function buildWaterSurfaceMaterialSource() {
|
|
|
725
829
|
float riverWave = mix(waveA, max(riverFlow, waveB * 0.72), 0.45);
|
|
726
830
|
float wave = mix(waveA, max(riverWave, lakeShimmer), waveStrength);
|
|
727
831
|
wave = max(wave, floodPulse * floodEnabled);
|
|
832
|
+
// flow mirrors the yunzhou-onemap WaterPrimitive water surface style without changing river/lake/flood.
|
|
833
|
+
float flowEnabled = step(3.5, waterType);
|
|
834
|
+
float yunzhouFlow = smoothstep(0.46, 1.0, waterNoise(moving * 18.0 + flow * time * 2.2)) * (0.52 + waveA * 0.48);
|
|
835
|
+
float flowWash = smoothstep(0.42, 1.0, waterNoise(moving * 7.0 + crossFlow * time * 0.28));
|
|
836
|
+
float flowHighlight = max(yunzhouFlow, flowWash * waveB * 0.74);
|
|
837
|
+
float flowWave = mix(waveA, flowHighlight, 0.62);
|
|
838
|
+
wave = mix(wave, flowWave, flowEnabled);
|
|
728
839
|
vec3 viewDirection = normalize(materialInput.positionToEyeEC);
|
|
729
840
|
float viewFacing = clamp(1.0 - abs(dot(normalize(materialInput.normalEC), -viewDirection)), 0.0, 1.0);
|
|
730
841
|
float fresnel = pow(viewFacing, fresnelPower) * reflectivity;
|
|
@@ -733,7 +844,10 @@ export function buildWaterSurfaceMaterialSource() {
|
|
|
733
844
|
vec3 lakeTint = mix(color.rgb, vec3(0.36, 0.92, 0.86), 0.22);
|
|
734
845
|
vec3 floodTint = mix(color.rgb, vec3(0.42, 0.68, 1.0), 0.36);
|
|
735
846
|
vec3 waterColor = riverTint * riverEnabled + lakeTint * lakeEnabled + floodTint * floodEnabled;
|
|
847
|
+
vec3 flowTint = mix(color.rgb, vec3(0.0, 0.47, 0.50), 0.18);
|
|
848
|
+
waterColor = mix(waterColor, flowTint, flowEnabled);
|
|
736
849
|
vec3 deepColor = mix(waterColor, vec3(0.015, 0.11, 0.18), 0.46);
|
|
850
|
+
deepColor = mix(deepColor, mix(flowTint, vec3(0.015, 0.11, 0.18), 0.54), flowEnabled);
|
|
737
851
|
vec3 refractionColor = mix(deepColor, waterColor, 0.42 + wave * 0.34);
|
|
738
852
|
refractionColor += vec3(0.02, 0.12, 0.16) * refractionStrength * (0.5 + waveB * 0.5);
|
|
739
853
|
vec3 skyReflection = mix(vec3(0.58, 0.86, 1.0), vec3(1.0), pow(smallWave, 5.0));
|
|
@@ -744,6 +858,7 @@ export function buildWaterSurfaceMaterialSource() {
|
|
|
744
858
|
material.normal = surfaceNormal;
|
|
745
859
|
material.diffuse = finalColor * (0.56 + wave * 0.18);
|
|
746
860
|
material.emission = reflectionColor * (0.14 + fresnel * 0.42) + waterColor * ((riverFlow * 0.08 + waveB * 0.06) * riverEnabled + floodPulse * floodEnabled * 0.22);
|
|
861
|
+
material.emission = mix(material.emission, reflectionColor * (0.14 + fresnel * 0.42) + waterColor * (flowHighlight * 0.11), flowEnabled);
|
|
747
862
|
material.alpha = opacity * (0.62 + wave * 0.12 + fresnel * 0.2 + refractionStrength * 0.06);
|
|
748
863
|
return material;
|
|
749
864
|
}
|
|
@@ -797,7 +912,8 @@ export function buildScanConeMaterialSource() {
|
|
|
797
912
|
vec2 centered = st - vec2(0.5);
|
|
798
913
|
float radius = length(centered) * 2.0;
|
|
799
914
|
float angle = atan(centered.y, centered.x) / 6.28318530718 + 0.5;
|
|
800
|
-
float
|
|
915
|
+
float scanTimeSeconds = max(timeSeconds, czm_frameNumber * 0.016667);
|
|
916
|
+
float time = fract(scanTimeSeconds * speed);
|
|
801
917
|
float verticalFade = smoothstep(0.0, 0.12, st.t) * (1.0 - smoothstep(0.92, 1.0, st.t));
|
|
802
918
|
float sweepBand = smoothstep(0.08, 0.0, abs(fract(angle - time) - 0.5));
|
|
803
919
|
float radialGrid = smoothstep(0.012, 0.0, abs(fract(radius * 7.0 - time * 2.0) - 0.5));
|
|
@@ -2370,6 +2486,211 @@ export class FlyLineEffect {
|
|
|
2370
2486
|
this.renderFrame = 0;
|
|
2371
2487
|
}
|
|
2372
2488
|
}
|
|
2489
|
+
export class MaterialPolylineEffect {
|
|
2490
|
+
viewer;
|
|
2491
|
+
dataSource;
|
|
2492
|
+
options;
|
|
2493
|
+
routeEntity = null;
|
|
2494
|
+
material = null;
|
|
2495
|
+
renderFrame = 0;
|
|
2496
|
+
destroyed = false;
|
|
2497
|
+
constructor(viewer, options) {
|
|
2498
|
+
this.viewer = viewer;
|
|
2499
|
+
this.options = normalizeMaterialPolylineOptions(options);
|
|
2500
|
+
this.dataSource = new CustomDataSource('geo-effect-kit-material-polyline');
|
|
2501
|
+
this.dataSource.show = this.options.visible;
|
|
2502
|
+
this.viewer.dataSources.add(this.dataSource);
|
|
2503
|
+
this.renderEntity();
|
|
2504
|
+
this.startRenderLoop();
|
|
2505
|
+
this.viewer.scene.requestRender();
|
|
2506
|
+
}
|
|
2507
|
+
update(options) {
|
|
2508
|
+
if (this.destroyed)
|
|
2509
|
+
return;
|
|
2510
|
+
const nextImage = options.image !== undefined
|
|
2511
|
+
? options.image
|
|
2512
|
+
: options.imagePreset !== undefined
|
|
2513
|
+
? normalizeMaterialPolylineOptions({ positions: this.options.positions, imagePreset: options.imagePreset }).image
|
|
2514
|
+
: this.options.image;
|
|
2515
|
+
const next = normalizeMaterialPolylineOptions({
|
|
2516
|
+
...this.options,
|
|
2517
|
+
...options,
|
|
2518
|
+
positions: options.positions ?? this.options.positions,
|
|
2519
|
+
repeat: options.repeat ?? this.options.repeat,
|
|
2520
|
+
image: nextImage,
|
|
2521
|
+
clampToGround: options.clampToGround ?? this.options.clampToGround,
|
|
2522
|
+
visible: options.visible ?? this.options.visible,
|
|
2523
|
+
});
|
|
2524
|
+
const rebuildEntity = shouldRebuildMaterialPolyline(this.options, next);
|
|
2525
|
+
const materialClassChanged = isNativeMaterialPolylineStyle(this.options.style) !== isNativeMaterialPolylineStyle(next.style);
|
|
2526
|
+
this.options = next;
|
|
2527
|
+
if (rebuildEntity || materialClassChanged) {
|
|
2528
|
+
this.renderEntity();
|
|
2529
|
+
}
|
|
2530
|
+
else {
|
|
2531
|
+
this.applyEntityOptions();
|
|
2532
|
+
}
|
|
2533
|
+
this.dataSource.show = this.options.visible;
|
|
2534
|
+
if (this.options.visible)
|
|
2535
|
+
this.startRenderLoop();
|
|
2536
|
+
else
|
|
2537
|
+
this.stopRenderLoop();
|
|
2538
|
+
this.viewer.scene.requestRender();
|
|
2539
|
+
}
|
|
2540
|
+
show() {
|
|
2541
|
+
if (this.destroyed)
|
|
2542
|
+
return;
|
|
2543
|
+
this.options = { ...this.options, visible: true };
|
|
2544
|
+
this.dataSource.show = true;
|
|
2545
|
+
this.startRenderLoop();
|
|
2546
|
+
this.viewer.scene.requestRender();
|
|
2547
|
+
}
|
|
2548
|
+
hide() {
|
|
2549
|
+
if (this.destroyed)
|
|
2550
|
+
return;
|
|
2551
|
+
this.options = { ...this.options, visible: false };
|
|
2552
|
+
this.dataSource.show = false;
|
|
2553
|
+
this.stopRenderLoop();
|
|
2554
|
+
this.viewer.scene.requestRender();
|
|
2555
|
+
}
|
|
2556
|
+
flyTo(options = {}) {
|
|
2557
|
+
if (this.destroyed)
|
|
2558
|
+
return;
|
|
2559
|
+
const { center, radius } = getPositionBounds(this.getRenderPositions(), Math.max(2000, this.options.width * 900));
|
|
2560
|
+
this.viewer.camera.flyToBoundingSphere(new BoundingSphere(center, radius), {
|
|
2561
|
+
duration: options.duration ?? 1,
|
|
2562
|
+
offset: new HeadingPitchRange(0, options.pitch ?? -0.62, radius * (options.rangeMultiplier ?? 2.4)),
|
|
2563
|
+
});
|
|
2564
|
+
}
|
|
2565
|
+
destroy() {
|
|
2566
|
+
if (this.destroyed)
|
|
2567
|
+
return;
|
|
2568
|
+
this.destroyed = true;
|
|
2569
|
+
this.stopRenderLoop();
|
|
2570
|
+
this.dataSource.entities.removeAll();
|
|
2571
|
+
this.routeEntity = null;
|
|
2572
|
+
this.material = null;
|
|
2573
|
+
this.viewer.dataSources.remove(this.dataSource, true);
|
|
2574
|
+
this.viewer.scene.requestRender();
|
|
2575
|
+
}
|
|
2576
|
+
isVisible() {
|
|
2577
|
+
return this.options.visible;
|
|
2578
|
+
}
|
|
2579
|
+
isDestroyed() {
|
|
2580
|
+
return this.destroyed;
|
|
2581
|
+
}
|
|
2582
|
+
getOptions() {
|
|
2583
|
+
return {
|
|
2584
|
+
...this.options,
|
|
2585
|
+
positions: clonePositions(this.options.positions),
|
|
2586
|
+
repeat: { ...this.options.repeat },
|
|
2587
|
+
};
|
|
2588
|
+
}
|
|
2589
|
+
renderEntity() {
|
|
2590
|
+
clearEntities(this.dataSource);
|
|
2591
|
+
this.material = null;
|
|
2592
|
+
const positions = positionsToCartesians(this.getRenderPositions());
|
|
2593
|
+
const material = this.createMaterial();
|
|
2594
|
+
this.routeEntity = this.dataSource.entities.add({
|
|
2595
|
+
id: 'geo-effect-kit-material-polyline-route',
|
|
2596
|
+
polyline: {
|
|
2597
|
+
positions,
|
|
2598
|
+
width: this.options.width,
|
|
2599
|
+
clampToGround: this.options.clampToGround && this.options.arcHeight <= 0,
|
|
2600
|
+
material,
|
|
2601
|
+
},
|
|
2602
|
+
});
|
|
2603
|
+
}
|
|
2604
|
+
applyEntityOptions() {
|
|
2605
|
+
if (!this.routeEntity?.polyline)
|
|
2606
|
+
return;
|
|
2607
|
+
this.routeEntity.polyline.width = new ConstantProperty(this.options.width);
|
|
2608
|
+
if (this.material) {
|
|
2609
|
+
this.applyDynamicMaterialUniforms(this.material);
|
|
2610
|
+
}
|
|
2611
|
+
else {
|
|
2612
|
+
this.routeEntity.polyline.material = this.createMaterial();
|
|
2613
|
+
}
|
|
2614
|
+
}
|
|
2615
|
+
createMaterial() {
|
|
2616
|
+
if (this.options.style === 'solid') {
|
|
2617
|
+
return new ColorMaterialProperty(Color.fromCssColorString(this.options.color));
|
|
2618
|
+
}
|
|
2619
|
+
if (this.options.style === 'outline') {
|
|
2620
|
+
return new PolylineOutlineMaterialProperty({
|
|
2621
|
+
color: Color.fromCssColorString(this.options.color),
|
|
2622
|
+
outlineColor: Color.fromCssColorString(this.options.secondaryColor),
|
|
2623
|
+
outlineWidth: this.options.outlineWidth,
|
|
2624
|
+
});
|
|
2625
|
+
}
|
|
2626
|
+
if (this.options.style === 'arrow') {
|
|
2627
|
+
return new PolylineArrowMaterialProperty(Color.fromCssColorString(this.options.color));
|
|
2628
|
+
}
|
|
2629
|
+
if (this.options.style === 'dash' || this.options.style === 'dual-dash') {
|
|
2630
|
+
return new PolylineDashMaterialProperty({
|
|
2631
|
+
color: Color.fromCssColorString(this.options.color),
|
|
2632
|
+
gapColor: Color.fromCssColorString(this.options.style === 'dual-dash' ? this.options.secondaryColor : 'rgba(0, 0, 0, 0)'),
|
|
2633
|
+
dashLength: Math.max(4, this.options.repeat.x * 4),
|
|
2634
|
+
dashPattern: this.options.style === 'dual-dash' ? 0b1111000000 : 255,
|
|
2635
|
+
});
|
|
2636
|
+
}
|
|
2637
|
+
registerMaterialPolylineMaterial();
|
|
2638
|
+
const material = new DynamicCesiumMaterialProperty(GEO_MATERIAL_POLYLINE_MATERIAL_TYPE, {});
|
|
2639
|
+
this.material = material;
|
|
2640
|
+
this.applyDynamicMaterialUniforms(material);
|
|
2641
|
+
return material;
|
|
2642
|
+
}
|
|
2643
|
+
applyDynamicMaterialUniforms(material) {
|
|
2644
|
+
material.uniforms.color = Color.fromCssColorString(this.options.color).withAlpha(1);
|
|
2645
|
+
material.uniforms.secondaryColor = Color.fromCssColorString(this.options.secondaryColor).withAlpha(1);
|
|
2646
|
+
material.uniforms.backgroundColor = Color.fromCssColorString(this.options.backgroundColor);
|
|
2647
|
+
material.uniforms.image = this.options.image;
|
|
2648
|
+
material.uniforms.speed = this.options.speed;
|
|
2649
|
+
material.uniforms.repeatX = this.options.repeat.x;
|
|
2650
|
+
material.uniforms.repeatY = this.options.repeat.y;
|
|
2651
|
+
material.uniforms.styleType = getMaterialPolylineStyleUniform(this.options.style);
|
|
2652
|
+
}
|
|
2653
|
+
getRenderPositions() {
|
|
2654
|
+
const rounded = roundPolylineCorners(this.options.positions, this.options.cornerRadius);
|
|
2655
|
+
if (this.options.arcHeight <= 0)
|
|
2656
|
+
return rounded;
|
|
2657
|
+
const result = [];
|
|
2658
|
+
for (let index = 1; index < rounded.length; index += 1) {
|
|
2659
|
+
const from = rounded[index - 1];
|
|
2660
|
+
const to = rounded[index];
|
|
2661
|
+
if (!from || !to)
|
|
2662
|
+
continue;
|
|
2663
|
+
const segment = sampleFlyLineArc({ from, to }, this.options.arcHeight, this.options.arcSamples);
|
|
2664
|
+
segment.forEach((position, segmentIndex) => {
|
|
2665
|
+
if (index > 1 && segmentIndex === 0)
|
|
2666
|
+
return;
|
|
2667
|
+
result.push(position);
|
|
2668
|
+
});
|
|
2669
|
+
}
|
|
2670
|
+
return result.length >= 2 ? result : rounded;
|
|
2671
|
+
}
|
|
2672
|
+
startRenderLoop() {
|
|
2673
|
+
if (this.renderFrame || !this.options.visible || typeof window === 'undefined')
|
|
2674
|
+
return;
|
|
2675
|
+
const tick = () => {
|
|
2676
|
+
if (this.destroyed || !this.options.visible) {
|
|
2677
|
+
this.renderFrame = 0;
|
|
2678
|
+
return;
|
|
2679
|
+
}
|
|
2680
|
+
this.viewer.scene.requestRender();
|
|
2681
|
+
this.renderFrame = window.requestAnimationFrame(tick);
|
|
2682
|
+
};
|
|
2683
|
+
this.renderFrame = window.requestAnimationFrame(tick);
|
|
2684
|
+
}
|
|
2685
|
+
stopRenderLoop() {
|
|
2686
|
+
if (!this.renderFrame || typeof window === 'undefined') {
|
|
2687
|
+
this.renderFrame = 0;
|
|
2688
|
+
return;
|
|
2689
|
+
}
|
|
2690
|
+
window.cancelAnimationFrame(this.renderFrame);
|
|
2691
|
+
this.renderFrame = 0;
|
|
2692
|
+
}
|
|
2693
|
+
}
|
|
2373
2694
|
export class PipeFlowEffect {
|
|
2374
2695
|
viewer;
|
|
2375
2696
|
dataSource;
|
|
@@ -3186,6 +3507,17 @@ function createRadarScanMaterial(options) {
|
|
|
3186
3507
|
});
|
|
3187
3508
|
return material;
|
|
3188
3509
|
}
|
|
3510
|
+
export function createRadarScanMaterialProperty(options) {
|
|
3511
|
+
const normalized = normalizeRadarScanOptions(options);
|
|
3512
|
+
registerRadarScanMaterial(normalized);
|
|
3513
|
+
return new DynamicCesiumMaterialProperty(GEO_RADAR_SCAN_MATERIAL_TYPE, {
|
|
3514
|
+
color: Color.fromCssColorString(normalized.color).withAlpha(1),
|
|
3515
|
+
opacity: normalized.opacity,
|
|
3516
|
+
ringsEnabled: normalized.rings ? 1 : 0,
|
|
3517
|
+
radarType: getRadarScanTypeUniform(normalized.type),
|
|
3518
|
+
scanDurationMs: normalized.scanDurationMs,
|
|
3519
|
+
});
|
|
3520
|
+
}
|
|
3189
3521
|
function registerRippleSpreadMaterial(options) {
|
|
3190
3522
|
const cache = Material._materialCache;
|
|
3191
3523
|
if (!cache || cache.getMaterial(GEO_RIPPLE_SPREAD_MATERIAL_TYPE))
|
|
@@ -3270,7 +3602,7 @@ function createTemperatureFieldUniforms(options) {
|
|
|
3270
3602
|
...createTemperatureFieldSampleUniforms(options),
|
|
3271
3603
|
};
|
|
3272
3604
|
}
|
|
3273
|
-
class DynamicCesiumMaterialProperty {
|
|
3605
|
+
export class DynamicCesiumMaterialProperty {
|
|
3274
3606
|
definitionChanged = new Event();
|
|
3275
3607
|
isConstant = false;
|
|
3276
3608
|
uniforms;
|
|
@@ -3300,14 +3632,16 @@ function createLightWallMaterialProperty(options) {
|
|
|
3300
3632
|
breathing: options.breathing ? 1 : 0,
|
|
3301
3633
|
});
|
|
3302
3634
|
}
|
|
3303
|
-
function createScanConeMaterialProperty(options) {
|
|
3635
|
+
export function createScanConeMaterialProperty(options) {
|
|
3636
|
+
const normalized = normalizeScanConeOptions(options);
|
|
3304
3637
|
registerScanConeMaterial();
|
|
3305
3638
|
return new DynamicCesiumMaterialProperty(GEO_SCAN_CONE_MATERIAL_TYPE, {
|
|
3306
|
-
color: Color.fromCssColorString(
|
|
3307
|
-
opacity:
|
|
3308
|
-
speed:
|
|
3309
|
-
|
|
3310
|
-
|
|
3639
|
+
color: Color.fromCssColorString(normalized.color).withAlpha(1),
|
|
3640
|
+
opacity: normalized.opacity,
|
|
3641
|
+
speed: normalized.speed,
|
|
3642
|
+
timeSeconds: -1,
|
|
3643
|
+
coneType: getScanConeTypeUniform(normalized.type),
|
|
3644
|
+
aperture: normalized.aperture,
|
|
3311
3645
|
});
|
|
3312
3646
|
}
|
|
3313
3647
|
function createShieldDomeMaterialProperty(options) {
|
|
@@ -3355,6 +3689,7 @@ function registerScanConeMaterial() {
|
|
|
3355
3689
|
color: Color.CYAN,
|
|
3356
3690
|
opacity: 0.62,
|
|
3357
3691
|
speed: 1,
|
|
3692
|
+
timeSeconds: -1,
|
|
3358
3693
|
coneType: 1,
|
|
3359
3694
|
aperture: 34,
|
|
3360
3695
|
}, buildScanConeMaterialSource());
|
|
@@ -3384,6 +3719,18 @@ function registerWaterSurfaceMaterial() {
|
|
|
3384
3719
|
flowDirection: 90,
|
|
3385
3720
|
}, buildWaterSurfaceMaterialSource());
|
|
3386
3721
|
}
|
|
3722
|
+
function registerMaterialPolylineMaterial() {
|
|
3723
|
+
registerMaterial(GEO_MATERIAL_POLYLINE_MATERIAL_TYPE, {
|
|
3724
|
+
color: Color.CYAN,
|
|
3725
|
+
secondaryColor: Color.WHITE,
|
|
3726
|
+
backgroundColor: Color.BLUE.withAlpha(0.35),
|
|
3727
|
+
image: getMaterialPolylinePresetImage('pulse'),
|
|
3728
|
+
speed: 1,
|
|
3729
|
+
repeatX: 4,
|
|
3730
|
+
repeatY: 1,
|
|
3731
|
+
styleType: 6,
|
|
3732
|
+
}, buildMaterialPolylineMaterialSource());
|
|
3733
|
+
}
|
|
3387
3734
|
function registerMaterial(type, uniforms, source) {
|
|
3388
3735
|
const cache = Material._materialCache;
|
|
3389
3736
|
if (!cache || cache.getMaterial(type))
|
|
@@ -3414,6 +3761,20 @@ function normalizePostProcessType(type) {
|
|
|
3414
3761
|
function normalizePolylineFlowType(type) {
|
|
3415
3762
|
return POLYLINE_FLOW_TYPE_VALUES.includes(type) ? type : 'dispatch';
|
|
3416
3763
|
}
|
|
3764
|
+
function normalizeMaterialPolylineStyle(style) {
|
|
3765
|
+
return MATERIAL_POLYLINE_STYLE_VALUES.includes(style) ? style : 'flow';
|
|
3766
|
+
}
|
|
3767
|
+
function normalizeMaterialPolylineImagePreset(imagePreset) {
|
|
3768
|
+
return MATERIAL_POLYLINE_IMAGE_PRESET_VALUES.includes(imagePreset)
|
|
3769
|
+
? imagePreset
|
|
3770
|
+
: 'pulse';
|
|
3771
|
+
}
|
|
3772
|
+
function normalizeMaterialPolylineRepeat(repeat) {
|
|
3773
|
+
return {
|
|
3774
|
+
x: clamp(finiteOr(repeat?.x ?? 4, 4), 1, 64),
|
|
3775
|
+
y: clamp(finiteOr(repeat?.y ?? 1, 1), 1, 16),
|
|
3776
|
+
};
|
|
3777
|
+
}
|
|
3417
3778
|
function normalizeFlyLineMode(mode) {
|
|
3418
3779
|
return FLY_LINE_MODE_VALUES.includes(mode) ? mode : 'single-arc';
|
|
3419
3780
|
}
|
|
@@ -3467,6 +3828,9 @@ function getPostProcessTypeUniform(type) {
|
|
|
3467
3828
|
return 5;
|
|
3468
3829
|
return 6;
|
|
3469
3830
|
}
|
|
3831
|
+
function getMaterialPolylineStyleUniform(style) {
|
|
3832
|
+
return MATERIAL_POLYLINE_STYLE_VALUES.indexOf(style) + 1;
|
|
3833
|
+
}
|
|
3470
3834
|
function getLightWallTypeUniform(type) {
|
|
3471
3835
|
if (type === 'security')
|
|
3472
3836
|
return 1;
|
|
@@ -3505,7 +3869,57 @@ function getWaterSurfaceTypeUniform(type) {
|
|
|
3505
3869
|
return 1;
|
|
3506
3870
|
if (type === 'lake')
|
|
3507
3871
|
return 2;
|
|
3508
|
-
|
|
3872
|
+
if (type === 'flood')
|
|
3873
|
+
return 3;
|
|
3874
|
+
return 4;
|
|
3875
|
+
}
|
|
3876
|
+
function isNativeMaterialPolylineStyle(style) {
|
|
3877
|
+
return style === 'solid' || style === 'outline' || style === 'arrow' || style === 'dash' || style === 'dual-dash';
|
|
3878
|
+
}
|
|
3879
|
+
function getMaterialPolylinePresetImage(imagePreset) {
|
|
3880
|
+
const presets = {
|
|
3881
|
+
pulse: createMaterialPolylineTextureDataUrl('pulse', '#ffffff', '#00ff66'),
|
|
3882
|
+
gradual: createMaterialPolylineTextureDataUrl('gradual', '#e8fff5', '#66bd63'),
|
|
3883
|
+
'arrow-blue': createMaterialPolylineTextureDataUrl('arrow-blue', '#ffffff', '#1f78ff'),
|
|
3884
|
+
rainbow: createMaterialPolylineTextureDataUrl('rainbow', '#ff4d4d', '#42e8ff'),
|
|
3885
|
+
'arrow-repeat': createMaterialPolylineTextureDataUrl('arrow-repeat', '#d9ffff', '#00d4ff'),
|
|
3886
|
+
dovetail: createMaterialPolylineTextureDataUrl('dovetail', '#e9ffd8', '#a6d96a'),
|
|
3887
|
+
'yellow-flow': createMaterialPolylineTextureDataUrl('yellow-flow', '#f2ff6a', '#95ff2f'),
|
|
3888
|
+
'transparent-flow': createMaterialPolylineTextureDataUrl('transparent-flow', '#59f9ff', '#0bfbff'),
|
|
3889
|
+
interval: createMaterialPolylineTextureDataUrl('interval', '#ffffff', '#59f9ff'),
|
|
3890
|
+
'small-arrow': createMaterialPolylineTextureDataUrl('small-arrow', '#ffffff', '#33f7ff'),
|
|
3891
|
+
gradient: createMaterialPolylineTextureDataUrl('gradient', '#ffffff', '#33f7ff'),
|
|
3892
|
+
};
|
|
3893
|
+
return presets[imagePreset];
|
|
3894
|
+
}
|
|
3895
|
+
function createMaterialPolylineTextureDataUrl(kind, first, second) {
|
|
3896
|
+
const svg = getMaterialPolylineTextureSvg(kind, first, second);
|
|
3897
|
+
return `data:image/svg+xml;utf8,${encodeURIComponent(svg)}`;
|
|
3898
|
+
}
|
|
3899
|
+
function getMaterialPolylineTextureSvg(kind, first, second) {
|
|
3900
|
+
if (kind === 'rainbow') {
|
|
3901
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><linearGradient id="g" x1="0" x2="1"><stop stop-color="#ff2347"/><stop offset=".25" stop-color="#ffec3d"/><stop offset=".5" stop-color="#4dff73"/><stop offset=".75" stop-color="#42e8ff"/><stop offset="1" stop-color="#b34dff"/></linearGradient><rect width="128" height="16" fill="none"/><path d="M0 8H128" stroke="url(#g)" stroke-width="11" stroke-linecap="round"/></svg>`;
|
|
3902
|
+
}
|
|
3903
|
+
if (kind === 'arrow-blue' || kind === 'arrow-repeat' || kind === 'small-arrow') {
|
|
3904
|
+
const repeat = kind === 'small-arrow' ? 'M16 3l10 5-10 5V9H0V7h16z M48 3l10 5-10 5V9H32V7h16z M80 3l10 5-10 5V9H64V7h16z' : 'M42 2l22 6-22 6V9H0V7h42z M106 2l22 6-22 6V9H64V7h42z';
|
|
3905
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><rect width="128" height="16" fill="none"/><path d="${repeat}" fill="${second}" opacity=".95"/><path d="M0 8H128" stroke="${first}" stroke-width="2" opacity=".55"/></svg>`;
|
|
3906
|
+
}
|
|
3907
|
+
if (kind === 'dovetail') {
|
|
3908
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><rect width="128" height="16" fill="none"/><path d="M0 2h38l10 6-10 6H0l10-6z M64 2h38l10 6-10 6H64l10-6z" fill="${second}" opacity=".88"/><path d="M0 8H128" stroke="${first}" stroke-width="2" opacity=".45"/></svg>`;
|
|
3909
|
+
}
|
|
3910
|
+
if (kind === 'interval') {
|
|
3911
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><rect width="128" height="16" fill="none"/><path d="M0 8H18M32 8H50M64 8H82M96 8H114" stroke="${first}" stroke-width="8" stroke-linecap="round"/><path d="M18 8H32M50 8H64M82 8H96M114 8H128" stroke="${second}" stroke-width="4" stroke-linecap="round" opacity=".82"/></svg>`;
|
|
3912
|
+
}
|
|
3913
|
+
if (kind === 'gradient') {
|
|
3914
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><linearGradient id="g" x1="0" x2="1"><stop stop-color="${second}" stop-opacity="0"/><stop offset=".55" stop-color="${second}" stop-opacity=".86"/><stop offset="1" stop-color="${first}"/></linearGradient><rect width="128" height="16" fill="none"/><path d="M0 8H128" stroke="url(#g)" stroke-width="10" stroke-linecap="round"/></svg>`;
|
|
3915
|
+
}
|
|
3916
|
+
if (kind === 'transparent-flow') {
|
|
3917
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><linearGradient id="g" x1="0" x2="1"><stop stop-color="${second}" stop-opacity="0"/><stop offset=".45" stop-color="${second}" stop-opacity=".35"/><stop offset="1" stop-color="${first}" stop-opacity=".95"/></linearGradient><rect width="128" height="16" fill="none"/><path d="M0 8H128" stroke="url(#g)" stroke-width="9" stroke-linecap="round"/></svg>`;
|
|
3918
|
+
}
|
|
3919
|
+
if (kind === 'yellow-flow') {
|
|
3920
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><rect width="128" height="16" fill="none"/><path d="M0 8H128" stroke="${second}" stroke-width="9" stroke-linecap="round" opacity=".72"/><path d="M64 8H128" stroke="${first}" stroke-width="5" stroke-linecap="round"/></svg>`;
|
|
3921
|
+
}
|
|
3922
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="128" height="16" viewBox="0 0 128 16"><linearGradient id="g" x1="0" x2="1"><stop stop-color="${second}" stop-opacity="0"/><stop offset=".62" stop-color="${second}" stop-opacity=".78"/><stop offset="1" stop-color="${first}"/></linearGradient><rect width="128" height="16" fill="none"/><path d="M0 8H128" stroke="url(#g)" stroke-width="10" stroke-linecap="round"/><circle cx="108" cy="8" r="5" fill="${first}"/></svg>`;
|
|
3509
3923
|
}
|
|
3510
3924
|
function getPolylineFlowColor(type, color) {
|
|
3511
3925
|
const base = Color.fromCssColorString(color);
|