deeptwins-engine-3d 0.1.49 → 0.1.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/esm/constant.d.ts +9 -0
  2. package/dist/esm/constant.js +16 -0
  3. package/dist/esm/drawCommand/index.d.ts +2 -0
  4. package/dist/esm/drawCommand/index.js +2 -0
  5. package/dist/esm/drawCommand/viewShed/Event.d.ts +42 -0
  6. package/dist/esm/drawCommand/viewShed/Event.js +142 -0
  7. package/dist/esm/drawCommand/viewShed/RectangularSensorPrimitive.d.ts +266 -0
  8. package/dist/esm/drawCommand/viewShed/RectangularSensorPrimitive.js +1271 -0
  9. package/dist/esm/drawCommand/viewShed/ViewShadowPrimitive.d.ts +29 -0
  10. package/dist/esm/drawCommand/viewShed/ViewShadowPrimitive.js +66 -0
  11. package/dist/esm/drawCommand/viewShed/ViewShedAnalyserLayer.d.ts +182 -0
  12. package/dist/esm/drawCommand/viewShed/ViewShedAnalyserLayer.js +466 -0
  13. package/dist/esm/drawCommand/viewShed/ViewShedMap.d.ts +22 -0
  14. package/dist/esm/drawCommand/viewShed/ViewShedMap.js +1238 -0
  15. package/dist/esm/drawCommand/viewShed/config.d.ts +20 -0
  16. package/dist/esm/drawCommand/viewShed/config.js +21 -0
  17. package/dist/esm/graphicLayer/PolygonGroundPrimitiveImageMaterialInstance.js +1 -1
  18. package/dist/esm/index.d.ts +2 -1
  19. package/dist/esm/index.js +7 -4
  20. package/dist/esm/map/Map.js +1 -1
  21. package/dist/esm/material/primitive/ImageMaterialAppearance.d.ts +1 -1
  22. package/dist/esm/tool/BuildClampedPolygonGrid.d.ts +2 -9
  23. package/dist/esm/tool/BuildClampedPolygonGrid.js +195 -73
  24. package/dist/esm/tool/utils.d.ts +1 -0
  25. package/dist/esm/tool/utils.js +21 -0
  26. package/dist/esm/videoFusion/BaseVideo.js +17 -17
  27. package/dist/esm/videoFusion/VideoProject.d.ts +5 -5
  28. package/dist/esm/videoFusion/VideoProject.js +174 -184
  29. package/dist/esm/videoFusion/VideoTexture.d.ts +5 -1
  30. package/dist/esm/videoFusion/VideoTexture.js +133 -46
  31. package/dist/umd/deeptwins-engine-3d.min.js +1 -1
  32. package/package.json +4 -2
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 公共着色器
3
+ * @returns {ShaderSource}
4
+ */
5
+ export declare const sensorComm = "\nuniform vec4 u_intersectionColor;\nuniform float u_intersectionWidth;\nuniform vec4 u_lineColor;\n\nbool inSensorShadow(vec3 coneVertexWC, vec3 pointWC)\n{ \n // Diagonal matrix from the unscaled ellipsoid space to the scaled space.\n vec3 D = czm_ellipsoidInverseRadii; \n // Sensor vertex in the scaled ellipsoid space \n vec3 q = D * coneVertexWC; \n float qMagnitudeSquared = dot(q, q); \n float test = qMagnitudeSquared - 1.0; \n // Sensor vertex to fragment vector in the ellipsoid's scaled space \n vec3 temp = D * pointWC - q; \n float d = dot(temp, q); \n // Behind silhouette plane and inside silhouette cone \n return (d < -test) && (d / length(temp) < -sqrt(test));\n}\n\nvec4 getLineColor()\n{ \n return u_lineColor;\n}\n\nvec4 getIntersectionColor()\n{ \n return u_intersectionColor;\n}\n\nfloat getIntersectionWidth()\n{ \n return u_intersectionWidth;\n}\n\nvec2 sensor2dTextureCoordinates(float sensorRadius, vec3 pointMC)\n{ \n // (s, t) both in the range [0, 1] \n float t = pointMC.z / sensorRadius; \n float s = 1.0 + (atan(pointMC.y, pointMC.x) / czm_twoPi); \n s = s - floor(s); \n return vec2(s, t);\n}\n\n";
6
+ /**
7
+ * VS着色器
8
+ * @returns {ShaderSource}
9
+ */
10
+ export declare const sensorVS = "\nin vec4 position;\nin vec3 normal;\nout vec3 v_position;\nout vec3 v_positionWC;\nout vec3 v_positionEC;\nout vec3 v_normalEC;\nvoid main()\n{ \n gl_Position = czm_modelViewProjection * position; \n v_position = vec3(position); \n v_positionWC = (czm_model * position).xyz; \n v_positionEC = (czm_modelView * position).xyz; \n v_normalEC = czm_normal * normal;\n}";
11
+ /**
12
+ * FS着色器
13
+ * @returns {ShaderSource}
14
+ */
15
+ export declare const sensorFS = "\nuniform bool u_showIntersection;\nuniform bool u_showThroughEllipsoid;\nuniform float u_radius;\nuniform float u_xHalfAngle;\nuniform float u_yHalfAngle;\nuniform float u_normalDirection;\nuniform float u_type;\nin vec3 v_position;\nin vec3 v_positionWC;\nin vec3 v_positionEC;\nin vec3 v_normalEC;\nvec4 getColor(float sensorRadius, vec3 pointEC)\n{ \n czm_materialInput materialInput; \n vec3 pointMC = (czm_inverseModelView * vec4(pointEC, 1.0)).xyz; \n materialInput.st = sensor2dTextureCoordinates(sensorRadius, pointMC); \n materialInput.str = pointMC / sensorRadius; \n\n vec3 positionToEyeEC = -v_positionEC; \n materialInput.positionToEyeEC = positionToEyeEC; \n\n vec3 normalEC = normalize(v_normalEC); \n materialInput.normalEC = u_normalDirection * normalEC; \n\n czm_material material = czm_getMaterial(materialInput); \n\n return mix(czm_phong(normalize(positionToEyeEC), material,czm_lightDirectionEC),vec4(material.diffuse, material.alpha), 0.4);\n}\n\nbool isOnBoundary(float value, float epsilon)\n{ \n float width = getIntersectionWidth(); \n float tolerance = width * epsilon;\n #ifdef GL_OES_standard_derivatives \n float delta = max(abs(dFdx(value)), abs(dFdy(value))); \n float pixels = width * delta; \n float temp = abs(value); \n // There are a couple things going on here. \n // First we test the value at the current fragment to see if it is within the tolerance. \n // We also want to check if the value of an adjacent pixel is within the tolerance, \n // but we don't want to admit points that are obviously not on the surface. \n // For example, if we are looking for \"value\" to be close to 0, but value is 1 and the adjacent value is 2, \n // then the delta would be 1 and \"temp - delta\" would be \"1 - 1\" which is zero even though neither of \n // the points is close to zero. \n return temp < tolerance && temp < pixels || (delta < 10.0 * tolerance && temp - delta < tolerance && temp < pixels);\n #else \n return abs(value) < tolerance;\n #endif\n}\n\n\nvec4 shade(bool isOnBoundary)\n{ \n\n if (u_showIntersection && isOnBoundary) \n { \n return getIntersectionColor(); \n } \n if(u_type == 1.0)\n { \n return getLineColor(); \n } \n\n return getColor(u_radius, v_positionEC);\n\n}\n \nfloat ellipsoidSurfaceFunction(vec3 point)\n{ \n vec3 scaled = czm_ellipsoidInverseRadii * point; \n return dot(scaled, scaled) - 1.0;\n}\n\nvoid main()\n{ \n vec3 sensorVertexWC = czm_model[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n vec3 sensorVertexEC = czm_modelView[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n //vec3 pixDir = normalize(v_position); \n float positionX = v_position.x; \n float positionY = v_position.y; \n float positionZ = v_position.z; \n vec3 zDir = vec3(0.0, 0.0, 1.0); \n vec3 lineX = vec3(positionX, 0 ,positionZ); \n vec3 lineY = vec3(0, positionY, positionZ); \n float resX = dot(normalize(lineX), zDir); \n if(resX < cos(u_xHalfAngle)-0.00001)\n { \n discard; \n } \n float resY = dot(normalize(lineY), zDir); \n if(resY < cos(u_yHalfAngle)-0.00001)\n { \n discard; \n } \n float ellipsoidValue = ellipsoidSurfaceFunction(v_positionWC);\n // Occluded by the ellipsoid?\n if (!u_showThroughEllipsoid)\n { \n // Discard if in the ellipsoid \n // PERFORMANCE_IDEA: A coarse check for ellipsoid intersection could be done on the CPU first. \n if (ellipsoidValue < 0.0) \n { \n discard; \n } \n // Discard if in the sensor's shadow \n if (inSensorShadow(sensorVertexWC, v_positionWC)) \n { \n discard; \n } \n } \n // Notes: Each surface functions should have an associated tolerance based on the floating point error. \n bool isOnEllipsoid = isOnBoundary(ellipsoidValue, czm_epsilon3); \n //isOnEllipsoid = false; \n // if((resX >= 0.8 && resX <= 0.81)||(resY >= 0.8 && resY <= 0.81))\n // { \n // out_FragColor = shade(false);\n // }\n out_FragColor = shade(isOnEllipsoid);\n}\n";
16
+ /**
17
+ * 扫描面FS着色器
18
+ * @returns {ShaderSource}
19
+ */
20
+ export declare const scanPlaneFS = "\nuniform bool u_showIntersection;\nuniform bool u_showThroughEllipsoid;\nuniform float u_radius;\nuniform float u_xHalfAngle;\nuniform float u_yHalfAngle;\nuniform float u_normalDirection;\nuniform vec4 u_color;\nin vec3 v_position;\nin vec3 v_positionWC;\nin vec3 v_positionEC;\nin vec3 v_normalEC;\nvec4 getColor(float sensorRadius, vec3 pointEC)\n{ \n czm_materialInput materialInput; \n vec3 pointMC = (czm_inverseModelView * vec4(pointEC, 1.0)).xyz; \n materialInput.st = sensor2dTextureCoordinates(sensorRadius, pointMC);\n materialInput.str = pointMC / sensorRadius; \n vec3 positionToEyeEC = -v_positionEC; \n materialInput.positionToEyeEC = positionToEyeEC; \n vec3 normalEC = normalize(v_normalEC); \n materialInput.normalEC = u_normalDirection * normalEC; \n czm_material material = czm_getMaterial(materialInput); \n material.diffuse = u_color.rgb; \n material.alpha = u_color.a; \n return mix(czm_phong(normalize(positionToEyeEC), material,czm_lightDirectionEC), vec4(material.diffuse, material.alpha), 0.4);\n}\n\nbool isOnBoundary(float value, float epsilon)\n{ \n float width = getIntersectionWidth(); \n float tolerance = width * epsilon;\n #ifdef GL_OES_standard_derivatives \n float delta = max(abs(dFdx(value)), abs(dFdy(value))); \n float pixels = width * delta; \n float temp = abs(value); \n // There are a couple things going on here. \n // First we test the value at the current fragment to see if it is within the tolerance. \n // We also want to check if the value of an adjacent pixel is within the tolerance, \n // but we don't want to admit points that are obviously not on the surface. \n // For example, if we are looking for value to be close to 0, but value is 1 and the adjacent value is 2, \n // then the delta would be 1 and temp - delta would be 1 - 1 which is zero even though neither of \n // the points is close to zero. \n return temp < tolerance && temp < pixels || (delta < 10.0 * tolerance && temp - delta < tolerance && temp < pixels);\n #else \n return abs(value) < tolerance;\n #endif\n}\n\n\nvec4 shade(bool isOnBoundary)\n { \n if (u_showIntersection && isOnBoundary) \n { \n return getIntersectionColor(); \n } \n return getColor(u_radius, v_positionEC);\n}\n\n\nfloat ellipsoidSurfaceFunction(vec3 point)\n{ \n vec3 scaled = czm_ellipsoidInverseRadii * point; \n return dot(scaled, scaled) - 1.0;\n}\n\n\nvoid main()\n{ \n vec3 sensorVertexWC = czm_model[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n vec3 sensorVertexEC = czm_modelView[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n //vec3 pixDir = normalize(v_position); \n float positionX = v_position.x; \n float positionY = v_position.y; \n float positionZ = v_position.z; \n vec3 zDir = vec3(0.0, 0.0, 1.0); \n vec3 lineX = vec3(positionX, 0 ,positionZ); \n vec3 lineY = vec3(0, positionY, positionZ); \n float resX = dot(normalize(lineX), zDir); \n if(resX < cos(u_xHalfAngle) - 0.0001)\n { \n discard; \n } \n float resY = dot(normalize(lineY), zDir); \n if(resY < cos(u_yHalfAngle)- 0.0001)\n { \n discard; \n } \n float ellipsoidValue = ellipsoidSurfaceFunction(v_positionWC); \n // Occluded by the ellipsoid\n if (!u_showThroughEllipsoid)\n { \n // Discard if in the ellipsoid \n // PERFORMANCE_IDEA: A coarse check for ellipsoid intersection could be done on the CPU first. \n if (ellipsoidValue < 0.0) \n { \n discard; \n } \n // Discard if in the sensor's shadow \n if (inSensorShadow(sensorVertexWC, v_positionWC)) \n { \n discard; \n } \n } \n // Notes: Each surface functions should have an associated tolerance based on the floating point error. \n bool isOnEllipsoid = isOnBoundary(ellipsoidValue, czm_epsilon3); \n out_FragColor = shade(isOnEllipsoid);\n}\n ";
@@ -0,0 +1,21 @@
1
+ /**
2
+ * 公共着色器
3
+ * @returns {ShaderSource}
4
+ */
5
+ export var sensorComm = "\nuniform vec4 u_intersectionColor;\nuniform float u_intersectionWidth;\nuniform vec4 u_lineColor;\n\nbool inSensorShadow(vec3 coneVertexWC, vec3 pointWC)\n{ \n // Diagonal matrix from the unscaled ellipsoid space to the scaled space.\n vec3 D = czm_ellipsoidInverseRadii; \n // Sensor vertex in the scaled ellipsoid space \n vec3 q = D * coneVertexWC; \n float qMagnitudeSquared = dot(q, q); \n float test = qMagnitudeSquared - 1.0; \n // Sensor vertex to fragment vector in the ellipsoid's scaled space \n vec3 temp = D * pointWC - q; \n float d = dot(temp, q); \n // Behind silhouette plane and inside silhouette cone \n return (d < -test) && (d / length(temp) < -sqrt(test));\n}\n\nvec4 getLineColor()\n{ \n return u_lineColor;\n}\n\nvec4 getIntersectionColor()\n{ \n return u_intersectionColor;\n}\n\nfloat getIntersectionWidth()\n{ \n return u_intersectionWidth;\n}\n\nvec2 sensor2dTextureCoordinates(float sensorRadius, vec3 pointMC)\n{ \n // (s, t) both in the range [0, 1] \n float t = pointMC.z / sensorRadius; \n float s = 1.0 + (atan(pointMC.y, pointMC.x) / czm_twoPi); \n s = s - floor(s); \n return vec2(s, t);\n}\n\n";
6
+ /**
7
+ * VS着色器
8
+ * @returns {ShaderSource}
9
+ */
10
+ export var sensorVS = "\nin vec4 position;\nin vec3 normal;\nout vec3 v_position;\nout vec3 v_positionWC;\nout vec3 v_positionEC;\nout vec3 v_normalEC;\nvoid main()\n{ \n gl_Position = czm_modelViewProjection * position; \n v_position = vec3(position); \n v_positionWC = (czm_model * position).xyz; \n v_positionEC = (czm_modelView * position).xyz; \n v_normalEC = czm_normal * normal;\n}";
11
+
12
+ /**
13
+ * FS着色器
14
+ * @returns {ShaderSource}
15
+ */
16
+ export var sensorFS = "\nuniform bool u_showIntersection;\nuniform bool u_showThroughEllipsoid;\nuniform float u_radius;\nuniform float u_xHalfAngle;\nuniform float u_yHalfAngle;\nuniform float u_normalDirection;\nuniform float u_type;\nin vec3 v_position;\nin vec3 v_positionWC;\nin vec3 v_positionEC;\nin vec3 v_normalEC;\nvec4 getColor(float sensorRadius, vec3 pointEC)\n{ \n czm_materialInput materialInput; \n vec3 pointMC = (czm_inverseModelView * vec4(pointEC, 1.0)).xyz; \n materialInput.st = sensor2dTextureCoordinates(sensorRadius, pointMC); \n materialInput.str = pointMC / sensorRadius; \n\n vec3 positionToEyeEC = -v_positionEC; \n materialInput.positionToEyeEC = positionToEyeEC; \n\n vec3 normalEC = normalize(v_normalEC); \n materialInput.normalEC = u_normalDirection * normalEC; \n\n czm_material material = czm_getMaterial(materialInput); \n\n return mix(czm_phong(normalize(positionToEyeEC), material,czm_lightDirectionEC),vec4(material.diffuse, material.alpha), 0.4);\n}\n\nbool isOnBoundary(float value, float epsilon)\n{ \n float width = getIntersectionWidth(); \n float tolerance = width * epsilon;\n #ifdef GL_OES_standard_derivatives \n float delta = max(abs(dFdx(value)), abs(dFdy(value))); \n float pixels = width * delta; \n float temp = abs(value); \n // There are a couple things going on here. \n // First we test the value at the current fragment to see if it is within the tolerance. \n // We also want to check if the value of an adjacent pixel is within the tolerance, \n // but we don't want to admit points that are obviously not on the surface. \n // For example, if we are looking for \"value\" to be close to 0, but value is 1 and the adjacent value is 2, \n // then the delta would be 1 and \"temp - delta\" would be \"1 - 1\" which is zero even though neither of \n // the points is close to zero. \n return temp < tolerance && temp < pixels || (delta < 10.0 * tolerance && temp - delta < tolerance && temp < pixels);\n #else \n return abs(value) < tolerance;\n #endif\n}\n\n\nvec4 shade(bool isOnBoundary)\n{ \n\n if (u_showIntersection && isOnBoundary) \n { \n return getIntersectionColor(); \n } \n if(u_type == 1.0)\n { \n return getLineColor(); \n } \n\n return getColor(u_radius, v_positionEC);\n\n}\n \nfloat ellipsoidSurfaceFunction(vec3 point)\n{ \n vec3 scaled = czm_ellipsoidInverseRadii * point; \n return dot(scaled, scaled) - 1.0;\n}\n\nvoid main()\n{ \n vec3 sensorVertexWC = czm_model[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n vec3 sensorVertexEC = czm_modelView[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n //vec3 pixDir = normalize(v_position); \n float positionX = v_position.x; \n float positionY = v_position.y; \n float positionZ = v_position.z; \n vec3 zDir = vec3(0.0, 0.0, 1.0); \n vec3 lineX = vec3(positionX, 0 ,positionZ); \n vec3 lineY = vec3(0, positionY, positionZ); \n float resX = dot(normalize(lineX), zDir); \n if(resX < cos(u_xHalfAngle)-0.00001)\n { \n discard; \n } \n float resY = dot(normalize(lineY), zDir); \n if(resY < cos(u_yHalfAngle)-0.00001)\n { \n discard; \n } \n float ellipsoidValue = ellipsoidSurfaceFunction(v_positionWC);\n // Occluded by the ellipsoid?\n if (!u_showThroughEllipsoid)\n { \n // Discard if in the ellipsoid \n // PERFORMANCE_IDEA: A coarse check for ellipsoid intersection could be done on the CPU first. \n if (ellipsoidValue < 0.0) \n { \n discard; \n } \n // Discard if in the sensor's shadow \n if (inSensorShadow(sensorVertexWC, v_positionWC)) \n { \n discard; \n } \n } \n // Notes: Each surface functions should have an associated tolerance based on the floating point error. \n bool isOnEllipsoid = isOnBoundary(ellipsoidValue, czm_epsilon3); \n //isOnEllipsoid = false; \n // if((resX >= 0.8 && resX <= 0.81)||(resY >= 0.8 && resY <= 0.81))\n // { \n // out_FragColor = shade(false);\n // }\n out_FragColor = shade(isOnEllipsoid);\n}\n";
17
+ /**
18
+ * 扫描面FS着色器
19
+ * @returns {ShaderSource}
20
+ */
21
+ export var scanPlaneFS = "\nuniform bool u_showIntersection;\nuniform bool u_showThroughEllipsoid;\nuniform float u_radius;\nuniform float u_xHalfAngle;\nuniform float u_yHalfAngle;\nuniform float u_normalDirection;\nuniform vec4 u_color;\nin vec3 v_position;\nin vec3 v_positionWC;\nin vec3 v_positionEC;\nin vec3 v_normalEC;\nvec4 getColor(float sensorRadius, vec3 pointEC)\n{ \n czm_materialInput materialInput; \n vec3 pointMC = (czm_inverseModelView * vec4(pointEC, 1.0)).xyz; \n materialInput.st = sensor2dTextureCoordinates(sensorRadius, pointMC);\n materialInput.str = pointMC / sensorRadius; \n vec3 positionToEyeEC = -v_positionEC; \n materialInput.positionToEyeEC = positionToEyeEC; \n vec3 normalEC = normalize(v_normalEC); \n materialInput.normalEC = u_normalDirection * normalEC; \n czm_material material = czm_getMaterial(materialInput); \n material.diffuse = u_color.rgb; \n material.alpha = u_color.a; \n return mix(czm_phong(normalize(positionToEyeEC), material,czm_lightDirectionEC), vec4(material.diffuse, material.alpha), 0.4);\n}\n\nbool isOnBoundary(float value, float epsilon)\n{ \n float width = getIntersectionWidth(); \n float tolerance = width * epsilon;\n #ifdef GL_OES_standard_derivatives \n float delta = max(abs(dFdx(value)), abs(dFdy(value))); \n float pixels = width * delta; \n float temp = abs(value); \n // There are a couple things going on here. \n // First we test the value at the current fragment to see if it is within the tolerance. \n // We also want to check if the value of an adjacent pixel is within the tolerance, \n // but we don't want to admit points that are obviously not on the surface. \n // For example, if we are looking for value to be close to 0, but value is 1 and the adjacent value is 2, \n // then the delta would be 1 and temp - delta would be 1 - 1 which is zero even though neither of \n // the points is close to zero. \n return temp < tolerance && temp < pixels || (delta < 10.0 * tolerance && temp - delta < tolerance && temp < pixels);\n #else \n return abs(value) < tolerance;\n #endif\n}\n\n\nvec4 shade(bool isOnBoundary)\n { \n if (u_showIntersection && isOnBoundary) \n { \n return getIntersectionColor(); \n } \n return getColor(u_radius, v_positionEC);\n}\n\n\nfloat ellipsoidSurfaceFunction(vec3 point)\n{ \n vec3 scaled = czm_ellipsoidInverseRadii * point; \n return dot(scaled, scaled) - 1.0;\n}\n\n\nvoid main()\n{ \n vec3 sensorVertexWC = czm_model[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n vec3 sensorVertexEC = czm_modelView[3].xyz; // (0.0, 0.0, 0.0) in model coordinates \n //vec3 pixDir = normalize(v_position); \n float positionX = v_position.x; \n float positionY = v_position.y; \n float positionZ = v_position.z; \n vec3 zDir = vec3(0.0, 0.0, 1.0); \n vec3 lineX = vec3(positionX, 0 ,positionZ); \n vec3 lineY = vec3(0, positionY, positionZ); \n float resX = dot(normalize(lineX), zDir); \n if(resX < cos(u_xHalfAngle) - 0.0001)\n { \n discard; \n } \n float resY = dot(normalize(lineY), zDir); \n if(resY < cos(u_yHalfAngle)- 0.0001)\n { \n discard; \n } \n float ellipsoidValue = ellipsoidSurfaceFunction(v_positionWC); \n // Occluded by the ellipsoid\n if (!u_showThroughEllipsoid)\n { \n // Discard if in the ellipsoid \n // PERFORMANCE_IDEA: A coarse check for ellipsoid intersection could be done on the CPU first. \n if (ellipsoidValue < 0.0) \n { \n discard; \n } \n // Discard if in the sensor's shadow \n if (inSensorShadow(sensorVertexWC, v_positionWC)) \n { \n discard; \n } \n } \n // Notes: Each surface functions should have an associated tolerance based on the floating point error. \n bool isOnEllipsoid = isOnBoundary(ellipsoidValue, czm_epsilon3); \n out_FragColor = shade(isOnEllipsoid);\n}\n ";
@@ -46,7 +46,7 @@ var PolygonGroundPrimitiveImageMaterialInstance = /*#__PURE__*/function (_Polygo
46
46
  position: new Cesium.GeometryAttribute({
47
47
  componentDatatype: Cesium.ComponentDatatype.DOUBLE,
48
48
  componentsPerAttribute: 3,
49
- values: Cesium.Cartesian3.packArray(positions)
49
+ values: Cesium.Cartesian3.packArray(utils.buildPolygonHierarchy(positions).positions)
50
50
  })
51
51
  },
