@hztxi/cesium-engine 25.0.6 → 26.2.1

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 (484) hide show
  1. package/Build/Workers/chunk-2GJAWJJT.js +1344 -0
  2. package/Build/Workers/chunk-2J2VS5RI.js +288 -0
  3. package/Build/Workers/chunk-2NCNUVAT.js +56 -0
  4. package/Build/Workers/chunk-2ZYRUVVU.js +301 -0
  5. package/Build/Workers/chunk-36IU7N4V.js +1284 -0
  6. package/Build/Workers/chunk-375SHKGW.js +44 -0
  7. package/Build/Workers/chunk-3BDLET5S.js +198 -0
  8. package/Build/Workers/chunk-3PRHI4KX.js +241 -0
  9. package/Build/Workers/chunk-3R6E2SH4.js +672 -0
  10. package/Build/Workers/chunk-3ZKKXEXL.js +415 -0
  11. package/Build/Workers/chunk-47KVKPTO.js +415 -0
  12. package/Build/Workers/chunk-4N227IPR.js +973 -0
  13. package/Build/Workers/chunk-4P6OAPBM.js +97 -0
  14. package/Build/Workers/chunk-4ZOLEPZK.js +519 -0
  15. package/Build/Workers/chunk-5EF3WWQG.js +352 -0
  16. package/Build/Workers/chunk-5FYUSABU.js +945 -0
  17. package/Build/Workers/chunk-5I76476T.js +288 -0
  18. package/Build/Workers/chunk-5PBZKBAP.js +511 -0
  19. package/Build/Workers/chunk-5RVAAW26.js +82 -0
  20. package/Build/Workers/chunk-5VWK76PO.js +511 -0
  21. package/Build/Workers/chunk-5WU37CUJ.js +630 -0
  22. package/Build/Workers/chunk-6EBDN5WS.js +97 -0
  23. package/Build/Workers/chunk-75HIWCEV.js +301 -0
  24. package/Build/Workers/chunk-77DBX23X.js +455 -0
  25. package/Build/Workers/chunk-7AMVPXZY.js +1992 -0
  26. package/Build/Workers/chunk-7BMDD6SM.js +124 -0
  27. package/Build/Workers/chunk-7GQOWCSN.js +959 -0
  28. package/Build/Workers/chunk-7J2ONMKC.js +198 -0
  29. package/Build/Workers/chunk-7MHUHXZZ.js +219 -0
  30. package/Build/Workers/chunk-7MQPHOAS.js +455 -0
  31. package/Build/Workers/chunk-7NJ5O7TP.js +387 -0
  32. package/Build/Workers/chunk-7OME2OKM.js +171 -0
  33. package/Build/Workers/chunk-7Y642MCO.js +352 -0
  34. package/Build/Workers/chunk-7ZFKBLUE.js +1054 -0
  35. package/Build/Workers/chunk-A2BROW3D.js +352 -0
  36. package/Build/Workers/chunk-A7LGY5XS.js +140 -0
  37. package/Build/Workers/chunk-AN2NVYL6.js +1483 -0
  38. package/Build/Workers/chunk-B4XOVZGA.js +476 -0
  39. package/Build/Workers/chunk-B7PT2VL5.js +630 -0
  40. package/Build/Workers/chunk-C6XQGBPV.js +476 -0
  41. package/Build/Workers/chunk-CAEC5DA2.js +57 -0
  42. package/Build/Workers/chunk-CBCOHH5O.js +837 -0
  43. package/Build/Workers/chunk-CDLPLYLV.js +1287 -0
  44. package/Build/Workers/chunk-CEKCKPFN.js +368 -0
  45. package/Build/Workers/chunk-CEMXKBQO.js +1800 -0
  46. package/Build/Workers/chunk-CHMDKP5L.js +2342 -0
  47. package/Build/Workers/chunk-CKW3STKA.js +1067 -0
  48. package/Build/Workers/chunk-CV5RICKT.js +1992 -0
  49. package/Build/Workers/chunk-CWGB3D4Z.js +257 -0
  50. package/Build/Workers/chunk-DBWSISJT.js +56 -0
  51. package/Build/Workers/chunk-DQEUGBGA.js +2719 -0
  52. package/Build/Workers/chunk-DSBSPPPJ.js +1344 -0
  53. package/Build/Workers/chunk-DSGLDRTI.js +278 -0
  54. package/Build/Workers/chunk-DUBE5G2H.js +497 -0
  55. package/Build/Workers/chunk-DXD7OPSP.js +1992 -0
  56. package/Build/Workers/chunk-DXECZBSA.js +368 -0
  57. package/Build/Workers/chunk-DZIRO6ZK.js +682 -0
  58. package/Build/Workers/chunk-E4CRPGX5.js +140 -0
  59. package/Build/Workers/chunk-E4IVMEBH.js +52 -0
  60. package/Build/Workers/chunk-E4PBNWWK.js +58 -0
  61. package/Build/Workers/chunk-E5MWOMVC.js +57 -0
  62. package/Build/Workers/chunk-ECN3VUMA.js +73 -0
  63. package/Build/Workers/chunk-ECSKVHUB.js +476 -0
  64. package/Build/Workers/chunk-EE3XBOQI.js +1483 -0
  65. package/Build/Workers/chunk-EHA2ZDPZ.js +415 -0
  66. package/Build/Workers/chunk-EKEKPAJF.js +454 -0
  67. package/Build/Workers/chunk-EL4B5CSQ.js +162 -0
  68. package/Build/Workers/chunk-EOHKUXPX.js +198 -0
  69. package/Build/Workers/chunk-ERENMHG2.js +754 -0
  70. package/Build/Workers/chunk-ESQGFRLZ.js +163 -0
  71. package/Build/Workers/chunk-FAYBQGKO.js +219 -0
  72. package/Build/Workers/chunk-FGCXPEZM.js +3201 -0
  73. package/Build/Workers/chunk-FHCRXPA6.js +44 -0
  74. package/Build/Workers/chunk-FQ42MT7M.js +58 -0
  75. package/Build/Workers/chunk-FQDYQG4P.js +1284 -0
  76. package/Build/Workers/chunk-FTCBY5HH.js +138 -0
  77. package/Build/Workers/chunk-FV4OWDV4.js +9230 -0
  78. package/Build/Workers/chunk-FYRNNQSL.js +280 -0
  79. package/Build/Workers/chunk-GI5RWJAY.js +101 -0
  80. package/Build/Workers/chunk-GNLMSDRO.js +945 -0
  81. package/Build/Workers/chunk-GVUJ6O3R.js +73 -0
  82. package/Build/Workers/chunk-HCGU7OCG.js +97 -0
  83. package/Build/Workers/chunk-HRIPVWSC.js +58 -0
  84. package/Build/Workers/chunk-IC3BR6SC.js +102 -0
  85. package/Build/Workers/chunk-IU3YAYPT.js +1344 -0
  86. package/Build/Workers/chunk-J7MZR7B2.js +1483 -0
  87. package/Build/Workers/chunk-JMF4ATAS.js +3794 -0
  88. package/Build/Workers/chunk-KEJKMITY.js +82 -0
  89. package/Build/Workers/chunk-KSIEJYNL.js +3822 -0
  90. package/Build/Workers/chunk-KT3GG7AW.js +754 -0
  91. package/Build/Workers/chunk-KW2QZDUS.js +147 -0
  92. package/Build/Workers/chunk-KYCEM22I.js +1800 -0
  93. package/Build/Workers/chunk-L6B5XPBL.js +73 -0
  94. package/Build/Workers/chunk-LGJXN2VP.js +352 -0
  95. package/Build/Workers/chunk-LJTQW46H.js +57 -0
  96. package/Build/Workers/chunk-LMQGYJME.js +672 -0
  97. package/Build/Workers/chunk-LOBYJQA4.js +76 -0
  98. package/Build/Workers/chunk-LOF32O7F.js +163 -0
  99. package/Build/Workers/chunk-LOTIJA7D.js +124 -0
  100. package/Build/Workers/chunk-LY2UG3HV.js +38 -0
  101. package/Build/Workers/chunk-M7Z3MPAX.js +973 -0
  102. package/Build/Workers/chunk-MHNLTQHO.js +3201 -0
  103. package/Build/Workers/chunk-ML7OMD72.js +2342 -0
  104. package/Build/Workers/chunk-NBTGXEMT.js +945 -0
  105. package/Build/Workers/chunk-NCPJBP24.js +140 -0
  106. package/Build/Workers/chunk-NFY5V6MR.js +102 -0
  107. package/Build/Workers/chunk-NQZC37F7.js +38 -0
  108. package/Build/Workers/chunk-O3X3D2Z3.js +352 -0
  109. package/Build/Workers/chunk-OBUIHPKF.js +352 -0
  110. package/Build/Workers/chunk-OYPSUED3.js +1067 -0
  111. package/Build/Workers/chunk-PAEWNYIV.js +138 -0
  112. package/Build/Workers/chunk-PANJ7YH6.js +102 -0
  113. package/Build/Workers/chunk-PCL3Y7H5.js +82 -0
  114. package/Build/Workers/chunk-PIIUGRQD.js +387 -0
  115. package/Build/Workers/chunk-POKD22OT.js +2719 -0
  116. package/Build/Workers/chunk-PQMA7MFS.js +9237 -0
  117. package/Build/Workers/chunk-PURIPUSY.js +682 -0
  118. package/Build/Workers/chunk-QIOOTLWN.js +56 -0
  119. package/Build/Workers/chunk-QQZPPXY4.js +3822 -0
  120. package/Build/Workers/chunk-QUPRALOD.js +101 -0
  121. package/Build/Workers/chunk-QXLQLGL2.js +1067 -0
  122. package/Build/Workers/chunk-RBEVHHXK.js +3201 -0
  123. package/Build/Workers/chunk-RC4YC3VU.js +278 -0
  124. package/Build/Workers/chunk-RGNNWVR6.js +171 -0
  125. package/Build/Workers/chunk-RHO5HV52.js +305 -0
  126. package/Build/Workers/chunk-SBBIEHYT.js +44 -0
  127. package/Build/Workers/chunk-SVCZUP5R.js +837 -0
  128. package/Build/Workers/chunk-SWVZTU6X.js +305 -0
  129. package/Build/Workers/chunk-T3EUPM5A.js +454 -0
  130. package/Build/Workers/chunk-TA6IU2XL.js +171 -0
  131. package/Build/Workers/chunk-TBHW5UME.js +973 -0
  132. package/Build/Workers/chunk-TLSGD5TR.js +280 -0
  133. package/Build/Workers/chunk-TOXDLWKZ.js +368 -0
  134. package/Build/Workers/chunk-TPOX6IOR.js +1054 -0
  135. package/Build/Workers/chunk-TZBM6TAB.js +124 -0
  136. package/Build/Workers/chunk-U2OY6MX6.js +398 -0
  137. package/Build/Workers/chunk-UCY4B5EV.js +288 -0
  138. package/Build/Workers/chunk-ULNBTI6R.js +138 -0
  139. package/Build/Workers/chunk-UMUS2AQQ.js +398 -0
  140. package/Build/Workers/chunk-UZ7GTP2L.js +162 -0
  141. package/Build/Workers/chunk-V52FEPCV.js +754 -0
  142. package/Build/Workers/chunk-VBEXZBG5.js +147 -0
  143. package/Build/Workers/chunk-VC76B6GM.js +959 -0
  144. package/Build/Workers/chunk-VCUOYHWC.js +519 -0
  145. package/Build/Workers/chunk-VJIL5H6K.js +2719 -0
  146. package/Build/Workers/chunk-VMF7KOGY.js +162 -0
  147. package/Build/Workers/chunk-W3C7OHXF.js +387 -0
  148. package/Build/Workers/chunk-W5OCKMPJ.js +101 -0
  149. package/Build/Workers/chunk-WB5GWYDP.js +455 -0
  150. package/Build/Workers/chunk-WN6MAL25.js +682 -0
  151. package/Build/Workers/chunk-WTR7KMQA.js +693 -0
  152. package/Build/Workers/chunk-WTTFMU3P.js +241 -0
  153. package/Build/Workers/chunk-WULONJZC.js +1800 -0
  154. package/Build/Workers/chunk-WZPMAVTV.js +511 -0
  155. package/Build/Workers/chunk-XHT5SVP4.js +52 -0
  156. package/Build/Workers/chunk-XITBARMZ.js +2342 -0
  157. package/Build/Workers/chunk-XLQZNQ4Z.js +163 -0
  158. package/Build/Workers/chunk-XZ6HDXKM.js +76 -0
  159. package/Build/Workers/chunk-Y7KVUJEB.js +219 -0
  160. package/Build/Workers/chunk-Y7NDFEQ3.js +398 -0
  161. package/Build/Workers/chunk-YBBQDYX2.js +301 -0
  162. package/Build/Workers/chunk-YHPYPVAB.js +837 -0
  163. package/Build/Workers/chunk-YNKK6BXY.js +454 -0
  164. package/Build/Workers/chunk-YRAJ74HR.js +305 -0
  165. package/Build/Workers/chunk-YULTZK5O.js +147 -0
  166. package/Build/Workers/chunk-YUNQYP3Z.js +9237 -0
  167. package/Build/Workers/chunk-Z6JV4DZG.js +1046 -0
  168. package/Build/Workers/chunk-Z7BONRW2.js +241 -0
  169. package/Build/Workers/chunk-ZK2R3DEJ.js +1054 -0
  170. package/Build/Workers/chunk-ZTK5EBUI.js +76 -0
  171. package/Build/Workers/chunk-ZZPDORJK.js +56 -0
  172. package/Build/Workers/combineGeometry.js +24 -24
  173. package/Build/Workers/createBoxGeometry.js +18 -18
  174. package/Build/Workers/createBoxOutlineGeometry.js +18 -18
  175. package/Build/Workers/createCircleGeometry.js +26 -26
  176. package/Build/Workers/createCircleOutlineGeometry.js +19 -19
  177. package/Build/Workers/createCoplanarPolygonGeometry.js +39 -39
  178. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +33 -33
  179. package/Build/Workers/createCorridorGeometry.js +36 -37
  180. package/Build/Workers/createCorridorOutlineGeometry.js +34 -35
  181. package/Build/Workers/createCylinderGeometry.js +20 -20
  182. package/Build/Workers/createCylinderOutlineGeometry.js +20 -20
  183. package/Build/Workers/createEllipseGeometry.js +26 -26
  184. package/Build/Workers/createEllipseOutlineGeometry.js +19 -19
  185. package/Build/Workers/createEllipsoidGeometry.js +19 -19
  186. package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -18
  187. package/Build/Workers/createFrustumGeometry.js +18 -18
  188. package/Build/Workers/createFrustumOutlineGeometry.js +20 -20
  189. package/Build/Workers/createGeometry.js +25 -24
  190. package/Build/Workers/createGroundPolylineGeometry.js +98 -34
  191. package/Build/Workers/createMvtTile.js +111 -19
  192. package/Build/Workers/createPlaneGeometry.js +18 -18
  193. package/Build/Workers/createPlaneOutlineGeometry.js +17 -17
  194. package/Build/Workers/createPolygonGeometry.js +36 -36
  195. package/Build/Workers/createPolygonOutlineGeometry.js +33 -33
  196. package/Build/Workers/createPolylineGeometry.js +28 -28
  197. package/Build/Workers/createPolylineVolumeGeometry.js +38 -36
  198. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +32 -31
  199. package/Build/Workers/createRectangleGeometry.js +29 -29
  200. package/Build/Workers/createRectangleOutlineGeometry.js +23 -23
  201. package/Build/Workers/createSimplePolylineGeometry.js +26 -26
  202. package/Build/Workers/createSphereGeometry.js +19 -19
  203. package/Build/Workers/createSphereOutlineGeometry.js +18 -18
  204. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  205. package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
  206. package/Build/Workers/createVectorTileGeometries.js +24 -24
  207. package/Build/Workers/createVectorTilePoints.js +13 -13
  208. package/Build/Workers/createVectorTilePolygons.js +22 -22
  209. package/Build/Workers/createVectorTilePolylines.js +14 -14
  210. package/Build/Workers/createVerticesFromCesium3DTilesTerrain.js +26 -26
  211. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +23 -23
  212. package/Build/Workers/createVerticesFromHeightmap.js +23 -23
  213. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +21 -21
  214. package/Build/Workers/createWallGeometry.js +26 -26
  215. package/Build/Workers/createWallOutlineGeometry.js +26 -26
  216. package/Build/Workers/decodeDraco.js +10 -10
  217. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +993 -2334
  218. package/Build/Workers/decodeI3S.js +10 -10
  219. package/Build/Workers/gaussianSplatSorter.js +4 -4
  220. package/Build/Workers/gaussianSplatTextureGenerator.js +4 -4
  221. package/Build/Workers/incrementallyBuildTerrainPicker.js +10 -10
  222. package/Build/Workers/transcodeKTX2.js +6 -6
  223. package/Build/Workers/transferTypedArrayTest.js +1 -1
  224. package/Build/Workers/upsampleQuantizedTerrainMesh.js +23 -23
  225. package/Build/Workers/upsampleVerticesFromCesium3DTilesTerrain.js +26 -26
  226. package/Source/Core/ArcGISTiledElevationTerrainProvider.js +1 -5
  227. package/Source/Core/BoundingRectangle.js +6 -8
  228. package/Source/Core/BoundingSphere.js +0 -3
  229. package/Source/Core/Cartesian2.js +1 -1
  230. package/Source/Core/Cartesian3.js +1 -1
  231. package/Source/Core/Cartesian4.js +1 -1
  232. package/Source/Core/Cesium3DTilesTerrainGeometryProcessor.js +3 -4
  233. package/Source/Core/Color.js +1 -0
  234. package/Source/Core/ComponentDatatype.js +35 -0
  235. package/Source/Core/CoplanarPolygonGeometry.js +2 -2
  236. package/Source/Core/CorridorGeometry.js +2 -4
  237. package/Source/Core/CorridorOutlineGeometry.js +1 -3
  238. package/Source/Core/EarthOrientationParameters.js +2 -2
  239. package/Source/Core/EllipseGeometryLibrary.js +2 -2
  240. package/Source/Core/EllipsoidGeodesic.js +3 -3
  241. package/Source/Core/EllipsoidRhumbLine.js +1 -1
  242. package/Source/Core/GroundPolylineGeometry.js +99 -4
  243. package/Source/Core/Heap.js +1 -1
  244. package/Source/Core/HermitePolynomialApproximation.js +215 -179
  245. package/Source/Core/InterpolationAlgorithm.js +58 -50
  246. package/Source/Core/Ion.js +1 -1
  247. package/Source/Core/JulianDate.js +1 -1
  248. package/Source/Core/LagrangePolynomialApproximation.js +55 -52
  249. package/Source/Core/LinearApproximation.js +69 -66
  250. package/Source/Core/MapProjection.js +1 -0
  251. package/Source/Core/Math.js +59 -0
  252. package/Source/Core/Matrix2.js +3 -3
  253. package/Source/Core/Matrix3.js +3 -3
  254. package/Source/Core/Matrix4.js +1 -1
  255. package/Source/Core/OrthographicFrustum.js +1 -1
  256. package/Source/Core/PerspectiveFrustum.js +1 -1
  257. package/Source/Core/PolygonGeometry.js +2 -2
  258. package/Source/Core/PolygonGeometryLibrary.js +1 -1
  259. package/Source/Core/PolygonOutlineGeometry.js +1 -1
  260. package/Source/Core/PolylineGeometry.js +1 -1
  261. package/Source/Core/PolylinePipeline.js +9 -2
  262. package/Source/Core/PolylineVolumeGeometryLibrary.js +1 -1
  263. package/Source/Core/Rectangle.js +7 -1
  264. package/Source/Core/RectangleOutlineGeometry.js +1 -1
  265. package/Source/Core/Resource.js +1 -1
  266. package/Source/Core/ScreenSpaceEventHandler.js +51 -41
  267. package/Source/Core/SimplePolylineGeometry.js +1 -1
  268. package/Source/Core/TerrainEncoding.js +2 -2
  269. package/Source/Core/TerrainMesh.js +3 -3
  270. package/Source/Core/TerrainPicker.js +180 -168
  271. package/Source/Core/TimeIntervalCollection.js +1 -3
  272. package/Source/Core/Tipsify.js +1 -1
  273. package/Source/Core/Transforms.js +5 -1
  274. package/Source/Core/VectorPipeline.js +1117 -0
  275. package/Source/Core/VectorProvider.js +429 -0
  276. package/Source/Core/WallOutlineGeometry.js +1 -1
  277. package/Source/Core/createColorRamp.js +37 -0
  278. package/Source/Core/getTimestamp.js +4 -2
  279. package/Source/Core/globalTypes.js +25 -0
  280. package/Source/Core/writeTextToCanvas.js +1 -0
  281. package/Source/DataSources/CompositeEntityCollection.js +0 -1
  282. package/Source/DataSources/CzmlDataSource.js +14 -0
  283. package/Source/DataSources/DataSourceDisplay.js +1 -1
  284. package/Source/DataSources/GeoJsonDataSource.js +0 -1
  285. package/Source/DataSources/GeometryVisualizer.js +1 -1
  286. package/Source/DataSources/KmlDataSource.js +529 -557
  287. package/Source/DataSources/PathGraphics.js +8 -1
  288. package/Source/DataSources/PathMode.js +27 -0
  289. package/Source/DataSources/PathVisualizer.js +298 -1
  290. package/Source/DataSources/PolylineGeometryUpdater.js +125 -7
  291. package/Source/DataSources/PolylineVisualizer.js +1 -1
  292. package/Source/DataSources/StaticOutlineGeometryBatch.js +1 -1
  293. package/Source/Renderer/AutomaticUniforms.js +23 -0
  294. package/Source/Renderer/Context.js +9 -3
  295. package/Source/Renderer/DrawCommand.js +22 -0
  296. package/Source/Renderer/Framebuffer.js +4 -0
  297. package/Source/Renderer/Pass.js +11 -9
  298. package/Source/Renderer/Texture.js +12 -1
  299. package/Source/Renderer/UniformState.js +7 -0
  300. package/Source/Renderer/VertexArray.js +1 -1
  301. package/Source/Renderer/createUniform.js +346 -239
  302. package/Source/Renderer/createUniformArray.js +494 -381
  303. package/Source/Scene/ArcGisMapServerImageryProvider.js +0 -5
  304. package/Source/Scene/ArcGisMapService.js +1 -1
  305. package/Source/Scene/Billboard.js +2 -1
  306. package/Source/Scene/BillboardCollection.js +15 -5
  307. package/Source/Scene/BillboardTexture.js +5 -3
  308. package/Source/Scene/BufferPointCollection.js +11 -1
  309. package/Source/Scene/BufferPolygonCollection.js +26 -0
  310. package/Source/Scene/BufferPolylineCollection.js +2 -0
  311. package/Source/Scene/BufferPrimitiveCollection.js +105 -32
  312. package/Source/Scene/Camera.js +137 -8
  313. package/Source/Scene/CameraEventAggregator.js +30 -18
  314. package/Source/Scene/CameraFlightPath.js +17 -0
  315. package/Source/Scene/Cesium3DTile.js +102 -4
  316. package/Source/Scene/Cesium3DTileContent.js +195 -254
  317. package/Source/Scene/Cesium3DTileContentFactory.js +10 -2
  318. package/Source/Scene/Cesium3DTileOptimizations.js +4 -6
  319. package/Source/Scene/Cesium3DTileStyle.js +40 -0
  320. package/Source/Scene/Cesium3DTileset.js +213 -8
  321. package/Source/Scene/Cesium3DTilesetTraversal.js +14 -0
  322. package/Source/Scene/ClippingPlaneCollection.js +4 -4
  323. package/Source/Scene/ClippingPolygon.js +2 -0
  324. package/Source/Scene/ClippingPolygonCollection.js +2 -2
  325. package/Source/Scene/ColumbusWorlds.js +190 -0
  326. package/Source/Scene/Composite3DTileContent.js +254 -292
  327. package/Source/Scene/Controllers/Controller.js +63 -0
  328. package/Source/Scene/Controllers/ControllerHost.js +78 -0
  329. package/Source/Scene/Controllers/HybridScreenSpacePanCameraController.js +106 -0
  330. package/Source/Scene/Controllers/MouseButton.js +32 -0
  331. package/Source/Scene/Controllers/ScreenSpaceElevatorCameraController.js +295 -0
  332. package/Source/Scene/Controllers/ScreenSpaceInputBindings.js +154 -0
  333. package/Source/Scene/Controllers/ScreenSpaceMapCameraController.js +310 -0
  334. package/Source/Scene/Controllers/ScreenSpaceTiltOrbitCameraController.js +642 -0
  335. package/Source/Scene/Controllers/ScreenSpaceZoomCameraController.js +431 -0
  336. package/Source/Scene/Controllers/defaultPickWorldPosition.js +84 -0
  337. package/Source/Scene/DerivedCommand.js +98 -0
  338. package/Source/Scene/EdgeDisplayMode.js +50 -0
  339. package/Source/Scene/EdgeFramebuffer.js +1 -5
  340. package/Source/Scene/Empty3DTileContent.js +100 -132
  341. package/Source/Scene/Expression.js +6 -8
  342. package/Source/Scene/FrameState.js +27 -0
  343. package/Source/Scene/GaussianSplat3DTileContent.js +436 -478
  344. package/Source/Scene/GeoJsonPrimitive.js +874 -0
  345. package/Source/Scene/Geometry3DTileContent.js +151 -185
  346. package/Source/Scene/Globe.js +110 -22
  347. package/Source/Scene/GlobeDepth.js +243 -6
  348. package/Source/Scene/GlobeSurfaceShaderSet.js +637 -540
  349. package/Source/Scene/GlobeSurfaceTile.js +575 -398
  350. package/Source/Scene/GlobeSurfaceTileProvider.js +2289 -1842
  351. package/Source/Scene/GltfBufferViewLoader.js +3 -3
  352. package/Source/Scene/GltfLoader.js +146 -3
  353. package/Source/Scene/GltfLoaderUtil.js +20 -4
  354. package/Source/Scene/GltfPipeline/forEachTextureInMaterial.js +10 -0
  355. package/Source/Scene/GltfPipeline/removeUnusedElements.js +21 -11
  356. package/Source/Scene/GltfSpzLoader.js +1 -1
  357. package/Source/Scene/GltfVertexBufferLoader.js +6 -3
  358. package/Source/Scene/GroundPolylinePrimitive.js +2 -1
  359. package/Source/Scene/I3SDataProvider.js +1 -1
  360. package/Source/Scene/I3SLayer.js +1 -1
  361. package/Source/Scene/I3SNode.js +2 -2
  362. package/Source/Scene/ImageryLayer.js +2 -2
  363. package/Source/Scene/ImageryLayerCollection.js +190 -6
  364. package/Source/Scene/Implicit3DTileContent.js +192 -216
  365. package/Source/Scene/ImplicitTileCoordinates.js +17 -0
  366. package/Source/Scene/IonImageryProvider.js +1 -5
  367. package/Source/Scene/Label.js +4 -4
  368. package/Source/Scene/LabelCollection.js +4 -1
  369. package/Source/Scene/MVTDataProvider.js +555 -0
  370. package/Source/Scene/Material.js +1 -0
  371. package/Source/Scene/Model/B3dmLoader.js +1 -2
  372. package/Source/Scene/Model/EdgeVisibilityPipelineStage.js +82 -312
  373. package/Source/Scene/Model/Extensions/Gpm/GltfGpmLoader.js +4 -0
  374. package/Source/Scene/Model/I3dmLoader.js +1 -1
  375. package/Source/Scene/Model/InstancingPipelineStage.js +4 -7
  376. package/Source/Scene/Model/MaterialPipelineStage.js +124 -1
  377. package/Source/Scene/Model/Model.js +45 -10
  378. package/Source/Scene/Model/Model3DTileContent.js +424 -458
  379. package/Source/Scene/Model/ModelClippingPlanesPipelineStage.js +28 -1
  380. package/Source/Scene/Model/ModelDrawCommand.js +180 -8
  381. package/Source/Scene/Model/ModelDrawCommands.js +4 -0
  382. package/Source/Scene/Model/ModelSceneGraph.js +21 -0
  383. package/Source/Scene/Model/ModelUtility.js +5 -0
  384. package/Source/Scene/Model/PickingPipelineStage.js +29 -0
  385. package/Source/Scene/Model/PrimitiveRenderResources.js +24 -0
  386. package/Source/Scene/Model/createVectorTileBuffersFromModelComponents.js +645 -153
  387. package/Source/Scene/ModelComponents.js +112 -0
  388. package/Source/Scene/Multiple3DTileContent.js +291 -334
  389. package/Source/Scene/MvtLabelCandidates.js +295 -0
  390. package/Source/Scene/MvtLabelManager.js +1069 -0
  391. package/Source/Scene/Picking.js +19 -3
  392. package/Source/Scene/PlanarFillIdFramebuffer.js +172 -0
  393. package/Source/Scene/PntsParser.js +1 -1
  394. package/Source/Scene/Polyline.js +32 -5
  395. package/Source/Scene/PolylineCollection.js +39 -0
  396. package/Source/Scene/PostProcessStage.js +4 -2
  397. package/Source/Scene/Primitive.js +12 -13
  398. package/Source/Scene/PrimitivePipeline.js +158 -28
  399. package/Source/Scene/QuadtreePrimitive.js +3 -2
  400. package/Source/Scene/ResourceCache.js +7 -4
  401. package/Source/Scene/ResourceCacheKey.js +21 -18
  402. package/Source/Scene/Scene.js +655 -6
  403. package/Source/Scene/SceneTransforms.js +18 -0
  404. package/Source/Scene/ScreenSpaceCameraController.js +12 -3
  405. package/Source/Scene/ShadowMap.js +9 -3
  406. package/Source/Scene/ShadowMapShader.js +50 -2
  407. package/Source/Scene/SnapFramebuffer.js +121 -0
  408. package/Source/Scene/Snapping.js +184 -0
  409. package/Source/Scene/TerrainFillMesh.js +3 -2
  410. package/Source/Scene/Tileset3DTileContent.js +113 -146
  411. package/Source/Scene/UrlTemplate3DTilesDataProvider.js +543 -0
  412. package/Source/Scene/Vector3DTileContent.js +207 -237
  413. package/Source/Scene/VectorGltf3DTileContent.js +185 -45
  414. package/Source/Scene/View.js +10 -8
  415. package/Source/Scene/VoxelPrimitive.js +159 -175
  416. package/Source/Scene/VoxelProvider.js +64 -91
  417. package/Source/Scene/VoxelTraversal.js +1 -1
  418. package/Source/Scene/buildVectorGltfFromMVT.js +1208 -0
  419. package/Source/Scene/buildVoxelCustomShader.js +199 -0
  420. package/Source/Scene/createElevationBandMaterial.js +1 -1
  421. package/Source/Scene/decodeMVT.js +877 -0
  422. package/Source/Scene/findMeshoptExtension.js +23 -0
  423. package/Source/Scene/renderBufferPointCollection.js +114 -64
  424. package/Source/Scene/renderBufferPolygonCollection.js +245 -53
  425. package/Source/Scene/renderBufferPolylineCollection.js +271 -145
  426. package/Source/Shaders/BillboardCollectionVS.glsl +23 -25
  427. package/Source/Shaders/BillboardCollectionVS.js +23 -25
  428. package/Source/Shaders/BufferPointMaterialFS.glsl +1 -0
  429. package/Source/Shaders/BufferPointMaterialFS.js +1 -0
  430. package/Source/Shaders/BufferPointMaterialVS.glsl +19 -9
  431. package/Source/Shaders/BufferPointMaterialVS.js +20 -10
  432. package/Source/Shaders/BufferPolygonMaterialFS.glsl +13 -0
  433. package/Source/Shaders/BufferPolygonMaterialFS.js +13 -0
  434. package/Source/Shaders/BufferPolygonMaterialVS.glsl +22 -4
  435. package/Source/Shaders/BufferPolygonMaterialVS.js +23 -5
  436. package/Source/Shaders/BufferPolylineMaterialVS.glsl +16 -2
  437. package/Source/Shaders/BufferPolylineMaterialVS.js +17 -3
  438. package/Source/Shaders/Builtin/Constants/passCesium3DTile.glsl +1 -1
  439. package/Source/Shaders/Builtin/Constants/passCesium3DTile.js +1 -1
  440. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.glsl +1 -1
  441. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassification.js +1 -1
  442. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.glsl +1 -1
  443. package/Source/Shaders/Builtin/Constants/passCesium3DTileClassificationIgnoreShow.js +1 -1
  444. package/Source/Shaders/Builtin/Constants/passCesium3DTileEdgesDirect.glsl +9 -0
  445. package/Source/Shaders/Builtin/Constants/passCesium3DTileEdgesDirect.js +11 -0
  446. package/Source/Shaders/Builtin/Constants/passCesium3DTilePlanarFillId.glsl +9 -0
  447. package/Source/Shaders/Builtin/Constants/passCesium3DTilePlanarFillId.js +11 -0
  448. package/Source/Shaders/Builtin/Constants/passClassification.glsl +1 -1
  449. package/Source/Shaders/Builtin/Constants/passClassification.js +1 -1
  450. package/Source/Shaders/Builtin/Constants/passGaussianSplats.glsl +1 -1
  451. package/Source/Shaders/Builtin/Constants/passGaussianSplats.js +1 -1
  452. package/Source/Shaders/Builtin/Constants/passOpaque.glsl +1 -1
  453. package/Source/Shaders/Builtin/Constants/passOpaque.js +1 -1
  454. package/Source/Shaders/Builtin/Constants/passOverlay.glsl +1 -1
  455. package/Source/Shaders/Builtin/Constants/passOverlay.js +1 -1
  456. package/Source/Shaders/Builtin/Constants/passTranslucent.glsl +1 -1
  457. package/Source/Shaders/Builtin/Constants/passTranslucent.js +1 -1
  458. package/Source/Shaders/Builtin/Constants/passVoxels.glsl +1 -1
  459. package/Source/Shaders/Builtin/Constants/passVoxels.js +1 -1
  460. package/Source/Shaders/Builtin/CzmBuiltins.js +4 -0
  461. package/Source/Shaders/GlobeFS.glsl +10 -6
  462. package/Source/Shaders/GlobeFS.js +10 -6
  463. package/Source/Shaders/Materials/PolylineGlowMaterial.glsl +1 -1
  464. package/Source/Shaders/Materials/PolylineGlowMaterial.js +1 -1
  465. package/Source/Shaders/Model/EdgeVisibilityStageVS.glsl +0 -1
  466. package/Source/Shaders/Model/EdgeVisibilityStageVS.js +0 -1
  467. package/Source/Shaders/Model/MaterialStageFS.glsl +8 -2
  468. package/Source/Shaders/Model/MaterialStageFS.js +8 -2
  469. package/Source/Shaders/Model/ModelFS.glsl +105 -0
  470. package/Source/Shaders/Model/ModelFS.js +105 -0
  471. package/Source/Shaders/PolylineShadowVolumeFS.glsl +14 -0
  472. package/Source/Shaders/PolylineShadowVolumeFS.js +14 -0
  473. package/Source/Shaders/RestoreDepth.glsl +8 -0
  474. package/Source/Shaders/RestoreDepth.js +10 -0
  475. package/Source/Shaders/VectorCommon.glsl +178 -0
  476. package/Source/Shaders/VectorCommon.js +180 -0
  477. package/Source/ThirdParty/zip-module.wasm +0 -0
  478. package/Source/Widget/CesiumWidget.js +30 -0
  479. package/Source/Workers/createMvtTile.js +39 -0
  480. package/Source/Workers/decodeGoogleEarthEnterprisePacket.js +2 -2
  481. package/Source/Workers/incrementallyBuildTerrainPicker.js +2 -0
  482. package/index.d.ts +535 -1393
  483. package/index.js +125 -93
  484. package/package.json +13 -13
