ansel0926
2022-05-15 ebc4c778854c8d2666b1bbaf3dcba2ba00f08453
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
 * Radar Scan from center
 */
 
(function (window) {
    'use strict';
 
    function define_CesiumRadarScan(){
        //Main object
        var CesiumRadarScan = {};
        
        /*
         * 添加雷达扫描线
         * viewer
         * cartographicCenter 扫描中心
         * radius  半径 米
         * scanColor 扫描颜色
         * duration 持续时间 毫秒
         */
        function AddRadarScanPostStage(viewer, cartographicCenter, radius, scanColor, duration) {
            var ScanSegmentShader =
                "uniform sampler2D colorTexture;\n" +
                "uniform sampler2D depthTexture;\n" +
                "varying vec2 v_textureCoordinates;\n" +
                "uniform vec4 u_scanCenterEC;\n" +
                "uniform vec3 u_scanPlaneNormalEC;\n" +
                "uniform vec3 u_scanLineNormalEC;\n" +
                "uniform float u_radius;\n" +
                "uniform vec4 u_scanColor;\n" +
                "vec4 toEye(in vec2 uv, in float depth)\n" +
                " {\n" +
                  " vec2 xy = vec2((uv.x * 2.0 - 1.0),(uv.y * 2.0 - 1.0));\n" +
                  " vec4 posInCamera = czm_inverseProjection * vec4(xy, depth, 1.0);\n" +
                  " posInCamera = posInCamera / posInCamera.w;\n" +
                  " return posInCamera;\n" +
                " }\n" +
                "bool isPointOnLineRight(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt)\n" +
                "{\n" +
                    "vec3 v01 = testPt - ptOnLine;\n" +
                    "normalize(v01);\n" +
                    "vec3 temp = cross(v01, lineNormal);\n" +
                    "float d = dot(temp, u_scanPlaneNormalEC);\n" +
                    "return d > 0.5;\n" +
                "}\n" +
                "vec3 pointProjectOnPlane(in vec3 planeNormal, in vec3 planeOrigin, in vec3 point)\n" +
                "{\n" +
                    "vec3 v01 = point - planeOrigin;\n" +
                    "float d = dot(planeNormal, v01) ;\n" +
                    "return (point - planeNormal * d);\n" +
                 "}\n" +
                 "float distancePointToLine(in vec3 ptOnLine, in vec3 lineNormal, in vec3 testPt)\n" +
                 "{\n" +
                    "vec3 tempPt = pointProjectOnPlane(lineNormal, ptOnLine, testPt);\n" +
                    "return length(tempPt - ptOnLine);\n" +
                 "}\n" +
                 "float getDepth(in vec4 depth)\n" +
                 "{\n" +
                    "float z_window = czm_unpackDepth(depth);\n" +
                    "z_window = czm_reverseLogDepth(z_window);\n" +
                    "float n_range = czm_depthRange.near;\n" +
                    "float f_range = czm_depthRange.far;\n" +
                    "return (2.0 * z_window - n_range - f_range) / (f_range - n_range);\n" +
                 "}\n" +
                 "void main()\n" +
                 "{\n" +
                    "gl_FragColor = texture2D(colorTexture, v_textureCoordinates);\n" +
                    "float depth = getDepth(texture2D(depthTexture, v_textureCoordinates));\n" +
                    "vec4 viewPos = toEye(v_textureCoordinates, depth);\n" +
                    "vec3 prjOnPlane = pointProjectOnPlane(u_scanPlaneNormalEC.xyz, u_scanCenterEC.xyz, viewPos.xyz);\n" +
                    "float dis = length(prjOnPlane.xyz - u_scanCenterEC.xyz);\n" +
                    "float twou_radius = u_radius * 2.0;\n" +
                    "if(dis < u_radius)\n" +
                    "{\n" +
                        "float f0 = 1.0 - abs(u_radius - dis) / u_radius;\n" +
                        "f0 = pow(f0, 64.0);\n" +
                        "vec3 lineEndPt = vec3(u_scanCenterEC.xyz) + u_scanLineNormalEC * u_radius;\n" +
                        "float f = 0.0;\n" +
                        "if(isPointOnLineRight(u_scanCenterEC.xyz, u_scanLineNormalEC.xyz, prjOnPlane.xyz))\n" +
                        "{\n" +
                            "float dis1 = length(prjOnPlane.xyz - lineEndPt);\n" +
                            "f = abs(twou_radius - dis1) / twou_radius;\n" +
                            "f = pow(f, 6.0);\n" +
                        "}\n" +
                        "gl_FragColor = mix(gl_FragColor, u_scanColor, f + f0);\n" +
                     "}\n" +
                  "}\n";
            var _Cartesian3Center = Cesium.Cartographic.toCartesian(cartographicCenter);
            var _Cartesian4Center = new Cesium.Cartesian4(_Cartesian3Center.x, _Cartesian3Center.y, _Cartesian3Center.z, 1);
            var _CartographicCenter1 = new Cesium.Cartographic(cartographicCenter.longitude, cartographicCenter.latitude, cartographicCenter.height + 500);
            var _Cartesian3Center1 = Cesium.Cartographic.toCartesian(_CartographicCenter1);
            var _Cartesian4Center1 = new Cesium.Cartesian4(_Cartesian3Center1.x, _Cartesian3Center1.y, _Cartesian3Center1.z, 1);
            var _CartographicCenter2 = new Cesium.Cartographic(cartographicCenter.longitude + Cesium.Math.toRadians(0.001), cartographicCenter.latitude, cartographicCenter.height);
            var _Cartesian3Center2 = Cesium.Cartographic.toCartesian(_CartographicCenter2);
            var _Cartesian4Center2 = new Cesium.Cartesian4(_Cartesian3Center2.x, _Cartesian3Center2.y, _Cartesian3Center2.z, 1);
            var _RotateQ = new Cesium.Quaternion();
            var _RotateM = new Cesium.Matrix3();
            var _time = (new Date()).getTime();
            var _scratchCartesian4Center = new Cesium.Cartesian4();
            var _scratchCartesian4Center1 = new Cesium.Cartesian4();
            var _scratchCartesian4Center2 = new Cesium.Cartesian4();
            var _scratchCartesian3Normal = new Cesium.Cartesian3();
            var _scratchCartesian3Normal1 = new Cesium.Cartesian3();
            var ScanPostStage = new Cesium.PostProcessStage({
                fragmentShader: ScanSegmentShader,
                uniforms: {
                    u_scanCenterEC: function () {
                        return Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                    },
                    u_scanPlaneNormalEC: function () {
                        var temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                        var temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1, _scratchCartesian4Center1);
                        _scratchCartesian3Normal.x = temp1.x - temp.x;
                        _scratchCartesian3Normal.y = temp1.y - temp.y;
                        _scratchCartesian3Normal.z = temp1.z - temp.z;
                        Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);
                        return _scratchCartesian3Normal;
                    },
                    u_radius: radius,
                    u_scanLineNormalEC: function () {
                        var temp = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center, _scratchCartesian4Center);
                        var temp1 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center1, _scratchCartesian4Center1);
                        var temp2 = Cesium.Matrix4.multiplyByVector(viewer.camera._viewMatrix, _Cartesian4Center2, _scratchCartesian4Center2);
                        _scratchCartesian3Normal.x = temp1.x - temp.x;
                        _scratchCartesian3Normal.y = temp1.y - temp.y;
                        _scratchCartesian3Normal.z = temp1.z - temp.z;
                        Cesium.Cartesian3.normalize(_scratchCartesian3Normal, _scratchCartesian3Normal);
                        _scratchCartesian3Normal1.x = temp2.x - temp.x;
                        _scratchCartesian3Normal1.y = temp2.y - temp.y;
                        _scratchCartesian3Normal1.z = temp2.z - temp.z;
                        var tempTime = (((new Date()).getTime() - _time) % duration) / duration;
                        Cesium.Quaternion.fromAxisAngle(_scratchCartesian3Normal, tempTime * Cesium.Math.PI * 2, _RotateQ);
                        Cesium.Matrix3.fromQuaternion(_RotateQ, _RotateM);
                        Cesium.Matrix3.multiplyByVector(_RotateM, _scratchCartesian3Normal1, _scratchCartesian3Normal1);
                        Cesium.Cartesian3.normalize(_scratchCartesian3Normal1, _scratchCartesian3Normal1);
                        return _scratchCartesian3Normal1;
                    },
                    u_scanColor: scanColor
                }
            });
            viewer.scene.postProcessStages.add(ScanPostStage);
            return ScanPostStage;
        }
        
        CesiumRadarScan.add = function(options){
            var CartographicCenter = new Cesium.Cartographic(Cesium.Math.toRadians(options.lon), Cesium.Math.toRadians(options.lat), 0);
            var ScanPostStage = AddRadarScanPostStage(options.viewer, CartographicCenter, options.maxRadius, options.scanColor, options.duration);
            return ScanPostStage;
        };
        
        CesiumRadarScan.removes = function(viewer,ScanPostStages){
            for ( var i = 0; i < ScanPostStages.length; i++) {
                viewer.scene.postProcessStages.remove(ScanPostStages[i]);
            }
        };
        
        return CesiumRadarScan;
    }
    
    if (typeof(CesiumRadarScan) === 'undefined') {
        window.CesiumRadarScan = define_CesiumRadarScan();
    } else {
        console.log("CesiumRadarScan already defined.");
    }
})(window);