52
52
  indices: new Uint32Array(indices),
@@ -70,6 +70,7 @@ export declare class DeepTwinsEngine3D {
70
70
  static PoiLayer: any;
71
71
  static FlightPlanning: any;
72
72
  static FlightRiskEvaluation: any;
73
- static BuildClampedPolygonGrid: any;
73
+ static BuildClampedPolygonGridUnified: any;
74
+ static ViewShedAnalyserLayer: any;
74
75
  }
75
76
  export default DeepTwinsEngine3D;
package/dist/esm/index.js CHANGED
@@ -42,7 +42,7 @@ import ArcGisLayer from "./tileLayer/ArcGisLayer";
42
42
  import RasterLayer from "./tileLayer/RasterLayer";
43
43
  import WmsLayer from "./tileLayer/WmsLayer";
44
44
  import WmtsLayer from "./tileLayer/WmtsLayer";
45
- import BuildClampedPolygonGrid from "./tool/BuildClampedPolygonGrid";
45
+ import BuildClampedPolygonGridUnified from "./tool/BuildClampedPolygonGrid";
46
46
  import Compass from "./tool/Compass";
47
47
  import TimerInterval from "./tool/TimerInterval";
48
48
  import { ClampToGround, ShapeSection } from "./tool/common";
@@ -53,17 +53,19 @@ import Frustum from "./visualization/Frustum";
53
53
  import Heatmap2d from "./visualization/Heatmap2d";