@@ -45,6 +45,8 @@ import BrdfLutGenerator from "./BrdfLutGenerator.js";
45
45
  import Camera from "./Camera.js";
46
46
  import Cesium3DTilePass from "./Cesium3DTilePass.js";
47
47
  import Cesium3DTilePassState from "./Cesium3DTilePassState.js";
48
+ import ControllerHost from "./Controllers/ControllerHost.js";
49
+ import ColumbusWorlds from "./ColumbusWorlds.js";
48
50
  import CreditDisplay from "./CreditDisplay.js";
49
51
  import DebugCameraPrimitive from "./DebugCameraPrimitive.js";
50
52
  import DepthPlane from "./DepthPlane.js";
@@ -69,6 +71,7 @@ import SceneTransitioner from "./SceneTransitioner.js";
69
71
  import ScreenSpaceCameraController from "./ScreenSpaceCameraController.js";
70
72
  import ShadowMap from "./ShadowMap.js";
71
73
  import SharedContext from "../Renderer/SharedContext.js";
74
+ import Snapping from "./Snapping.js";
72
75
  import SpecularEnvironmentCubeMap from "./SpecularEnvironmentCubeMap.js";
73
76
  import StencilConstants from "./StencilConstants.js";
74
77
  import SunLight from "./SunLight.js";
