@cesium/engine 26.1.0 → 26.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/Build/ThirdParty/Workers/zip-web-worker.js +764 -520
- package/Build/Workers/{chunk-HS6AD4P2.js → chunk-2DKJSPYF.js} +14 -14
- package/Build/Workers/{chunk-QVLAFFJY.js → chunk-2PWVICP6.js} +1 -1
- package/Build/Workers/{chunk-ILME5BXA.js → chunk-2YY724ZX.js} +8 -8
- package/Build/Workers/{chunk-ENNFMWDW.js → chunk-4DMAXPKB.js} +12 -12
- package/Build/Workers/{chunk-CDJDJ5LK.js → chunk-4LRFYRBX.js} +2 -2
- package/Build/Workers/{chunk-76FDC45O.js → chunk-5JCZHJUU.js} +13 -13
- package/Build/Workers/{chunk-5LSOO2KD.js → chunk-5KG7KDDW.js} +7 -7
- package/Build/Workers/{chunk-A6X24AZI.js → chunk-6BSNYZZG.js} +5 -5
- package/Build/Workers/{chunk-IGAZBTFZ.js → chunk-6R6SGKYN.js} +6 -6
- package/Build/Workers/{chunk-SS5ABQGY.js → chunk-6V2KDEHL.js} +4 -4
- package/Build/Workers/{chunk-ZMBHFYOX.js → chunk-75BC2IHI.js} +7 -7
- package/Build/Workers/{chunk-LGNDTZVX.js → chunk-7SESBH2I.js} +4 -4
- package/Build/Workers/{chunk-CLCTQVVL.js → chunk-7WXBTNRV.js} +8 -8
- package/Build/Workers/{chunk-WBSY7HDY.js → chunk-A7SMPV6B.js} +12 -12
- package/Build/Workers/{chunk-CEEZE3YZ.js → chunk-ATSXKJ3L.js} +7 -7
- package/Build/Workers/{chunk-AHWAZRBV.js → chunk-B4AVL7VI.js} +1 -1
- package/Build/Workers/{chunk-6HK6IXK2.js → chunk-B7Q2WF6Q.js} +4 -4
- package/Build/Workers/{chunk-YKU2Q3A2.js → chunk-BNDSDQ7D.js} +9 -12
- package/Build/Workers/{chunk-R4FPNAZ2.js → chunk-CKK6CUXK.js} +9 -9
- package/Build/Workers/{chunk-FCP2QY4G.js → chunk-COKOYTRS.js} +5 -5
- package/Build/Workers/{chunk-7D2HZKH7.js → chunk-CQ4TZXAT.js} +7 -7
- package/Build/Workers/{chunk-TVZD72WJ.js → chunk-DKSANM4A.js} +12 -12
- package/Build/Workers/{chunk-FDK4K5IA.js → chunk-DZK34ZVD.js} +1 -1
- package/Build/Workers/{chunk-N7CCOFLX.js → chunk-E7G32DWL.js} +1 -1
- package/Build/Workers/{chunk-XDWCTQCZ.js → chunk-EDETO6NY.js} +2 -2
- package/Build/Workers/{chunk-2EFYUSUY.js → chunk-F34TJJLA.js} +16 -16
- package/Build/Workers/{chunk-GXWQZBAI.js → chunk-GLHDTTTO.js} +2 -2
- package/Build/Workers/{chunk-T5QBPLE3.js → chunk-GS7RY2DH.js} +11 -11
- package/Build/Workers/{chunk-C7JQVRLM.js → chunk-HDD3RFLT.js} +25 -3
- package/Build/Workers/{chunk-E7NZJOK7.js → chunk-HDPNFEPP.js} +121 -93
- package/Build/Workers/{chunk-VAL7DYNR.js → chunk-JBJ6BRIM.js} +4 -4
- package/Build/Workers/{chunk-XQ3SKCMM.js → chunk-JKTWW7IO.js} +5 -5
- package/Build/Workers/{chunk-UVO6COT2.js → chunk-JL4NWWQY.js} +5 -5
- package/Build/Workers/{chunk-DBD5WWG2.js → chunk-JMUUAW4X.js} +10 -10
- package/Build/Workers/{chunk-UEY73NRN.js → chunk-KBGAHN5R.js} +1 -1
- package/Build/Workers/{chunk-LD64RPYV.js → chunk-KEWK6VZL.js} +12 -12
- package/Build/Workers/{chunk-JW6OZT4R.js → chunk-L73K5UPP.js} +10 -10
- package/Build/Workers/{chunk-DIGUUD6G.js → chunk-LL2SGJYH.js} +6 -6
- package/Build/Workers/{chunk-XLXSDIP5.js → chunk-LYJUL4XQ.js} +6 -6
- package/Build/Workers/{chunk-SM2CDCYF.js → chunk-M6W46OAP.js} +7 -7
- package/Build/Workers/{chunk-EHTS2YPT.js → chunk-MDDKCLMF.js} +17 -17
- package/Build/Workers/{chunk-FGQFQHN5.js → chunk-MUW4DJV7.js} +18 -18
- package/Build/Workers/{chunk-HHV3MCGV.js → chunk-N5YK44FS.js} +5 -5
- package/Build/Workers/{chunk-RG4F5R57.js → chunk-NZQUP52G.js} +9 -9
- package/Build/Workers/{chunk-B4CQSLZJ.js → chunk-PKZA44LH.js} +6 -6
- package/Build/Workers/{chunk-OBEU25PI.js → chunk-Q2JS5LCB.js} +17 -17
- package/Build/Workers/{chunk-KGXSYGBG.js → chunk-QTAEVUED.js} +13 -13
- package/Build/Workers/{chunk-NIWITKQK.js → chunk-SEJIXZZ4.js} +11 -11
- package/Build/Workers/{chunk-SGRGNDOD.js → chunk-SL2HCFYW.js} +10 -10
- package/Build/Workers/{chunk-SF6K72D7.js → chunk-SLHK3KAR.js} +5 -5
- package/Build/Workers/{chunk-JKXV6PG5.js → chunk-UZY5XRL2.js} +1 -1
- package/Build/Workers/{chunk-LNSQVXFH.js → chunk-VRECSMG3.js} +2 -2
- package/Build/Workers/{chunk-A3O6EDBK.js → chunk-X27HKF5E.js} +2 -2
- package/Build/Workers/{chunk-7KVKHY7O.js → chunk-XBY3354M.js} +6 -6
- package/Build/Workers/{chunk-GSWMAFTE.js → chunk-XRZCS3HE.js} +23 -16
- package/Build/Workers/{chunk-6YR6JBMY.js → chunk-XSIUYAT6.js} +2 -2
- package/Build/Workers/{chunk-ZSGUV73H.js → chunk-Z2DW5NM2.js} +6 -6
- package/Build/Workers/combineGeometry.js +24 -24
- package/Build/Workers/createBoxGeometry.js +18 -18
- package/Build/Workers/createBoxOutlineGeometry.js +16 -16
- package/Build/Workers/createCircleGeometry.js +26 -26
- package/Build/Workers/createCircleOutlineGeometry.js +19 -19
- package/Build/Workers/createCoplanarPolygonGeometry.js +35 -35
- package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -31
- package/Build/Workers/createCorridorGeometry.js +31 -33
- package/Build/Workers/createCorridorOutlineGeometry.js +29 -31
- package/Build/Workers/createCylinderGeometry.js +20 -20
- package/Build/Workers/createCylinderOutlineGeometry.js +18 -18
- package/Build/Workers/createEllipseGeometry.js +26 -26
- package/Build/Workers/createEllipseOutlineGeometry.js +19 -19
- package/Build/Workers/createEllipsoidGeometry.js +19 -19
- package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -18
- package/Build/Workers/createFrustumGeometry.js +18 -18
- package/Build/Workers/createFrustumOutlineGeometry.js +18 -18
- package/Build/Workers/createGeometry.js +24 -24
- package/Build/Workers/createGroundPolylineGeometry.js +24 -24
- package/Build/Workers/createPlaneGeometry.js +16 -16
- package/Build/Workers/createPlaneOutlineGeometry.js +15 -15
- package/Build/Workers/createPolygonGeometry.js +34 -34
- package/Build/Workers/createPolygonOutlineGeometry.js +31 -31
- package/Build/Workers/createPolylineGeometry.js +26 -26
- package/Build/Workers/createPolylineVolumeGeometry.js +31 -31
- package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -27
- package/Build/Workers/createRectangleGeometry.js +27 -27
- package/Build/Workers/createRectangleOutlineGeometry.js +21 -21
- package/Build/Workers/createSimplePolylineGeometry.js +24 -24
- package/Build/Workers/createSphereGeometry.js +19 -19
- package/Build/Workers/createSphereOutlineGeometry.js +18 -18
- package/Build/Workers/createTaskProcessorWorker.js +3 -3
- package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
- package/Build/Workers/createVectorTileGeometries.js +24 -24
- package/Build/Workers/createVectorTilePoints.js +13 -13
- package/Build/Workers/createVectorTilePolygons.js +22 -22
- package/Build/Workers/createVectorTilePolylines.js +14 -14
- package/Build/Workers/createVerticesFromCesium3DTilesTerrain.js +25 -25
- package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -22
- package/Build/Workers/createVerticesFromHeightmap.js +22 -22
- package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +20 -20
- package/Build/Workers/createWallGeometry.js +24 -24
- package/Build/Workers/createWallOutlineGeometry.js +24 -24
- package/Build/Workers/decodeDraco.js +10 -10
- package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
- package/Build/Workers/decodeI3S.js +10 -10
- package/Build/Workers/gaussianSplatSorter.js +4 -4
- package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
- package/Build/Workers/incrementallyBuildTerrainPicker.js +10 -10
- package/Build/Workers/transcodeKTX2.js +6 -6
- package/Build/Workers/transferTypedArrayTest.js +1 -1
- package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -22
- package/Build/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +25 -25
- package/Source/Core/ArcGISTiledElevationTerrainProvider.js +1 -5
- package/Source/Core/BoundingSphere.js +0 -3
- package/Source/Core/Cesium3DTilesTerrainGeometryProcessor.js +3 -4
- package/Source/Core/CoplanarPolygonGeometry.js +2 -2
- package/Source/Core/CorridorGeometry.js +2 -4
- package/Source/Core/CorridorOutlineGeometry.js +1 -3
- package/Source/Core/EarthOrientationParameters.js +2 -2
- package/Source/Core/EllipseGeometryLibrary.js +2 -2
- package/Source/Core/EllipsoidGeodesic.js +3 -3
- package/Source/Core/EllipsoidRhumbLine.js +1 -1
- package/Source/Core/GroundPolylineGeometry.js +2 -2
- package/Source/Core/Heap.js +1 -1
- package/Source/Core/HermitePolynomialApproximation.js +215 -179
- package/Source/Core/InterpolationAlgorithm.js +1 -0
- package/Source/Core/Ion.js +1 -1
- package/Source/Core/IonResource.js +5 -0
- package/Source/Core/IonSnapGeometryType.js +59 -0
- package/Source/Core/IonSnapHeat.js +33 -0
- package/Source/Core/IonSnapMode.js +45 -0
- package/Source/Core/IonSnapParentGeometryType.js +52 -0
- package/Source/Core/IonSnapService.js +369 -0
- package/Source/Core/JulianDate.js +1 -1
- package/Source/Core/LagrangePolynomialApproximation.js +55 -52
- package/Source/Core/LinearApproximation.js +69 -66
- package/Source/Core/Math.js +59 -0
- package/Source/Core/Matrix2.js +2 -2
- package/Source/Core/Matrix3.js +2 -2
- package/Source/Core/OrthographicFrustum.js +1 -1
- package/Source/Core/PerspectiveFrustum.js +1 -1
- package/Source/Core/PolygonGeometry.js +2 -2
- package/Source/Core/PolygonGeometryLibrary.js +1 -1
- package/Source/Core/PolygonOutlineGeometry.js +1 -1
- package/Source/Core/PolylineGeometry.js +1 -1
- package/Source/Core/PolylineVolumeGeometryLibrary.js +1 -1
- package/Source/Core/Rectangle.js +7 -1
- package/Source/Core/RectangleOutlineGeometry.js +1 -1
- package/Source/Core/SimplePolylineGeometry.js +1 -1
- package/Source/Core/SnapService.js +63 -0
- package/Source/Core/TerrainEncoding.js +2 -2
- package/Source/Core/TerrainPicker.js +179 -168
- package/Source/Core/TimeIntervalCollection.js +1 -3
- package/Source/Core/Tipsify.js +1 -1
- package/Source/Core/Transforms.js +5 -1
- package/Source/Core/VectorPipeline.js +1211 -0
- package/Source/Core/VectorProvider.js +669 -0
- package/Source/Core/WallOutlineGeometry.js +1 -1
- package/Source/Core/getTimestamp.js +4 -2
- package/Source/DataSources/CompositeEntityCollection.js +0 -1
- package/Source/DataSources/CzmlDataSource.js +2 -0
- package/Source/DataSources/DataSourceDisplay.js +1 -1
- package/Source/DataSources/GeoJsonDataSource.js +0 -1
- package/Source/DataSources/GeometryVisualizer.js +1 -1
- package/Source/DataSources/KmlDataSource.js +1 -2
- package/Source/DataSources/PolylineVisualizer.js +1 -1
- package/Source/DataSources/StaticOutlineGeometryBatch.js +1 -1
- package/Source/Renderer/AutomaticUniforms.js +67 -2
- package/Source/Renderer/Context.js +9 -3
- package/Source/Renderer/DrawCommand.js +22 -0
- package/Source/Renderer/Framebuffer.js +4 -0
- package/Source/Renderer/Pass.js +11 -10
- package/Source/Renderer/ShaderBuilder.js +1 -1
- package/Source/Renderer/Texture.js +11 -0
- package/Source/Renderer/UniformState.js +54 -1
- package/Source/Renderer/VertexArray.js +0 -1
- package/Source/Scene/ArcGisMapServerImageryProvider.js +0 -5
- package/Source/Scene/ArcGisMapService.js +1 -1
- package/Source/Scene/Billboard.js +2 -1
- package/Source/Scene/BillboardCollection.js +7 -3
- package/Source/Scene/BufferPointCollection.js +4 -7
- package/Source/Scene/BufferPolygonCollection.js +56 -27
- package/Source/Scene/BufferPolylineCollection.js +61 -8
- package/Source/Scene/BufferPolylineMaterial.js +6 -5
- package/Source/Scene/BufferPrimitiveCollection.js +226 -34
- package/Source/Scene/Camera.js +71 -5
- package/Source/Scene/Cesium3DTile.js +12 -0
- package/Source/Scene/Cesium3DTileset.js +62 -9
- package/Source/Scene/Cesium3DTilesetBaseTraversal.js +15 -3
- package/Source/Scene/Cesium3DTilesetCache.js +15 -0
- package/Source/Scene/ClippingPlaneCollection.js +2 -2
- package/Source/Scene/ClippingPolygon.js +154 -100
- package/Source/Scene/ClippingPolygonCollection.js +352 -694
- package/Source/Scene/Controllers/Controller.js +63 -0
- package/Source/Scene/Controllers/ControllerHost.js +78 -0
- package/Source/Scene/Controllers/HybridScreenSpacePanCameraController.js +106 -0
- package/Source/Scene/Controllers/MouseButton.js +32 -0
- package/Source/Scene/Controllers/ScreenSpaceElevatorCameraController.js +295 -0
- package/Source/Scene/Controllers/ScreenSpaceInputBindings.js +154 -0
- package/Source/Scene/Controllers/ScreenSpaceMapCameraController.js +310 -0
- package/Source/Scene/Controllers/ScreenSpaceTiltOrbitCameraController.js +642 -0
- package/Source/Scene/Controllers/ScreenSpaceZoomCameraController.js +431 -0
- package/Source/Scene/Controllers/defaultPickWorldPosition.js +84 -0
- package/Source/Scene/CreditDisplay.js +62 -0
- package/Source/Scene/DerivedCommand.js +94 -0
- package/Source/Scene/EdgeFramebuffer.js +1 -5
- package/Source/Scene/FrameState.js +17 -0
- package/Source/Scene/GeoJsonPrimitive.js +114 -24
- package/Source/Scene/Globe.js +20 -0
- package/Source/Scene/GlobeDepth.js +27 -1
- package/Source/Scene/GlobeSurfaceShaderSet.js +42 -53
- package/Source/Scene/GlobeSurfaceTile.js +61 -10
- package/Source/Scene/GlobeSurfaceTileProvider.js +351 -26
- package/Source/Scene/GltfLoader.js +88 -9
- package/Source/Scene/GltfSpzLoader.js +1 -1
- package/Source/Scene/GltfVertexBufferLoader.js +6 -3
- package/Source/Scene/HeightReference.js +1 -1
- package/Source/Scene/I3SDataProvider.js +1 -1
- package/Source/Scene/I3SLayer.js +1 -1
- package/Source/Scene/I3SNode.js +2 -2
- package/Source/Scene/ImageryLayerCollection.js +188 -4
- package/Source/Scene/IonImageryProvider.js +1 -5
- package/Source/Scene/Label.js +4 -4
- package/Source/Scene/LabelCollection.js +1 -1
- package/Source/Scene/MVTDataProvider.js +11 -0
- package/Source/Scene/Model/B3dmLoader.js +1 -2
- package/Source/Scene/Model/EdgeVisibilityPipelineStage.js +10 -8
- package/Source/Scene/Model/I3dmLoader.js +1 -1
- package/Source/Scene/Model/InstancingPipelineStage.js +4 -7
- package/Source/Scene/Model/MaterialPipelineStage.js +124 -1
- package/Source/Scene/Model/Model.js +250 -26
- package/Source/Scene/Model/Model3DTileContent.js +5 -0
- package/Source/Scene/Model/ModelClippingPlanesPipelineStage.js +28 -1
- package/Source/Scene/Model/ModelClippingPolygonsPipelineStage.js +54 -19
- package/Source/Scene/Model/ModelDrawCommand.js +160 -16
- package/Source/Scene/Model/ModelDrawCommands.js +4 -0
- package/Source/Scene/Model/ModelRenderResources.js +2 -3
- package/Source/Scene/Model/ModelSceneGraph.js +31 -1
- package/Source/Scene/Model/ModelVectorLookupPipelineStage.js +205 -0
- package/Source/Scene/Model/PickingPipelineStage.js +33 -0
- package/Source/Scene/Model/PrimitiveRenderResources.js +24 -0
- package/Source/Scene/ModelComponents.js +71 -0
- package/Source/Scene/Picking.js +16 -5
- package/Source/Scene/PlanarFillIdFramebuffer.js +172 -0
- package/Source/Scene/PntsParser.js +0 -1
- package/Source/Scene/PolylineCollection.js +1 -1
- package/Source/Scene/PostProcessStage.js +26 -5
- package/Source/Scene/ResourceCache.js +7 -4
- package/Source/Scene/ResourceCacheKey.js +16 -13
- package/Source/Scene/Scene.js +258 -6
- package/Source/Scene/ScreenSpaceCameraController.js +1 -2
- package/Source/Scene/ShadowMap.js +9 -3
- package/Source/Scene/ShadowMapShader.js +50 -2
- package/Source/Scene/SnapFramebuffer.js +121 -0
- package/Source/Scene/Snapping.js +241 -0
- package/Source/Scene/TerrainFillMesh.js +3 -2
- package/Source/Scene/UrlTemplate3DTilesDataProvider.js +13 -2
- package/Source/Scene/Vector3DTileContent.js +2 -3
- package/Source/Scene/VectorGltf3DTileContent.js +31 -3
- package/Source/Scene/View.js +10 -8
- package/Source/Scene/VoxelTraversal.js +1 -1
- package/Source/Scene/WebMapServiceImageryProvider.js +5 -1
- package/Source/Scene/WebMapTileServiceImageryProvider.js +6 -1
- package/Source/Scene/createElevationBandMaterial.js +1 -1
- package/Source/Scene/renderBufferPointCollection.js +1 -2
- package/Source/Scene/renderBufferPolygonCollection.js +1 -2
- package/Source/Scene/renderBufferPolylineCollection.js +6 -3
- package/Source/Shaders/BufferPolylineMaterialVS.glsl +14 -2
- package/Source/Shaders/BufferPolylineMaterialVS.js +14 -2
- package/Source/Shaders/Builtin/Constants/passCesium3DTile.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passCesium3DTile.js +1 -1
- package/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.js +1 -1
- package/Source/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.js +1 -1
- package/Source/Shaders/Builtin/Constants/passCesium3DTilePlanarFillId.glsl +9 -0
- package/Source/Shaders/Builtin/Constants/passCesium3DTilePlanarFillId.js +11 -0
- package/Source/Shaders/Builtin/Constants/passClassification.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passClassification.js +1 -1
- package/Source/Shaders/Builtin/Constants/passGaussianSplats.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passGaussianSplats.js +1 -1
- package/Source/Shaders/Builtin/Constants/passOpaque.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passOpaque.js +1 -1
- package/Source/Shaders/Builtin/Constants/passTranslucent.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passTranslucent.js +1 -1
- package/Source/Shaders/Builtin/Constants/passVoxels.glsl +1 -1
- package/Source/Shaders/Builtin/Constants/passVoxels.js +1 -1
- package/Source/Shaders/Builtin/CzmBuiltins.js +4 -4
- package/Source/Shaders/Builtin/Functions/eyeToCartographicDelta.glsl +74 -0
- package/Source/Shaders/Builtin/Functions/eyeToCartographicDelta.js +76 -0
- package/Source/Shaders/GlobeFS.glsl +20 -14
- package/Source/Shaders/GlobeFS.js +20 -14
- package/Source/Shaders/GlobeVS.glsl +0 -32
- package/Source/Shaders/GlobeVS.js +0 -32
- package/Source/Shaders/Materials/PolylineGlowMaterial.glsl +1 -1
- package/Source/Shaders/Materials/PolylineGlowMaterial.js +1 -1
- package/Source/Shaders/Model/MaterialStageFS.glsl +8 -2
- package/Source/Shaders/Model/MaterialStageFS.js +8 -2
- package/Source/Shaders/Model/ModelClippingPolygonsStageFS.glsl +15 -3
- package/Source/Shaders/Model/ModelClippingPolygonsStageFS.js +15 -3
- package/Source/Shaders/Model/ModelClippingPolygonsStageVS.glsl +20 -24
- package/Source/Shaders/Model/ModelClippingPolygonsStageVS.js +20 -24
- package/Source/Shaders/Model/ModelFS.glsl +109 -0
- package/Source/Shaders/Model/ModelFS.js +109 -0
- package/Source/Shaders/Model/ModelVS.glsl +7 -2
- package/Source/Shaders/Model/ModelVS.js +7 -2
- package/Source/Shaders/Model/ModelVectorLookupStageFS.glsl +6 -0
- package/Source/Shaders/Model/ModelVectorLookupStageFS.js +8 -0
- package/Source/Shaders/Model/ModelVectorLookupStageVS.glsl +15 -0
- package/Source/Shaders/Model/ModelVectorLookupStageVS.js +17 -0
- package/Source/Shaders/Model/VerticalExaggerationStageVS.glsl +9 -10
- package/Source/Shaders/Model/VerticalExaggerationStageVS.js +9 -11
- package/Source/Shaders/VectorCommon.glsl +305 -0
- package/Source/Shaders/VectorCommon.js +307 -0
- package/Source/ThirdParty/Workers/zip-web-worker.js +1 -1
- package/Source/ThirdParty/zip-module.wasm +0 -0
- package/Source/Widget/CesiumWidget.js +30 -0
- package/index.d.ts +1326 -65
- package/index.js +179 -155
- package/package.json +6 -6
- package/Source/Shaders/Builtin/Functions/clipPolygons.glsl +0 -37
- package/Source/Shaders/Builtin/Functions/clipPolygons.js +0 -39
- package/Source/Shaders/Builtin/Functions/unpackClippingExtents.glsl +0 -14
- package/Source/Shaders/Builtin/Functions/unpackClippingExtents.js +0 -15
- package/Source/Shaders/PolygonSignedDistanceFS.glsl +0 -131
- package/Source/Shaders/PolygonSignedDistanceFS.js +0 -132
|
@@ -0,0 +1,1211 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import PixelDatatype from "../Renderer/PixelDatatype.js";
|
|
4
|
+
import Sampler from "../Renderer/Sampler.js";
|
|
5
|
+
import Texture from "../Renderer/Texture.js";
|
|
6
|
+
import BufferPolygon from "../Scene/BufferPolygon.js";
|
|
7
|
+
import BufferPolygonMaterial from "../Scene/BufferPolygonMaterial.js";
|
|
8
|
+
import BufferPolyline from "../Scene/BufferPolyline.js";
|
|
9
|
+
import BufferPolylineMaterial from "../Scene/BufferPolylineMaterial.js";
|
|
10
|
+
import Cartesian2 from "./Cartesian2.js";
|
|
11
|
+
import Cartesian3 from "./Cartesian3.js";
|
|
12
|
+
import Cartographic from "./Cartographic.js";
|
|
13
|
+
import Color from "./Color.js";
|
|
14
|
+
import CesiumMath from "./Math.js";
|
|
15
|
+
import Matrix4 from "./Matrix4.js";
|
|
16
|
+
import PixelFormat from "./PixelFormat.js";
|
|
17
|
+
import defined from "./defined.js";
|
|
18
|
+
import Rectangle from "./Rectangle.js";
|
|
19
|
+
|
|
20
|
+
/** @import BufferPrimitive from "../Scene/BufferPrimitive.js"; */
|
|
21
|
+
/** @import BufferPrimitiveCollection from "../Scene/BufferPrimitiveCollection.js"; */
|
|
22
|
+
/** @import BufferPolygonCollection from "../Scene/BufferPolygonCollection.js"; */
|
|
23
|
+
/** @import BufferPolylineCollection from "../Scene/BufferPolylineCollection.js"; */
|
|
24
|
+
/** @import Context from "../Renderer/Context.js"; */
|
|
25
|
+
/** @import Ellipsoid from "./Ellipsoid.js"; */
|
|
26
|
+
/** @import TilingScheme from "./TilingScheme.js"; */
|
|
27
|
+
/** @import {TypedArray, TypedArrayConstructor} from "./globalTypes.js"; */
|
|
28
|
+
|
|
29
|
+
const GRID_TARGET_SEGMENTS_PER_CELL = 16;
|
|
30
|
+
const GRID_NEIGHBOR_PADDING_SCALE = 0.35;
|
|
31
|
+
|
|
32
|
+
const scratchPolyline = new BufferPolyline();
|
|
33
|
+
const scratchPolylineMaterial = new BufferPolylineMaterial();
|
|
34
|
+
const scratchPolygon = new BufferPolygon();
|
|
35
|
+
const scratchPolygonMaterial = new BufferPolygonMaterial();
|
|
36
|
+
const scratchLocalPosition = new Cartesian3();
|
|
37
|
+
const scratchWorldPosition = new Cartesian3();
|
|
38
|
+
const scratchCartographic = new Cartographic();
|
|
39
|
+
const scratchSegmentStart = new Cartesian2();
|
|
40
|
+
const scratchSegmentEnd = new Cartesian2();
|
|
41
|
+
const scratchPickColor = new Color();
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Vector geometry intersecting a terrain tile, mapped into the tile's [0,1]^2 UV domain.
|
|
45
|
+
*
|
|
46
|
+
* @typedef {object} VectorTileData
|
|
47
|
+
*
|
|
48
|
+
* @property {boolean} show Whether this vector data should be rendered.
|
|
49
|
+
* @property {boolean} hasPolylines Whether polyline lookup data was baked.
|
|
50
|
+
* @property {boolean} hasPolygons Whether polygon lookup data was baked.
|
|
51
|
+
* @property {Map<BufferPrimitiveCollection<BufferPrimitive>, number>} collectionVersions Version of each
|
|
52
|
+
* collection the data was baked from, for staleness checks.
|
|
53
|
+
* @property {Rectangle} rectangle Cartographic rectangle the data was baked for.
|
|
54
|
+
* @property {number} minimumTileScreenPixels Lower bound on the tile's screen size, in pixels,
|
|
55
|
+
* used to convert screen-space line widths into tile UV.
|
|
56
|
+
* @property {Cartesian2} metersPerUv Ground size of the tile, in meters, along each UV axis. Measured on a
|
|
57
|
+
* plane tangent at the tile's center, so it drifts from true surface distance toward the tile's edges.
|
|
58
|
+
* @property {boolean} [hasPixelWidths] Whether any polyline width is in screen pixels.
|
|
59
|
+
* @property {boolean} [hasMeterWidths] Whether any polyline width is in meters.
|
|
60
|
+
*
|
|
61
|
+
* Stage 1: Collect vector segments and polygon rings intersecting tile.
|
|
62
|
+
* @property {number[][]} [polylineSegments] Tile-clipped polyline segments as [ax, ay, bx, by] in tile UV space.
|
|
63
|
+
* @property {number[]} [polylineSegmentPrimitiveIndices] Index per segment, mapping to material for the segment.
|
|
64
|
+
* @property {Float64Array[]} [polygonRings] Tile-clipped polygon rings as flat [x0, y0, x1, y1, ...] in tile UV space.
|
|
65
|
+
* @property {number[]} [polygonRingPrimitiveIndices] Index per ring, mapping to material for the ring.
|
|
66
|
+
* @property {Float32Array[]} [widths] Signed primitive widths, by primitive index.
|
|
67
|
+
* @property {Uint8Array[]} [colors] Primitive colors, by primitive index.
|
|
68
|
+
* @property {Uint8Array[]} [pickColors] Primitive pick colors, by primitive index.
|
|
69
|
+
* @property {number} [primitiveCount] Number of vector primitives in tile.
|
|
70
|
+
*
|
|
71
|
+
* Stage 2: Build CPU grid structures.
|
|
72
|
+
* @property {Float32Array} [polylineSegmentTexels] Packed RGBA line segments (ax, ay, bx, by) in tile UV space, -1 filled.
|
|
73
|
+
* @property {number} [polylineSegmentTextureWidth] Width of the segment texture, in texels.
|
|
74
|
+
* @property {number} [polylineSegmentTextureHeight] Height of the segment texture, in texels.
|
|
75
|
+
* @property {Float32Array} [polylineSegmentPrimitiveIndicesTexels] Index per segment, mapping to material for the segment.
|
|
76
|
+
* @property {Uint32Array} [polylineGridCellIndices] Polyline grid header [gridWidth, gridHeight, ...per-cell end offsets].
|
|
77
|
+
* @property {Float32Array} [polygonEdgeTexels] Packed RGBA polygon ring edges (ax, ay, bx, by), clipped per grid cell, -1 filled.
|
|
78
|
+
* @property {number} [polygonEdgeTextureWidth] Width of the polygon edge texture, in texels.
|
|
79
|
+
* @property {number} [polygonEdgeTextureHeight] Height of the polygon edge texture, in texels.
|
|
80
|
+
* @property {Float32Array} [polygonEdgePrimitiveIndicesTexels] Index per polygon edge, mapping to material for the edge.
|
|
81
|
+
* @property {Uint32Array} [polygonGridCellIndices] Polygon grid header [gridWidth, gridHeight, ...per-cell end offsets].
|
|
82
|
+
*
|
|
83
|
+
* Stage 3: Build GPU texture resources, uploaded lazily at draw time.
|
|
84
|
+
* @property {Texture} [polylineSegmentTexture] GPU texture of polylineSegmentTexels.
|
|
85
|
+
* @property {Texture} [polylineSegmentPrimitiveIndicesTexture] GPU texture of primitive indices per segment.
|
|
86
|
+
* @property {Texture} [widthTexture] GPU texture of primitive widths, by primitive index.
|
|
87
|
+
* @property {Texture} [colorTexture] GPU texture of primitive colors, by primitive index.
|
|
88
|
+
* @property {Texture} [pickColorTexture] GPU texture of primitive pick colors, by primitive index.
|
|
89
|
+
* @property {Texture} [polylineGridCellIndicesTexture] GPU texture of polylineGridCellIndices.
|
|
90
|
+
* @property {Texture} [polygonEdgeTexture] GPU texture of polygonEdgeTexels.
|
|
91
|
+
* @property {Texture} [polygonEdgePrimitiveIndicesTexture] GPU texture of primitive indices per polygon edge.
|
|
92
|
+
* @property {Texture} [polygonGridCellIndicesTexture] GPU texture of polygonGridCellIndices.
|
|
93
|
+
*
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Snapshot of a vector collection — projected vertex positions and
|
|
99
|
+
* per-primitive material properties — extracted in a single pass so the
|
|
100
|
+
* collection can be marked clean immediately afterward.
|
|
101
|
+
*
|
|
102
|
+
* @typedef {object} VectorCollectionData
|
|
103
|
+
*
|
|
104
|
+
* @property {number} version State of `collection._version` at time data was last updated.
|
|
105
|
+
* @property {Rectangle} rectangle The rectangle of the vector collection's bounding volume.
|
|
106
|
+
* @property {Float64Array} positions Collection positions, projected to the ellipsoid as [lng, lat] in radians.
|
|
107
|
+
* @property {Float32Array} widths Signed primitive widths, by primitive index. A negative magnitude marks
|
|
108
|
+
* a width in meters on the ground; a positive one marks a width in screen pixels. Zero-filled for
|
|
109
|
+
* polygon collections.
|
|
110
|
+
* @property {boolean} [widthInMeters] Whether widths are in meters on the ground rather than screen pixels.
|
|
111
|
+
* @property {Uint8Array} colors Primitive colors, by primitive index.
|
|
112
|
+
* @property {Uint8Array} pickColors Primitive pick colors, by primitive index. Zero-filled when the
|
|
113
|
+
* collection does not allow picking.
|
|
114
|
+
*
|
|
115
|
+
* @private
|
|
116
|
+
*/
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Pipeline for vector data rendered using clamped {@link HeightReference} modes.
|
|
120
|
+
*
|
|
121
|
+
* Projects vector data into the [0,1]^2 UV domain of a given {@link TilingScheme}, clips to tile
|
|
122
|
+
* bounds, and packs grid-indexed segment lookup tables consumed by Globe and 3D Tiles renderers.
|
|
123
|
+
*
|
|
124
|
+
* @see VectorProvider
|
|
125
|
+
* @ignore
|
|
126
|
+
*/
|
|
127
|
+
class VectorPipeline {
|
|
128
|
+
/**
|
|
129
|
+
* @param {BufferPolylineCollection} collection
|
|
130
|
+
* @param {Ellipsoid} ellipsoid
|
|
131
|
+
* @param {VectorCollectionData} [result]
|
|
132
|
+
* @returns {VectorCollectionData}
|
|
133
|
+
*/
|
|
134
|
+
static packPolylineCollectionData(collection, ellipsoid, result) {
|
|
135
|
+
if (
|
|
136
|
+
defined(result) &&
|
|
137
|
+
collection._dirtyCount === 0 &&
|
|
138
|
+
collection._version === result.version
|
|
139
|
+
) {
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const primitiveCount = collection.primitiveCount;
|
|
144
|
+
const boundingVolume = collection.boundingVolume;
|
|
145
|
+
|
|
146
|
+
const rectangle = Rectangle.fromBoundingSphere(boundingVolume, ellipsoid);
|
|
147
|
+
const positions = _getProjectedPositions(collection, ellipsoid);
|
|
148
|
+
|
|
149
|
+
const widths = new Float32Array(primitiveCount);
|
|
150
|
+
const colors = new Uint8Array(primitiveCount * 4);
|
|
151
|
+
const pickColors = new Uint8Array(primitiveCount * 4);
|
|
152
|
+
const widthInMeters = collection.widthUnits === "meters";
|
|
153
|
+
|
|
154
|
+
for (let i = 0; i < primitiveCount; i++) {
|
|
155
|
+
const polyline = /** @type {BufferPolyline} */ (
|
|
156
|
+
collection.get(i, scratchPolyline)
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
// Append materials unconditionally, to simplify indexing and updates.
|
|
160
|
+
const polylineMaterial = /** @type {BufferPolylineMaterial} */ (
|
|
161
|
+
polyline.getMaterial(scratchPolylineMaterial)
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
widths[i] = widthInMeters
|
|
165
|
+
? -polylineMaterial.width
|
|
166
|
+
: polylineMaterial.width;
|
|
167
|
+
|
|
168
|
+
colors[i * 4] = Color.floatToByte(polylineMaterial.color.red);
|
|
169
|
+
colors[i * 4 + 1] = Color.floatToByte(polylineMaterial.color.green);
|
|
170
|
+
colors[i * 4 + 2] = Color.floatToByte(polylineMaterial.color.blue);
|
|
171
|
+
colors[i * 4 + 3] = Color.floatToByte(polylineMaterial.color.alpha);
|
|
172
|
+
|
|
173
|
+
_writePickColor(pickColors, i, polyline._pickId);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return Object.assign(
|
|
177
|
+
result ?? {},
|
|
178
|
+
/** @type {VectorCollectionData} */ ({
|
|
179
|
+
version: collection._version,
|
|
180
|
+
rectangle: rectangle,
|
|
181
|
+
positions: positions,
|
|
182
|
+
widths: widths,
|
|
183
|
+
widthInMeters: widthInMeters,
|
|
184
|
+
colors: colors,
|
|
185
|
+
pickColors: pickColors,
|
|
186
|
+
}),
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Projects all visible polylines in a collection into tile-local UV segments,
|
|
192
|
+
* clipped to the tile, appending [ax, ay, bx, by] to the segments array.
|
|
193
|
+
*
|
|
194
|
+
* @param {BufferPolylineCollection} collection
|
|
195
|
+
* @param {VectorCollectionData} collectionData
|
|
196
|
+
* @param {Rectangle} rectangle
|
|
197
|
+
* @param {VectorTileData} result
|
|
198
|
+
*/
|
|
199
|
+
static packPolylineSegments(collection, collectionData, rectangle, result) {
|
|
200
|
+
result.polylineSegments ??= [];
|
|
201
|
+
result.widths ??= [];
|
|
202
|
+
result.colors ??= [];
|
|
203
|
+
result.pickColors ??= [];
|
|
204
|
+
result.polylineSegmentPrimitiveIndices ??= [];
|
|
205
|
+
result.primitiveCount ??= 0;
|
|
206
|
+
result.rectangle ??= Rectangle.clone(rectangle);
|
|
207
|
+
|
|
208
|
+
const width = rectangle.width;
|
|
209
|
+
const primitiveCount = collection.primitiveCount;
|
|
210
|
+
const positions = collectionData.positions;
|
|
211
|
+
|
|
212
|
+
for (let i = 0; i < primitiveCount; i++) {
|
|
213
|
+
const polyline = /** @type {BufferPolyline} */ (
|
|
214
|
+
collection.get(i, scratchPolyline)
|
|
215
|
+
);
|
|
216
|
+
if (!polyline.show) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const vertexCount = polyline.vertexCount;
|
|
221
|
+
const vertexOffset = polyline.vertexOffset;
|
|
222
|
+
|
|
223
|
+
// A line whose centerline lies outside the tile still covers pixels inside it.
|
|
224
|
+
const margin = Math.max(
|
|
225
|
+
CesiumMath.EPSILON3,
|
|
226
|
+
_halfWidthToTileUv(collectionData.widths[i], result),
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
for (let j = 0; j + 1 < vertexCount; j++) {
|
|
230
|
+
const segmentStart = Cartesian2.fromArray(
|
|
231
|
+
// @ts-expect-error https://github.com/CesiumGS/cesium/pull/13302
|
|
232
|
+
positions,
|
|
233
|
+
(vertexOffset + j) * 2,
|
|
234
|
+
scratchSegmentStart,
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
const segmentEnd = Cartesian2.fromArray(
|
|
238
|
+
// @ts-expect-error https://github.com/CesiumGS/cesium/pull/13302
|
|
239
|
+
positions,
|
|
240
|
+
(vertexOffset + j + 1) * 2,
|
|
241
|
+
scratchSegmentEnd,
|
|
242
|
+
);
|
|
243
|
+
|
|
244
|
+
_projectSegmentToTileUv(segmentStart, segmentEnd, rectangle, width);
|
|
245
|
+
|
|
246
|
+
const clipped = _clipSegmentToTile(segmentStart, segmentEnd, margin);
|
|
247
|
+
|
|
248
|
+
if (clipped) {
|
|
249
|
+
result.polylineSegments.push([
|
|
250
|
+
segmentStart.x,
|
|
251
|
+
segmentStart.y,
|
|
252
|
+
segmentEnd.x,
|
|
253
|
+
segmentEnd.y,
|
|
254
|
+
]);
|
|
255
|
+
result.polylineSegmentPrimitiveIndices.push(
|
|
256
|
+
result.primitiveCount + i,
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Append materials unconditionally, to simplify indexing and updates.
|
|
263
|
+
result.widths.push(collectionData.widths);
|
|
264
|
+
result.colors.push(collectionData.colors);
|
|
265
|
+
result.pickColors.push(collectionData.pickColors);
|
|
266
|
+
if (primitiveCount > 0) {
|
|
267
|
+
result.hasPixelWidths ||= !collectionData.widthInMeters;
|
|
268
|
+
result.hasMeterWidths ||= collectionData.widthInMeters;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
result.primitiveCount += primitiveCount;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Packs UV-space segments into a grid-indexed segment lookup. Returns the packed
|
|
276
|
+
* segment texels (RGBA, -1 filled) plus a grid-cell index header.
|
|
277
|
+
*
|
|
278
|
+
* @param {VectorTileData} result
|
|
279
|
+
*/
|
|
280
|
+
static packPolylineGrid(result) {
|
|
281
|
+
const segments = result.polylineSegments;
|
|
282
|
+
const segmentPrimitiveIndices = result.polylineSegmentPrimitiveIndices;
|
|
283
|
+
|
|
284
|
+
const gridSize = Math.max(
|
|
285
|
+
1,
|
|
286
|
+
Math.ceil(Math.sqrt(segments.length / GRID_TARGET_SEGMENTS_PER_CELL)),
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
const grid = new Array(gridSize * gridSize);
|
|
290
|
+
for (let i = 0; i < grid.length; i++) {
|
|
291
|
+
grid[i] = [];
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
let packedSegmentCount = 0;
|
|
295
|
+
// Each segment is assigned to every cell its padded bounding box overlaps, so
|
|
296
|
+
// the shader also sees lines just outside the cell it samples.
|
|
297
|
+
const cellPadding = GRID_NEIGHBOR_PADDING_SCALE / gridSize;
|
|
298
|
+
const widths = _concatTypedArrays(result.widths);
|
|
299
|
+
for (let i = 0; i < segments.length; i++) {
|
|
300
|
+
const segment = segments[i];
|
|
301
|
+
const padding = Math.max(
|
|
302
|
+
cellPadding,
|
|
303
|
+
_halfWidthToTileUv(widths[segmentPrimitiveIndices[i]], result),
|
|
304
|
+
);
|
|
305
|
+
const minX = Math.max(0.0, Math.min(segment[0], segment[2]) - padding);
|
|
306
|
+
const maxX = Math.min(1.0, Math.max(segment[0], segment[2]) + padding);
|
|
307
|
+
const minY = Math.max(0.0, Math.min(segment[1], segment[3]) - padding);
|
|
308
|
+
const maxY = Math.min(1.0, Math.max(segment[1], segment[3]) + padding);
|
|
309
|
+
|
|
310
|
+
const startCellX = _clampCellIndex(Math.floor(minX * gridSize), gridSize);
|
|
311
|
+
const endCellX = _clampCellIndex(Math.floor(maxX * gridSize), gridSize);
|
|
312
|
+
const startCellY = _clampCellIndex(Math.floor(minY * gridSize), gridSize);
|
|
313
|
+
const endCellY = _clampCellIndex(Math.floor(maxY * gridSize), gridSize);
|
|
314
|
+
|
|
315
|
+
for (let y = startCellY; y <= endCellY; y++) {
|
|
316
|
+
for (let x = startCellX; x <= endCellX; x++) {
|
|
317
|
+
grid[y * gridSize + x].push(i);
|
|
318
|
+
packedSegmentCount++;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const [textureWidth, textureHeight] =
|
|
324
|
+
_nextPowerOfTwoSize(packedSegmentCount);
|
|
325
|
+
const capacity = textureWidth * textureHeight;
|
|
326
|
+
|
|
327
|
+
const segmentTexels = new Float32Array(capacity * 4).fill(-1.0);
|
|
328
|
+
const segmentPrimitiveIndicesTexels = new Float32Array(capacity).fill(-1.0);
|
|
329
|
+
|
|
330
|
+
const gridCellIndices = new Uint32Array(grid.length + 2);
|
|
331
|
+
gridCellIndices[0] = gridSize;
|
|
332
|
+
gridCellIndices[1] = gridSize;
|
|
333
|
+
|
|
334
|
+
let offset = 0;
|
|
335
|
+
for (let i = 0; i < grid.length; i++) {
|
|
336
|
+
const cellSegments = grid[i];
|
|
337
|
+
for (let j = 0; j < cellSegments.length; j++) {
|
|
338
|
+
const segmentIndex = cellSegments[j];
|
|
339
|
+
const segment = segments[segmentIndex];
|
|
340
|
+
segmentTexels[offset * 4] = segment[0]; // R
|
|
341
|
+
segmentTexels[offset * 4 + 1] = segment[1]; // G
|
|
342
|
+
segmentTexels[offset * 4 + 2] = segment[2]; // B
|
|
343
|
+
segmentTexels[offset * 4 + 3] = segment[3]; // A
|
|
344
|
+
|
|
345
|
+
const primitiveIndex = segmentPrimitiveIndices[segmentIndex];
|
|
346
|
+
segmentPrimitiveIndicesTexels[offset] = primitiveIndex;
|
|
347
|
+
|
|
348
|
+
offset++;
|
|
349
|
+
}
|
|
350
|
+
gridCellIndices[i + 2] = offset;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
result.polylineSegmentTexels = segmentTexels;
|
|
354
|
+
result.polylineSegmentTextureWidth = textureWidth;
|
|
355
|
+
result.polylineSegmentTextureHeight = textureHeight;
|
|
356
|
+
result.polylineSegmentPrimitiveIndicesTexels =
|
|
357
|
+
segmentPrimitiveIndicesTexels;
|
|
358
|
+
result.polylineGridCellIndices = gridCellIndices;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* @param {BufferPolygonCollection} collection
|
|
363
|
+
* @param {Ellipsoid} ellipsoid
|
|
364
|
+
* @param {VectorCollectionData} [result]
|
|
365
|
+
* @returns {VectorCollectionData}
|
|
366
|
+
*/
|
|
367
|
+
static packPolygonCollectionData(collection, ellipsoid, result) {
|
|
368
|
+
if (
|
|
369
|
+
defined(result) &&
|
|
370
|
+
collection._dirtyCount === 0 &&
|
|
371
|
+
collection._version === result.version
|
|
372
|
+
) {
|
|
373
|
+
return result;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
const primitiveCount = collection.primitiveCount;
|
|
377
|
+
const boundingVolume = collection.boundingVolume;
|
|
378
|
+
|
|
379
|
+
const rectangle = Rectangle.fromBoundingSphere(boundingVolume, ellipsoid);
|
|
380
|
+
const positions = _getProjectedPositions(collection, ellipsoid);
|
|
381
|
+
|
|
382
|
+
// Widths are unused by polygon fills; zero-filled so polygons share the
|
|
383
|
+
// primitive index space (and width/color textures) with polylines.
|
|
384
|
+
const widths = new Float32Array(primitiveCount);
|
|
385
|
+
const colors = new Uint8Array(primitiveCount * 4);
|
|
386
|
+
const pickColors = new Uint8Array(primitiveCount * 4);
|
|
387
|
+
|
|
388
|
+
for (let i = 0; i < primitiveCount; i++) {
|
|
389
|
+
const polygon = /** @type {BufferPolygon} */ (
|
|
390
|
+
collection.get(i, scratchPolygon)
|
|
391
|
+
);
|
|
392
|
+
|
|
393
|
+
// Append materials unconditionally, to simplify indexing and updates.
|
|
394
|
+
const polygonMaterial = /** @type {BufferPolygonMaterial} */ (
|
|
395
|
+
polygon.getMaterial(scratchPolygonMaterial)
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
colors[i * 4] = Color.floatToByte(polygonMaterial.color.red);
|
|
399
|
+
colors[i * 4 + 1] = Color.floatToByte(polygonMaterial.color.green);
|
|
400
|
+
colors[i * 4 + 2] = Color.floatToByte(polygonMaterial.color.blue);
|
|
401
|
+
colors[i * 4 + 3] = Color.floatToByte(polygonMaterial.color.alpha);
|
|
402
|
+
|
|
403
|
+
_writePickColor(pickColors, i, polygon._pickId);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return Object.assign(
|
|
407
|
+
result ?? {},
|
|
408
|
+
/** @type {VectorCollectionData} */ ({
|
|
409
|
+
version: collection._version,
|
|
410
|
+
rectangle: rectangle,
|
|
411
|
+
positions: positions,
|
|
412
|
+
widths: widths,
|
|
413
|
+
colors: colors,
|
|
414
|
+
pickColors: pickColors,
|
|
415
|
+
}),
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* Projects all visible polygon rings (outer rings and holes) in a collection
|
|
421
|
+
* into tile-local UV space, clipped to the tile, appending each surviving
|
|
422
|
+
* ring as a flat [x0, y0, x1, y1, ...] closed loop.
|
|
423
|
+
*
|
|
424
|
+
* @param {BufferPolygonCollection} collection
|
|
425
|
+
* @param {VectorCollectionData} collectionData
|
|
426
|
+
* @param {Rectangle} rectangle
|
|
427
|
+
* @param {VectorTileData} result
|
|
428
|
+
*/
|
|
429
|
+
static packPolygonRings(collection, collectionData, rectangle, result) {
|
|
430
|
+
result.polygonRings ??= [];
|
|
431
|
+
result.polygonRingPrimitiveIndices ??= [];
|
|
432
|
+
result.widths ??= [];
|
|
433
|
+
result.colors ??= [];
|
|
434
|
+
result.pickColors ??= [];
|
|
435
|
+
result.primitiveCount ??= 0;
|
|
436
|
+
result.rectangle ??= Rectangle.clone(rectangle);
|
|
437
|
+
|
|
438
|
+
const width = rectangle.width;
|
|
439
|
+
const primitiveCount = collection.primitiveCount;
|
|
440
|
+
const positions = collectionData.positions;
|
|
441
|
+
|
|
442
|
+
for (let i = 0; i < primitiveCount; i++) {
|
|
443
|
+
const polygon = /** @type {BufferPolygon} */ (
|
|
444
|
+
collection.get(i, scratchPolygon)
|
|
445
|
+
);
|
|
446
|
+
if (!polygon.show) {
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
const vertexOffset = polygon.vertexOffset;
|
|
451
|
+
const vertexCount = polygon.vertexCount;
|
|
452
|
+
const holes = polygon.getHoles();
|
|
453
|
+
|
|
454
|
+
// Ring r spans [ringStart, ringEnd): the outer ring, then each hole.
|
|
455
|
+
// The shader's even-odd test makes hole rings cancel enclosing coverage.
|
|
456
|
+
for (let r = 0; r <= holes.length; r++) {
|
|
457
|
+
const ringStart = r === 0 ? 0 : holes[r - 1];
|
|
458
|
+
const ringEnd = r === holes.length ? vertexCount : holes[r];
|
|
459
|
+
const ringVertexCount = ringEnd - ringStart;
|
|
460
|
+
if (ringVertexCount < 3) {
|
|
461
|
+
continue;
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
const ringUv = _projectRingToTileUv(
|
|
465
|
+
positions,
|
|
466
|
+
vertexOffset + ringStart,
|
|
467
|
+
ringVertexCount,
|
|
468
|
+
rectangle,
|
|
469
|
+
width,
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
// Clip to the tile plus the shared tile clip margin. A ring enclosing
|
|
473
|
+
// the whole tile clips to the tile rectangle itself, so tiles
|
|
474
|
+
// interior to a large polygon remain covered.
|
|
475
|
+
const clipped = _clipRingToRect(
|
|
476
|
+
ringUv,
|
|
477
|
+
ringVertexCount,
|
|
478
|
+
-CesiumMath.EPSILON3,
|
|
479
|
+
1.0 + CesiumMath.EPSILON3,
|
|
480
|
+
-CesiumMath.EPSILON3,
|
|
481
|
+
1.0 + CesiumMath.EPSILON3,
|
|
482
|
+
scratchClippedRing,
|
|
483
|
+
);
|
|
484
|
+
if (clipped.vertexCount < 3) {
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
result.polygonRings.push(
|
|
489
|
+
clipped.positions.slice(0, clipped.vertexCount * 2),
|
|
490
|
+
);
|
|
491
|
+
result.polygonRingPrimitiveIndices.push(result.primitiveCount + i);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
// Append materials unconditionally, to simplify indexing and updates.
|
|
496
|
+
result.widths.push(collectionData.widths);
|
|
497
|
+
result.colors.push(collectionData.colors);
|
|
498
|
+
result.pickColors.push(collectionData.pickColors);
|
|
499
|
+
|
|
500
|
+
result.primitiveCount += primitiveCount;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Packs UV-space polygon rings into a grid-indexed edge lookup. Each ring
|
|
505
|
+
* is clipped to every grid cell it overlaps — unlike polyline segments,
|
|
506
|
+
* which are only assigned to cells — so a cell's edges form closed loops
|
|
507
|
+
* and a fragment can evaluate even-odd coverage from its own cell alone.
|
|
508
|
+
*
|
|
509
|
+
* @param {VectorTileData} result
|
|
510
|
+
*/
|
|
511
|
+
static packPolygonGrid(result) {
|
|
512
|
+
const rings = result.polygonRings;
|
|
513
|
+
const ringPrimitiveIndices = result.polygonRingPrimitiveIndices;
|
|
514
|
+
|
|
515
|
+
let ringEdgeCount = 0;
|
|
516
|
+
for (let i = 0; i < rings.length; i++) {
|
|
517
|
+
ringEdgeCount += rings[i].length / 2;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const gridSize = Math.max(
|
|
521
|
+
1,
|
|
522
|
+
Math.ceil(Math.sqrt(ringEdgeCount / GRID_TARGET_SEGMENTS_PER_CELL)),
|
|
523
|
+
);
|
|
524
|
+
|
|
525
|
+
// Per-cell packed edges [ax, ay, bx, by, primitiveIndex, ...].
|
|
526
|
+
/** @type {number[][]} */
|
|
527
|
+
const grid = new Array(gridSize * gridSize);
|
|
528
|
+
for (let i = 0; i < grid.length; i++) {
|
|
529
|
+
grid[i] = [];
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Rings are appended in primitive order, so each cell's edge list stays
|
|
533
|
+
// grouped by primitive; the shader resolves parity per group.
|
|
534
|
+
let packedEdgeCount = 0;
|
|
535
|
+
for (let r = 0; r < rings.length; r++) {
|
|
536
|
+
const ring = rings[r];
|
|
537
|
+
const primitiveIndex = ringPrimitiveIndices[r];
|
|
538
|
+
const ringVertexCount = ring.length / 2;
|
|
539
|
+
|
|
540
|
+
let minX = Infinity;
|
|
541
|
+
let minY = Infinity;
|
|
542
|
+
let maxX = -Infinity;
|
|
543
|
+
let maxY = -Infinity;
|
|
544
|
+
for (let k = 0; k < ringVertexCount; k++) {
|
|
545
|
+
minX = Math.min(minX, ring[k * 2]);
|
|
546
|
+
maxX = Math.max(maxX, ring[k * 2]);
|
|
547
|
+
minY = Math.min(minY, ring[k * 2 + 1]);
|
|
548
|
+
maxY = Math.max(maxY, ring[k * 2 + 1]);
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
const startCellX = _clampCellIndex(Math.floor(minX * gridSize), gridSize);
|
|
552
|
+
const endCellX = _clampCellIndex(Math.floor(maxX * gridSize), gridSize);
|
|
553
|
+
const startCellY = _clampCellIndex(Math.floor(minY * gridSize), gridSize);
|
|
554
|
+
const endCellY = _clampCellIndex(Math.floor(maxY * gridSize), gridSize);
|
|
555
|
+
|
|
556
|
+
for (let y = startCellY; y <= endCellY; y++) {
|
|
557
|
+
for (let x = startCellX; x <= endCellX; x++) {
|
|
558
|
+
// Expand the clip rectangle slightly so fragments at shared cell
|
|
559
|
+
// boundaries fall strictly inside the clipped loops. Smaller than
|
|
560
|
+
// the tile clip margin above: that one is a fraction of a tile and
|
|
561
|
+
// preserves geometry across the shared tile boundary, while this is
|
|
562
|
+
// a fraction of a grid cell and only has to exceed the float32
|
|
563
|
+
// rounding of a UV coordinate.
|
|
564
|
+
const clipped = _clipRingToRect(
|
|
565
|
+
ring,
|
|
566
|
+
ringVertexCount,
|
|
567
|
+
x / gridSize - CesiumMath.EPSILON5,
|
|
568
|
+
(x + 1) / gridSize + CesiumMath.EPSILON5,
|
|
569
|
+
y / gridSize - CesiumMath.EPSILON5,
|
|
570
|
+
(y + 1) / gridSize + CesiumMath.EPSILON5,
|
|
571
|
+
scratchClippedRing,
|
|
572
|
+
);
|
|
573
|
+
const clippedCount = clipped.vertexCount;
|
|
574
|
+
if (clippedCount < 3) {
|
|
575
|
+
continue;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
const clippedPositions = clipped.positions;
|
|
579
|
+
const cell = grid[y * gridSize + x];
|
|
580
|
+
for (let k = 0; k < clippedCount; k++) {
|
|
581
|
+
const k2 = (k + 1) % clippedCount;
|
|
582
|
+
const ax = clippedPositions[k * 2];
|
|
583
|
+
const ay = clippedPositions[k * 2 + 1];
|
|
584
|
+
const bx = clippedPositions[k2 * 2];
|
|
585
|
+
const by = clippedPositions[k2 * 2 + 1];
|
|
586
|
+
// Horizontal edges never toggle parity against the shader's
|
|
587
|
+
// horizontal ray; clipping produces many along cell bounds.
|
|
588
|
+
if (ay === by) {
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
cell.push(ax, ay, bx, by, primitiveIndex);
|
|
592
|
+
packedEdgeCount++;
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
const [textureWidth, textureHeight] = _nextPowerOfTwoSize(packedEdgeCount);
|
|
599
|
+
const capacity = textureWidth * textureHeight;
|
|
600
|
+
|
|
601
|
+
const edgeTexels = new Float32Array(capacity * 4).fill(-1.0);
|
|
602
|
+
const edgePrimitiveIndicesTexels = new Float32Array(capacity).fill(-1.0);
|
|
603
|
+
|
|
604
|
+
const gridCellIndices = new Uint32Array(grid.length + 2);
|
|
605
|
+
gridCellIndices[0] = gridSize;
|
|
606
|
+
gridCellIndices[1] = gridSize;
|
|
607
|
+
|
|
608
|
+
let offset = 0;
|
|
609
|
+
for (let i = 0; i < grid.length; i++) {
|
|
610
|
+
const cellEdges = grid[i];
|
|
611
|
+
for (let j = 0; j < cellEdges.length; j += 5) {
|
|
612
|
+
edgeTexels[offset * 4] = cellEdges[j]; // R
|
|
613
|
+
edgeTexels[offset * 4 + 1] = cellEdges[j + 1]; // G
|
|
614
|
+
edgeTexels[offset * 4 + 2] = cellEdges[j + 2]; // B
|
|
615
|
+
edgeTexels[offset * 4 + 3] = cellEdges[j + 3]; // A
|
|
616
|
+
|
|
617
|
+
edgePrimitiveIndicesTexels[offset] = cellEdges[j + 4];
|
|
618
|
+
|
|
619
|
+
offset++;
|
|
620
|
+
}
|
|
621
|
+
gridCellIndices[i + 2] = offset;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
result.polygonEdgeTexels = edgeTexels;
|
|
625
|
+
result.polygonEdgeTextureWidth = textureWidth;
|
|
626
|
+
result.polygonEdgeTextureHeight = textureHeight;
|
|
627
|
+
result.polygonEdgePrimitiveIndicesTexels = edgePrimitiveIndicesTexels;
|
|
628
|
+
result.polygonGridCellIndices = gridCellIndices;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Creates the width and color textures indexed by the primitive index space
|
|
633
|
+
* shared between polylines and polygons.
|
|
634
|
+
*
|
|
635
|
+
* @param {Context} context
|
|
636
|
+
* @param {VectorTileData} result
|
|
637
|
+
*/
|
|
638
|
+
static packPrimitiveTextures(context, result) {
|
|
639
|
+
const [primTextureWidth, primTextureHeight] = _nextPowerOfTwoSize(
|
|
640
|
+
result.primitiveCount,
|
|
641
|
+
);
|
|
642
|
+
|
|
643
|
+
const widthTextureView = new Float32Array(
|
|
644
|
+
primTextureWidth * primTextureHeight,
|
|
645
|
+
);
|
|
646
|
+
widthTextureView.set(_concatTypedArrays(result.widths));
|
|
647
|
+
result.widthTexture = new Texture({
|
|
648
|
+
context,
|
|
649
|
+
pixelFormat: PixelFormat.RED,
|
|
650
|
+
pixelDatatype: PixelDatatype.FLOAT,
|
|
651
|
+
source: {
|
|
652
|
+
width: primTextureWidth,
|
|
653
|
+
height: primTextureHeight,
|
|
654
|
+
arrayBufferView: widthTextureView,
|
|
655
|
+
},
|
|
656
|
+
sampler: Sampler.NEAREST,
|
|
657
|
+
flipY: false,
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
const colorTextureView = new Uint8Array(
|
|
661
|
+
primTextureWidth * primTextureHeight * 4,
|
|
662
|
+
);
|
|
663
|
+
colorTextureView.set(_concatTypedArrays(result.colors));
|
|
664
|
+
result.colorTexture = new Texture({
|
|
665
|
+
context,
|
|
666
|
+
pixelFormat: PixelFormat.RGBA,
|
|
667
|
+
pixelDatatype: PixelDatatype.UNSIGNED_BYTE,
|
|
668
|
+
source: {
|
|
669
|
+
width: primTextureWidth,
|
|
670
|
+
height: primTextureHeight,
|
|
671
|
+
arrayBufferView: colorTextureView,
|
|
672
|
+
},
|
|
673
|
+
sampler: Sampler.NEAREST,
|
|
674
|
+
flipY: false,
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
const pickColorTextureView = new Uint8Array(
|
|
678
|
+
primTextureWidth * primTextureHeight * 4,
|
|
679
|
+
);
|
|
680
|
+
pickColorTextureView.set(_concatTypedArrays(result.pickColors));
|
|
681
|
+
result.pickColorTexture = new Texture({
|
|
682
|
+
context,
|
|
683
|
+
pixelFormat: PixelFormat.RGBA,
|
|
684
|
+
pixelDatatype: PixelDatatype.UNSIGNED_BYTE,
|
|
685
|
+
source: {
|
|
686
|
+
width: primTextureWidth,
|
|
687
|
+
height: primTextureHeight,
|
|
688
|
+
arrayBufferView: pickColorTextureView,
|
|
689
|
+
},
|
|
690
|
+
sampler: Sampler.NEAREST,
|
|
691
|
+
flipY: false,
|
|
692
|
+
});
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
/**
|
|
696
|
+
* @param {Context} context
|
|
697
|
+
* @param {VectorTileData} result
|
|
698
|
+
*/
|
|
699
|
+
static packPolylineTextures(context, result) {
|
|
700
|
+
result.polylineSegmentTexture = new Texture({
|
|
701
|
+
context,
|
|
702
|
+
pixelFormat: PixelFormat.RGBA,
|
|
703
|
+
pixelDatatype: PixelDatatype.FLOAT,
|
|
704
|
+
source: {
|
|
705
|
+
width: result.polylineSegmentTextureWidth,
|
|
706
|
+
height: result.polylineSegmentTextureHeight,
|
|
707
|
+
arrayBufferView: result.polylineSegmentTexels,
|
|
708
|
+
},
|
|
709
|
+
sampler: Sampler.NEAREST,
|
|
710
|
+
flipY: false,
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
result.polylineSegmentPrimitiveIndicesTexture = new Texture({
|
|
714
|
+
context,
|
|
715
|
+
pixelFormat: PixelFormat.RED,
|
|
716
|
+
pixelDatatype: PixelDatatype.FLOAT,
|
|
717
|
+
source: {
|
|
718
|
+
width: result.polylineSegmentTextureWidth,
|
|
719
|
+
height: result.polylineSegmentTextureHeight,
|
|
720
|
+
arrayBufferView: result.polylineSegmentPrimitiveIndicesTexels,
|
|
721
|
+
},
|
|
722
|
+
sampler: Sampler.NEAREST,
|
|
723
|
+
flipY: false,
|
|
724
|
+
});
|
|
725
|
+
|
|
726
|
+
result.polylineGridCellIndicesTexture = _createGridCellIndicesTexture(
|
|
727
|
+
context,
|
|
728
|
+
result.polylineGridCellIndices,
|
|
729
|
+
);
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* @param {Context} context
|
|
734
|
+
* @param {VectorTileData} result
|
|
735
|
+
*/
|
|
736
|
+
static packPolygonTextures(context, result) {
|
|
737
|
+
result.polygonEdgeTexture = new Texture({
|
|
738
|
+
context,
|
|
739
|
+
pixelFormat: PixelFormat.RGBA,
|
|
740
|
+
pixelDatatype: PixelDatatype.FLOAT,
|
|
741
|
+
source: {
|
|
742
|
+
width: result.polygonEdgeTextureWidth,
|
|
743
|
+
height: result.polygonEdgeTextureHeight,
|
|
744
|
+
arrayBufferView: result.polygonEdgeTexels,
|
|
745
|
+
},
|
|
746
|
+
sampler: Sampler.NEAREST,
|
|
747
|
+
flipY: false,
|
|
748
|
+
});
|
|
749
|
+
|
|
750
|
+
result.polygonEdgePrimitiveIndicesTexture = new Texture({
|
|
751
|
+
context,
|
|
752
|
+
pixelFormat: PixelFormat.RED,
|
|
753
|
+
pixelDatatype: PixelDatatype.FLOAT,
|
|
754
|
+
source: {
|
|
755
|
+
width: result.polygonEdgeTextureWidth,
|
|
756
|
+
height: result.polygonEdgeTextureHeight,
|
|
757
|
+
arrayBufferView: result.polygonEdgePrimitiveIndicesTexels,
|
|
758
|
+
},
|
|
759
|
+
sampler: Sampler.NEAREST,
|
|
760
|
+
flipY: false,
|
|
761
|
+
});
|
|
762
|
+
|
|
763
|
+
result.polygonGridCellIndicesTexture = _createGridCellIndicesTexture(
|
|
764
|
+
context,
|
|
765
|
+
result.polygonGridCellIndices,
|
|
766
|
+
);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
/**
|
|
770
|
+
* @param {VectorTileData} data
|
|
771
|
+
*/
|
|
772
|
+
static freeResources(data) {
|
|
773
|
+
data.polylineSegmentTexture?.destroy();
|
|
774
|
+
data.widthTexture?.destroy();
|
|
775
|
+
data.colorTexture?.destroy();
|
|
776
|
+
data.pickColorTexture?.destroy();
|
|
777
|
+
data.polylineSegmentPrimitiveIndicesTexture?.destroy();
|
|
778
|
+
data.polylineGridCellIndicesTexture?.destroy();
|
|
779
|
+
data.polygonEdgeTexture?.destroy();
|
|
780
|
+
data.polygonEdgePrimitiveIndicesTexture?.destroy();
|
|
781
|
+
data.polygonGridCellIndicesTexture?.destroy();
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/////////////////////////////////////////////////////////////////////////////
|
|
786
|
+
// INTERNAL METHODS
|
|
787
|
+
|
|
788
|
+
/**
|
|
789
|
+
* Writes a primitive's pick color, as RGBA bytes, at the given primitive index.
|
|
790
|
+
*
|
|
791
|
+
* @param {Uint8Array} pickColors
|
|
792
|
+
* @param {number} index
|
|
793
|
+
* @param {number} pickId Pick color of the primitive, as a packed RGBA value.
|
|
794
|
+
* @private
|
|
795
|
+
*/
|
|
796
|
+
function _writePickColor(pickColors, index, pickId) {
|
|
797
|
+
Color.fromRgba(pickId, scratchPickColor);
|
|
798
|
+
pickColors[index * 4] = Color.floatToByte(scratchPickColor.red);
|
|
799
|
+
pickColors[index * 4 + 1] = Color.floatToByte(scratchPickColor.green);
|
|
800
|
+
pickColors[index * 4 + 2] = Color.floatToByte(scratchPickColor.blue);
|
|
801
|
+
pickColors[index * 4 + 3] = Color.floatToByte(scratchPickColor.alpha);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Converts half of a line's width, plus its antialiased edge, to tile UV.
|
|
806
|
+
*
|
|
807
|
+
* @param {number} width Signed line width; negative magnitudes are in meters, positive in pixels.
|
|
808
|
+
* @param {VectorTileData} tileData
|
|
809
|
+
* @returns {number}
|
|
810
|
+
* @private
|
|
811
|
+
*/
|
|
812
|
+
function _halfWidthToTileUv(width, tileData) {
|
|
813
|
+
if (width >= 0.0) {
|
|
814
|
+
return ((width + 1.0) * 0.5) / tileData.minimumTileScreenPixels;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
// A meter is a different amount of UV on each axis; callers apply one isotropic
|
|
818
|
+
// margin, so use the axis that yields the larger of the two.
|
|
819
|
+
const metersPerUv = tileData.metersPerUv;
|
|
820
|
+
return (-width * 0.5) / Math.min(metersPerUv.x, metersPerUv.y);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Projects a polyline segment (start/end Cartesian2s, x=lng, y=lat, in radians) into the
|
|
825
|
+
* tile's [0,1]^2 UV domain. Endpoint B's longitude is first unwrapped to within
|
|
826
|
+
* π of A so an antimeridian-crossing segment stays geometrically short instead
|
|
827
|
+
* of spanning the globe; then both endpoints are shifted together to the 2π
|
|
828
|
+
* frame nearest the tile center so a segment adjacent to (or crossing) the
|
|
829
|
+
* tile's west/east edge projects correctly. Result written to input Cartesian2s.
|
|
830
|
+
*
|
|
831
|
+
* Only supporting geographic tiling scheme (UV maps linearly to lon/lat)
|
|
832
|
+
*
|
|
833
|
+
* @param {Cartesian2} a [lonA, latA] radians, modified in place.
|
|
834
|
+
* @param {Cartesian2} b [lonB, latB] radians, modified in place.
|
|
835
|
+
* @param {Rectangle} rectangle
|
|
836
|
+
* @param {number} width
|
|
837
|
+
* @private
|
|
838
|
+
*/
|
|
839
|
+
function _projectSegmentToTileUv(a, b, rectangle, width) {
|
|
840
|
+
let lonA = a.x;
|
|
841
|
+
let lonB = b.x;
|
|
842
|
+
|
|
843
|
+
// Unwrap B relative to A so the segment follows the shortest longitudinal
|
|
844
|
+
// path (handles antimeridian-crossing segments).
|
|
845
|
+
lonB = lonA + CesiumMath.negativePiToPi(lonB - lonA);
|
|
846
|
+
|
|
847
|
+
// Shift the whole segment to the 2π frame nearest the tile center.
|
|
848
|
+
const center = rectangle.west + width * 0.5;
|
|
849
|
+
const shift = center + CesiumMath.negativePiToPi(lonA - center) - lonA;
|
|
850
|
+
lonA += shift;
|
|
851
|
+
lonB += shift;
|
|
852
|
+
|
|
853
|
+
const height = rectangle.north - rectangle.south;
|
|
854
|
+
a.x = (lonA - rectangle.west) / width;
|
|
855
|
+
a.y = (a.y - rectangle.south) / height;
|
|
856
|
+
b.x = (lonB - rectangle.west) / width;
|
|
857
|
+
b.y = (b.y - rectangle.south) / height;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
/**
|
|
861
|
+
* Clips a UV-space segment to the tile domain expanded by `margin` on each
|
|
862
|
+
* side ([-margin, 1 + margin]^2) using Liang-Barsky, so a segment just outside
|
|
863
|
+
* the tile boundary is still kept. Writes the clipped endpoints to result;
|
|
864
|
+
* returns false when the segment is entirely outside.
|
|
865
|
+
*
|
|
866
|
+
* @param {Cartesian2} a
|
|
867
|
+
* @param {Cartesian2} b
|
|
868
|
+
* @param {number} margin
|
|
869
|
+
* @returns {boolean}
|
|
870
|
+
* @private
|
|
871
|
+
*/
|
|
872
|
+
function _clipSegmentToTile(a, b, margin) {
|
|
873
|
+
const lo = -margin;
|
|
874
|
+
const hi = 1.0 + margin;
|
|
875
|
+
|
|
876
|
+
let tMin = 0.0;
|
|
877
|
+
let tMax = 1.0;
|
|
878
|
+
|
|
879
|
+
const ax = a.x;
|
|
880
|
+
const ay = a.y;
|
|
881
|
+
const bx = b.x;
|
|
882
|
+
const by = b.y;
|
|
883
|
+
|
|
884
|
+
const dx = bx - ax;
|
|
885
|
+
const dy = by - ay;
|
|
886
|
+
const p = [-dx, dx, -dy, dy];
|
|
887
|
+
const q = [ax - lo, hi - ax, ay - lo, hi - ay];
|
|
888
|
+
|
|
889
|
+
for (let i = 0; i < 4; i++) {
|
|
890
|
+
if (Math.abs(p[i]) < 1.0e-12) {
|
|
891
|
+
if (q[i] < 0.0) {
|
|
892
|
+
return false;
|
|
893
|
+
}
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
const t = q[i] / p[i];
|
|
898
|
+
if (p[i] < 0.0) {
|
|
899
|
+
tMin = Math.max(tMin, t);
|
|
900
|
+
} else {
|
|
901
|
+
tMax = Math.min(tMax, t);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (tMin > tMax) {
|
|
905
|
+
return false;
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
a.x = ax + tMin * dx;
|
|
910
|
+
a.y = ay + tMin * dy;
|
|
911
|
+
b.x = ax + tMax * dx;
|
|
912
|
+
b.y = ay + tMax * dy;
|
|
913
|
+
|
|
914
|
+
return true;
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
/**
|
|
918
|
+
* @param {number} index
|
|
919
|
+
* @param {number} gridSize
|
|
920
|
+
* @returns {number}
|
|
921
|
+
* @private
|
|
922
|
+
*/
|
|
923
|
+
function _clampCellIndex(index, gridSize) {
|
|
924
|
+
return Math.max(0, Math.min(gridSize - 1, index));
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
// Growable module scratch for ring projection and Sutherland-Hodgman clipping.
|
|
928
|
+
/**
|
|
929
|
+
* @type {Float64Array}
|
|
930
|
+
* @private
|
|
931
|
+
*/
|
|
932
|
+
let scratchRingUv = new Float64Array(512);
|
|
933
|
+
/**
|
|
934
|
+
* @type {Float64Array}
|
|
935
|
+
* @private
|
|
936
|
+
*/
|
|
937
|
+
let scratchClipWorking = new Float64Array(512);
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
* A ring clipped by {@link _clipRingToRect}.
|
|
941
|
+
*
|
|
942
|
+
* `positions` is reallocated when the clipped ring outgrows it, so callers
|
|
943
|
+
* must read it back from this object after each call rather than caching it.
|
|
944
|
+
*
|
|
945
|
+
* @typedef {object} ClippedRing
|
|
946
|
+
* @property {Float64Array} positions Flat [x0, y0, x1, y1, ...] ring coordinates.
|
|
947
|
+
* @property {number} vertexCount Number of valid vertices in `positions`.
|
|
948
|
+
* @private
|
|
949
|
+
*/
|
|
950
|
+
|
|
951
|
+
/**
|
|
952
|
+
* @type {ClippedRing}
|
|
953
|
+
* @private
|
|
954
|
+
*/
|
|
955
|
+
const scratchClippedRing = {
|
|
956
|
+
positions: new Float64Array(512),
|
|
957
|
+
vertexCount: 0,
|
|
958
|
+
};
|
|
959
|
+
|
|
960
|
+
/**
|
|
961
|
+
* Projects a polygon ring ([lng, lat] radian pairs from `positions`) into the
|
|
962
|
+
* tile's [0,1]^2 UV domain. Longitudes are sequentially unwrapped so an
|
|
963
|
+
* antimeridian-crossing ring stays continuous, then the whole ring is shifted
|
|
964
|
+
* to the 2π frame nearest the tile center (matching the polyline projection).
|
|
965
|
+
* Returns a module scratch valid until the next call.
|
|
966
|
+
*
|
|
967
|
+
* Only supporting geographic tiling scheme (UV maps linearly to lon/lat)
|
|
968
|
+
*
|
|
969
|
+
* @param {Float64Array} positions Projected collection positions ([lng, lat] radians).
|
|
970
|
+
* @param {number} vertexStart Index of the ring's first vertex.
|
|
971
|
+
* @param {number} vertexCount Number of vertices in the ring.
|
|
972
|
+
* @param {Rectangle} rectangle
|
|
973
|
+
* @param {number} width
|
|
974
|
+
* @returns {Float64Array} Flat [u0, v0, u1, v1, ...] ring coordinates.
|
|
975
|
+
* @private
|
|
976
|
+
*/
|
|
977
|
+
function _projectRingToTileUv(
|
|
978
|
+
positions,
|
|
979
|
+
vertexStart,
|
|
980
|
+
vertexCount,
|
|
981
|
+
rectangle,
|
|
982
|
+
width,
|
|
983
|
+
) {
|
|
984
|
+
if (scratchRingUv.length < vertexCount * 2) {
|
|
985
|
+
scratchRingUv = new Float64Array(vertexCount * 4);
|
|
986
|
+
}
|
|
987
|
+
const result = scratchRingUv;
|
|
988
|
+
const height = rectangle.north - rectangle.south;
|
|
989
|
+
|
|
990
|
+
let previousLon = positions[vertexStart * 2];
|
|
991
|
+
result[0] = previousLon;
|
|
992
|
+
result[1] = positions[vertexStart * 2 + 1];
|
|
993
|
+
for (let i = 1; i < vertexCount; i++) {
|
|
994
|
+
const lon =
|
|
995
|
+
previousLon +
|
|
996
|
+
CesiumMath.negativePiToPi(positions[(vertexStart + i) * 2] - previousLon);
|
|
997
|
+
result[i * 2] = lon;
|
|
998
|
+
result[i * 2 + 1] = positions[(vertexStart + i) * 2 + 1];
|
|
999
|
+
previousLon = lon;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
const center = rectangle.west + width * 0.5;
|
|
1003
|
+
const lon0 = result[0];
|
|
1004
|
+
const shift = center + CesiumMath.negativePiToPi(lon0 - center) - lon0;
|
|
1005
|
+
|
|
1006
|
+
for (let i = 0; i < vertexCount; i++) {
|
|
1007
|
+
result[i * 2] = (result[i * 2] + shift - rectangle.west) / width;
|
|
1008
|
+
result[i * 2 + 1] = (result[i * 2 + 1] - rectangle.south) / height;
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
return result;
|
|
1012
|
+
}
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* Clips a closed ring to an axis-aligned rectangle with Sutherland-Hodgman.
|
|
1016
|
+
* Writes the clipped ring into `result`, whose `vertexCount` is 0 when the
|
|
1017
|
+
* ring is entirely outside the rectangle.
|
|
1018
|
+
*
|
|
1019
|
+
* @param {Float64Array} ring Flat [x0, y0, x1, y1, ...] ring coordinates.
|
|
1020
|
+
* @param {number} vertexCount
|
|
1021
|
+
* @param {number} minX
|
|
1022
|
+
* @param {number} maxX
|
|
1023
|
+
* @param {number} minY
|
|
1024
|
+
* @param {number} maxY
|
|
1025
|
+
* @param {ClippedRing} result
|
|
1026
|
+
* @returns {ClippedRing} The modified result parameter.
|
|
1027
|
+
* @private
|
|
1028
|
+
*/
|
|
1029
|
+
function _clipRingToRect(ring, vertexCount, minX, maxX, minY, maxY, result) {
|
|
1030
|
+
let input = ring;
|
|
1031
|
+
let inputCount = vertexCount;
|
|
1032
|
+
|
|
1033
|
+
// axis (0 = x, 1 = y), keep side (1 = keep >= limit, -1 = keep <= limit).
|
|
1034
|
+
for (let plane = 0; plane < 4; plane++) {
|
|
1035
|
+
const axis = plane >> 1;
|
|
1036
|
+
const sign = (plane & 1) === 0 ? 1.0 : -1.0;
|
|
1037
|
+
const limit =
|
|
1038
|
+
plane === 0 ? minX : plane === 1 ? maxX : plane === 2 ? minY : maxY;
|
|
1039
|
+
|
|
1040
|
+
// Ping-pong between the working scratch and the result, writing odd
|
|
1041
|
+
// planes to the result so the fourth and final plane lands there.
|
|
1042
|
+
// Each input vertex emits at most 2 output vertices.
|
|
1043
|
+
const requiredLength = inputCount * 4 + 4;
|
|
1044
|
+
const isWorkingPlane = (plane & 1) === 0;
|
|
1045
|
+
let output = isWorkingPlane ? scratchClipWorking : result.positions;
|
|
1046
|
+
if (output.length < requiredLength) {
|
|
1047
|
+
output = new Float64Array(requiredLength * 2);
|
|
1048
|
+
if (isWorkingPlane) {
|
|
1049
|
+
scratchClipWorking = output;
|
|
1050
|
+
} else {
|
|
1051
|
+
result.positions = output;
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
let outputCount = 0;
|
|
1056
|
+
let prevX = input[(inputCount - 1) * 2];
|
|
1057
|
+
let prevY = input[(inputCount - 1) * 2 + 1];
|
|
1058
|
+
let prevInside = sign * ((axis === 0 ? prevX : prevY) - limit) >= 0.0;
|
|
1059
|
+
|
|
1060
|
+
for (let i = 0; i < inputCount; i++) {
|
|
1061
|
+
const x = input[i * 2];
|
|
1062
|
+
const y = input[i * 2 + 1];
|
|
1063
|
+
const inside = sign * ((axis === 0 ? x : y) - limit) >= 0.0;
|
|
1064
|
+
|
|
1065
|
+
if (inside !== prevInside) {
|
|
1066
|
+
// Pin the clipped coordinate exactly to the plane so boundary edges
|
|
1067
|
+
// stay axis-aligned.
|
|
1068
|
+
const t =
|
|
1069
|
+
axis === 0
|
|
1070
|
+
? (limit - prevX) / (x - prevX)
|
|
1071
|
+
: (limit - prevY) / (y - prevY);
|
|
1072
|
+
output[outputCount * 2] = axis === 0 ? limit : prevX + t * (x - prevX);
|
|
1073
|
+
output[outputCount * 2 + 1] =
|
|
1074
|
+
axis === 0 ? prevY + t * (y - prevY) : limit;
|
|
1075
|
+
outputCount++;
|
|
1076
|
+
}
|
|
1077
|
+
if (inside) {
|
|
1078
|
+
output[outputCount * 2] = x;
|
|
1079
|
+
output[outputCount * 2 + 1] = y;
|
|
1080
|
+
outputCount++;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
prevX = x;
|
|
1084
|
+
prevY = y;
|
|
1085
|
+
prevInside = inside;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
if (outputCount === 0) {
|
|
1089
|
+
result.vertexCount = 0;
|
|
1090
|
+
return result;
|
|
1091
|
+
}
|
|
1092
|
+
|
|
1093
|
+
input = output;
|
|
1094
|
+
inputCount = outputCount;
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
result.vertexCount = inputCount;
|
|
1098
|
+
return result;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* @param {number} count
|
|
1103
|
+
* @returns {number[]}
|
|
1104
|
+
* @private
|
|
1105
|
+
*/
|
|
1106
|
+
function _nextPowerOfTwoSize(count) {
|
|
1107
|
+
const width = CesiumMath.nextPowerOfTwo(
|
|
1108
|
+
Math.max(1, Math.ceil(Math.sqrt(count))),
|
|
1109
|
+
);
|
|
1110
|
+
const height = CesiumMath.nextPowerOfTwo(
|
|
1111
|
+
Math.max(1, Math.ceil(count / width)),
|
|
1112
|
+
);
|
|
1113
|
+
return [width, height];
|
|
1114
|
+
}
|
|
1115
|
+
|
|
1116
|
+
/**
|
|
1117
|
+
* Creates a grid header texture, wrapped to a 2D power-of-two size so the
|
|
1118
|
+
* header length is not limited by the maximum texture width.
|
|
1119
|
+
*
|
|
1120
|
+
* @param {Context} context
|
|
1121
|
+
* @param {Uint32Array} gridCellIndices
|
|
1122
|
+
* @returns {Texture}
|
|
1123
|
+
* @private
|
|
1124
|
+
*/
|
|
1125
|
+
function _createGridCellIndicesTexture(context, gridCellIndices) {
|
|
1126
|
+
const [width, height] = _nextPowerOfTwoSize(gridCellIndices.length);
|
|
1127
|
+
const texels = new Float32Array(width * height);
|
|
1128
|
+
texels.set(gridCellIndices);
|
|
1129
|
+
return new Texture({
|
|
1130
|
+
context: context,
|
|
1131
|
+
pixelFormat: PixelFormat.RED,
|
|
1132
|
+
pixelDatatype: PixelDatatype.FLOAT,
|
|
1133
|
+
source: {
|
|
1134
|
+
width: width,
|
|
1135
|
+
height: height,
|
|
1136
|
+
arrayBufferView: texels,
|
|
1137
|
+
},
|
|
1138
|
+
sampler: Sampler.NEAREST,
|
|
1139
|
+
flipY: false,
|
|
1140
|
+
});
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
/**
|
|
1144
|
+
* Returns the collection's vertex positions, projected to [lng, lat]
|
|
1145
|
+
* coordinates, in radians, on the given ellipsoid.
|
|
1146
|
+
*
|
|
1147
|
+
* @param {BufferPrimitiveCollection<BufferPrimitive>} collection
|
|
1148
|
+
* @param {Ellipsoid} ellipsoid
|
|
1149
|
+
* @param {Float64Array} [result]
|
|
1150
|
+
* @ignore
|
|
1151
|
+
*/
|
|
1152
|
+
function _getProjectedPositions(collection, ellipsoid, result) {
|
|
1153
|
+
if (!defined(result)) {
|
|
1154
|
+
result = new Float64Array(collection._positionCountMax * 2);
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
const positions = collection._positionView;
|
|
1158
|
+
const modelMatrix = collection.modelMatrix;
|
|
1159
|
+
|
|
1160
|
+
for (let i = 0; i < collection._positionCount; i++) {
|
|
1161
|
+
const local = Cartesian3.fromArray(
|
|
1162
|
+
// @ts-expect-error https://github.com/CesiumGS/cesium/pull/13302
|
|
1163
|
+
positions,
|
|
1164
|
+
i * 3,
|
|
1165
|
+
scratchLocalPosition,
|
|
1166
|
+
);
|
|
1167
|
+
const world = Matrix4.multiplyByPoint(
|
|
1168
|
+
modelMatrix,
|
|
1169
|
+
local,
|
|
1170
|
+
scratchWorldPosition,
|
|
1171
|
+
);
|
|
1172
|
+
const cartographic = ellipsoid.cartesianToCartographic(
|
|
1173
|
+
world,
|
|
1174
|
+
scratchCartographic,
|
|
1175
|
+
);
|
|
1176
|
+
|
|
1177
|
+
result[i * 2] = cartographic.longitude;
|
|
1178
|
+
result[i * 2 + 1] = cartographic.latitude;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
return result;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
/**
|
|
1185
|
+
* Concatenates N typed arrays.
|
|
1186
|
+
* @template {TypedArray} T
|
|
1187
|
+
* @param {T[]} arrays
|
|
1188
|
+
* @returns {T}
|
|
1189
|
+
* @ignore
|
|
1190
|
+
*/
|
|
1191
|
+
function _concatTypedArrays(arrays) {
|
|
1192
|
+
let byteLength = 0;
|
|
1193
|
+
for (const array of arrays) {
|
|
1194
|
+
byteLength += array.byteLength;
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
const TypedArray = /** @type {TypedArrayConstructor} */ (
|
|
1198
|
+
arrays[0].constructor
|
|
1199
|
+
);
|
|
1200
|
+
const result = new TypedArray(byteLength / TypedArray.BYTES_PER_ELEMENT);
|
|
1201
|
+
|
|
1202
|
+
let offset = 0;
|
|
1203
|
+
for (const array of arrays) {
|
|
1204
|
+
result.set(array, offset);
|
|
1205
|
+
offset += array.length;
|
|
1206
|
+
}
|
|
1207
|
+
|
|
1208
|
+
return /** @type {T} */ (result);
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
export default VectorPipeline;
|