54
54
  import Heatmap3d from "./visualization/Heatmap3d";
55
55
  import PointCluster from "./visualization/PointCluster";
56
+ // drawCommand
57
+ import { ViewShedAnalyserLayer } from "./drawCommand";
56
58
  window.Cesium = Cesium;
57
59
  // 将DEEP_TWINS_BASE_URL赋值给CESIUM_BASE_URL
58
60
  DEEP_TWINS_BASE_URL && (window.CESIUM_BASE_URL = DEEP_TWINS_BASE_URL);
59
61
  // 全局加载css
60
62
  loadCss(Cesium.buildModuleUrl('Widgets/widgets.css'));
61
63
  // 打印版本信息
62
- console.log('DeepTwinsEngine3D Version:', "0.1.49");
64
+ console.log('DeepTwinsEngine3D Version:', "0.1.50");
63
65
  export var DeepTwinsEngine3D = /*#__PURE__*/_createClass(function DeepTwinsEngine3D() {
64
66
  _classCallCheck(this, DeepTwinsEngine3D);
65
67
  });
66
- _defineProperty(DeepTwinsEngine3D, "Version", "0.1.49");
68
+ _defineProperty(DeepTwinsEngine3D, "Version", "0.1.50");
67
69
  _defineProperty(DeepTwinsEngine3D, "Map", Map);