@@ -108,6 +111,9 @@ const requestRenderAfterFrame = function (scene) {
108
111
  * @param {boolean} [options.scene3DOnly=false] If true, optimizes memory use and performance for 3D mode but disables the ability to use 2D or Columbus View.
109
112
  * @param {boolean} [options.shadows=false] Determines if shadows are cast by light sources.
110
113
  * @param {MapMode2D} [options.mapMode2D=MapMode2D.INFINITE_SCROLL] Determines if the 2D map is rotatable or can be scrolled infinitely in the horizontal direction.
114
+ * @param {boolean} [options.columbusRepeatWorlds=false] If true, the 2D or Columbus View map repeats horizontally:
115
+ * translated copies of the globe surface tiles are rendered beyond the ±180° meridian so the map, entity
116
+ * placement, and picking continue seamlessly across the antimeridian.
111
117
  * @param {boolean} [options.requestRenderMode=false] If true, rendering a frame will only occur when needed as determined by changes within the scene. Enabling improves performance of the application, but requires using {@link Scene#requestRender} to render a new frame explicitly in this mode. This will be necessary in many cases after making changes to the scene in other parts of the API. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
112
118
  * @param {number} [options.maximumRenderTimeChange=0.0] If requestRenderMode is true, this value defines the maximum change in simulation time allowed before a render is requested. See {@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|Improving Performance with Explicit Rendering}.
113
119
  * @param {number} [options.depthPlaneEllipsoidOffset=0.0] Adjust the DepthPlane to address rendering artefacts below ellipsoid zero elevation.
@@ -241,6 +247,8 @@ function Scene(options) {
241
247
  this._preRender = new Event();
242
248
  this._postRender = new Event();
243
249
 
250
+ this._controllerHost = new ControllerHost();
251
+
244
252
  this._minimumDisableDepthTestDistance = 0.0;
245
253
  this._debugInspector = new DebugInspector();
246
254
 
@@ -627,6 +635,7 @@ function Scene(options) {
627
635
  this._screenSpaceCameraController = new ScreenSpaceCameraController(this);
628
636
  this._cameraUnderground = false;
629
637
  this._mapMode2D = options.mapMode2D ?? MapMode2D.INFINITE_SCROLL;
638
+ this._columbusRepeatWorlds = options.columbusRepeatWorlds ?? false;
630
639
 
631
640
  // Keeps track of the state of a frame. FrameState is the state across
632
641
  // the primitives of the scene. This state is for internally keeping track
@@ -770,6 +779,15 @@ function Scene(options) {
770
779
  */
771
780
  this._enableEdgeVisibility = false;
772
781
 
782
+ /**
783
+ * Whether or not to enable the planar fill feature-ID pre-pass.
784
+ * Updated each frame from FrameState.planarFillRequested.
785
+ * @type {boolean}
786
+ * @default false
787
+ * @private
788
+ */
789
+ this._enablePlanarFillId = false;
790
+
773
791
  // Give frameState, camera, and screen space camera controller initial state before rendering
774
792
  updateFrameNumber(this, 0.0, JulianDate.now());
775
793
  this.updateFrameState();
@@ -1079,6 +1097,25 @@ Object.defineProperties(Scene.prototype, {
1079
1097
  },
1080
1098
  },
1081
1099
 
1100
+ /**
1101
+ * Collects an array of <code>Controller</code> objects that can be registered with the scene to handle input events, camera animations, and other interactions.
1102
+ * @see {@link Controller}
1103
+ * @type {ControllerHost}
1104
+ * @memberof Scene.prototype
1105
+ * @readonly
1106
+ * @example
1107
+ * scene.screenSpaceCameraController.enableInputs = false;
1108
+ * scene.screenSpaceCameraController.enableCollisionDetection = false;
1109
+ *
1110
+ * const tiltOrbitController = new Cesium.ScreenSpaceTiltOrbitCameraController();
1111
+ * scene.controllerHost.registerController(tiltOrbitController, scene.canvas.parentNode);
1112
+ */
1113
+ controllerHost: {
1114
+ get: function () {
1115
+ return this._controllerHost;
1116
+ },
1117
+ },
1118
+
1082
1119
  /**
1083
1120
  * Gets the controller for camera input handling.
1084
1121
  * @memberof Scene.prototype
@@ -1227,6 +1264,17 @@ Object.defineProperties(Scene.prototype, {
1227
1264
  },
1228
1265
  },
1229
1266
 
1267
+ /**
1268
+ * @memberof Scene.prototype
1269
+ * @type {VectorProvider}
1270
+ * @ignore
1271
+ */
1272
+ vectorProvider: {
1273
+ get: function () {
1274
+ return this.globe?.vectorProvider;
1275
+ },
1276
+ },
1277
+
1230
1278
  /**
1231
1279
  * Gets the event that will be raised before the scene is updated or rendered. Subscribers to the event
1232
1280
  * receive the Scene instance as the first parameter and the current time as the second parameter.
@@ -1524,6 +1572,27 @@ Object.defineProperties(Scene.prototype, {
1524
1572
  },
1525
1573
  },
1526
1574
 
1575
+ /**
1576
+ * Gets or sets whether the 2D or Columbus View map repeats horizontally. When
1577
+ * true, translated copies of the globe surface tiles are rendered beyond the
1578
+ * ±180° meridian, and entity placement/picking wrap to the copy nearest the
1579
+ * camera, so editing and animation work seamlessly across the antimeridian.
1580
+ * Only has an effect in {@link SceneMode.SCENE2D} and
1581
+ * {@link SceneMode.COLUMBUS_VIEW}.
1582
+ * @memberof Scene.prototype
1583
+ *
1584
+ * @type {boolean}
1585
+ * @default false
1586
+ */
1587
+ columbusRepeatWorlds: {
1588
+ get: function () {
1589
+ return this._columbusRepeatWorlds;
1590
+ },
1591
+ set: function (value) {
1592
+ this._columbusRepeatWorlds = value;
1593
+ },
1594
+ },
1595
+
1527
1596
  /**
1528
1597
  * Gets or sets the position of the splitter within the viewport. Valid values are between 0.0 and 1.0.
1529
1598
  * @memberof Scene.prototype
@@ -1770,6 +1839,16 @@ function updateDerivedCommands(scene, command, shadowsDirty) {
1770
1839
  derivedCommands.picking,
1771
1840
  );
1772
1841
  }
1842
+ // Snap derived commands are only created on demand, during a snapping pass,
1843
+ // so applications that never call Scene.snap pay no shader-derivation cost.
1844
+ if (defined(command.snapId) && frameState.passes.snap) {
1845
+ derivedCommands.snapping = DerivedCommand.createSnapDerivedCommand(
1846
+ scene,
1847
+ command,
1848
+ context,
1849
+ derivedCommands.snapping,
1850
+ );
1851
+ }
1773
1852
  if (frameState.pickingMetadata && command.pickMetadataAllowed) {
1774
1853
  command.pickedMetadataInfo = frameState.pickedMetadataInfo;
1775
1854
  if (defined(command.pickedMetadataInfo)) {
@@ -1867,12 +1946,17 @@ Scene.prototype.updateDerivedCommands = function (command) {
1867
1946
  const needsUpdateForMetadataPicking =
1868
1947
  frameState.pickingMetadata &&
1869
1948
  pickedMetadataInfoChanged(command, frameState);
1949
+ const needsUpdateForSnap =
1950
+ frameState.passes.snap &&
1951
+ defined(command.snapId) &&
1952
+ !defined(derivedCommands.snapping);
1870
1953
  command.dirty =
1871
1954
  command.dirty ||
1872
1955
  needsLogDepthDerivedCommands ||
1873
1956
  needsHdrCommands ||
1874
1957
  needsDerivedCommands ||
1875
- needsUpdateForMetadataPicking;
1958
+ needsUpdateForMetadataPicking ||
1959
+ needsUpdateForSnap;
1876
1960
 
1877
1961
  if (!command.dirty) {
1878
1962
  return;
@@ -1960,6 +2044,7 @@ Scene.prototype.clearPasses = function (passes) {
1960
2044
  passes.render = false;
1961
2045
  passes.pick = false;
1962
2046
  passes.pickVoxel = false;
2047
+ passes.snap = false;
1963
2048
  passes.depth = false;
1964
2049
  passes.postProcess = false;
1965
2050
  passes.offscreen = false;
@@ -1985,6 +2070,7 @@ Scene.prototype.updateFrameState = function () {
1985
2070
  frameState.mode = this._mode;
1986
2071
  frameState.morphTime = this.morphTime;
1987
2072
  frameState.mapProjection = this.mapProjection;
2073
+ frameState.columbusRepeatWorlds = this._columbusRepeatWorlds;
1988
2074
  frameState.camera = camera;
1989
2075
  frameState.cullingVolume = camera.frustum.computeCullingVolume(
1990
2076
  camera.positionWC,
@@ -2245,6 +2331,21 @@ function executeCommand(command, scene, passState, debugFramebuffer) {
2245
2331
 
2246
2332
  if (passes.pick || passes.depth) {
2247
2333
  if (passes.pick && !passes.depth) {
2334
+ if (frameState.passes.snap) {
2335
+ // Snapping pass: only commands with a snap variant write the float
2336
+ // snap payload. Commands without one (no snapId, e.g. globe/terrain)
2337
+ // execute depth-only so they still occlude snappable geometry behind
2338
+ // them without polluting the RGBA32F snap framebuffer with RGBA8
2339
+ // pick colors.
2340
+ if (defined(command.derivedCommands.snapping)) {
2341
+ command = command.derivedCommands.snapping.snapCommand;
2342
+ command.execute(context, passState);
2343
+ } else if (defined(command.derivedCommands.depth)) {
2344
+ command = command.derivedCommands.depth.depthOnlyCommand;
2345
+ command.execute(context, passState);
2346
+ }
2347
+ return;
2348
+ }
2248
2349
  if (
2249
2350
  frameState.pickingMetadata &&
2250
2351
  defined(command.derivedCommands.pickingMetadata)
@@ -2466,6 +2567,7 @@ function createWorkingFrustum(camera) {
2466
2567
  *
2467
2568
  * @param {Scene} scene The scene.
2468
2569
  * @returns {Function} A function to execute translucent commands.
2570
+ * @ignore
2469
2571
  */
2470
2572
  function obtainTranslucentCommandExecutionFunction(scene) {
2471
2573
  if (scene._environmentState.useOIT) {
@@ -2618,6 +2720,426 @@ function performCesium3DTileEdgesPass(scene, passState, frustumCommands) {
2618
2720
  passState.framebuffer = originalFramebuffer;
2619
2721
  }
2620
2722
 
2723
+ const COLUMBUS_MAX_COPY_WORLDS = 2;
2724
+ const columbusWorldIndicesScratch = [];
2725
+
2726
+ /**
2727
+ * Finds the primary pass' frustum whose depth range best matches a copy's
2728
+ * frustum. A copy's visible set is culled from the shifted camera, so its
2729
+ * frustum split can differ from the primary pass' (the globe emits translated
2730
+ * tile commands whose distances change under the shift). Pairing by index then
2731
+ * matches a copy's terrain commands with a primary frustum that holds no
2732
+ * terrain, and the classification shader samples that frustum's empty globe
2733
+ * depth copy, discarding every fragment. Pair by depth range instead: a frustum
2734
+ * whose midpoint falls inside a primary range maps to that range, and a frustum
2735
+ * outside every range maps to the closest one.
2736
+ *
2737
+ * @param {FrustumCommands[]} primaryFrustumCommandsList The primary pass' bins.
2738
+ * @param {FrustumCommands} frustumCommands The copy's bin.
2739
+ * @returns {number} The index of the matching primary frustum, or -1 when the primary visible set is empty.
2740
+ * @private
2741
+ */
2742
+ function matchPrimaryFrustumIndex(primaryFrustumCommandsList, frustumCommands) {
2743
+ const count = primaryFrustumCommandsList.length;
2744
+ if (count === 0) {
2745
+ return -1;
2746
+ }
2747
+
2748
+ const midpoint = (frustumCommands.near + frustumCommands.far) * 0.5;
2749
+ let bestIndex = count - 1;
2750
+ let bestDistance = Number.POSITIVE_INFINITY;
2751
+ for (let i = 0; i < count; ++i) {
2752
+ const primary = primaryFrustumCommandsList[i];
2753
+ let distance = 0.0;
2754
+ if (midpoint < primary.near) {
2755
+ distance = primary.near - midpoint;
2756
+ } else if (midpoint > primary.far) {
2757
+ distance = midpoint - primary.far;
2758
+ }
2759
+ if (distance < bestDistance) {
2760
+ bestDistance = distance;
2761
+ bestIndex = i;
2762
+ }
2763
+ }
2764
+ return bestIndex;
2765
+ }
2766
+
2767
+ const columbusCopyCullingVolume = new CullingVolume();
2768
+ const columbusSavedPositionWC = new Cartesian3();
2769
+ const columbusSavedViewMatrix = new Matrix4();
2770
+ const columbusSavedInvViewMatrix = new Matrix4();
2771
+
2772
+ /**
2773
+ * Renders the data passes again for each visible world copy when Columbus
2774
+ * repeat worlds is enabled, so primitives authored in the primary world also
2775
+ * appear on the copies around the camera. Each copy is the primary-world
2776
+ * command list viewed by a camera shifted a whole world along map-u, which
2777
+ * replicates every draw command type (and its pick derived command) without
2778
+ * duplicating geometry, memory or per-element placement logic.
2779
+ *
2780
+ * Globe tiles are deliberately excluded: {@link GlobeSurfaceTileProvider}
2781
+ * already emits its own translated tile commands, which the regular GLOBE
2782
+ * pass renders once.
2783
+ *
2784
+ * @param {Scene} scene The scene.
2785
+ * @param {PassState} passState The render pass state.
2786
+ * @param {Frustum} frustum The working frustum used by executeCommands.
2787
+ * @param {Function} performPass Executes a pass for a frustum's command bin.
2788
+ * @param {boolean} classifyInline Whether the copies' ground classification was already executed by executeCommands.
2789
+ * @private
2790
+ */
2791
+ function executeColumbusWorldCopyCommands(
2792
+ scene,
2793
+ passState,
2794
+ frustum,
2795
+ performPass,
2796
+ classifyInline,
2797
+ ) {
2798
+ const { camera, context, frameState } = scene;
2799
+ const { uniformState } = context;
2800
+
2801
+ const worldWidth = ColumbusWorlds.getWorldWidth(frameState.mapProjection);
2802
+ const worldIndices = ColumbusWorlds.getVisibleWorldIndices(
2803
+ camera._positionWC.y,
2804
+ worldWidth,
2805
+ frameState.cullingVolume,
2806
+ COLUMBUS_MAX_COPY_WORLDS,
2807
+ columbusWorldIndicesScratch,
2808
+ );
2809
+ if (worldIndices.length === 0) {
2810
+ return;
2811
+ }
2812
+
2813
+ const view = scene._view;
2814
+
2815
+ // The globe depth texture is produced inside the primary pass' frustum loop.
2816
+ // That loop is skipped when no command is visible from the camera's own copy
2817
+ // (the camera can sit on a non-primary copy, with all data a world away), so
2818
+ // billboards, labels and other shaders sampling czm_globeDepthTexture would
2819
+ // get an undefined uniform while the copies draw. Produce the (cleared) globe
2820
+ // depth once here - the copies share the primary pass' screen space, so the
2821
+ // texture is as valid for them as it would be for a regular frame.
2822
+ if (!defined(uniformState.globeDepthTexture) && defined(view.globeDepth)) {
2823
+ view.globeDepth.executeCopyDepth(context, passState);
2824
+ }
2825
+
2826
+ const baseFrustumCommandsList = view.frustumCommandsList;
2827
+ let copyFrustumCommandsList = scene._columbusFrustumCommands;
2828
+ if (!defined(copyFrustumCommandsList)) {
2829
+ copyFrustumCommandsList = scene._columbusFrustumCommands = [];
2830
+ }
2831
+
2832
+ const cullingVolume = frameState.cullingVolume;
2833
+ const positionWC = Cartesian3.clone(
2834
+ camera._positionWC,
2835
+ columbusSavedPositionWC,
2836
+ );
2837
+ const viewMatrix = Matrix4.clone(camera._viewMatrix, columbusSavedViewMatrix);
2838
+ const invViewMatrix = Matrix4.clone(
2839
+ camera._invViewMatrix,
2840
+ columbusSavedInvViewMatrix,
2841
+ );
2842
+
2843
+ for (let c = 0; c < worldIndices.length; ++c) {
2844
+ const worldOffset = worldIndices[c] * worldWidth;
2845
+
2846
+ // Shift the camera to the copy and cull the data against its frustum,
2847
+ // building the bins in a list private to the copies so the primary
2848
+ // world's bins (used by pickPosition) stay intact.
2849
+ ColumbusWorlds.applyCameraWorldOffset(camera, worldOffset);
2850
+ frameState.cullingVolume = ColumbusWorlds.translateCullingVolume(
2851
+ cullingVolume,
2852
+ worldOffset,
2853
+ columbusCopyCullingVolume,
2854
+ );
2855
+
2856
+ view.frustumCommandsList = copyFrustumCommandsList;
2857
+ view.createPotentiallyVisibleSet(scene);
2858
+ view.frustumCommandsList = baseFrustumCommandsList;
2859
+
2860
+ uniformState.update(frameState);
2861
+
2862
+ const numFrustums = copyFrustumCommandsList.length;
2863
+ for (let i = 0; i < numFrustums; ++i) {
2864
+ const index = numFrustums - i - 1;
2865
+ const frustumCommands = copyFrustumCommandsList[index];
2866
+
2867
+ // Draw with the primary pass' frustum ranges. Shifting the camera does
2868
+ // not change any distance, so a copy's commands must be depth-encoded
2869
+ // exactly like the primary pass - the depth buffer was written with
2870
+ // these ranges, and log depth (or any frustum-dependent depth math) only
2871
+ // decodes correctly against them. The copy's bins are not guaranteed to
2872
+ // split at the same distances as the primary's, so match by range rather
2873
+ // than by position in the list.
2874
+ //
2875
+ // The primary visible set is empty when nothing of the camera's own world
2876
+ // is on screen (the camera can sit on a world copy with all data a world
2877
+ // away). There is then no primary depth to match, so the copy falls back
2878
+ // to its own ranges instead of indexing past the empty list.
2879
+ const primaryIndex = matchPrimaryFrustumIndex(
2880
+ baseFrustumCommandsList,
2881
+ frustumCommands,
2882
+ );
2883
+ const primaryFrustum =
2884
+ primaryIndex >= 0
2885
+ ? baseFrustumCommandsList[primaryIndex]
2886
+ : frustumCommands;
2887
+ frustum.near =
2888
+ primaryIndex !== 0
2889
+ ? primaryFrustum.near * scene.opaqueFrustumNearOffset
2890
+ : primaryFrustum.near;
2891
+ frustum.far = primaryFrustum.far;
2892
+ uniformState.updateFrustum(frustum);
2893
+
2894
+ if (context.stencilBuffer) {
2895
+ scene._stencilClearCommand.execute(context, passState);
2896
+ }
2897
+
2898
+ // Classic ground classification samples czm_globeDepthTexture. Bind the
2899
+ // copy that the primary pass produced for the matching frustum: each copy
2900
+ // is packed against its own frustum's near/far, so sampling another
2901
+ // frustum's copy decodes garbage - the near frustum contains no terrain
2902
+ // and packs to zero, which the ground polyline shader treats as sky, so
2903
+ // every clamped line in the copy would be discarded.
2904
+ const globeDepth = view.globeDepth;
2905
+ const copyFrustumIndex = primaryIndex >= 0 ? primaryIndex : index;
2906
+
2907
+ // This bin's classification was already executed by the primary loop
2908
+ // (executeColumbusWorldCopyClassification) against the live terrain
2909
+ // depth. Replaying it here would only re-do the stencil work against a
2910
+ // restored copy of that depth, so it is skipped - except when the primary
2911
+ // loop could not cover it: pick passes, or a bin matching no primary
2912
+ // frustum (the primary visible set can be empty).
2913
+ const classifiedInline = classifyInline && primaryIndex >= 0;
2914
+
2915
+ let restoredDepth = false;
2916
+ if (defined(globeDepth)) {
2917
+ globeDepth.useCopyDepth(context, copyFrustumIndex);
2918
+
2919
+ // Ground classification is resolved against the terrain depth in the
2920
+ // depth buffer (its stencil pass depth tests the shadow volume against
2921
+ // it), not against czm_globeDepthTexture. The primary loop clears the
2922
+ // globe depth right after its classification pass when the globe does
2923
+ // not depth test against terrain - the default. Put the matching
2924
+ // frustum's globe depth back before re-running the classification
2925
+ // commands, otherwise every copy's ground element is classified
2926
+ // against an empty buffer and silently dropped.
2927
+ restoredDepth =
2928
+ !classifiedInline &&
2929
+ frameState.passes.render &&
2930
+ scene._environmentState.clearGlobeDepth &&
2931
+ frustumCommands.indices[Pass.TERRAIN_CLASSIFICATION] > 0;
2932
+ if (restoredDepth) {
2933
+ globeDepth.executeRestoreDepth(context, passState, copyFrustumIndex);
2934
+ }
2935
+ }
2936
+
2937
+ if (!classifiedInline) {
2938
+ performPass(frustumCommands, Pass.TERRAIN_CLASSIFICATION);
2939
+ }
2940
+
2941
+ // Mirror the primary pass, which clears the globe depth before its opaque
2942
+ // commands so primitives drawn on the ground are not occluded by the
2943
+ // terrain. The restore above is only for the classification.
2944
+ if (restoredDepth) {
2945
+ scene._depthClearCommand.execute(context, passState);
2946
+ }
2947
+
2948
+ performPass(frustumCommands, Pass.OPAQUE);
2949
+ performTranslucentPass(scene, passState, frustumCommands);
2950
+ }
2951
+
2952
+ Cartesian3.clone(positionWC, camera._positionWC);
2953
+ Matrix4.clone(viewMatrix, camera._viewMatrix);
2954
+ Matrix4.clone(invViewMatrix, camera._invViewMatrix);
2955
+ }
2956
+
2957
+ frameState.cullingVolume = cullingVolume;
2958
+ uniformState.update(frameState);
2959
+ }
2960
+
2961
+ /**
2962
+ * Executes the world copies' terrain classification while the primary pass'
2963
+ * terrain depth is still in the depth buffer.
2964
+ *
2965
+ * Ground classification is resolved by depth testing the shadow volume against
2966
+ * the terrain depth (z-fail stencil counting), so it needs the live buffer.
2967
+ * Replaying those commands later - after `clearGlobeDepth` wiped the buffer -
2968
+ * only works off a restored copy of the globe depth, and a restored copy is not
2969
+ * equivalent to the live buffer: it is a resolved, packed copy of it, so
2970
+ * coplanar ground surfaces miss the comparison and drop out once the view is
2971
+ * oblique (partial or speckled fills). Running the copies here, right after the
2972
+ * primary classification and before the depth clear, hands them exactly the
2973
+ * depth buffer the primary classification used.
2974
+ *
2975
+ * @param {Scene} scene The scene.
2976
+ * @param {PassState} passState The render pass state.
2977
+ * @param {Frustum} frustum The working frustum, already set to the primary frustum's depth ranges.
2978
+ * @param {number} frustumIndex The primary frustum index currently being drawn.
2979
+ * @param {Function} performPass Executes a pass for a frustum's command bin.
2980
+ * @private
2981
+ */
2982
+ function executeColumbusWorldCopyClassification(
2983
+ scene,
2984
+ passState,
2985
+ frustum,
2986
+ frustumIndex,
2987
+ performPass,
2988
+ ) {
2989
+ const { camera, frameState } = scene;
2990
+ const { uniformState } = scene.context;
2991
+
2992
+ const worldWidth = ColumbusWorlds.getWorldWidth(frameState.mapProjection);
2993
+ const worldIndices = ColumbusWorlds.getVisibleWorldIndices(
2994
+ camera._positionWC.y,
2995
+ worldWidth,
2996
+ frameState.cullingVolume,
2997
+ COLUMBUS_MAX_COPY_WORLDS,
2998
+ columbusWorldIndicesScratch,
2999
+ );
3000
+ if (worldIndices.length === 0) {
3001
+ return;
3002
+ }
3003
+
3004
+ const view = scene._view;
3005
+ const baseFrustumCommandsList = view.frustumCommandsList;
3006
+ let copyFrustumCommandsList = scene._columbusFrustumCommands;
3007
+ if (!defined(copyFrustumCommandsList)) {
3008
+ copyFrustumCommandsList = scene._columbusFrustumCommands = [];
3009
+ }
3010
+
3011
+ const cullingVolume = frameState.cullingVolume;
3012
+ const positionWC = Cartesian3.clone(
3013
+ camera._positionWC,
3014
+ columbusSavedPositionWC,
3015
+ );
3016
+ const viewMatrix = Matrix4.clone(camera._viewMatrix, columbusSavedViewMatrix);
3017
+ const invViewMatrix = Matrix4.clone(
3018
+ camera._invViewMatrix,
3019
+ columbusSavedInvViewMatrix,
3020
+ );
3021
+
3022
+ for (let c = 0; c < worldIndices.length; ++c) {
3023
+ const worldOffset = worldIndices[c] * worldWidth;
3024
+
3025
+ ColumbusWorlds.applyCameraWorldOffset(camera, worldOffset);
3026
+ frameState.cullingVolume = ColumbusWorlds.translateCullingVolume(
3027
+ cullingVolume,
3028
+ worldOffset,
3029
+ columbusCopyCullingVolume,
3030
+ );
3031
+
3032
+ view.frustumCommandsList = copyFrustumCommandsList;
3033
+ view.createPotentiallyVisibleSet(scene);
3034
+ view.frustumCommandsList = baseFrustumCommandsList;
3035
+
3036
+ // Draw with the primary frustum's ranges: the depth buffer was written
3037
+ // with them, and the copies are only translations of the same distances.
3038
+ uniformState.update(frameState);
3039
+ uniformState.updateFrustum(frustum);
3040
+
3041
+ const numFrustums = copyFrustumCommandsList.length;
3042
+ for (let i = 0; i < numFrustums; ++i) {
3043
+ const copyFrustumCommands = copyFrustumCommandsList[numFrustums - i - 1];
3044
+ // Every copy bin belongs to exactly one primary frustum, so it is
3045
+ // classified once while that frustum is drawn.
3046
+ if (
3047
+ matchPrimaryFrustumIndex(
3048
+ baseFrustumCommandsList,
3049
+ copyFrustumCommands,
3050
+ ) !== frustumIndex
3051
+ ) {
3052
+ continue;
3053
+ }
3054
+
3055
+ if (scene.context.stencilBuffer) {
3056
+ scene._stencilClearCommand.execute(scene.context, passState);
3057
+ }
3058
+
3059
+ performPass(copyFrustumCommands, Pass.TERRAIN_CLASSIFICATION);
3060
+ }
3061
+
3062
+ Cartesian3.clone(positionWC, camera._positionWC);
3063
+ Matrix4.clone(viewMatrix, camera._viewMatrix);
3064
+ Matrix4.clone(invViewMatrix, camera._invViewMatrix);
3065
+ }
3066
+
3067
+ frameState.cullingVolume = cullingVolume;
3068
+ uniformState.update(frameState);
3069
+ uniformState.updateFrustum(frustum);
3070
+ }
3071
+
3072
+ /**
3073
+ * Execute the planar fill feature-ID pre-pass.
3074
+ *
3075
+ * Non-behind planar fill geometry writes its per-fragment feature ID into the
3076
+ * planar fill ID framebuffer. This allows behind fills in the main 3D tile
3077
+ * pass to check whether the existing pixel belongs to the same logical object.
3078
+ *
3079
+ * @param {Scene} scene
3080
+ * @param {PassState} passState
3081
+ * @param {FrustumCommands} frustumCommands
3082
+ * @private
3083
+ */
3084
+ function performPlanarFillIdPass(scene, passState, frustumCommands) {
3085
+ const { context } = scene;
3086
+ const { uniformState } = context;
3087
+
3088
+ uniformState.updatePass(Pass.CESIUM_3D_TILE_PLANAR_FILL_ID);
3089
+
3090
+ // Default to a blank texture so shaders always have something to sample.
3091
+ uniformState.planarFillIdTexture = context.defaultTexture;
3092
+
3093
+ const view = scene._view;
3094
+ const fb = view && view.planarFillIdFramebuffer;
3095
+
3096
+ const commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_PLANAR_FILL_ID];
3097
+ const commandCount =
3098
+ frustumCommands.indices[Pass.CESIUM_3D_TILE_PLANAR_FILL_ID];
3099
+
3100
+ if (commandCount === 0) {
3101
+ return;
3102
+ }
3103
+
3104
+ if (scene._enablePlanarFillId && defined(fb) && defined(fb.framebuffer)) {
3105
+ const originalFramebuffer = passState.framebuffer;
3106
+ passState.framebuffer = fb.framebuffer;
3107
+
3108
+ // Clear to (0,0,0,0) — feature ID 0 means "no planar fill here".
3109
+ const clearCommand = fb.getClearCommand(new Color(0.0, 0.0, 0.0, 0.0));
3110
+ clearCommand.execute(context, passState);
3111
+
3112
+ for (let j = 0; j < commandCount; ++j) {
3113
+ executeCommand(commands[j], scene, passState);
3114
+ }
3115
+
3116
+ passState.framebuffer = originalFramebuffer;
3117
+ }
3118
+ }
3119
+
3120
+ /**
3121
+ * Execute edge commands that should render directly to the main framebuffer
3122
+ * (EDGES_ONLY mode). These edges bypass the MRT edge framebuffer and render
3123
+ * on top of surface geometry.
3124
+ *
3125
+ * @param {Scene} scene
3126
+ * @param {PassState} passState
3127
+ * @param {FrustumCommands} frustumCommands
3128
+ *
3129
+ * @private
3130
+ */
3131
+ function performCesium3DTileEdgesDirectPass(scene, passState, frustumCommands) {
3132
+ scene.context.uniformState.updatePass(Pass.CESIUM_3D_TILE_EDGES_DIRECT);
3133
+
3134
+ const commands = frustumCommands.commands[Pass.CESIUM_3D_TILE_EDGES_DIRECT];
3135
+ const commandCount =
3136
+ frustumCommands.indices[Pass.CESIUM_3D_TILE_EDGES_DIRECT];
3137
+
3138
+ for (let j = 0; j < commandCount; ++j) {
3139
+ executeCommand(commands[j], scene, passState);
3140
+ }
3141
+ }
3142
+
2621
3143
  /**
2622
3144
  * Execute the draw commands for all the render passes.
2623
3145
  *
@@ -2632,6 +3154,10 @@ function executeCommands(scene, passState) {
2632
3154
 
2633
3155
  uniformState.updateCamera(camera);
2634
3156
 
3157
+ // Ensure planar fill ID texture is always available (even during edge pass)
3158
+ // so that shaders referencing czm_planarFillIdTexture never see undefined.
3159
+ uniformState.planarFillIdTexture = context.defaultTexture;
3160
+
2635
3161
  const frustum = createWorkingFrustum(camera);
2636
3162
  frustum.near = camera.frustum.near;
2637
3163
  frustum.far = camera.frustum.far;
@@ -2655,6 +3181,20 @@ function executeCommands(scene, passState) {
2655
3181
  usePostProcessSelected,
2656
3182
  } = scene._environmentState;
2657
3183
 
3184
+ // World copies classify per frustum, inside the loop below, so they see the
3185
+ // live terrain depth of the frustum they belong to - for color and for pick
3186
+ // passes alike, since the primary loop classifies in both. Requires the globe
3187
+ // depth framebuffer: that is what the primary loop packs for the frustum and
3188
+ // what ground classification shaders sample. Everything else (no globe depth,
3189
+ // translucent depth pick) keeps classifying in the copy pass further down.
3190
+ const classifyCopyInline =
3191
+ !renderTranslucentDepthForPick &&
3192
+ useGlobeDepthFramebuffer &&
3193
+ frameState.columbusRepeatWorlds === true &&
3194
+ (scene.mode === SceneMode.SCENE2D ||
3195
+ scene.mode === SceneMode.COLUMBUS_VIEW) &&
3196
+ (passes.render || passes.pick || passes.pickVoxel);
3197
+
2658
3198
  const {
2659
3199
  globeDepth,
2660
3200
  globeTranslucencyFramebuffer,
@@ -2733,7 +3273,16 @@ function executeCommands(scene, passState) {
2733
3273
  }
2734
3274
 
2735
3275
  if (useGlobeDepthFramebuffer) {
2736
- globeDepth.executeCopyDepth(context, passState);
3276
+ // Keep one globe depth copy per frustum when the Columbus world copies
3277
+ // are drawn: they re-execute a primary frustum's classification, which
3278
+ // decodes depth against that frustum's near/far, so they need the copy
3279
+ // packed with those same ranges. Without the copies a single shared
3280
+ // texture is enough (and avoids allocating a texture per frustum).
3281
+ globeDepth.executeCopyDepth(
3282
+ context,
3283
+ passState,
3284
+ frameState.columbusRepeatWorlds === true ? index : 0,
3285
+ );
2737
3286
  }
2738
3287
 
2739
3288
  // Draw terrain classification
@@ -2752,6 +3301,19 @@ function executeCommands(scene, passState) {
2752
3301
  }
2753
3302
  }
2754
3303
 
3304
+ // The world copies classify while this frustum's terrain depth is still
3305
+ // live - the depth clear below destroys it, and a restored copy of it is
3306
+ // not good enough for an oblique view.
3307
+ if (classifyCopyInline) {
3308
+ executeColumbusWorldCopyClassification(
3309
+ scene,
3310
+ passState,
3311
+ frustum,
3312
+ index,
3313
+ performPass,
3314
+ );
3315
+ }
3316
+
2755
3317
  if (clearGlobeDepth) {
2756
3318
  clearDepth.execute(context, passState);
2757
3319
  if (useDepthPlane) {
@@ -2802,6 +3364,23 @@ function executeCommands(scene, passState) {
2802
3364
  scene.context.defaultTexture;
2803
3365
  }
2804
3366
 
3367
+ // Planar fill feature-ID pre-pass: write feature IDs from non-behind
3368
+ // planar fill geometry so that behind fills can test same-object.
3369
+ performPlanarFillIdPass(scene, passState, frustumCommands);
3370
+
3371
+ if (
3372
+ scene._enablePlanarFillId &&
3373
+ defined(scene._view) &&
3374
+ defined(scene._view.planarFillIdFramebuffer)
3375
+ ) {
3376
+ const pfIdTexture = scene._view.planarFillIdFramebuffer.idTexture;
3377
+ uniformState.planarFillIdTexture = defined(pfIdTexture)
3378
+ ? pfIdTexture
3379
+ : context.defaultTexture;
3380
+ } else {
3381
+ uniformState.planarFillIdTexture = context.defaultTexture;
3382
+ }
3383
+
2805
3384
  if (!useInvertClassification || picking || renderTranslucentDepthForPick) {
2806
3385
  // Common/fastest path. Draw 3D Tiles and classification normally.
2807
3386
 
@@ -2865,7 +3444,7 @@ function executeCommands(scene, passState) {
2865
3444
  passState.framebuffer = scene._invertClassification._fbo.framebuffer;
2866
3445
 
2867
3446
  // Draw normally
2868
- commandCount = performPass(frustumCommands, Pass.CESIUM_3D_TILE);
3447
+ performPass(frustumCommands, Pass.CESIUM_3D_TILE);
2869
3448
 
2870
3449
  if (useGlobeDepthFramebuffer) {
2871
3450
  scene._invertClassification.prepareTextures(context);
@@ -2911,6 +3490,9 @@ function executeCommands(scene, passState) {
2911
3490
 
2912
3491
  performPass(frustumCommands, Pass.OPAQUE);
2913
3492
 
3493
+ // Draw direct edges (EDGES_ONLY mode) after opaque surfaces
3494
+ performCesium3DTileEdgesDirectPass(scene, passState, frustumCommands);
3495
+
2914
3496
  performGaussianSplatPass(scene, passState, frustumCommands);
2915
3497
 
2916
3498
  if (index !== 0 && scene.mode !== SceneMode.SCENE2D) {
@@ -2978,6 +3560,21 @@ function executeCommands(scene, passState) {
2978
3560
 
2979
3561
  passState.framebuffer = originalFramebuffer;
2980
3562
  }
3563
+
3564
+ if (
3565
+ frameState.columbusRepeatWorlds === true &&
3566
+ (frameState.mode === SceneMode.SCENE2D ||
3567
+ frameState.mode === SceneMode.COLUMBUS_VIEW) &&
3568
+ (passes.render || passes.pick || passes.pickVoxel)
3569
+ ) {
3570
+ executeColumbusWorldCopyCommands(
3571
+ scene,
3572
+ passState,
3573
+ frustum,
3574
+ performPass,
3575
+ classifyCopyInline,
3576
+ );
3577
+ }
2981
3578
  }
2982
3579
 
2983
3580
  /**
@@ -3609,10 +4206,9 @@ Scene.prototype.updateEnvironment = function () {
3609
4206
  );
3610
4207
 
3611
4208
  const envMaps = this.specularEnvironmentMaps;
3612
- let specularEnvironmentCubeMap = this._specularEnvironmentCubeMap;
4209
+ const specularEnvironmentCubeMap = this._specularEnvironmentCubeMap;
3613
4210
  if (defined(envMaps) && specularEnvironmentCubeMap?.url !== envMaps) {
3614
- specularEnvironmentCubeMap =
3615
- specularEnvironmentCubeMap && specularEnvironmentCubeMap.destroy();
4211
+ specularEnvironmentCubeMap?.destroy();
3616
4212
  this._specularEnvironmentCubeMap = new SpecularEnvironmentCubeMap(envMaps);
3617
4213
  } else if (!defined(envMaps) && defined(specularEnvironmentCubeMap)) {
3618
4214
  specularEnvironmentCubeMap.destroy();
@@ -3702,6 +4298,7 @@ function updateAndRenderPrimitives(scene) {
3702
4298
 
3703
4299
  // Reset per-frame edge visibility request flag before primitives update
3704
4300
  frameState.edgeVisibilityRequested = false;
4301
+ frameState.planarFillRequested = false;
3705
4302
 
3706
4303
  scene._groundPrimitives.update(frameState);
3707
4304
  scene._primitives.update(frameState);
@@ -3714,6 +4311,10 @@ function updateAndRenderPrimitives(scene) {
3714
4311
  scene._enableEdgeVisibility = true;
3715
4312
  }
3716
4313
 
4314
+ // True only while at least one planar fill primitive is rendering;
4315
+ // the request flag is renewed each frame by ModelSceneGraph.
4316
+ scene._enablePlanarFillId = frameState.planarFillRequested;
4317
+
3717
4318
  updateDebugFrustumPlanes(scene);
3718
4319
  updateShadowMaps(scene);
3719
4320
 
@@ -3732,6 +4333,7 @@ function updateAndClearFramebuffers(scene, passState, clearColor) {
3732
4333
  const picking = passes.pick || passes.pickVoxel;
3733
4334
  if (defined(view.globeDepth)) {
3734
4335
  view.globeDepth.picking = picking;
4336
+ view.globeDepth.snapping = passes.snap;
3735
4337
  }
3736
4338
  const useWebVR = environmentState.useWebVR;
3737
4339
 
@@ -3837,6 +4439,15 @@ function updateAndClearFramebuffers(scene, passState, clearColor) {
3837
4439
  view.edgeFramebuffer.update(context, view.viewport, scene._hdr);
3838
4440
  }
3839
4441
 
4442
+ // Update planar fill ID framebuffer
4443
+ const usePlanarFillIdFramebuffer = !picking && scene._enablePlanarFillId;
4444
+ if (usePlanarFillIdFramebuffer) {
4445
+ view.planarFillIdFramebuffer.update(context, view.viewport, scene._hdr);
4446
+ } else if (!picking) {
4447
+ // Release GPU resources while unused; recreated on demand by update().
4448
+ view.planarFillIdFramebuffer.releaseResources();
4449
+ }
4450
+
3840
4451
  if (useInvertClassification) {
3841
4452
  let depthFramebuffer;
3842
4453
  if (frameState.invertClassificationColor.alpha === 1.0) {
@@ -4393,6 +5004,8 @@ Scene.prototype.render = function (time) {
4393
5004
  time = JulianDate.now();
4394
5005
  }
4395
5006
 
5007
+ this._controllerHost.update(this, time);
5008
+
4396
5009
  const cameraChanged = this._view.checkForCameraUpdates(this);
4397
5010
  if (cameraChanged) {
4398
5011
  this._globeHeightDirty = true;
@@ -4530,6 +5143,42 @@ Scene.prototype.pick = function (windowPosition, width, height) {
4530
5143
  return this._picking.pick(this, windowPosition, width, height, 1)[0];
4531
5144
  };
4532
5145
 
5146
+ /**
5147
+ * The result of a snap operation. See {@link Scene#snap}.
5148
+ *
5149
+ * @typedef {object} SceneSnapResult
5150
+ * @property {object} object The snapped primitive or feature.
5151
+ * @property {Cartesian3} position The world-space position of the snap point, un-projected from the snap framebuffer's eye-space depth.
5152
+ * @property {Cartesian2} screenPosition The window coordinates of the snap point.
5153
+ * @property {boolean} isEdge <code>true</code> if the snap point lies on an edge; <code>false</code> if it lies on a surface.
5154
+ *
5155
+ * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
5156
+ */
5157
+
5158
+ /**
5159
+ * Returns the best snap target in a screen-space region around <code>windowPosition</code>.
5160
+ * Edges are preferred over surfaces; among hits of the same kind the one
5161
+ * nearest the cursor wins. Returns <code>undefined</code> if the region contains
5162
+ * no snappable geometry.
5163
+ * <p>
5164
+ * Only primitives rendered through the Model pipeline (e.g. 3D Tiles and glTF
5165
+ * models) are snappable. Snapping requires float color attachments
5166
+ * (WebGL2 with <code>EXT_color_buffer_float</code>); if unsupported, this
5167
+ * function returns <code>undefined</code>.
5168
+ * </p>
5169
+ *
5170
+ * @param {Cartesian2} windowPosition Window coordinates at the center of the search region.
5171
+ * @param {object} [options] Object with the following properties:
5172
+ * @param {number} [options.width=25] Width of the search region in pixels.
5173
+ * @param {number} [options.height=options.width] Height of the search region in pixels.
5174
+ * @returns {SceneSnapResult | undefined} The best snap target in the region, or <code>undefined</code> if there is none.
5175
+ *
5176
+ * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
5177
+ */
5178
+ Scene.prototype.snap = function (windowPosition, options) {
5179
+ return Snapping.snap(this, windowPosition, options);
5180
+ };
5181
+
4533
5182
  /**
4534
5183
  * Performs the same operation as Scene.pick but asynchonosly without blocking the main render thread.
4535
5184
  * Requires WebGL2 else using fallback.