@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.
Files changed (325) hide show
  1. package/Build/ThirdParty/Workers/zip-web-worker.js +764 -520
  2. package/Build/Workers/{chunk-HS6AD4P2.js → chunk-2DKJSPYF.js} +14 -14
  3. package/Build/Workers/{chunk-QVLAFFJY.js → chunk-2PWVICP6.js} +1 -1
  4. package/Build/Workers/{chunk-ILME5BXA.js → chunk-2YY724ZX.js} +8 -8
  5. package/Build/Workers/{chunk-ENNFMWDW.js → chunk-4DMAXPKB.js} +12 -12
  6. package/Build/Workers/{chunk-CDJDJ5LK.js → chunk-4LRFYRBX.js} +2 -2
  7. package/Build/Workers/{chunk-76FDC45O.js → chunk-5JCZHJUU.js} +13 -13
  8. package/Build/Workers/{chunk-5LSOO2KD.js → chunk-5KG7KDDW.js} +7 -7
  9. package/Build/Workers/{chunk-A6X24AZI.js → chunk-6BSNYZZG.js} +5 -5
  10. package/Build/Workers/{chunk-IGAZBTFZ.js → chunk-6R6SGKYN.js} +6 -6
  11. package/Build/Workers/{chunk-SS5ABQGY.js → chunk-6V2KDEHL.js} +4 -4
  12. package/Build/Workers/{chunk-ZMBHFYOX.js → chunk-75BC2IHI.js} +7 -7
  13. package/Build/Workers/{chunk-LGNDTZVX.js → chunk-7SESBH2I.js} +4 -4
  14. package/Build/Workers/{chunk-CLCTQVVL.js → chunk-7WXBTNRV.js} +8 -8
  15. package/Build/Workers/{chunk-WBSY7HDY.js → chunk-A7SMPV6B.js} +12 -12
  16. package/Build/Workers/{chunk-CEEZE3YZ.js → chunk-ATSXKJ3L.js} +7 -7
  17. package/Build/Workers/{chunk-AHWAZRBV.js → chunk-B4AVL7VI.js} +1 -1
  18. package/Build/Workers/{chunk-6HK6IXK2.js → chunk-B7Q2WF6Q.js} +4 -4
  19. package/Build/Workers/{chunk-YKU2Q3A2.js → chunk-BNDSDQ7D.js} +9 -12
  20. package/Build/Workers/{chunk-R4FPNAZ2.js → chunk-CKK6CUXK.js} +9 -9
  21. package/Build/Workers/{chunk-FCP2QY4G.js → chunk-COKOYTRS.js} +5 -5
  22. package/Build/Workers/{chunk-7D2HZKH7.js → chunk-CQ4TZXAT.js} +7 -7
  23. package/Build/Workers/{chunk-TVZD72WJ.js → chunk-DKSANM4A.js} +12 -12
  24. package/Build/Workers/{chunk-FDK4K5IA.js → chunk-DZK34ZVD.js} +1 -1
  25. package/Build/Workers/{chunk-N7CCOFLX.js → chunk-E7G32DWL.js} +1 -1
  26. package/Build/Workers/{chunk-XDWCTQCZ.js → chunk-EDETO6NY.js} +2 -2
  27. package/Build/Workers/{chunk-2EFYUSUY.js → chunk-F34TJJLA.js} +16 -16
  28. package/Build/Workers/{chunk-GXWQZBAI.js → chunk-GLHDTTTO.js} +2 -2
  29. package/Build/Workers/{chunk-T5QBPLE3.js → chunk-GS7RY2DH.js} +11 -11
  30. package/Build/Workers/{chunk-C7JQVRLM.js → chunk-HDD3RFLT.js} +25 -3
  31. package/Build/Workers/{chunk-E7NZJOK7.js → chunk-HDPNFEPP.js} +121 -93
  32. package/Build/Workers/{chunk-VAL7DYNR.js → chunk-JBJ6BRIM.js} +4 -4
  33. package/Build/Workers/{chunk-XQ3SKCMM.js → chunk-JKTWW7IO.js} +5 -5
  34. package/Build/Workers/{chunk-UVO6COT2.js → chunk-JL4NWWQY.js} +5 -5
  35. package/Build/Workers/{chunk-DBD5WWG2.js → chunk-JMUUAW4X.js} +10 -10
  36. package/Build/Workers/{chunk-UEY73NRN.js → chunk-KBGAHN5R.js} +1 -1
  37. package/Build/Workers/{chunk-LD64RPYV.js → chunk-KEWK6VZL.js} +12 -12
  38. package/Build/Workers/{chunk-JW6OZT4R.js → chunk-L73K5UPP.js} +10 -10
  39. package/Build/Workers/{chunk-DIGUUD6G.js → chunk-LL2SGJYH.js} +6 -6
  40. package/Build/Workers/{chunk-XLXSDIP5.js → chunk-LYJUL4XQ.js} +6 -6
  41. package/Build/Workers/{chunk-SM2CDCYF.js → chunk-M6W46OAP.js} +7 -7
  42. package/Build/Workers/{chunk-EHTS2YPT.js → chunk-MDDKCLMF.js} +17 -17
  43. package/Build/Workers/{chunk-FGQFQHN5.js → chunk-MUW4DJV7.js} +18 -18
  44. package/Build/Workers/{chunk-HHV3MCGV.js → chunk-N5YK44FS.js} +5 -5
  45. package/Build/Workers/{chunk-RG4F5R57.js → chunk-NZQUP52G.js} +9 -9
  46. package/Build/Workers/{chunk-B4CQSLZJ.js → chunk-PKZA44LH.js} +6 -6
  47. package/Build/Workers/{chunk-OBEU25PI.js → chunk-Q2JS5LCB.js} +17 -17
  48. package/Build/Workers/{chunk-KGXSYGBG.js → chunk-QTAEVUED.js} +13 -13
  49. package/Build/Workers/{chunk-NIWITKQK.js → chunk-SEJIXZZ4.js} +11 -11
  50. package/Build/Workers/{chunk-SGRGNDOD.js → chunk-SL2HCFYW.js} +10 -10
  51. package/Build/Workers/{chunk-SF6K72D7.js → chunk-SLHK3KAR.js} +5 -5
  52. package/Build/Workers/{chunk-JKXV6PG5.js → chunk-UZY5XRL2.js} +1 -1
  53. package/Build/Workers/{chunk-LNSQVXFH.js → chunk-VRECSMG3.js} +2 -2
  54. package/Build/Workers/{chunk-A3O6EDBK.js → chunk-X27HKF5E.js} +2 -2
  55. package/Build/Workers/{chunk-7KVKHY7O.js → chunk-XBY3354M.js} +6 -6
  56. package/Build/Workers/{chunk-GSWMAFTE.js → chunk-XRZCS3HE.js} +23 -16
  57. package/Build/Workers/{chunk-6YR6JBMY.js → chunk-XSIUYAT6.js} +2 -2
  58. package/Build/Workers/{chunk-ZSGUV73H.js → chunk-Z2DW5NM2.js} +6 -6
  59. package/Build/Workers/combineGeometry.js +24 -24
  60. package/Build/Workers/createBoxGeometry.js +18 -18
  61. package/Build/Workers/createBoxOutlineGeometry.js +16 -16
  62. package/Build/Workers/createCircleGeometry.js +26 -26
  63. package/Build/Workers/createCircleOutlineGeometry.js +19 -19
  64. package/Build/Workers/createCoplanarPolygonGeometry.js +35 -35
  65. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -31
  66. package/Build/Workers/createCorridorGeometry.js +31 -33
  67. package/Build/Workers/createCorridorOutlineGeometry.js +29 -31
  68. package/Build/Workers/createCylinderGeometry.js +20 -20
  69. package/Build/Workers/createCylinderOutlineGeometry.js +18 -18
  70. package/Build/Workers/createEllipseGeometry.js +26 -26
  71. package/Build/Workers/createEllipseOutlineGeometry.js +19 -19
  72. package/Build/Workers/createEllipsoidGeometry.js +19 -19
  73. package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -18
  74. package/Build/Workers/createFrustumGeometry.js +18 -18
  75. package/Build/Workers/createFrustumOutlineGeometry.js +18 -18
  76. package/Build/Workers/createGeometry.js +24 -24
  77. package/Build/Workers/createGroundPolylineGeometry.js +24 -24
  78. package/Build/Workers/createPlaneGeometry.js +16 -16
  79. package/Build/Workers/createPlaneOutlineGeometry.js +15 -15
  80. package/Build/Workers/createPolygonGeometry.js +34 -34
  81. package/Build/Workers/createPolygonOutlineGeometry.js +31 -31
  82. package/Build/Workers/createPolylineGeometry.js +26 -26
  83. package/Build/Workers/createPolylineVolumeGeometry.js +31 -31
  84. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -27
  85. package/Build/Workers/createRectangleGeometry.js +27 -27
  86. package/Build/Workers/createRectangleOutlineGeometry.js +21 -21
  87. package/Build/Workers/createSimplePolylineGeometry.js +24 -24
  88. package/Build/Workers/createSphereGeometry.js +19 -19
  89. package/Build/Workers/createSphereOutlineGeometry.js +18 -18
  90. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  91. package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
  92. package/Build/Workers/createVectorTileGeometries.js +24 -24
  93. package/Build/Workers/createVectorTilePoints.js +13 -13
  94. package/Build/Workers/createVectorTilePolygons.js +22 -22
  95. package/Build/Workers/createVectorTilePolylines.js +14 -14
  96. package/Build/Workers/createVerticesFromCesium3DTilesTerrain.js +25 -25
  97. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -22
  98. package/Build/Workers/createVerticesFromHeightmap.js +22 -22
  99. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +20 -20
  100. package/Build/Workers/createWallGeometry.js +24 -24
  101. package/Build/Workers/createWallOutlineGeometry.js +24 -24
  102. package/Build/Workers/decodeDraco.js +10 -10
  103. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  104. package/Build/Workers/decodeI3S.js +10 -10
  105. package/Build/Workers/gaussianSplatSorter.js +4 -4
  106. package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
  107. package/Build/Workers/incrementallyBuildTerrainPicker.js +10 -10
  108. package/Build/Workers/transcodeKTX2.js +6 -6
  109. package/Build/Workers/transferTypedArrayTest.js +1 -1
  110. package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -22
  111. package/Build/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +25 -25
  112. package/Source/Core/ArcGISTiledElevationTerrainProvider.js +1 -5
  113. package/Source/Core/BoundingSphere.js +0 -3
  114. package/Source/Core/Cesium3DTilesTerrainGeometryProcessor.js +3 -4
  115. package/Source/Core/CoplanarPolygonGeometry.js +2 -2
  116. package/Source/Core/CorridorGeometry.js +2 -4
  117. package/Source/Core/CorridorOutlineGeometry.js +1 -3
  118. package/Source/Core/EarthOrientationParameters.js +2 -2
  119. package/Source/Core/EllipseGeometryLibrary.js +2 -2
  120. package/Source/Core/EllipsoidGeodesic.js +3 -3
  121. package/Source/Core/EllipsoidRhumbLine.js +1 -1
  122. package/Source/Core/GroundPolylineGeometry.js +2 -2
  123. package/Source/Core/Heap.js +1 -1
  124. package/Source/Core/HermitePolynomialApproximation.js +215 -179
  125. package/Source/Core/InterpolationAlgorithm.js +1 -0
  126. package/Source/Core/Ion.js +1 -1
  127. package/Source/Core/IonResource.js +5 -0
  128. package/Source/Core/IonSnapGeometryType.js +59 -0
  129. package/Source/Core/IonSnapHeat.js +33 -0
  130. package/Source/Core/IonSnapMode.js +45 -0
  131. package/Source/Core/IonSnapParentGeometryType.js +52 -0
  132. package/Source/Core/IonSnapService.js +369 -0
  133. package/Source/Core/JulianDate.js +1 -1
  134. package/Source/Core/LagrangePolynomialApproximation.js +55 -52
  135. package/Source/Core/LinearApproximation.js +69 -66
  136. package/Source/Core/Math.js +59 -0
  137. package/Source/Core/Matrix2.js +2 -2
  138. package/Source/Core/Matrix3.js +2 -2
  139. package/Source/Core/OrthographicFrustum.js +1 -1
  140. package/Source/Core/PerspectiveFrustum.js +1 -1
  141. package/Source/Core/PolygonGeometry.js +2 -2
  142. package/Source/Core/PolygonGeometryLibrary.js +1 -1
  143. package/Source/Core/PolygonOutlineGeometry.js +1 -1
  144. package/Source/Core/PolylineGeometry.js +1 -1
  145. package/Source/Core/PolylineVolumeGeometryLibrary.js +1 -1
  146. package/Source/Core/Rectangle.js +7 -1
  147. package/Source/Core/RectangleOutlineGeometry.js +1 -1
  148. package/Source/Core/SimplePolylineGeometry.js +1 -1
  149. package/Source/Core/SnapService.js +63 -0
  150. package/Source/Core/TerrainEncoding.js +2 -2
  151. package/Source/Core/TerrainPicker.js +179 -168
  152. package/Source/Core/TimeIntervalCollection.js +1 -3
  153. package/Source/Core/Tipsify.js +1 -1
  154. package/Source/Core/Transforms.js +5 -1
  155. package/Source/Core/VectorPipeline.js +1211 -0
  156. package/Source/Core/VectorProvider.js +669 -0
  157. package/Source/Core/WallOutlineGeometry.js +1 -1
  158. package/Source/Core/getTimestamp.js +4 -2
  159. package/Source/DataSources/CompositeEntityCollection.js +0 -1
  160. package/Source/DataSources/CzmlDataSource.js +2 -0
  161. package/Source/DataSources/DataSourceDisplay.js +1 -1
  162. package/Source/DataSources/GeoJsonDataSource.js +0 -1
  163. package/Source/DataSources/GeometryVisualizer.js +1 -1
  164. package/Source/DataSources/KmlDataSource.js +1 -2
  165. package/Source/DataSources/PolylineVisualizer.js +1 -1
  166. package/Source/DataSources/StaticOutlineGeometryBatch.js +1 -1
  167. package/Source/Renderer/AutomaticUniforms.js +67 -2
  168. package/Source/Renderer/Context.js +9 -3
  169. package/Source/Renderer/DrawCommand.js +22 -0
  170. package/Source/Renderer/Framebuffer.js +4 -0
  171. package/Source/Renderer/Pass.js +11 -10
  172. package/Source/Renderer/ShaderBuilder.js +1 -1
  173. package/Source/Renderer/Texture.js +11 -0
  174. package/Source/Renderer/UniformState.js +54 -1
  175. package/Source/Renderer/VertexArray.js +0 -1
  176. package/Source/Scene/ArcGisMapServerImageryProvider.js +0 -5
  177. package/Source/Scene/ArcGisMapService.js +1 -1
  178. package/Source/Scene/Billboard.js +2 -1
  179. package/Source/Scene/BillboardCollection.js +7 -3
  180. package/Source/Scene/BufferPointCollection.js +4 -7
  181. package/Source/Scene/BufferPolygonCollection.js +56 -27
  182. package/Source/Scene/BufferPolylineCollection.js +61 -8
  183. package/Source/Scene/BufferPolylineMaterial.js +6 -5
  184. package/Source/Scene/BufferPrimitiveCollection.js +226 -34
  185. package/Source/Scene/Camera.js +71 -5
  186. package/Source/Scene/Cesium3DTile.js +12 -0
  187. package/Source/Scene/Cesium3DTileset.js +62 -9
  188. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +15 -3
  189. package/Source/Scene/Cesium3DTilesetCache.js +15 -0
  190. package/Source/Scene/ClippingPlaneCollection.js +2 -2
  191. package/Source/Scene/ClippingPolygon.js +154 -100
  192. package/Source/Scene/ClippingPolygonCollection.js +352 -694
  193. package/Source/Scene/Controllers/Controller.js +63 -0
  194. package/Source/Scene/Controllers/ControllerHost.js +78 -0
  195. package/Source/Scene/Controllers/HybridScreenSpacePanCameraController.js +106 -0
  196. package/Source/Scene/Controllers/MouseButton.js +32 -0
  197. package/Source/Scene/Controllers/ScreenSpaceElevatorCameraController.js +295 -0
  198. package/Source/Scene/Controllers/ScreenSpaceInputBindings.js +154 -0
  199. package/Source/Scene/Controllers/ScreenSpaceMapCameraController.js +310 -0
  200. package/Source/Scene/Controllers/ScreenSpaceTiltOrbitCameraController.js +642 -0
  201. package/Source/Scene/Controllers/ScreenSpaceZoomCameraController.js +431 -0
  202. package/Source/Scene/Controllers/defaultPickWorldPosition.js +84 -0
  203. package/Source/Scene/CreditDisplay.js +62 -0
  204. package/Source/Scene/DerivedCommand.js +94 -0
  205. package/Source/Scene/EdgeFramebuffer.js +1 -5
  206. package/Source/Scene/FrameState.js +17 -0
  207. package/Source/Scene/GeoJsonPrimitive.js +114 -24
  208. package/Source/Scene/Globe.js +20 -0
  209. package/Source/Scene/GlobeDepth.js +27 -1
  210. package/Source/Scene/GlobeSurfaceShaderSet.js +42 -53
  211. package/Source/Scene/GlobeSurfaceTile.js +61 -10
  212. package/Source/Scene/GlobeSurfaceTileProvider.js +351 -26
  213. package/Source/Scene/GltfLoader.js +88 -9
  214. package/Source/Scene/GltfSpzLoader.js +1 -1
  215. package/Source/Scene/GltfVertexBufferLoader.js +6 -3
  216. package/Source/Scene/HeightReference.js +1 -1
  217. package/Source/Scene/I3SDataProvider.js +1 -1
  218. package/Source/Scene/I3SLayer.js +1 -1
  219. package/Source/Scene/I3SNode.js +2 -2
  220. package/Source/Scene/ImageryLayerCollection.js +188 -4
  221. package/Source/Scene/IonImageryProvider.js +1 -5
  222. package/Source/Scene/Label.js +4 -4
  223. package/Source/Scene/LabelCollection.js +1 -1
  224. package/Source/Scene/MVTDataProvider.js +11 -0
  225. package/Source/Scene/Model/B3dmLoader.js +1 -2
  226. package/Source/Scene/Model/EdgeVisibilityPipelineStage.js +10 -8
  227. package/Source/Scene/Model/I3dmLoader.js +1 -1
  228. package/Source/Scene/Model/InstancingPipelineStage.js +4 -7
  229. package/Source/Scene/Model/MaterialPipelineStage.js +124 -1
  230. package/Source/Scene/Model/Model.js +250 -26
  231. package/Source/Scene/Model/Model3DTileContent.js +5 -0
  232. package/Source/Scene/Model/ModelClippingPlanesPipelineStage.js +28 -1
  233. package/Source/Scene/Model/ModelClippingPolygonsPipelineStage.js +54 -19
  234. package/Source/Scene/Model/ModelDrawCommand.js +160 -16
  235. package/Source/Scene/Model/ModelDrawCommands.js +4 -0
  236. package/Source/Scene/Model/ModelRenderResources.js +2 -3
  237. package/Source/Scene/Model/ModelSceneGraph.js +31 -1
  238. package/Source/Scene/Model/ModelVectorLookupPipelineStage.js +205 -0
  239. package/Source/Scene/Model/PickingPipelineStage.js +33 -0
  240. package/Source/Scene/Model/PrimitiveRenderResources.js +24 -0
  241. package/Source/Scene/ModelComponents.js +71 -0
  242. package/Source/Scene/Picking.js +16 -5
  243. package/Source/Scene/PlanarFillIdFramebuffer.js +172 -0
  244. package/Source/Scene/PntsParser.js +0 -1
  245. package/Source/Scene/PolylineCollection.js +1 -1
  246. package/Source/Scene/PostProcessStage.js +26 -5
  247. package/Source/Scene/ResourceCache.js +7 -4
  248. package/Source/Scene/ResourceCacheKey.js +16 -13
  249. package/Source/Scene/Scene.js +258 -6
  250. package/Source/Scene/ScreenSpaceCameraController.js +1 -2
  251. package/Source/Scene/ShadowMap.js +9 -3
  252. package/Source/Scene/ShadowMapShader.js +50 -2
  253. package/Source/Scene/SnapFramebuffer.js +121 -0
  254. package/Source/Scene/Snapping.js +241 -0
  255. package/Source/Scene/TerrainFillMesh.js +3 -2
  256. package/Source/Scene/UrlTemplate3DTilesDataProvider.js +13 -2
  257. package/Source/Scene/Vector3DTileContent.js +2 -3
  258. package/Source/Scene/VectorGltf3DTileContent.js +31 -3
  259. package/Source/Scene/View.js +10 -8
  260. package/Source/Scene/VoxelTraversal.js +1 -1
  261. package/Source/Scene/WebMapServiceImageryProvider.js +5 -1
  262. package/Source/Scene/WebMapTileServiceImageryProvider.js +6 -1
  263. package/Source/Scene/createElevationBandMaterial.js +1 -1
  264. package/Source/Scene/renderBufferPointCollection.js +1 -2
  265. package/Source/Scene/renderBufferPolygonCollection.js +1 -2
  266. package/Source/Scene/renderBufferPolylineCollection.js +6 -3
  267. package/Source/Shaders/BufferPolylineMaterialVS.glsl +14 -2
  268. package/Source/Shaders/BufferPolylineMaterialVS.js +14 -2
  269. package/Source/Shaders/Builtin/Constants/passCesium3DTile.glsl +1 -1
  270. package/Source/Shaders/Builtin/Constants/passCesium3DTile.js +1 -1
  271. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl +1 -1
  272. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.js +1 -1
  273. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.glsl +1 -1
  274. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.js +1 -1
  275. package/Source/Shaders/Builtin/Constants/passCesium3DTilePlanarFillId.glsl +9 -0
  276. package/Source/Shaders/Builtin/Constants/passCesium3DTilePlanarFillId.js +11 -0
  277. package/Source/Shaders/Builtin/Constants/passClassification.glsl +1 -1
  278. package/Source/Shaders/Builtin/Constants/passClassification.js +1 -1
  279. package/Source/Shaders/Builtin/Constants/passGaussianSplats.glsl +1 -1
  280. package/Source/Shaders/Builtin/Constants/passGaussianSplats.js +1 -1
  281. package/Source/Shaders/Builtin/Constants/passOpaque.glsl +1 -1
  282. package/Source/Shaders/Builtin/Constants/passOpaque.js +1 -1
  283. package/Source/Shaders/Builtin/Constants/passTranslucent.glsl +1 -1
  284. package/Source/Shaders/Builtin/Constants/passTranslucent.js +1 -1
  285. package/Source/Shaders/Builtin/Constants/passVoxels.glsl +1 -1
  286. package/Source/Shaders/Builtin/Constants/passVoxels.js +1 -1
  287. package/Source/Shaders/Builtin/CzmBuiltins.js +4 -4
  288. package/Source/Shaders/Builtin/Functions/eyeToCartographicDelta.glsl +74 -0
  289. package/Source/Shaders/Builtin/Functions/eyeToCartographicDelta.js +76 -0
  290. package/Source/Shaders/GlobeFS.glsl +20 -14
  291. package/Source/Shaders/GlobeFS.js +20 -14
  292. package/Source/Shaders/GlobeVS.glsl +0 -32
  293. package/Source/Shaders/GlobeVS.js +0 -32
  294. package/Source/Shaders/Materials/PolylineGlowMaterial.glsl +1 -1
  295. package/Source/Shaders/Materials/PolylineGlowMaterial.js +1 -1
  296. package/Source/Shaders/Model/MaterialStageFS.glsl +8 -2
  297. package/Source/Shaders/Model/MaterialStageFS.js +8 -2
  298. package/Source/Shaders/Model/ModelClippingPolygonsStageFS.glsl +15 -3
  299. package/Source/Shaders/Model/ModelClippingPolygonsStageFS.js +15 -3
  300. package/Source/Shaders/Model/ModelClippingPolygonsStageVS.glsl +20 -24
  301. package/Source/Shaders/Model/ModelClippingPolygonsStageVS.js +20 -24
  302. package/Source/Shaders/Model/ModelFS.glsl +109 -0
  303. package/Source/Shaders/Model/ModelFS.js +109 -0
  304. package/Source/Shaders/Model/ModelVS.glsl +7 -2
  305. package/Source/Shaders/Model/ModelVS.js +7 -2
  306. package/Source/Shaders/Model/ModelVectorLookupStageFS.glsl +6 -0
  307. package/Source/Shaders/Model/ModelVectorLookupStageFS.js +8 -0
  308. package/Source/Shaders/Model/ModelVectorLookupStageVS.glsl +15 -0
  309. package/Source/Shaders/Model/ModelVectorLookupStageVS.js +17 -0
  310. package/Source/Shaders/Model/VerticalExaggerationStageVS.glsl +9 -10
  311. package/Source/Shaders/Model/VerticalExaggerationStageVS.js +9 -11
  312. package/Source/Shaders/VectorCommon.glsl +305 -0
  313. package/Source/Shaders/VectorCommon.js +307 -0
  314. package/Source/ThirdParty/Workers/zip-web-worker.js +1 -1
  315. package/Source/ThirdParty/zip-module.wasm +0 -0
  316. package/Source/Widget/CesiumWidget.js +30 -0
  317. package/index.d.ts +1326 -65
  318. package/index.js +179 -155
  319. package/package.json +6 -6
  320. package/Source/Shaders/Builtin/Functions/clipPolygons.glsl +0 -37
  321. package/Source/Shaders/Builtin/Functions/clipPolygons.js +0 -39
  322. package/Source/Shaders/Builtin/Functions/unpackClippingExtents.glsl +0 -14
  323. package/Source/Shaders/Builtin/Functions/unpackClippingExtents.js +0 -15
  324. package/Source/Shaders/PolygonSignedDistanceFS.glsl +0 -131
  325. 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;