68
70
  _defineProperty(DeepTwinsEngine3D, "GroundSkyBox", GroundSkyBox);
69
71
  _defineProperty(DeepTwinsEngine3D, "RasterLayer", RasterLayer);
@@ -133,5 +135,6 @@ _defineProperty(DeepTwinsEngine3D, "VisitLayer", VisitLayer);
133
135
  _defineProperty(DeepTwinsEngine3D, "PoiLayer", PoiLayer);
134
136
  _defineProperty(DeepTwinsEngine3D, "FlightPlanning", FlightPlanning);
135
137
  _defineProperty(DeepTwinsEngine3D, "FlightRiskEvaluation", FlightRiskEvaluation);
136
- _defineProperty(DeepTwinsEngine3D, "BuildClampedPolygonGrid", BuildClampedPolygonGrid);
138
+ _defineProperty(DeepTwinsEngine3D, "BuildClampedPolygonGridUnified", BuildClampedPolygonGridUnified);
139
+ _defineProperty(DeepTwinsEngine3D, "ViewShedAnalyserLayer", ViewShedAnalyserLayer);
137
140
  export default DeepTwinsEngine3D;
@@ -151,7 +151,7 @@ var Map = /*#__PURE__*/function (_Cesium$Viewer) {
151
151
  value: function _createVideoContainer() {
152
152
  var el = document.createElement('div');
153
153
  el.id = constant.VIDEO_CONTAINER_ID;
154
- el.style.cssText = 'position: absolute; left: 0; top: 0; right: 0; bottom: 0; pointer-events: none; overflow: hidden; display: none';
154
+ el.style.cssText = 'position: absolute; left: 0; top: 0; pointer-events: none; opacity: 0';
155
155
  this.container.appendChild(el);
156
156
  }
157
157
 
@@ -2,7 +2,7 @@ import BaseMaterialAppearance from './BaseMaterialAppearance';
2
2
  declare class ImageMaterialAppearance extends BaseMaterialAppearance {
3
3
  private readonly currMaterial;
4
4
  private readonly currAppearance;
5
- constructor(material: any, appearance: any);
5
+ constructor(material: any, appearance?: any);
6
6
  static handleMaterial(style: any): any;
7
7
  private _createMaterial;
8
8
  private _createAppearance;
@@ -1,11 +1,4 @@
1
- import * as Cesium from 'deeptwins-cesium';
2
- /**
3
- * 构建贴地的多边形网格
4
- */
5
- export default function BuildClampedPolygonGrid(map: any, geoJson: any, gridSize?: number, heightBuffer?: number): Promise<{
1
+ export default function BuildClampedPolygonGridUnified(map: any, geoJson: any, gridSize?: number, heightBuffer?: number): Promise<{
6
2
  type: string;
7
- source: {
8
- positions: Cesium.Cartesian3[];
9
- indices: number[];
10
- }[];
3
+ source: any[];
11
4
  }>;
@@ -1,11 +1,40 @@
1
1
  function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
2
  function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
4
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
5
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
6
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
7
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
3
11
  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
12
  function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
13
+ import { Delaunay } from 'd3-delaunay';
5
14
  import * as Cesium from 'deeptwins-cesium';
6
15
  import BaseSource from "../graphicLayer/BaseSource";
7
16
  import { translateSource } from "../tool/common";
8
17
  import * as utils from "./utils";
18
+ function distanceToSegment(p, a, b) {
19
+ var abx = b.x - a.x;
20
+ var aby = b.y - a.y;
21
+ var apx = p.x - a.x;
22
+ var apy = p.y - a.y;
23
+ var abLen2 = abx * abx + aby * aby;
24
+ var t = abLen2 === 0 ? 0 : Math.max(0, Math.min(1, (apx * abx + apy * aby) / abLen2));
25
+ var dx = a.x + t * abx - p.x;
26
+ var dy = a.y + t * aby - p.y;
27
+ return Math.sqrt(dx * dx + dy * dy);
28
+ }
29
+ function distanceToPolygonEdge(p, polygon) {
30
+ var min = Infinity;
31
+ for (var i = 0; i < polygon.length; i++) {
32
+ var a = polygon[i];
33
+ var b = polygon[(i + 1) % polygon.length];
34
+ min = Math.min(min, distanceToSegment(p, a, b));
35
+ }
36
+ return min;
37
+ }
9
38
  function pointInPolygon(pt, polygon) {
10
39
  var inside = false;
11
40
  for (var i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
@@ -19,38 +48,15 @@ function pointInPolygon(pt, polygon) {
19
48
  return inside;
20
49
  }
21
50
 
22
- // 修改 buildGridIndices:不删顶点,只生成 polygon 内部三角形索引
23
- function buildGridIndices(cols, rows, polygon, gridPoints2D, step) {
24
- var indices = [];
25
- for (var y = 0; y < rows - 1; y++) {
26
- for (var x = 0; x < cols - 1; x++) {
27
- var i0 = y * cols + x;
28
- var i1 = i0 + 1;
29
- var i2 = i0 + cols;
30
- var i3 = i2 + 1;
31
-
32
- // 三角形中心点,判断是否在 polygon 内
33
- var cx = (x + 0.5) * step + gridPoints2D[0].x; // 这里偏移加上最小X
34
- var cy = (y + 0.5) * step + gridPoints2D[0].y; // 偏移加上最小Y
35
- if (pointInPolygon(new Cesium.Cartesian2(cx, cy), polygon)) {
36
- indices.push(i0, i1, i2);
37
- indices.push(i1, i3, i2);
38
- }
39
- }
40
- }
41
- return indices;
42
- }
43
-
44
- /**
45
- * 构建贴地的多边形网格
46
- */
47
- export default function BuildClampedPolygonGrid(_x, _x2) {
48
- return _BuildClampedPolygonGrid.apply(this, arguments);
51
+ // 构建贴模型/贴地网格
52
+ export default function BuildClampedPolygonGridUnified(_x, _x2) {
53
+ return _BuildClampedPolygonGridUnified.apply(this, arguments);
49
54
  }
50
- function _BuildClampedPolygonGrid() {
51
- _BuildClampedPolygonGrid = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(map, geoJson) {
55
+ function _BuildClampedPolygonGridUnified() {
56
+ _BuildClampedPolygonGridUnified = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(map, geoJson) {
52
57
  var gridSize,
53
58
  heightBuffer,
59
+ scene,
54
60
  translatedSource,
55
61
  source,
56
62
  finalSource,
@@ -62,90 +68,206 @@ function _BuildClampedPolygonGrid() {
62
68
  case 0:
63
69
  gridSize = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : 10;
64
70
  heightBuffer = _args2.length > 3 && _args2[3] !== undefined ? _args2[3] : 0.5;
65
- if (!(!map.terrainProvider || map.terrainProvider instanceof Cesium.EllipsoidTerrainProvider)) {
66
- _context2.next = 4;
67
- break;
68
- }
69
- throw new Error('请设置地形');
70
- case 4:
71
+ scene = map.scene; // 地形至少加载一次(给 fallback 用)
72
+ _context2.next = 5;
73
+ return utils.isTerrainReady(map);
74
+ case 5:
71
75
  translatedSource = translateSource(geoJson);
72
76
  source = BaseSource.geoJsonToGeoCartesian3Array(translatedSource);
73
77
  finalSource = [];
74
78
  _loop = /*#__PURE__*/_regeneratorRuntime().mark(function _loop() {
75
- var positions, ring, center, plane, poly2D, minX, minY, maxX, maxY, cols, rows, gridPoints2D, y, x, indices, positions3D, cartographics, clamped, finalPositions;
79
+ var positions, ring, center, plane, poly2D, minX, minY, maxX, maxY, _iterator, _step, p, gridPoints2D, edgeFactor, edgeThreshold, y, x, center2D, dist, step, j, a, b, edgeLen, n, k, t, delaunay, indices, positions3D, modelClamped, needTerrain, terrainClamped, cartos, sampled, finalPositions;
76
80
  return _regeneratorRuntime().wrap(function _loop$(_context) {
77
81
  while (1) switch (_context.prev = _context.next) {
78
82
  case 0:
79
- positions = source[i].positions; // 1️⃣ 去闭合
80
- ring = utils.buildPolygonHierarchy(positions).positions; // 2️⃣ 局部切平面
83
+ positions = source[i].positions;
84
+ ring = utils.buildPolygonHierarchy(positions).positions;
85
+ /* ---------------------------------- */
86
+ /* 1. 局部切平面 */
87
+ /* ---------------------------------- */
81
88
  center = Cesium.BoundingSphere.fromPoints(ring).center;
82
- plane = new Cesium.EllipsoidTangentPlane(center, Cesium.Ellipsoid.WGS84); // 3️⃣ 投影到 2D
89
+ plane = new Cesium.EllipsoidTangentPlane(center, Cesium.Ellipsoid.WGS84);
83
90
  poly2D = ring.map(function (p) {
84
91
  return plane.projectPointOntoPlane(p);
85
- }); // 4️⃣ 包围盒
86
- minX = Infinity, minY = Infinity;
87
- maxX = -Infinity, maxY = -Infinity;
88
- poly2D.forEach(function (p) {
89
- minX = Math.min(minX, p.x);
90
- minY = Math.min(minY, p.y);
91
- maxX = Math.max(maxX, p.x);
92
- maxY = Math.max(maxY, p.y);
93
92
  });
94
- cols = Math.floor((maxX - minX) / gridSize) + 1;
95
- rows = Math.floor((maxY - minY) / gridSize) + 1; // 5️⃣ 生成完整规则网格点(不删点)
93
+ /* ---------------------------------- */
94
+ /* 2. 包围盒 */
95
+ /* ---------------------------------- */
96
+ minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
97
+ _iterator = _createForOfIteratorHelper(poly2D);
98
+ try {
99
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
100
+ p = _step.value;
101
+ minX = Math.min(minX, p.x);
102
+ minY = Math.min(minY, p.y);
103
+ maxX = Math.max(maxX, p.x);
104
+ maxY = Math.max(maxY, p.y);
105
+ }
106
+
107
+ /* ---------------------------------- */
108
+ /* 3. 自适应采样 */
109
+ /* ---------------------------------- */
110
+ } catch (err) {
111
+ _iterator.e(err);
112
+ } finally {
113
+ _iterator.f();
114
+ }
96
115
  gridPoints2D = [];
97
- for (y = 0; y < rows; y++) {
98
- for (x = 0; x < cols; x++) {
99
- gridPoints2D.push(new Cesium.Cartesian2(minX + x * gridSize, minY + y * gridSize));
116
+ edgeFactor = 0.3;
117
+ edgeThreshold = gridSize;
118
+ y = minY;
119
+ case 12:
120
+ if (!(y < maxY)) {
121
+ _context.next = 28;
122
+ break;
123
+ }
124
+ x = minX;
125
+ case 14:
126
+ if (!(x < maxX)) {
127
+ _context.next = 25;
128
+ break;
129
+ }
130
+ center2D = new Cesium.Cartesian2(x + gridSize * 0.5, y + gridSize * 0.5);
131
+ if (pointInPolygon(center2D, poly2D)) {
132
+ _context.next = 19;
133
+ break;
134
+ }
135
+ x += gridSize;
136
+ return _context.abrupt("continue", 14);
137
+ case 19:
138
+ dist = distanceToPolygonEdge(center2D, poly2D);
139
+ step = dist < edgeThreshold ? gridSize * edgeFactor : gridSize;
140
+ gridPoints2D.push(center2D);
141
+ x += step;
142
+ _context.next = 14;
143
+ break;
144
+ case 25:
145
+ y += gridSize;
146
+ _context.next = 12;
147
+ break;
148
+ case 28:
149
+ /* ---------------------------------- */
150
+ /* 4. 边界插值 */
151
+ /* ---------------------------------- */
152
+
153
+ for (j = 0; j < poly2D.length; j++) {
154
+ a = poly2D[j];
155
+ b = poly2D[(j + 1) % poly2D.length];
156
+ edgeLen = Cesium.Cartesian2.distance(a, b);
157
+ n = Math.ceil(edgeLen / (gridSize * edgeFactor));
158
+ for (k = 0; k <= n; k++) {
159
+ t = k / n;
160
+ gridPoints2D.push(new Cesium.Cartesian2(Cesium.Math.lerp(a.x, b.x, t), Cesium.Math.lerp(a.y, b.y, t)));
100
161
  }
101
162
  }
102
163
 
103
- // 6️⃣ 生成三角形索引(只保留 polygon 内部三角形)
104
- indices = buildGridIndices(cols, rows, poly2D, gridPoints2D, gridSize); // 7️⃣ 回投 3D
164
+ /* ---------------------------------- */
165
+ /* 5. Delaunay */
166
+ /* ---------------------------------- */
167
+ delaunay = Delaunay.from(gridPoints2D.map(function (p) {
168
+ return [p.x, p.y];
169
+ }));
170
+ indices = Array.from(delaunay.triangles);
171
+ /* ---------------------------------- */
172
+ /* 6. 回投 3D(无高度) */
173
+ /* ---------------------------------- */
105
174
  positions3D = gridPoints2D.map(function (p) {
106
175
  return plane.projectPointOntoEllipsoid(p);
107
- }); // 8️⃣ 贴地
108
- cartographics = positions3D.map(function (p) {
176
+ });
177
+ /* ---------------------------------- */
178
+ /* 7. 贴模型(优先) */
179
+ /* ---------------------------------- */
180
+ // await scene.render();
181
+ modelClamped = null;
182
+ _context.prev = 33;
183
+ _context.next = 36;
184
+ return scene.clampToHeightMostDetailed(JSON.parse(JSON.stringify(positions3D)));
185
+ case 36:
186
+ modelClamped = _context.sent;
187
+ _context.next = 42;
188
+ break;
189
+ case 39:
190
+ _context.prev = 39;
191
+ _context.t0 = _context["catch"](33);
192
+ modelClamped = null;
193
+ case 42:
194
+ /* ---------------------------------- */
195
+ /* 8. terrain fallback(只给失败点) */
196
+ /* ---------------------------------- */
197
+ needTerrain = !modelClamped || modelClamped.some(function (p) {
198
+ return !Cesium.defined(p);
199
+ });
200
+ terrainClamped = null;
201
+ if (!needTerrain) {
202
+ _context.next = 50;
203
+ break;
204
+ }
205
+ cartos = JSON.parse(JSON.stringify(positions3D)).map(function (p) {
109
206
  return Cesium.Cartographic.fromCartesian(p);
110
207
  });
111
- _context.next = 17;
112
- return Cesium.sampleTerrainMostDetailed(map.terrainProvider, cartographics);
113
- case 17:
114
- clamped = _context.sent;
115
- finalPositions = clamped.map(function (c) {
116
- return Cesium.Cartesian3.fromRadians(c.longitude, c.latitude, c.height + heightBuffer);
208
+ _context.next = 48;
209
+ return Cesium.sampleTerrainMostDetailed(map.terrainProvider, cartos);
210
+ case 48:
211
+ sampled = _context.sent;
212
+ terrainClamped = sampled.map(function (c) {
213
+ return Cesium.Cartesian3.fromRadians(c.longitude, c.latitude, c.height);
214
+ });
215
+ case 50:
216
+ /* ---------------------------------- */
217
+ /* 9. 合并结果(模型优先,terrain 兜底) */
218
+ /* ---------------------------------- */
219
+ finalPositions = positions3D.map(function (_, idx) {
220
+ var p = modelClamped && Cesium.defined(modelClamped[idx]) ? modelClamped[idx] : terrainClamped ? terrainClamped[idx] : null;
221
+ if (!p) return null;
222
+ var carto = Cesium.Cartographic.fromCartesian(p);
223
+ return Cesium.Cartesian3.fromRadians(carto.longitude, carto.latitude, carto.height + heightBuffer);
117
224
  });
118
- finalSource.push({
225
+ if (!finalPositions.some(function (p) {
226
+ return !p;
227
+ })) {
228
+ _context.next = 54;
229
+ break;
230
+ }
231
+ console.warn('存在无法贴地/贴模型的点,已跳过该 polygon');
232
+ return _context.abrupt("return", 1);
233
+ case 54:
234
+ finalSource.push(_objectSpread(_objectSpread({}, source[i]), {}, {
119
235
  positions: finalPositions,
120
236
  indices: indices
121
- });
122
- case 20:
237
+ }));
238
+ case 55:
123
239
  case "end":
124
240
  return _context.stop();
125
241
  }
126
- }, _loop);
242
+ }, _loop, null, [[33, 39]]);
127
243
  });
128
244
  i = 0;
129
- case 9:
245
+ case 10:
130
246
  if (!(i < source.length)) {
247
+ _context2.next = 17;
248
+ break;
249
+ }
250
+ return _context2.delegateYield(_loop(), "t0", 12);
251
+ case 12:
252
+ if (!_context2.t0) {
131
253
  _context2.next = 14;
132
254
  break;
133
255
  }
134
- return _context2.delegateYield(_loop(), "t0", 11);
135
- case 11:
256
+ return _context2.abrupt("continue", 14);
257
+ case 14:
136
258
  i++;
137
- _context2.next = 9;
259
+ _context2.next = 10;
138
260
  break;
139
- case 14:
261
+ case 17:
140
262
  return _context2.abrupt("return", {
141
263
  type: 'clampedPolygonGrid',
142
264
  source: finalSource
143
265
  });
144
- case 15:
266
+ case 18:
145
267
  case "end":
146
268
  return _context2.stop();
147
269
  }
148
270
  }, _callee);
149
271
  }));
150
- return _BuildClampedPolygonGrid.apply(this, arguments);
272
+ return _BuildClampedPolygonGridUnified.apply(this, arguments);
151
273
  }
@@ -71,3 +71,4 @@ export declare function getMidpoint(position1: Cartesian3, position2: Cartesian3
71
71
  alt: number;
72
72
  };
73
73
  export declare function densifyLine(p1: Cartesian3, p2: Cartesian3, count?: number): Cesium.Cartesian3[];
74
+ export declare function isTerrainReady(map: any): Promise<void>;
@@ -477,4 +477,25 @@ export function densifyLine(p1, p2) {
477
477
  result.push(Cesium.Cartesian3.lerp(p1, p2, i / count, new Cesium.Cartesian3()));
478
478
  }
479
479
  return result;
480
+ }
481
+
482
+ // 判断地形是否加载完成
483
+ export function isTerrainReady(map) {
484
+ return new Promise(function (resolve) {
485
+ if (!map.scene.globe || !map.scene.terrainProvider) {
486
+ resolve();
487
+ return;
488
+ }
489
+ if (map.scene.globe.tilesLoaded) {
490
+ resolve();
491
+ return;
492
+ }
493
+ var remove = map.scene.postRender.addEventListener(function () {
494
+ if (map.scene.globe.tilesLoaded) {
495
+ remove();
496
+ resolve();
497
+ }
498
+ });
499
+ map.scene.requestRender();
500
+ });
480
501
  }
@@ -157,8 +157,10 @@ var BaseVideo = /*#__PURE__*/function () {
157
157
  }, {
158
158
  key: "_drawCanvas",
159
159
  value: function _drawCanvas(options) {
160
- var width = options.width,
161
- height = options.height;
160
+ var _options$videoOptions = options.videoOptions,
161
+ width = _options$videoOptions.width,
162
+ height = _options$videoOptions.height,
163
+ edgeFeather = options.style.edgeFeather;
162
164
  var canvas = document.createElement('canvas');
163
165
  canvas.width = width;
164
166
  canvas.height = height;
@@ -169,18 +171,20 @@ var BaseVideo = /*#__PURE__*/function () {
169
171
  ctx.drawImage(this.videoElement, 0, 0, width, height);
170
172
 
171
173
  // 2. 应用羽化遮罩
172
- ctx.globalCompositeOperation = 'destination-in'; // 使用遮罩影响透明度
174
+ if (edgeFeather) {
175
+ ctx.globalCompositeOperation = 'destination-in'; // 使用遮罩影响透明度
173
176
 
174
- var maskCanvas = document.createElement('canvas');
175
- maskCanvas.width = width;
176
- maskCanvas.height = height;
177
- var maskCtx = maskCanvas.getContext('2d');
178
- if (maskCtx && this._maskImage) {
179
- // 绘制并拉伸遮罩图片到整个画布
180
- maskCtx.drawImage(this._maskImage, 0, 0, width, height);
181
- ctx.drawImage(maskCanvas, 0, 0);
177
+ var maskCanvas = document.createElement('canvas');
178
+ maskCanvas.width = width;
179
+ maskCanvas.height = height;
180
+ var maskCtx = maskCanvas.getContext('2d');
181
+ if (maskCtx && this._maskImage) {
182
+ // 绘制并拉伸遮罩图片到整个画布
183
+ maskCtx.drawImage(this._maskImage, 0, 0, width, height);
184
+ ctx.drawImage(maskCanvas, 0, 0);
185
+ }
186
+ ctx.globalCompositeOperation = 'source-over'; // 还原默认混合模式
182
187
  }
183
- ctx.globalCompositeOperation = 'source-over'; // 还原默认混合模式
184
188
  return canvas;
185
189
  }
186
190
 
@@ -213,11 +217,6 @@ var BaseVideo = /*#__PURE__*/function () {
213
217
  _this2.onErrorFun && _this2.onErrorFun(e);
214
218
  });
215
219
  }
216
- if (this.videoPolygonLayer) {
217
- this.videoPolygonLayer.setStyle({
218
- material: this.videoElement
219
- });
220
- }
221
220
  }
222
221
  // 暂停后继续播放
223
222
  if (this.synchronizer && this.videoType === 'hls') {
@@ -250,6 +249,7 @@ var BaseVideo = /*#__PURE__*/function () {
250
249
  });
251
250
  this.getMap().clock.shouldAnimate = true;
252
251
  }
252
+ this.videoElement.style.display = 'none';
253
253
  }
254
254
 
255
255
  // 监听错误