@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
@@ -38,6 +38,7 @@ import VertexArray from "../Renderer/VertexArray.js";
38
38
  import BlendingState from "./BlendingState.js";
39
39
  import ClippingPlaneCollection from "./ClippingPlaneCollection.js";
40
40
  import ClippingPolygonCollection from "./ClippingPolygonCollection.js";
41
+ import ColumbusWorlds from "./ColumbusWorlds.js";
41
42
  import DepthFunction from "./DepthFunction.js";
42
43
  import GlobeSurfaceTile from "./GlobeSurfaceTile.js";
43
44
  import ImageryLayer from "./ImageryLayer.js";
@@ -52,1021 +53,1438 @@ import TerrainState from "./TerrainState.js";
52
53
  import TileBoundingRegion from "./TileBoundingRegion.js";
53
54
  import TileSelectionResult from "./TileSelectionResult.js";
54
55
 
56
+ /** @import Context from "../Renderer/Context.js"; */
57
+ /** @import EllipsoidalOccluder from "../Core/EllipsoidalOccluder.js"; */
58
+ /** @import FrameState from "./FrameState.js"; */
59
+ /** @import GlobeSurfaceShaderSet from "./GlobeSurfaceShaderSet.js"; */
60
+ /** @import ImageryLayerCollection from "./ImageryLayerCollection.js"; */
61
+ /** @import QuadtreeOccluders from "./QuadtreeOccluders.js"; */
62
+ /** @import QuadtreePrimitive from "./QuadtreePrimitive.js"; */
63
+ /** @import QuadtreeTile from "./QuadtreeTile.js"; */
64
+ /** @import TerrainMesh from "../Core/TerrainMesh.js"; */
65
+ /** @import TerrainProvider from "../Core/TerrainProvider.js"; */
66
+ /** @import TilingScheme from "../Core/TilingScheme.js"; */
67
+ /** @import VectorProvider, { VectorTileData } from "../Core/VectorProvider.js"; */
68
+ /** @import { GlobeSurfaceShaderSetOptions } from "./GlobeSurfaceShaderSet.js"; */
69
+
55
70
  /**
56
71
  * Provides quadtree tiles representing the surface of the globe. This type is intended to be used
57
72
  * with {@link QuadtreePrimitive}.
58
73
  *
59
- * @alias GlobeSurfaceTileProvider
60
- * @constructor
61
- *
62
- * @param {TerrainProvider} options.terrainProvider The terrain provider that describes the surface geometry.
63
- * @param {ImageryLayerCollection} option.imageryLayers The collection of imagery layers describing the shading of the surface.
64
- * @param {GlobeSurfaceShaderSet} options.surfaceShaderSet The set of shaders used to render the surface.
65
- *
66
74
  * @private
67
75
  */
68
- function GlobeSurfaceTileProvider(options) {
69
- //>>includeStart('debug', pragmas.debug);
70
- if (!defined(options)) {
71
- throw new DeveloperError("options is required.");
72
- }
73
- if (!defined(options.terrainProvider)) {
74
- throw new DeveloperError("options.terrainProvider is required.");
75
- } else if (!defined(options.imageryLayers)) {
76
- throw new DeveloperError("options.imageryLayers is required.");
77
- } else if (!defined(options.surfaceShaderSet)) {
78
- throw new DeveloperError("options.surfaceShaderSet is required.");
79
- }
80
- //>>includeEnd('debug');
81
-
82
- this.lightingFadeOutDistance = 6500000.0;
83
- this.lightingFadeInDistance = 9000000.0;
84
- this.hasWaterMask = false;
85
- this.showWaterEffect = false;
86
- this.oceanNormalMap = undefined;
87
- this.zoomedOutOceanSpecularIntensity = 0.5;
88
- this.enableLighting = false;
89
- this.dynamicAtmosphereLighting = false;
90
- this.dynamicAtmosphereLightingFromSun = false;
91
- this.showGroundAtmosphere = false;
92
- this.shadows = ShadowMode.RECEIVE_ONLY;
93
- this.vertexShadowDarkness = 0.3;
94
-
76
+ class GlobeSurfaceTileProvider {
95
77
  /**
96
- * The color to use to highlight terrain fill tiles. If undefined, fill tiles are not
97
- * highlighted at all. The alpha value is used to alpha blend with the tile's
98
- * actual color. Because terrain fill tiles do not represent the actual terrain surface,
99
- * it may be useful in some applications to indicate visually that they are not to be trusted.
100
- * @type {Color}
101
- * @default undefined
78
+ * @param {object} options
79
+ * @param {TerrainProvider} options.terrainProvider The terrain provider that describes the surface geometry.
80
+ * @param {ImageryLayerCollection} options.imageryLayers The collection of imagery layers describing the shading of the surface.
81
+ * @param {GlobeSurfaceShaderSet} options.surfaceShaderSet The set of shaders used to render the surface.
82
+ * @param {VectorProvider} options.vectorProvider
102
83
  */
103
- this.fillHighlightColor = undefined;
104
-
105
- this.hueShift = 0.0;
106
- this.saturationShift = 0.0;
107
- this.brightnessShift = 0.0;
108
-
109
- this.showSkirts = true;
110
- this.backFaceCulling = true;
111
- this.undergroundColor = undefined;
112
- this.undergroundColorAlphaByDistance = undefined;
113
-
114
- this.lambertDiffuseMultiplier = 0.0;
115
-
116
- this.materialUniformMap = undefined;
117
- this._materialUniformMap = undefined;
118
-
119
- this._quadtree = undefined;
120
- this._terrainProvider = options.terrainProvider;
121
- this._imageryLayers = options.imageryLayers;
122
- this._surfaceShaderSet = options.surfaceShaderSet;
84
+ constructor(options) {
85
+ //>>includeStart('debug', pragmas.debug);
86
+ if (!defined(options)) {
87
+ throw new DeveloperError("options is required.");
88
+ }
89
+ if (!defined(options.terrainProvider)) {
90
+ throw new DeveloperError("options.terrainProvider is required.");
91
+ } else if (!defined(options.imageryLayers)) {
92
+ throw new DeveloperError("options.imageryLayers is required.");
93
+ } else if (!defined(options.surfaceShaderSet)) {
94
+ throw new DeveloperError("options.surfaceShaderSet is required.");
95
+ } else if (!defined(options.vectorProvider)) {
96
+ throw new DeveloperError("options.vectorProvider is required.");
97
+ }
98
+ //>>includeEnd('debug');
99
+
100
+ this.lightingFadeOutDistance = 6500000.0;
101
+ this.lightingFadeInDistance = 9000000.0;
102
+ this.hasWaterMask = false;
103
+ this.showWaterEffect = false;
104
+ this.oceanNormalMap = undefined;
105
+ this.zoomedOutOceanSpecularIntensity = 0.5;
106
+ this.enableLighting = false;
107
+ this.dynamicAtmosphereLighting = false;
108
+ this.dynamicAtmosphereLightingFromSun = false;
109
+ this.showGroundAtmosphere = false;
110
+ this.shadows = ShadowMode.RECEIVE_ONLY;
111
+ this.vertexShadowDarkness = 0.3;
112
+
113
+ /**
114
+ * The color to use to highlight terrain fill tiles. If undefined, fill tiles are not
115
+ * highlighted at all. The alpha value is used to alpha blend with the tile's
116
+ * actual color. Because terrain fill tiles do not represent the actual terrain surface,
117
+ * it may be useful in some applications to indicate visually that they are not to be trusted.
118
+ * @type {Color}
119
+ * @default undefined
120
+ */
121
+ this.fillHighlightColor = undefined;
122
+
123
+ this.hueShift = 0.0;
124
+ this.saturationShift = 0.0;
125
+ this.brightnessShift = 0.0;
126
+
127
+ this.showSkirts = true;
128
+ this.backFaceCulling = true;
129
+ this.undergroundColor = undefined;
130
+ this.undergroundColorAlphaByDistance = undefined;
131
+
132
+ this.lambertDiffuseMultiplier = 0.0;
133
+
134
+ this.materialUniformMap = undefined;
135
+ this._materialUniformMap = undefined;
136
+
137
+ this._quadtree = undefined;
138
+ this._terrainProvider = options.terrainProvider;
139
+ this._vectorProvider = options.vectorProvider;
140
+ this._imageryLayers = options.imageryLayers;
141
+ this._surfaceShaderSet = options.surfaceShaderSet;
142
+
143
+ this._renderState = undefined;
144
+ this._blendRenderState = undefined;
145
+ this._disableCullingRenderState = undefined;
146
+ this._disableCullingBlendRenderState = undefined;
147
+
148
+ this._errorEvent = new Event();
149
+
150
+ this._removeLayerAddedListener =
151
+ this._imageryLayers.layerAdded.addEventListener(
152
+ GlobeSurfaceTileProvider.prototype._onLayerAdded,
153
+ this,
154
+ );
155
+ this._removeLayerRemovedListener =
156
+ this._imageryLayers.layerRemoved.addEventListener(
157
+ GlobeSurfaceTileProvider.prototype._onLayerRemoved,
158
+ this,
159
+ );
160
+ this._removeLayerMovedListener =
161
+ this._imageryLayers.layerMoved.addEventListener(
162
+ GlobeSurfaceTileProvider.prototype._onLayerMoved,
163
+ this,
164
+ );
165
+ this._removeLayerShownListener =
166
+ this._imageryLayers.layerShownOrHidden.addEventListener(
167
+ GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden,
168
+ this,
169
+ );
170
+ this._imageryLayersUpdatedEvent = new Event();
123
171
 
124
- this._renderState = undefined;
125
- this._blendRenderState = undefined;
126
- this._disableCullingRenderState = undefined;
127
- this._disableCullingBlendRenderState = undefined;
172
+ this._layerOrderChanged = false;
128
173
 
129
- this._errorEvent = new Event();
174
+ /** @type {QuadtreeTile[][]} */
175
+ this._tilesToRenderByTextureCount = [];
130
176
 
131
- this._removeLayerAddedListener =
132
- this._imageryLayers.layerAdded.addEventListener(
133
- GlobeSurfaceTileProvider.prototype._onLayerAdded,
134
- this,
135
- );
136
- this._removeLayerRemovedListener =
137
- this._imageryLayers.layerRemoved.addEventListener(
138
- GlobeSurfaceTileProvider.prototype._onLayerRemoved,
139
- this,
140
- );
141
- this._removeLayerMovedListener =
142
- this._imageryLayers.layerMoved.addEventListener(
143
- GlobeSurfaceTileProvider.prototype._onLayerMoved,
144
- this,
145
- );
146
- this._removeLayerShownListener =
147
- this._imageryLayers.layerShownOrHidden.addEventListener(
148
- GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden,
149
- this,
150
- );
151
- this._imageryLayersUpdatedEvent = new Event();
177
+ /** @type {DrawCommand[]} */
178
+ this._drawCommands = [];
152
179
 
153
- this._layerOrderChanged = false;
180
+ /** @type {object[]} */
181
+ this._uniformMaps = [];
154
182
 
155
- this._tilesToRenderByTextureCount = [];
156
- this._drawCommands = [];
157
- this._uniformMaps = [];
158
- this._usedDrawCommands = 0;
183
+ this._usedDrawCommands = 0;
159
184
 
160
- this._vertexArraysToDestroy = [];
185
+ /** @type {VertexArray[]} */
186
+ this._vertexArraysToDestroy = [];
161
187
 
162
- this._debug = {
163
- wireframe: false,
164
- boundingSphereTile: undefined,
165
- };
188
+ this._debug = {
189
+ wireframe: false,
190
+ boundingSphereTile: undefined,
191
+ tilesRendered: 0,
192
+ texturesRendered: 0,
193
+ };
166
194
 
167
- this._baseColor = undefined;
168
- this._firstPassInitialColor = undefined;
169
- this.baseColor = new Color(0.0, 0.0, 0.5, 1.0);
195
+ this._baseColor = undefined;
196
+ this._firstPassInitialColor = undefined;
197
+ this.baseColor = new Color(0.0, 0.0, 0.5, 1.0);
170
198
 
171
- /**
172
- * A property specifying a {@link ClippingPlaneCollection} used to selectively disable rendering on the outside of each plane.
173
- * @type {ClippingPlaneCollection}
174
- * @private
175
- */
176
- this._clippingPlanes = undefined;
199
+ /**
200
+ * A property specifying a {@link ClippingPlaneCollection} used to selectively disable rendering on the outside of each plane.
201
+ * @type {ClippingPlaneCollection}
202
+ * @ignore
203
+ */
204
+ this._clippingPlanes = undefined;
177
205
 
178
- /**
179
- * A property specifying a {@link ClippingPolygonCollection} used to selectively disable rendering inside or outside a list of polygons.
180
- * @type {ClippingPolygonCollection}
181
- * @private
182
- */
183
- this._clippingPolygons = undefined;
206
+ /**
207
+ * A property specifying a {@link ClippingPolygonCollection} used to selectively disable rendering inside or outside a list of polygons.
208
+ * @type {ClippingPolygonCollection}
209
+ * @ignore
210
+ */
211
+ this._clippingPolygons = undefined;
184
212
 
185
- /**
186
- * A property specifying a {@link Rectangle} used to selectively limit terrain and imagery rendering.
187
- * @type {Rectangle}
188
- */
189
- this.cartographicLimitRectangle = Rectangle.clone(Rectangle.MAX_VALUE);
213
+ /**
214
+ * A property specifying a {@link Rectangle} used to selectively limit terrain and imagery rendering.
215
+ * @type {Rectangle}
216
+ */
217
+ this.cartographicLimitRectangle = Rectangle.clone(Rectangle.MAX_VALUE);
190
218
 
191
- this._hasLoadedTilesThisFrame = false;
192
- this._hasFillTilesThisFrame = false;
219
+ this._hasLoadedTilesThisFrame = false;
220
+ this._hasFillTilesThisFrame = false;
193
221
 
194
- this._oldVerticalExaggeration = undefined;
195
- this._oldVerticalExaggerationRelativeHeight = undefined;
196
- this._oldSceneMode = SceneMode.SCENE3D;
197
- }
222
+ this._oldVerticalExaggeration = undefined;
223
+ this._oldVerticalExaggerationRelativeHeight = undefined;
224
+ this._oldSceneMode = SceneMode.SCENE3D;
225
+ }
198
226
 
199
- Object.defineProperties(GlobeSurfaceTileProvider.prototype, {
200
227
  /**
201
228
  * Gets or sets the color of the globe when no imagery is available.
202
- * @memberof GlobeSurfaceTileProvider.prototype
203
229
  * @type {Color}
204
230
  */
205
- baseColor: {
206
- get: function () {
207
- return this._baseColor;
208
- },
209
- set: function (value) {
210
- //>>includeStart('debug', pragmas.debug);
211
- if (!defined(value)) {
212
- throw new DeveloperError("value is required.");
213
- }
214
- //>>includeEnd('debug');
231
+ get baseColor() {
232
+ return this._baseColor;
233
+ }
234
+
235
+ set baseColor(value) {
236
+ //>>includeStart('debug', pragmas.debug);
237
+ if (!defined(value)) {
238
+ throw new DeveloperError("value is required.");
239
+ }
240
+ //>>includeEnd('debug');
241
+
242
+ this._baseColor = value;
243
+ this._firstPassInitialColor = Cartesian4.fromColor(
244
+ value,
245
+ this._firstPassInitialColor,
246
+ );
247
+ }
215
248
 
216
- this._baseColor = value;
217
- this._firstPassInitialColor = Cartesian4.fromColor(
218
- value,
219
- this._firstPassInitialColor,
220
- );
221
- },
222
- },
223
249
  /**
224
250
  * Gets or sets the {@link QuadtreePrimitive} for which this provider is
225
251
  * providing tiles. This property may be undefined if the provider is not yet associated
226
252
  * with a {@link QuadtreePrimitive}.
227
- * @memberof GlobeSurfaceTileProvider.prototype
228
253
  * @type {QuadtreePrimitive}
229
254
  */
230
- quadtree: {
231
- get: function () {
232
- return this._quadtree;
233
- },
234
- set: function (value) {
235
- //>>includeStart('debug', pragmas.debug);
236
- if (!defined(value)) {
237
- throw new DeveloperError("value is required.");
238
- }
239
- //>>includeEnd('debug');
255
+ get quadtree() {
256
+ return this._quadtree;
257
+ }
240
258
 
241
- this._quadtree = value;
242
- },
243
- },
259
+ set quadtree(value) {
260
+ //>>includeStart('debug', pragmas.debug);
261
+ if (!defined(value)) {
262
+ throw new DeveloperError("value is required.");
263
+ }
264
+ //>>includeEnd('debug');
265
+
266
+ this._quadtree = value;
267
+ }
244
268
 
245
269
  /**
246
270
  * Gets the tiling scheme used by the provider.
247
- * @memberof GlobeSurfaceTileProvider.prototype
248
271
  * @type {TilingScheme}
249
272
  */
250
- tilingScheme: {
251
- get: function () {
252
- if (!defined(this._terrainProvider)) {
253
- return undefined;
254
- }
273
+ get tilingScheme() {
274
+ if (!defined(this._terrainProvider)) {
275
+ return undefined;
276
+ }
255
277
 
256
- return this._terrainProvider.tilingScheme;
257
- },
258
- },
278
+ // @ts-expect-error Missing types.
279
+ return this._terrainProvider.tilingScheme;
280
+ }
259
281
 
260
282
  /**
261
283
  * Gets an event that is raised when the geometry provider encounters an asynchronous error. By subscribing
262
284
  * to the event, you will be notified of the error and can potentially recover from it. Event listeners
263
285
  * are passed an instance of {@link TileProviderError}.
264
- * @memberof GlobeSurfaceTileProvider.prototype
265
- * @type {Event}
286
+ * @type {Event<*>}
266
287
  */
267
- errorEvent: {
268
- get: function () {
269
- return this._errorEvent;
270
- },
271
- },
288
+ get errorEvent() {
289
+ return this._errorEvent;
290
+ }
272
291
 
273
292
  /**
274
293
  * Gets an event that is raised when an imagery layer is added, shown, hidden, moved, or removed.
275
- * @memberof GlobeSurfaceTileProvider.prototype
276
- * @type {Event}
294
+ * @type {Event<*>}
277
295
  */
278
- imageryLayersUpdatedEvent: {
279
- get: function () {
280
- return this._imageryLayersUpdatedEvent;
281
- },
282
- },
296
+ get imageryLayersUpdatedEvent() {
297
+ return this._imageryLayersUpdatedEvent;
298
+ }
283
299
 
284
300
  /**
285
301
  * Gets or sets the terrain provider that describes the surface geometry.
286
- * @memberof GlobeSurfaceTileProvider.prototype
287
302
  * @type {TerrainProvider}
288
303
  */
289
- terrainProvider: {
290
- get: function () {
291
- return this._terrainProvider;
292
- },
293
- set: function (terrainProvider) {
294
- if (this._terrainProvider === terrainProvider) {
295
- return;
296
- }
304
+ get terrainProvider() {
305
+ return this._terrainProvider;
306
+ }
307
+
308
+ set terrainProvider(terrainProvider) {
309
+ if (this._terrainProvider === terrainProvider) {
310
+ return;
311
+ }
297
312
 
298
- this._terrainProvider = terrainProvider;
313
+ this._terrainProvider = terrainProvider;
314
+
315
+ if (defined(this._quadtree)) {
316
+ this._quadtree.invalidateAllTiles();
317
+ }
318
+ }
319
+
320
+ /** @type {VectorProvider} */
321
+ get vectorProvider() {
322
+ return this._vectorProvider;
323
+ }
299
324
 
300
- if (defined(this._quadtree)) {
301
- this._quadtree.invalidateAllTiles();
302
- }
303
- },
304
- },
305
325
  /**
306
326
  * The {@link ClippingPlaneCollection} used to selectively disable rendering.
307
327
  *
308
328
  * @type {ClippingPlaneCollection}
309
329
  *
310
- * @private
330
+ * @ignore
311
331
  */
312
- clippingPlanes: {
313
- get: function () {
314
- return this._clippingPlanes;
315
- },
316
- set: function (value) {
317
- ClippingPlaneCollection.setOwner(value, this, "_clippingPlanes");
318
- },
319
- },
332
+ get clippingPlanes() {
333
+ return this._clippingPlanes;
334
+ }
335
+
336
+ set clippingPlanes(value) {
337
+ ClippingPlaneCollection.setOwner(value, this, "_clippingPlanes");
338
+ }
320
339
 
321
340
  /**
322
341
  * The {@link ClippingPolygonCollection} used to selectively disable rendering inside or outside a list of polygons.
323
342
  *
324
343
  * @type {ClippingPolygonCollection}
325
344
  *
326
- * @private
345
+ * @ignore
327
346
  */
328
- clippingPolygons: {
329
- get: function () {
330
- return this._clippingPolygons;
331
- },
332
- set: function (value) {
333
- ClippingPolygonCollection.setOwner(value, this, "_clippingPolygons");
334
- },
335
- },
336
- });
337
-
338
- function sortTileImageryByLayerIndex(a, b) {
339
- let aImagery = a.loadingImagery;
340
- if (!defined(aImagery)) {
341
- aImagery = a.readyImagery;
347
+ get clippingPolygons() {
348
+ return this._clippingPolygons;
342
349
  }
343
350
 
344
- let bImagery = b.loadingImagery;
345
- if (!defined(bImagery)) {
346
- bImagery = b.readyImagery;
351
+ set clippingPolygons(value) {
352
+ ClippingPolygonCollection.setOwner(value, this, "_clippingPolygons");
347
353
  }
348
354
 
349
- return aImagery.imageryLayer._layerIndex - bImagery.imageryLayer._layerIndex;
350
- }
351
-
352
- /**
353
- * Make updates to the tile provider that are not involved in rendering. Called before the render update cycle.
354
- */
355
- GlobeSurfaceTileProvider.prototype.update = function (frameState) {
356
- // update collection: imagery indices, base layers, raise layer show/hide event
357
- this._imageryLayers._update();
358
- };
359
-
360
- function updateCredits(surface, frameState) {
361
- const creditDisplay = frameState.creditDisplay;
362
- const terrainProvider = surface._terrainProvider;
363
- if (defined(terrainProvider) && defined(terrainProvider.credit)) {
364
- creditDisplay.addCreditToNextFrame(terrainProvider.credit);
355
+ /**
356
+ * Make updates to the tile provider that are not involved in rendering. Called before the render update cycle.
357
+ * @param {FrameState} frameState
358
+ */
359
+ update(frameState) {
360
+ // update collection: imagery indices, base layers, raise layer show/hide event
361
+ this._imageryLayers._update();
365
362
  }
366
363
 
367
- const imageryLayers = surface._imageryLayers;
368
- for (let i = 0, len = imageryLayers.length; i < len; ++i) {
369
- const layer = imageryLayers.get(i);
370
- if (layer.ready && layer.show && defined(layer.imageryProvider.credit)) {
371
- creditDisplay.addCreditToNextFrame(layer.imageryProvider.credit);
364
+ /**
365
+ * Called at the beginning of each render frame, before {@link QuadtreeTileProvider#showTileThisFrame}
366
+ * @param {FrameState} frameState The frame state.
367
+ */
368
+ initialize(frameState) {
369
+ // update each layer for texture reprojection.
370
+ this._imageryLayers.queueReprojectionCommands(frameState);
371
+
372
+ if (this._layerOrderChanged) {
373
+ this._layerOrderChanged = false;
374
+
375
+ // Sort the TileImagery instances in each tile by the layer index.
376
+ this._quadtree.forEachLoadedTile(
377
+ /** @param {QuadtreeTile} tile */
378
+ function (tile) {
379
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
380
+ surfaceTile.imagery.sort(sortTileImageryByLayerIndex);
381
+ },
382
+ );
372
383
  }
373
- }
374
- }
375
-
376
- /**
377
- * Called at the beginning of each render frame, before {@link QuadtreeTileProvider#showTileThisFrame}
378
- * @param {FrameState} frameState The frame state.
379
- */
380
- GlobeSurfaceTileProvider.prototype.initialize = function (frameState) {
381
- // update each layer for texture reprojection.
382
- this._imageryLayers.queueReprojectionCommands(frameState);
383
-
384
- if (this._layerOrderChanged) {
385
- this._layerOrderChanged = false;
386
-
387
- // Sort the TileImagery instances in each tile by the layer index.
388
- this._quadtree.forEachLoadedTile(function (tile) {
389
- tile.data.imagery.sort(sortTileImageryByLayerIndex);
390
- });
391
- }
392
384
 
393
- // Add credits for terrain and imagery providers.
394
- updateCredits(this, frameState);
385
+ // Record regions dirtied by changed collections, re-bake overlapping
386
+ // tiles, and build vector data for new surface tiles.
387
+ const vectorProvider = this._vectorProvider;
388
+ vectorProvider.update();
389
+ this._quadtree.forEachRenderedTile(
390
+ /** @param {QuadtreeTile} tile */
391
+ (tile) => {
392
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
393
+
394
+ if (defined(surfaceTile.vectorData)) {
395
+ surfaceTile.vectorData = vectorProvider.updateTileData(
396
+ tile.x,
397
+ tile.y,
398
+ tile.level,
399
+ frameState.context,
400
+ surfaceTile.vectorData,
401
+ );
402
+ } else {
403
+ surfaceTile.vectorData = vectorProvider.requestTileData(
404
+ tile.x,
405
+ tile.y,
406
+ tile.level,
407
+ frameState.context,
408
+ );
409
+ }
410
+ },
411
+ );
412
+ vectorProvider.makeClean();
395
413
 
396
- const vertexArraysToDestroy = this._vertexArraysToDestroy;
397
- const length = vertexArraysToDestroy.length;
398
- for (let j = 0; j < length; ++j) {
399
- GlobeSurfaceTile._freeVertexArray(vertexArraysToDestroy[j]);
400
- }
401
- vertexArraysToDestroy.length = 0;
402
- };
414
+ // Add credits for terrain and imagery providers.
415
+ updateCredits(this, frameState);
403
416
 
404
- /**
405
- * Called at the beginning of the update cycle for each render frame, before {@link QuadtreeTileProvider#showTileThisFrame}
406
- * or any other functions.
407
- *
408
- * @param {FrameState} frameState The frame state.
409
- */
410
- GlobeSurfaceTileProvider.prototype.beginUpdate = function (frameState) {
411
- const tilesToRenderByTextureCount = this._tilesToRenderByTextureCount;
412
- for (let i = 0, len = tilesToRenderByTextureCount.length; i < len; ++i) {
413
- const tiles = tilesToRenderByTextureCount[i];
414
- if (defined(tiles)) {
415
- tiles.length = 0;
417
+ const vertexArraysToDestroy = this._vertexArraysToDestroy;
418
+ const length = vertexArraysToDestroy.length;
419
+ for (let j = 0; j < length; ++j) {
420
+ GlobeSurfaceTile._freeVertexArray(vertexArraysToDestroy[j]);
416
421
  }
417
- }
418
- // update clipping planes
419
- const clippingPlanes = this._clippingPlanes;
420
- if (defined(clippingPlanes) && clippingPlanes.enabled) {
421
- clippingPlanes.update(frameState);
422
+ vertexArraysToDestroy.length = 0;
422
423
  }
423
424
 
424
- // update clipping polygons
425
- const clippingPolygons = this._clippingPolygons;
426
- if (defined(clippingPolygons) && clippingPolygons.enabled) {
427
- clippingPolygons.update(frameState);
428
- clippingPolygons.queueCommands(frameState);
429
- }
425
+ /**
426
+ * Called at the beginning of the update cycle for each render frame, before {@link QuadtreeTileProvider#showTileThisFrame}
427
+ * or any other functions.
428
+ *
429
+ * @param {FrameState} frameState The frame state.
430
+ */
431
+ beginUpdate(frameState) {
432
+ const tilesToRenderByTextureCount = this._tilesToRenderByTextureCount;
433
+ for (let i = 0, len = tilesToRenderByTextureCount.length; i < len; ++i) {
434
+ const tiles = tilesToRenderByTextureCount[i];
435
+ if (defined(tiles)) {
436
+ tiles.length = 0;
437
+ }
438
+ }
439
+ // update clipping planes
440
+ const clippingPlanes = this._clippingPlanes;
441
+ // @ts-expect-error Missing types.
442
+ if (defined(clippingPlanes) && clippingPlanes.enabled) {
443
+ clippingPlanes.update(frameState);
444
+ }
430
445
 
431
- this._usedDrawCommands = 0;
446
+ // update clipping polygons
447
+ const clippingPolygons = this._clippingPolygons;
448
+ if (defined(clippingPolygons) && clippingPolygons.enabled) {
449
+ // @ts-expect-error Missing types.
450
+ clippingPolygons.update(frameState);
451
+ // @ts-expect-error Missing types.
452
+ clippingPolygons.queueCommands(frameState);
453
+ }
432
454
 
433
- this._hasLoadedTilesThisFrame = false;
434
- this._hasFillTilesThisFrame = false;
435
- };
455
+ this._usedDrawCommands = 0;
436
456
 
437
- /**
438
- * Called at the end of the update cycle for each render frame, after {@link QuadtreeTileProvider#showTileThisFrame}
439
- * and any other functions.
440
- *
441
- * @param {FrameState} frameState The frame state.
442
- */
443
- GlobeSurfaceTileProvider.prototype.endUpdate = function (frameState) {
444
- if (!defined(this._renderState)) {
445
- this._renderState = RenderState.fromCache({
446
- // Write color and depth
447
- cull: {
448
- enabled: true,
449
- },
450
- depthTest: {
451
- enabled: true,
452
- func: DepthFunction.LESS,
453
- },
454
- });
457
+ this._hasLoadedTilesThisFrame = false;
458
+ this._hasFillTilesThisFrame = false;
459
+ }
455
460
 
456
- this._blendRenderState = RenderState.fromCache({
457
- // Write color and depth
458
- cull: {
459
- enabled: true,
460
- },
461
- depthTest: {
462
- enabled: true,
463
- func: DepthFunction.LESS_OR_EQUAL,
464
- },
465
- blending: BlendingState.ALPHA_BLEND,
466
- });
461
+ /**
462
+ * Called at the end of the update cycle for each render frame, after {@link QuadtreeTileProvider#showTileThisFrame}
463
+ * and any other functions.
464
+ *
465
+ * @param {FrameState} frameState The frame state.
466
+ */
467
+ endUpdate(frameState) {
468
+ if (!defined(this._renderState)) {
469
+ this._renderState = RenderState.fromCache({
470
+ // Write color and depth
471
+ cull: {
472
+ enabled: true,
473
+ },
474
+ depthTest: {
475
+ enabled: true,
476
+ func: DepthFunction.LESS,
477
+ },
478
+ });
467
479
 
468
- let rs = clone(this._renderState, true);
469
- rs.cull.enabled = false;
470
- this._disableCullingRenderState = RenderState.fromCache(rs);
480
+ this._blendRenderState = RenderState.fromCache({
481
+ // Write color and depth
482
+ cull: {
483
+ enabled: true,
484
+ },
485
+ depthTest: {
486
+ enabled: true,
487
+ func: DepthFunction.LESS_OR_EQUAL,
488
+ },
489
+ blending: BlendingState.ALPHA_BLEND,
490
+ });
471
491
 
472
- rs = clone(this._blendRenderState, true);
473
- rs.cull.enabled = false;
474
- this._disableCullingBlendRenderState = RenderState.fromCache(rs);
475
- }
492
+ let rs = /** @type {RenderState} */ (clone(this._renderState, true));
493
+ rs.cull.enabled = false;
494
+ this._disableCullingRenderState = RenderState.fromCache(rs);
476
495
 
477
- // If this frame has a mix of loaded and fill tiles, we need to propagate
478
- // loaded heights to the fill tiles.
479
- if (this._hasFillTilesThisFrame && this._hasLoadedTilesThisFrame) {
480
- TerrainFillMesh.updateFillTiles(
481
- this,
482
- this._quadtree._tilesToRender,
483
- frameState,
484
- this._vertexArraysToDestroy,
485
- );
486
- }
496
+ rs = /** @type {RenderState} */ (clone(this._blendRenderState, true));
497
+ rs.cull.enabled = false;
498
+ this._disableCullingBlendRenderState = RenderState.fromCache(rs);
499
+ }
487
500
 
488
- // When vertical exaggeration changes, all of the loaded tiles need to generate
489
- // geodetic surface normals so they can scale properly when rendered.
490
- // When exaggeration is reset, geodetic surface normals are removed to decrease
491
- // memory usage. Some tiles might have been constructed with the correct
492
- // exaggeration already, so skip over them.
501
+ // If this frame has a mix of loaded and fill tiles, we need to propagate
502
+ // loaded heights to the fill tiles.
503
+ if (this._hasFillTilesThisFrame && this._hasLoadedTilesThisFrame) {
504
+ TerrainFillMesh.updateFillTiles(
505
+ this,
506
+ this._quadtree._tilesToRender,
507
+ frameState,
508
+ this._vertexArraysToDestroy,
509
+ );
510
+ }
493
511
 
494
- // If the geodetic surface normals can't be created because the tile doesn't
495
- // have a mesh, keep checking until the tile does have a mesh. This can happen
496
- // if the tile's mesh starts construction in a worker thread right before the
497
- // exaggeration changes.
512
+ // When vertical exaggeration changes, all of the loaded tiles need to generate
513
+ // geodetic surface normals so they can scale properly when rendered.
514
+ // When exaggeration is reset, geodetic surface normals are removed to decrease
515
+ // memory usage. Some tiles might have been constructed with the correct
516
+ // exaggeration already, so skip over them.
498
517
 
499
- const quadtree = this.quadtree;
500
- const exaggeration = frameState.verticalExaggeration;
501
- const exaggerationRelativeHeight =
502
- frameState.verticalExaggerationRelativeHeight;
503
- const exaggerationChanged =
504
- this._oldVerticalExaggeration !== exaggeration ||
505
- this._oldVerticalExaggerationRelativeHeight !== exaggerationRelativeHeight;
506
-
507
- // Keep track of the next time there is a change in exaggeration
508
- this._oldVerticalExaggeration = exaggeration;
509
- this._oldVerticalExaggerationRelativeHeight = exaggerationRelativeHeight;
510
-
511
- if (exaggerationChanged) {
512
- quadtree.forEachLoadedTile(function (tile) {
513
- const surfaceTile = tile.data;
514
- surfaceTile.updateExaggeration(tile, frameState, quadtree);
515
- });
516
- }
518
+ // If the geodetic surface normals can't be created because the tile doesn't
519
+ // have a mesh, keep checking until the tile does have a mesh. This can happen
520
+ // if the tile's mesh starts construction in a worker thread right before the
521
+ // exaggeration changes.
517
522
 
518
- const sceneModeChanged = this._oldSceneMode !== frameState.mode;
519
- this._oldSceneMode = frameState.mode;
523
+ const quadtree = this.quadtree;
524
+ const exaggeration = frameState.verticalExaggeration;
525
+ const exaggerationRelativeHeight =
526
+ frameState.verticalExaggerationRelativeHeight;
527
+ const exaggerationChanged =
528
+ this._oldVerticalExaggeration !== exaggeration ||
529
+ this._oldVerticalExaggerationRelativeHeight !==
530
+ exaggerationRelativeHeight;
531
+
532
+ // Keep track of the next time there is a change in exaggeration
533
+ this._oldVerticalExaggeration = exaggeration;
534
+ this._oldVerticalExaggerationRelativeHeight = exaggerationRelativeHeight;
535
+
536
+ if (exaggerationChanged) {
537
+ quadtree.forEachLoadedTile(
538
+ /** @param {QuadtreeTile} tile */
539
+ function (tile) {
540
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
541
+ surfaceTile.updateExaggeration(tile, frameState, quadtree);
542
+ },
543
+ );
544
+ }
520
545
 
521
- if (sceneModeChanged) {
522
- quadtree.forEachLoadedTile(function (tile) {
523
- const surfaceTile = tile.data;
524
- surfaceTile.updateSceneMode(frameState.mode);
525
- });
526
- }
546
+ const sceneModeChanged = this._oldSceneMode !== frameState.mode;
547
+ this._oldSceneMode = frameState.mode;
527
548
 
528
- // Add the tile render commands to the command list, sorted by texture count.
529
- const tilesToRenderByTextureCount = this._tilesToRenderByTextureCount;
530
- for (
531
- let textureCountIndex = 0,
532
- textureCountLength = tilesToRenderByTextureCount.length;
533
- textureCountIndex < textureCountLength;
534
- ++textureCountIndex
535
- ) {
536
- const tilesToRender = tilesToRenderByTextureCount[textureCountIndex];
537
- if (!defined(tilesToRender)) {
538
- continue;
549
+ if (sceneModeChanged) {
550
+ quadtree.forEachLoadedTile(
551
+ /** @param {QuadtreeTile} tile */
552
+ function (tile) {
553
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
554
+ surfaceTile.updateSceneMode(frameState.mode);
555
+ },
556
+ );
539
557
  }
540
558
 
559
+ // Add the tile render commands to the command list, sorted by texture count.
560
+ const tilesToRenderByTextureCount = this._tilesToRenderByTextureCount;
541
561
  for (
542
- let tileIndex = 0, tileLength = tilesToRender.length;
543
- tileIndex < tileLength;
544
- ++tileIndex
562
+ let textureCountIndex = 0,
563
+ textureCountLength = tilesToRenderByTextureCount.length;
564
+ textureCountIndex < textureCountLength;
565
+ ++textureCountIndex
545
566
  ) {
546
- const tile = tilesToRender[tileIndex];
547
- const tileBoundingRegion = tile.data.tileBoundingRegion;
548
- addDrawCommandsForTile(this, tile, frameState);
549
- frameState.minimumTerrainHeight = Math.min(
550
- frameState.minimumTerrainHeight,
551
- tileBoundingRegion.minimumHeight,
552
- );
567
+ const tilesToRender = tilesToRenderByTextureCount[textureCountIndex];
568
+ if (!defined(tilesToRender)) {
569
+ continue;
570
+ }
571
+
572
+ for (
573
+ let tileIndex = 0, tileLength = tilesToRender.length;
574
+ tileIndex < tileLength;
575
+ ++tileIndex
576
+ ) {
577
+ const tile = tilesToRender[tileIndex];
578
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
579
+ const tileBoundingRegion = surfaceTile.tileBoundingRegion;
580
+ addDrawCommandsForTile(this, tile, frameState);
581
+ frameState.minimumTerrainHeight = Math.min(
582
+ frameState.minimumTerrainHeight,
583
+ tileBoundingRegion.minimumHeight,
584
+ );
585
+ }
553
586
  }
554
587
  }
555
- };
556
588
 
557
- function pushCommand(command, frameState) {
558
- const globeTranslucencyState = frameState.globeTranslucencyState;
559
- if (globeTranslucencyState.translucent) {
560
- const isBlendCommand = command.renderState.blending.enabled;
561
- globeTranslucencyState.pushDerivedCommands(
562
- command,
563
- isBlendCommand,
564
- frameState,
565
- );
566
- } else {
567
- frameState.commandList.push(command);
589
+ /**
590
+ * Adds draw commands for tiles rendered in the previous frame for a pick pass.
591
+ *
592
+ * @param {FrameState} frameState The frame state.
593
+ */
594
+ updateForPick(frameState) {
595
+ // Add the tile pick commands from the tiles drawn last frame.
596
+ const drawCommands = this._drawCommands;
597
+ for (let i = 0, length = this._usedDrawCommands; i < length; ++i) {
598
+ pushCommand(drawCommands[i], frameState);
599
+ }
568
600
  }
569
- }
570
601
 
571
- /**
572
- * Adds draw commands for tiles rendered in the previous frame for a pick pass.
573
- *
574
- * @param {FrameState} frameState The frame state.
575
- */
576
- GlobeSurfaceTileProvider.prototype.updateForPick = function (frameState) {
577
- // Add the tile pick commands from the tiles drawn last frame.
578
- const drawCommands = this._drawCommands;
579
- for (let i = 0, length = this._usedDrawCommands; i < length; ++i) {
580
- pushCommand(drawCommands[i], frameState);
602
+ /**
603
+ * Cancels any imagery re-projections in the queue.
604
+ */
605
+ cancelReprojections() {
606
+ this._imageryLayers.cancelReprojections();
581
607
  }
582
- };
583
608
 
584
- /**
585
- * Cancels any imagery re-projections in the queue.
586
- */
587
- GlobeSurfaceTileProvider.prototype.cancelReprojections = function () {
588
- this._imageryLayers.cancelReprojections();
589
- };
609
+ /**
610
+ * Gets the maximum geometric error allowed in a tile at a given level, in meters.
611
+ *
612
+ * @param {number} level The tile level for which to get the maximum geometric error.
613
+ * @returns {number} The maximum geometric error in meters.
614
+ */
615
+ getLevelMaximumGeometricError(level) {
616
+ if (!defined(this._terrainProvider)) {
617
+ return 0;
618
+ }
590
619
 
591
- /**
592
- * Gets the maximum geometric error allowed in a tile at a given level, in meters.
593
- *
594
- * @param {number} level The tile level for which to get the maximum geometric error.
595
- * @returns {number} The maximum geometric error in meters.
596
- */
597
- GlobeSurfaceTileProvider.prototype.getLevelMaximumGeometricError = function (
598
- level,
599
- ) {
600
- if (!defined(this._terrainProvider)) {
601
- return 0;
620
+ // @ts-expect-error Missing types.
621
+ return this._terrainProvider.getLevelMaximumGeometricError(level);
602
622
  }
603
623
 
604
- return this._terrainProvider.getLevelMaximumGeometricError(level);
605
- };
624
+ /**
625
+ * Loads, or continues loading, a given tile. This function will continue to be called
626
+ * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}.
627
+ *
628
+ * @param {FrameState} frameState The frame state.
629
+ * @param {QuadtreeTile} tile The tile to load.
630
+ */
631
+ loadTile(frameState, tile) {
632
+ // We don't want to load imagery until we're certain that the terrain tiles are actually visible.
633
+ // So if our bounding volume isn't accurate because it came from another tile, load terrain only
634
+ // initially. If we load some terrain and suddenly have a more accurate bounding volume and the
635
+ // tile is _still_ visible, give the tile a chance to load imagery immediately rather than
636
+ // waiting for next frame.
637
+
638
+ let surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
639
+ let terrainOnly = true;
640
+ let terrainStateBefore;
641
+ if (defined(surfaceTile)) {
642
+ terrainOnly =
643
+ surfaceTile.boundingVolumeSourceTile !== tile ||
644
+ tile._lastSelectionResult === TileSelectionResult.CULLED_BUT_NEEDED;
645
+ terrainStateBefore = surfaceTile.terrainState;
646
+ }
606
647
 
607
- /**
608
- * Loads, or continues loading, a given tile. This function will continue to be called
609
- * until {@link QuadtreeTile#state} is no longer {@link QuadtreeTileLoadState#LOADING}.
610
- *
611
- * @param {FrameState} frameState The frame state.
612
- * @param {QuadtreeTile} tile The tile to load.
613
- */
614
- GlobeSurfaceTileProvider.prototype.loadTile = function (frameState, tile) {
615
- // We don't want to load imagery until we're certain that the terrain tiles are actually visible.
616
- // So if our bounding volume isn't accurate because it came from another tile, load terrain only
617
- // initially. If we load some terrain and suddenly have a more accurate bounding volume and the
618
- // tile is _still_ visible, give the tile a chance to load imagery immediately rather than
619
- // waiting for next frame.
620
-
621
- let surfaceTile = tile.data;
622
- let terrainOnly = true;
623
- let terrainStateBefore;
624
- if (defined(surfaceTile)) {
625
- terrainOnly =
626
- surfaceTile.boundingVolumeSourceTile !== tile ||
627
- tile._lastSelectionResult === TileSelectionResult.CULLED_BUT_NEEDED;
628
- terrainStateBefore = surfaceTile.terrainState;
629
- }
630
-
631
- GlobeSurfaceTile.processStateMachine(
632
- tile,
633
- frameState,
634
- this.terrainProvider,
635
- this._imageryLayers,
636
- this.quadtree,
637
- this._vertexArraysToDestroy,
638
- terrainOnly,
639
- );
648
+ GlobeSurfaceTile.processStateMachine(
649
+ tile,
650
+ frameState,
651
+ this.terrainProvider,
652
+ this.vectorProvider,
653
+ this._imageryLayers,
654
+ this.quadtree,
655
+ this._vertexArraysToDestroy,
656
+ terrainOnly,
657
+ );
640
658
 
641
- surfaceTile = tile.data;
642
- if (terrainOnly && terrainStateBefore !== tile.data.terrainState) {
643
- // Terrain state changed. If:
644
- // a) The tile is visible, and
645
- // b) The bounding volume is accurate (updated as a side effect of computing visibility)
646
- // Then we'll load imagery, too.
647
- if (
648
- this.computeTileVisibility(tile, frameState, this.quadtree.occluders) !==
649
- Visibility.NONE &&
650
- surfaceTile.boundingVolumeSourceTile === tile
651
- ) {
652
- terrainOnly = false;
653
- GlobeSurfaceTile.processStateMachine(
654
- tile,
655
- frameState,
656
- this.terrainProvider,
657
- this._imageryLayers,
658
- this.quadtree,
659
- this._vertexArraysToDestroy,
660
- terrainOnly,
661
- );
659
+ surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
660
+ if (terrainOnly && terrainStateBefore !== surfaceTile.terrainState) {
661
+ // Terrain state changed. If:
662
+ // a) The tile is visible, and
663
+ // b) The bounding volume is accurate (updated as a side effect of computing visibility)
664
+ // Then we'll load imagery, too.
665
+ if (
666
+ this.computeTileVisibility(
667
+ tile,
668
+ frameState,
669
+ // @ts-expect-error Missing types.
670
+ this.quadtree.occluders,
671
+ ) !== Visibility.NONE &&
672
+ surfaceTile.boundingVolumeSourceTile === tile
673
+ ) {
674
+ terrainOnly = false;
675
+ GlobeSurfaceTile.processStateMachine(
676
+ tile,
677
+ frameState,
678
+ this.terrainProvider,
679
+ this.vectorProvider,
680
+ this._imageryLayers,
681
+ this.quadtree,
682
+ this._vertexArraysToDestroy,
683
+ terrainOnly,
684
+ );
685
+ }
662
686
  }
663
687
  }
664
- };
665
688
 
666
- const boundingSphereScratch = new BoundingSphere();
667
- const rectangleIntersectionScratch = new Rectangle();
668
- const splitCartographicLimitRectangleScratch = new Rectangle();
669
- const rectangleCenterScratch = new Cartographic();
670
-
671
- // cartographicLimitRectangle may span the IDL, but tiles never will.
672
- function clipRectangleAntimeridian(tileRectangle, cartographicLimitRectangle) {
673
- if (cartographicLimitRectangle.west < cartographicLimitRectangle.east) {
674
- return cartographicLimitRectangle;
675
- }
676
- const splitRectangle = Rectangle.clone(
677
- cartographicLimitRectangle,
678
- splitCartographicLimitRectangleScratch,
679
- );
680
- const tileCenter = Rectangle.center(tileRectangle, rectangleCenterScratch);
681
- if (tileCenter.longitude > 0.0) {
682
- splitRectangle.east = CesiumMath.PI;
683
- } else {
684
- splitRectangle.west = -CesiumMath.PI;
685
- }
686
- return splitRectangle;
687
- }
689
+ /**
690
+ * Determines the visibility of a given tile. The tile may be fully visible, partially visible, or not
691
+ * visible at all. Tiles that are renderable and are at least partially visible will be shown by a call
692
+ * to {@link GlobeSurfaceTileProvider#showTileThisFrame}.
693
+ *
694
+ * @param {QuadtreeTile} tile The tile instance.
695
+ * @param {FrameState} frameState The state information about the current frame.
696
+ * @param {QuadtreeOccluders} occluders The objects that may occlude this tile.
697
+ *
698
+ * @returns {Visibility} Visibility.NONE if the tile is not visible,
699
+ * Visibility.PARTIAL if the tile is partially visible, or
700
+ * Visibility.FULL if the tile is fully visible.
701
+ */
702
+ computeTileVisibility(tile, frameState, occluders) {
703
+ const distance = this.computeDistanceToTile(tile, frameState);
704
+ tile._distance = distance;
705
+
706
+ // Translated Columbus-world copies may be visible even when the tile's
707
+ // primary position is not. Resolve them up front so fog and frustum tests
708
+ // account for every copy, and use the nearest copy for LOD distance.
709
+ let columbusOffsets;
710
+ if (isColumbusRepeatActive(frameState)) {
711
+ columbusOffsets = computeColumbusTileWorldOffsets(this, tile, frameState);
712
+ if (defined(columbusOffsets)) {
713
+ if (columbusOffsets.length === 0) {
714
+ return Visibility.NONE;
715
+ }
716
+ tile._distance = nearestColumbusSphereDistance(
717
+ frameState.camera.positionWC,
718
+ columbusTileSphereScratch,
719
+ columbusOffsets,
720
+ );
721
+ }
722
+ }
688
723
 
689
- function isUndergroundVisible(tileProvider, frameState) {
690
- if (frameState.cameraUnderground) {
691
- return true;
692
- }
724
+ const undergroundVisible = isUndergroundVisible(this, frameState);
693
725
 
694
- if (frameState.globeTranslucencyState.translucent) {
695
- return true;
696
- }
726
+ if (frameState.fog.enabled && !undergroundVisible) {
727
+ if (CesiumMath.fog(tile._distance, frameState.fog.density) >= 1.0) {
728
+ // Tile is completely in fog so return that it is not visible.
729
+ return Visibility.NONE;
730
+ }
731
+ }
697
732
 
698
- if (tileProvider.backFaceCulling) {
699
- return false;
733
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
734
+ const tileBoundingRegion = surfaceTile.tileBoundingRegion;
735
+
736
+ if (surfaceTile.boundingVolumeSourceTile === undefined) {
737
+ // We have no idea where this tile is, so let's just call it partially visible.
738
+ return Visibility.PARTIAL;
739
+ }
740
+
741
+ const cullingVolume = frameState.cullingVolume;
742
+ // @ts-expect-error Missing types.
743
+ let boundingVolume = tileBoundingRegion.boundingVolume;
744
+
745
+ if (!defined(boundingVolume)) {
746
+ // @ts-expect-error Missing types.
747
+ boundingVolume = tileBoundingRegion.boundingSphere;
748
+ }
749
+
750
+ // Check if the tile is outside the limit area in cartographic space
751
+ surfaceTile.clippedByBoundaries = false;
752
+ const clippedCartographicLimitRectangle = clipRectangleAntimeridian(
753
+ tile.rectangle,
754
+ this.cartographicLimitRectangle,
755
+ );
756
+ const areaLimitIntersection = Rectangle.simpleIntersection(
757
+ clippedCartographicLimitRectangle,
758
+ tile.rectangle,
759
+ rectangleIntersectionScratch,
760
+ );
761
+ if (!defined(areaLimitIntersection)) {
762
+ return Visibility.NONE;
763
+ }
764
+ if (!Rectangle.equals(areaLimitIntersection, tile.rectangle)) {
765
+ surfaceTile.clippedByBoundaries = true;
766
+ }
767
+
768
+ if (frameState.mode !== SceneMode.SCENE3D) {
769
+ boundingVolume = boundingSphereScratch;
770
+ BoundingSphere.fromRectangleWithHeights2D(
771
+ tile.rectangle,
772
+ frameState.mapProjection,
773
+ tileBoundingRegion.minimumHeight,
774
+ tileBoundingRegion.maximumHeight,
775
+ boundingVolume,
776
+ );
777
+ Cartesian3.fromElements(
778
+ boundingVolume.center.z,
779
+ boundingVolume.center.x,
780
+ boundingVolume.center.y,
781
+ boundingVolume.center,
782
+ );
783
+
784
+ if (
785
+ frameState.mode === SceneMode.MORPHING &&
786
+ defined(surfaceTile.renderedMesh)
787
+ ) {
788
+ boundingVolume = BoundingSphere.union(
789
+ // @ts-expect-error Missing types.
790
+ tileBoundingRegion.boundingSphere,
791
+ boundingVolume,
792
+ boundingVolume,
793
+ );
794
+ }
795
+ }
796
+
797
+ if (!defined(boundingVolume)) {
798
+ return Visibility.PARTIAL;
799
+ }
800
+
801
+ const clippingPlanes = this._clippingPlanes;
802
+ // @ts-expect-error Missing types.
803
+ if (defined(clippingPlanes) && clippingPlanes.enabled) {
804
+ const planeIntersection =
805
+ clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume);
806
+ // @ts-expect-error Possibly an error? isClipped is defined on surfaceTile, not tile.
807
+ tile.isClipped = planeIntersection !== Intersect.INSIDE;
808
+ if (planeIntersection === Intersect.OUTSIDE) {
809
+ return Visibility.NONE;
810
+ }
811
+ }
812
+
813
+ const clippingPolygons = this._clippingPolygons;
814
+ if (defined(clippingPolygons) && clippingPolygons.enabled) {
815
+ const polygonIntersection =
816
+ clippingPolygons.computeIntersectionWithBoundingVolume(
817
+ tileBoundingRegion,
818
+ );
819
+ // @ts-expect-error Possibly an error? isClipped is defined on surfaceTile, not tile.
820
+ tile.isClipped = polygonIntersection !== Intersect.OUTSIDE;
821
+ // Polygon clipping intersections are determined by outer rectangles, therefore we cannot
822
+ // preemptively determine if a tile is completely clipped or not here.
823
+ }
824
+
825
+ let visibility;
826
+ const intersection = cullingVolume.computeVisibility(boundingVolume);
827
+
828
+ if (intersection === Intersect.OUTSIDE) {
829
+ visibility = Visibility.NONE;
830
+ } else if (intersection === Intersect.INTERSECTING) {
831
+ visibility = Visibility.PARTIAL;
832
+ } else if (intersection === Intersect.INSIDE) {
833
+ visibility = Visibility.FULL;
834
+ }
835
+
836
+ if (
837
+ visibility === Visibility.NONE &&
838
+ defined(columbusOffsets) &&
839
+ columbusOffsets.length > 0
840
+ ) {
841
+ // The primary tile is outside the frustum, but a translated copy is visible.
842
+ visibility = Visibility.PARTIAL;
843
+ }
844
+
845
+ if (visibility === Visibility.NONE) {
846
+ return visibility;
847
+ }
848
+
849
+ const ortho3D =
850
+ frameState.mode === SceneMode.SCENE3D &&
851
+ frameState.camera.frustum instanceof OrthographicFrustum;
852
+ if (
853
+ frameState.mode === SceneMode.SCENE3D &&
854
+ !ortho3D &&
855
+ defined(occluders) &&
856
+ !undergroundVisible
857
+ ) {
858
+ const occludeePointInScaledSpace = surfaceTile.occludeePointInScaledSpace;
859
+ if (!defined(occludeePointInScaledSpace)) {
860
+ return visibility;
861
+ }
862
+
863
+ if (
864
+ occluders.ellipsoid.isScaledSpacePointVisiblePossiblyUnderEllipsoid(
865
+ occludeePointInScaledSpace,
866
+ tileBoundingRegion.minimumHeight,
867
+ )
868
+ ) {
869
+ return visibility;
870
+ }
871
+
872
+ return Visibility.NONE;
873
+ }
874
+
875
+ return visibility;
700
876
  }
701
877
 
702
- const clippingPlanes = tileProvider._clippingPlanes;
703
- if (defined(clippingPlanes) && clippingPlanes.enabled) {
704
- return true;
878
+ /**
879
+ * Determines if the given tile can be refined
880
+ * @param {QuadtreeTile} tile The tile to check.
881
+ * @returns {boolean} True if the tile can be refined, false if it cannot.
882
+ */
883
+ canRefine(tile) {
884
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
885
+
886
+ // Only allow refinement it we know whether or not the children of this tile exist.
887
+ // For a tileset with `availability`, we'll always be able to refine.
888
+ // We can ask for availability of _any_ child tile because we only need to confirm
889
+ // that we get a yes or no answer, it doesn't matter what the answer is.
890
+ if (defined(surfaceTile.terrainData)) {
891
+ return true;
892
+ }
893
+ const childAvailable = this.terrainProvider.getTileDataAvailable(
894
+ // @ts-expect-error Missing types.
895
+ tile.x * 2,
896
+ tile.y * 2,
897
+ tile.level + 1,
898
+ );
899
+ return childAvailable !== undefined;
705
900
  }
706
901
 
707
- const clippingPolygons = tileProvider._clippingPolygons;
708
- if (defined(clippingPolygons) && clippingPolygons.enabled) {
902
+ /**
903
+ * Determines if the given not-fully-loaded tile can be rendered without losing detail that
904
+ * was present last frame as a result of rendering descendant tiles. This method will only be
905
+ * called if this tile's descendants were rendered last frame. If the tile is fully loaded,
906
+ * it is assumed that this method will return true and it will not be called.
907
+ * @param {QuadtreeTile} tile The tile to check.
908
+ * @returns {boolean} True if the tile can be rendered without losing detail.
909
+ */
910
+ canRenderWithoutLosingDetail(tile) {
911
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
912
+
913
+ const readyImagery = readyImageryScratch;
914
+ // @ts-expect-error Missing types.
915
+ readyImagery.length = this._imageryLayers.length;
916
+
917
+ let terrainReady = false;
918
+ let initialImageryState = false;
919
+ let imagery;
920
+
921
+ if (defined(surfaceTile)) {
922
+ // We can render even with non-ready terrain as long as all our rendered descendants
923
+ // are missing terrain geometry too. i.e. if we rendered fills for more detailed tiles
924
+ // last frame, it's ok to render a fill for this tile this frame.
925
+ terrainReady = surfaceTile.terrainState === TerrainState.READY;
926
+
927
+ // Initially assume all imagery layers are ready, unless imagery hasn't been initialized at all.
928
+ initialImageryState = true;
929
+
930
+ imagery = surfaceTile.imagery;
931
+ }
932
+
933
+ let i;
934
+ let len;
935
+
936
+ for (i = 0, len = readyImagery.length; i < len; ++i) {
937
+ readyImagery[i] = initialImageryState;
938
+ }
939
+
940
+ if (defined(imagery)) {
941
+ for (i = 0, len = imagery.length; i < len; ++i) {
942
+ const tileImagery = imagery[i];
943
+ const loadingImagery = tileImagery.loadingImagery;
944
+ const isReady =
945
+ !defined(loadingImagery) ||
946
+ loadingImagery.state === ImageryState.FAILED ||
947
+ loadingImagery.state === ImageryState.INVALID;
948
+ const layerIndex = (
949
+ tileImagery.loadingImagery || tileImagery.readyImagery
950
+ ).imageryLayer._layerIndex;
951
+
952
+ // For a layer to be ready, all tiles belonging to that layer must be ready.
953
+ readyImagery[layerIndex] = isReady && readyImagery[layerIndex];
954
+ }
955
+ }
956
+
957
+ const lastFrame = this.quadtree._lastSelectionFrameNumber;
958
+
959
+ // Traverse the descendants looking for one with terrain or imagery that is not loaded on this tile.
960
+ const stack = canRenderTraversalStack;
961
+ stack.length = 0;
962
+ stack.push(
963
+ tile.southwestChild,
964
+ tile.southeastChild,
965
+ tile.northwestChild,
966
+ tile.northeastChild,
967
+ );
968
+
969
+ while (stack.length > 0) {
970
+ const descendant = stack.pop();
971
+ const lastFrameSelectionResult =
972
+ descendant._lastSelectionResultFrame === lastFrame
973
+ ? descendant._lastSelectionResult
974
+ : TileSelectionResult.NONE;
975
+
976
+ if (lastFrameSelectionResult === TileSelectionResult.RENDERED) {
977
+ const descendantSurface = descendant.data;
978
+
979
+ if (!defined(descendantSurface)) {
980
+ // Descendant has no data, so it can't block rendering.
981
+ continue;
982
+ }
983
+
984
+ if (
985
+ !terrainReady &&
986
+ descendant.data.terrainState === TerrainState.READY
987
+ ) {
988
+ // Rendered descendant has real terrain, but we don't. Rendering is blocked.
989
+ return false;
990
+ }
991
+
992
+ const descendantImagery = descendant.data.imagery;
993
+ for (i = 0, len = descendantImagery.length; i < len; ++i) {
994
+ const descendantTileImagery = descendantImagery[i];
995
+ const descendantLoadingImagery = descendantTileImagery.loadingImagery;
996
+ const descendantIsReady =
997
+ !defined(descendantLoadingImagery) ||
998
+ descendantLoadingImagery.state === ImageryState.FAILED ||
999
+ descendantLoadingImagery.state === ImageryState.INVALID;
1000
+ const descendantLayerIndex = (
1001
+ descendantTileImagery.loadingImagery ||
1002
+ descendantTileImagery.readyImagery
1003
+ ).imageryLayer._layerIndex;
1004
+
1005
+ // If this imagery tile of a descendant is ready but the layer isn't ready in this tile,
1006
+ // then rendering is blocked.
1007
+ if (descendantIsReady && !readyImagery[descendantLayerIndex]) {
1008
+ return false;
1009
+ }
1010
+ }
1011
+ } else if (lastFrameSelectionResult === TileSelectionResult.REFINED) {
1012
+ stack.push(
1013
+ descendant.southwestChild,
1014
+ descendant.southeastChild,
1015
+ descendant.northwestChild,
1016
+ descendant.northeastChild,
1017
+ );
1018
+ }
1019
+ }
1020
+
709
1021
  return true;
710
1022
  }
711
1023
 
712
- if (
713
- !Rectangle.equals(
714
- tileProvider.cartographicLimitRectangle,
715
- Rectangle.MAX_VALUE,
716
- )
717
- ) {
718
- return true;
1024
+ /**
1025
+ * Determines the priority for loading this tile. Lower priority values load sooner.
1026
+ * @param {QuadtreeTile} tile The tile.
1027
+ * @param {FrameState} frameState The frame state.
1028
+ * @returns {number} The load priority value.
1029
+ */
1030
+ computeTileLoadPriority(tile, frameState) {
1031
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
1032
+ if (surfaceTile === undefined) {
1033
+ return 0.0;
1034
+ }
1035
+
1036
+ const obb = surfaceTile.tileBoundingRegion.boundingVolume;
1037
+ if (obb === undefined) {
1038
+ return 0.0;
1039
+ }
1040
+
1041
+ const cameraPosition = frameState.camera.positionWC;
1042
+ const cameraDirection = frameState.camera.directionWC;
1043
+ const tileDirection = Cartesian3.subtract(
1044
+ obb.center,
1045
+ cameraPosition,
1046
+ tileDirectionScratch,
1047
+ );
1048
+ const magnitude = Cartesian3.magnitude(tileDirection);
1049
+ if (magnitude < CesiumMath.EPSILON5) {
1050
+ return 0.0;
1051
+ }
1052
+ Cartesian3.divideByScalar(tileDirection, magnitude, tileDirection);
1053
+ return (
1054
+ (1.0 - Cartesian3.dot(tileDirection, cameraDirection)) * tile._distance
1055
+ );
719
1056
  }
720
1057
 
721
- return false;
722
- }
1058
+ /**
1059
+ * Shows a specified tile in this frame. The provider can cause the tile to be shown by adding
1060
+ * render commands to the commandList, or use any other method as appropriate. The tile is not
1061
+ * expected to be visible next frame as well, unless this method is called next frame, too.
1062
+ *
1063
+ * @param {QuadtreeTile} tile The tile instance.
1064
+ * @param {FrameState} frameState The state information of the current rendering frame.
1065
+ */
1066
+ showTileThisFrame(tile, frameState) {
1067
+ let readyTextureCount = 0;
1068
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
1069
+ const tileImageryCollection = surfaceTile.imagery;
1070
+ for (let i = 0, len = tileImageryCollection.length; i < len; ++i) {
1071
+ const tileImagery = tileImageryCollection[i];
1072
+ if (
1073
+ defined(tileImagery.readyImagery) &&
1074
+ tileImagery.readyImagery.imageryLayer.alpha !== 0.0
1075
+ ) {
1076
+ ++readyTextureCount;
1077
+ }
1078
+ }
723
1079
 
724
- /**
725
- * Determines the visibility of a given tile. The tile may be fully visible, partially visible, or not
726
- * visible at all. Tiles that are renderable and are at least partially visible will be shown by a call
727
- * to {@link GlobeSurfaceTileProvider#showTileThisFrame}.
728
- *
729
- * @param {QuadtreeTile} tile The tile instance.
730
- * @param {FrameState} frameState The state information about the current frame.
731
- * @param {QuadtreeOccluders} occluders The objects that may occlude this tile.
732
- *
733
- * @returns {Visibility} Visibility.NONE if the tile is not visible,
734
- * Visibility.PARTIAL if the tile is partially visible, or
735
- * Visibility.FULL if the tile is fully visible.
736
- */
737
- GlobeSurfaceTileProvider.prototype.computeTileVisibility = function (
738
- tile,
739
- frameState,
740
- occluders,
741
- ) {
742
- const distance = this.computeDistanceToTile(tile, frameState);
743
- tile._distance = distance;
1080
+ let tileSet = this._tilesToRenderByTextureCount[readyTextureCount];
1081
+ if (!defined(tileSet)) {
1082
+ tileSet = [];
1083
+ this._tilesToRenderByTextureCount[readyTextureCount] = tileSet;
1084
+ }
744
1085
 
745
- const undergroundVisible = isUndergroundVisible(this, frameState);
1086
+ tileSet.push(tile);
746
1087
 
747
- if (frameState.fog.enabled && !undergroundVisible) {
748
- if (CesiumMath.fog(distance, frameState.fog.density) >= 1.0) {
749
- // Tile is completely in fog so return that it is not visible.
750
- return Visibility.NONE;
1088
+ if (!defined(surfaceTile.vertexArray)) {
1089
+ this._hasFillTilesThisFrame = true;
1090
+ } else {
1091
+ this._hasLoadedTilesThisFrame = true;
751
1092
  }
1093
+
1094
+ const debug = this._debug;
1095
+ ++debug.tilesRendered;
1096
+ debug.texturesRendered += readyTextureCount;
752
1097
  }
753
1098
 
754
- const surfaceTile = tile.data;
755
- const tileBoundingRegion = surfaceTile.tileBoundingRegion;
1099
+ /**
1100
+ * Gets the distance from the camera to the closest point on the tile. This is used for level-of-detail selection.
1101
+ *
1102
+ * @param {QuadtreeTile} tile The tile instance.
1103
+ * @param {FrameState} frameState The state information of the current rendering frame.
1104
+ *
1105
+ * @returns {number} The distance from the camera to the closest point on the tile, in meters.
1106
+ */
1107
+ computeDistanceToTile(tile, frameState) {
1108
+ // The distance should be:
1109
+ // 1. the actual distance to the tight-fitting bounding volume, or
1110
+ // 2. a distance that is equal to or greater than the actual distance to the tight-fitting bounding volume.
1111
+ //
1112
+ // When we don't know the min/max heights for a tile, but we do know the min/max of an ancestor tile, we can
1113
+ // build a tight-fitting bounding volume horizontally, but not vertically. The min/max heights from the
1114
+ // ancestor will likely form a volume that is much bigger than it needs to be. This means that the volume may
1115
+ // be deemed to be much closer to the camera than it really is, causing us to select tiles that are too detailed.
1116
+ // Loading too-detailed tiles is super expensive, so we don't want to do that. We don't know where the child
1117
+ // tile really lies within the parent range of heights, but we _do_ know the child tile can't be any closer than
1118
+ // the ancestor height surface (min or max) that is _farthest away_ from the camera. So if we compute distance
1119
+ // based on that conservative metric, we may end up loading tiles that are not detailed enough, but that's much
1120
+ // better (faster) than loading tiles that are too detailed.
1121
+
1122
+ updateTileBoundingRegion(tile, this, frameState);
1123
+
1124
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
1125
+ const boundingVolumeSourceTile = surfaceTile.boundingVolumeSourceTile;
1126
+ if (boundingVolumeSourceTile === undefined) {
1127
+ // Can't find any min/max heights anywhere? Ok, let's just say the
1128
+ // tile is really far away so we'll load and render it rather than
1129
+ // refining.
1130
+ return 9999999999.0;
1131
+ }
756
1132
 
757
- if (surfaceTile.boundingVolumeSourceTile === undefined) {
758
- // We have no idea where this tile is, so let's just call it partially visible.
759
- return Visibility.PARTIAL;
760
- }
1133
+ const tileBoundingRegion = surfaceTile.tileBoundingRegion;
1134
+ const min = tileBoundingRegion.minimumHeight;
1135
+ const max = tileBoundingRegion.maximumHeight;
1136
+
1137
+ if (surfaceTile.boundingVolumeSourceTile !== tile) {
1138
+ const cameraHeight = frameState.camera.positionCartographic.height;
1139
+ const distanceToMin = Math.abs(cameraHeight - min);
1140
+ const distanceToMax = Math.abs(cameraHeight - max);
1141
+ if (distanceToMin > distanceToMax) {
1142
+ tileBoundingRegion.minimumHeight = min;
1143
+ tileBoundingRegion.maximumHeight = min;
1144
+ } else {
1145
+ tileBoundingRegion.minimumHeight = max;
1146
+ tileBoundingRegion.maximumHeight = max;
1147
+ }
1148
+ }
761
1149
 
762
- const cullingVolume = frameState.cullingVolume;
763
- let boundingVolume = tileBoundingRegion.boundingVolume;
1150
+ const result = tileBoundingRegion.distanceToCamera(frameState);
764
1151
 
765
- if (!defined(boundingVolume)) {
766
- boundingVolume = tileBoundingRegion.boundingSphere;
767
- }
1152
+ tileBoundingRegion.minimumHeight = min;
1153
+ tileBoundingRegion.maximumHeight = max;
768
1154
 
769
- // Check if the tile is outside the limit area in cartographic space
770
- surfaceTile.clippedByBoundaries = false;
771
- const clippedCartographicLimitRectangle = clipRectangleAntimeridian(
772
- tile.rectangle,
773
- this.cartographicLimitRectangle,
774
- );
775
- const areaLimitIntersection = Rectangle.simpleIntersection(
776
- clippedCartographicLimitRectangle,
777
- tile.rectangle,
778
- rectangleIntersectionScratch,
779
- );
780
- if (!defined(areaLimitIntersection)) {
781
- return Visibility.NONE;
1155
+ return result;
782
1156
  }
783
- if (!Rectangle.equals(areaLimitIntersection, tile.rectangle)) {
784
- surfaceTile.clippedByBoundaries = true;
1157
+
1158
+ /**
1159
+ * Returns true if this object was destroyed; otherwise, false.
1160
+ * <br /><br />
1161
+ * If this object was destroyed, it should not be used; calling any function other than
1162
+ * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
1163
+ *
1164
+ * @returns {boolean} True if this object was destroyed; otherwise, false.
1165
+ *
1166
+ * @see GlobeSurfaceTileProvider#destroy
1167
+ */
1168
+ isDestroyed() {
1169
+ return false;
785
1170
  }
786
1171
 
787
- if (frameState.mode !== SceneMode.SCENE3D) {
788
- boundingVolume = boundingSphereScratch;
789
- BoundingSphere.fromRectangleWithHeights2D(
790
- tile.rectangle,
791
- frameState.mapProjection,
792
- tileBoundingRegion.minimumHeight,
793
- tileBoundingRegion.maximumHeight,
794
- boundingVolume,
795
- );
796
- Cartesian3.fromElements(
797
- boundingVolume.center.z,
798
- boundingVolume.center.x,
799
- boundingVolume.center.y,
800
- boundingVolume.center,
801
- );
1172
+ /**
1173
+ * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
1174
+ * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
1175
+ * <br /><br />
1176
+ * Once an object is destroyed, it should not be used; calling any function other than
1177
+ * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
1178
+ * assign the return value (<code>undefined</code>) to the object as done in the example.
1179
+ *
1180
+ * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
1181
+ *
1182
+ *
1183
+ * @example
1184
+ * provider = provider && provider.destroy();
1185
+ *
1186
+ * @see GlobeSurfaceTileProvider#isDestroyed
1187
+ */
1188
+ destroy() {
1189
+ this._tileProvider = this._tileProvider && this._tileProvider.destroy();
1190
+ this._clippingPlanes =
1191
+ this._clippingPlanes && this._clippingPlanes.destroy();
1192
+ this._clippingPolygons =
1193
+ this._clippingPolygons && this._clippingPolygons.destroy();
1194
+ this._removeLayerAddedListener =
1195
+ this._removeLayerAddedListener && this._removeLayerAddedListener();
1196
+ this._removeLayerRemovedListener =
1197
+ this._removeLayerRemovedListener && this._removeLayerRemovedListener();
1198
+ this._removeLayerMovedListener =
1199
+ this._removeLayerMovedListener && this._removeLayerMovedListener();
1200
+ this._removeLayerShownListener =
1201
+ this._removeLayerShownListener && this._removeLayerShownListener();
1202
+
1203
+ return destroyObject(this);
1204
+ }
1205
+
1206
+ _onLayerAdded(layer, index) {
1207
+ if (this.isDestroyed()) {
1208
+ return;
1209
+ }
802
1210
 
803
- if (
804
- frameState.mode === SceneMode.MORPHING &&
805
- defined(surfaceTile.renderedMesh)
806
- ) {
807
- boundingVolume = BoundingSphere.union(
808
- tileBoundingRegion.boundingSphere,
809
- boundingVolume,
810
- boundingVolume,
811
- );
1211
+ if (layer.show) {
1212
+ const terrainProvider = this._terrainProvider;
1213
+
1214
+ const that = this;
1215
+ const tileImageryUpdatedEvent = this._imageryLayersUpdatedEvent;
1216
+ const reloadFunction = function () {
1217
+ // Clear the layer's cache
1218
+ layer._imageryCache = {};
1219
+
1220
+ that._quadtree.forEachLoadedTile(function (tile) {
1221
+ // If this layer is still waiting to for the loaded callback, just return
1222
+ if (defined(tile._loadedCallbacks[layer._layerIndex])) {
1223
+ return;
1224
+ }
1225
+
1226
+ let i;
1227
+
1228
+ // Figure out how many TileImageries we will need to remove and where to insert new ones
1229
+ const tileImageryCollection = tile.data.imagery;
1230
+ const length = tileImageryCollection.length;
1231
+ let startIndex = -1;
1232
+ let tileImageriesToFree = 0;
1233
+ for (i = 0; i < length; ++i) {
1234
+ const tileImagery = tileImageryCollection[i];
1235
+ const imagery =
1236
+ tileImagery.readyImagery ?? tileImagery.loadingImagery;
1237
+ if (imagery.imageryLayer === layer) {
1238
+ if (startIndex === -1) {
1239
+ startIndex = i;
1240
+ }
1241
+
1242
+ ++tileImageriesToFree;
1243
+ } else if (startIndex !== -1) {
1244
+ // iterated past the section of TileImageries belonging to this layer, no need to continue.
1245
+ break;
1246
+ }
1247
+ }
1248
+
1249
+ if (startIndex === -1) {
1250
+ return;
1251
+ }
1252
+
1253
+ // Insert immediately after existing TileImageries
1254
+ const insertionPoint = startIndex + tileImageriesToFree;
1255
+
1256
+ // Create new TileImageries for all loaded tiles
1257
+ if (
1258
+ layer._createTileImagerySkeletons(
1259
+ tile,
1260
+ terrainProvider,
1261
+ insertionPoint,
1262
+ )
1263
+ ) {
1264
+ // Add callback to remove old TileImageries when the new TileImageries are ready
1265
+ tile._loadedCallbacks[layer._layerIndex] = getTileReadyCallback(
1266
+ tileImageriesToFree,
1267
+ layer,
1268
+ terrainProvider,
1269
+ );
1270
+
1271
+ tile.state = QuadtreeTileLoadState.LOADING;
1272
+ }
1273
+ });
1274
+ };
1275
+
1276
+ if (layer.ready) {
1277
+ const imageryProvider = layer.imageryProvider;
1278
+ imageryProvider._reload = reloadFunction;
1279
+ }
1280
+
1281
+ // create TileImageries for this layer for all previously loaded tiles
1282
+ this._quadtree.forEachLoadedTile(function (tile) {
1283
+ if (layer._createTileImagerySkeletons(tile, terrainProvider)) {
1284
+ tile.state = QuadtreeTileLoadState.LOADING;
1285
+
1286
+ // Tiles that are not currently being rendered need to load the new layer before they're renderable.
1287
+ // We don't mark the rendered tiles non-renderable, though, because that would make the globe disappear.
1288
+ if (
1289
+ tile.level !== 0 &&
1290
+ (tile._lastSelectionResultFrame !==
1291
+ that.quadtree._lastSelectionFrameNumber ||
1292
+ tile._lastSelectionResult !== TileSelectionResult.RENDERED)
1293
+ ) {
1294
+ tile.renderable = false;
1295
+ }
1296
+ }
1297
+ });
1298
+
1299
+ this._layerOrderChanged = true;
1300
+ tileImageryUpdatedEvent.raiseEvent();
812
1301
  }
813
1302
  }
814
1303
 
815
- if (!defined(boundingVolume)) {
816
- return Visibility.PARTIAL;
817
- }
1304
+ _onLayerRemoved(layer, index) {
1305
+ // destroy TileImagerys for this layer for all previously loaded tiles
1306
+ this._quadtree.forEachLoadedTile(function (tile) {
1307
+ const tileImageryCollection = tile.data.imagery;
1308
+
1309
+ let startIndex = -1;
1310
+ let numDestroyed = 0;
1311
+ for (let i = 0, len = tileImageryCollection.length; i < len; ++i) {
1312
+ const tileImagery = tileImageryCollection[i];
1313
+ let imagery = tileImagery.loadingImagery;
1314
+ if (!defined(imagery)) {
1315
+ imagery = tileImagery.readyImagery;
1316
+ }
1317
+ if (imagery.imageryLayer === layer) {
1318
+ if (startIndex === -1) {
1319
+ startIndex = i;
1320
+ }
818
1321
 
819
- const clippingPlanes = this._clippingPlanes;
820
- if (defined(clippingPlanes) && clippingPlanes.enabled) {
821
- const planeIntersection =
822
- clippingPlanes.computeIntersectionWithBoundingVolume(boundingVolume);
823
- tile.isClipped = planeIntersection !== Intersect.INSIDE;
824
- if (planeIntersection === Intersect.OUTSIDE) {
825
- return Visibility.NONE;
1322
+ tileImagery.freeResources();
1323
+ ++numDestroyed;
1324
+ } else if (startIndex !== -1) {
1325
+ // iterated past the section of TileImagerys belonging to this layer, no need to continue.
1326
+ break;
1327
+ }
1328
+ }
1329
+
1330
+ if (startIndex !== -1) {
1331
+ tileImageryCollection.splice(startIndex, numDestroyed);
1332
+ }
1333
+ });
1334
+
1335
+ if (defined(layer.imageryProvider)) {
1336
+ layer.imageryProvider._reload = undefined;
826
1337
  }
1338
+
1339
+ this._imageryLayersUpdatedEvent.raiseEvent();
827
1340
  }
828
1341
 
829
- const clippingPolygons = this._clippingPolygons;
830
- if (defined(clippingPolygons) && clippingPolygons.enabled) {
831
- const polygonIntersection =
832
- clippingPolygons.computeIntersectionWithBoundingVolume(
833
- tileBoundingRegion,
834
- );
835
- tile.isClipped = polygonIntersection !== Intersect.OUTSIDE;
836
- // Polygon clipping intersections are determined by outer rectangles, therefore we cannot
837
- // preemptively determine if a tile is completely clipped or not here.
1342
+ _onLayerMoved(layer, newIndex, oldIndex) {
1343
+ this._layerOrderChanged = true;
1344
+ this._imageryLayersUpdatedEvent.raiseEvent();
838
1345
  }
839
1346
 
840
- let visibility;
841
- const intersection = cullingVolume.computeVisibility(boundingVolume);
1347
+ _onLayerShownOrHidden(layer, index, show) {
1348
+ if (show) {
1349
+ this._onLayerAdded(layer, index);
1350
+ } else {
1351
+ this._onLayerRemoved(layer, index);
1352
+ }
1353
+ }
1354
+ }
842
1355
 
843
- if (intersection === Intersect.OUTSIDE) {
844
- visibility = Visibility.NONE;
845
- } else if (intersection === Intersect.INTERSECTING) {
846
- visibility = Visibility.PARTIAL;
847
- } else if (intersection === Intersect.INSIDE) {
848
- visibility = Visibility.FULL;
1356
+ function sortTileImageryByLayerIndex(a, b) {
1357
+ let aImagery = a.loadingImagery;
1358
+ if (!defined(aImagery)) {
1359
+ aImagery = a.readyImagery;
849
1360
  }
850
1361
 
851
- if (visibility === Visibility.NONE) {
852
- return visibility;
1362
+ let bImagery = b.loadingImagery;
1363
+ if (!defined(bImagery)) {
1364
+ bImagery = b.readyImagery;
853
1365
  }
854
1366
 
855
- const ortho3D =
856
- frameState.mode === SceneMode.SCENE3D &&
857
- frameState.camera.frustum instanceof OrthographicFrustum;
858
- if (
859
- frameState.mode === SceneMode.SCENE3D &&
860
- !ortho3D &&
861
- defined(occluders) &&
862
- !undergroundVisible
863
- ) {
864
- const occludeePointInScaledSpace = surfaceTile.occludeePointInScaledSpace;
865
- if (!defined(occludeePointInScaledSpace)) {
866
- return visibility;
867
- }
1367
+ return aImagery.imageryLayer._layerIndex - bImagery.imageryLayer._layerIndex;
1368
+ }
868
1369
 
869
- if (
870
- occluders.ellipsoid.isScaledSpacePointVisiblePossiblyUnderEllipsoid(
871
- occludeePointInScaledSpace,
872
- tileBoundingRegion.minimumHeight,
873
- )
874
- ) {
875
- return visibility;
1370
+ /**
1371
+ * @param {GlobeSurfaceTileProvider} surface
1372
+ * @param {FrameState} frameState
1373
+ * @ignore
1374
+ */
1375
+ function updateCredits(surface, frameState) {
1376
+ const creditDisplay = frameState.creditDisplay;
1377
+ const terrainProvider = surface._terrainProvider;
1378
+ // @ts-expect-error Missing types.
1379
+ if (defined(terrainProvider) && defined(terrainProvider.credit)) {
1380
+ // @ts-expect-error Missing types.
1381
+ creditDisplay.addCreditToNextFrame(terrainProvider.credit);
1382
+ }
1383
+
1384
+ const imageryLayers = surface._imageryLayers;
1385
+ // @ts-expect-error Missing types.
1386
+ for (let i = 0, len = imageryLayers.length; i < len; ++i) {
1387
+ const layer = imageryLayers.get(i);
1388
+ // @ts-expect-error Missing types.
1389
+ if (layer.ready && layer.show && defined(layer.imageryProvider.credit)) {
1390
+ // @ts-expect-error Missing types.
1391
+ creditDisplay.addCreditToNextFrame(layer.imageryProvider.credit);
876
1392
  }
1393
+ }
1394
+ }
877
1395
 
878
- return Visibility.NONE;
1396
+ /**
1397
+ * @param {DrawCommand} command
1398
+ * @param {FrameState} frameState
1399
+ * @ignore
1400
+ */
1401
+ function pushCommand(command, frameState) {
1402
+ const globeTranslucencyState = frameState.globeTranslucencyState;
1403
+ if (globeTranslucencyState.translucent) {
1404
+ // @ts-expect-error Missing types.
1405
+ const isBlendCommand = command.renderState.blending.enabled;
1406
+ globeTranslucencyState.pushDerivedCommands(
1407
+ command,
1408
+ isBlendCommand,
1409
+ frameState,
1410
+ );
1411
+ } else {
1412
+ frameState.commandList.push(command);
879
1413
  }
1414
+ }
880
1415
 
881
- return visibility;
882
- };
1416
+ const boundingSphereScratch = new BoundingSphere();
1417
+ const rectangleIntersectionScratch = new Rectangle();
1418
+ const splitCartographicLimitRectangleScratch = new Rectangle();
1419
+ const rectangleCenterScratch = new Cartographic();
883
1420
 
884
1421
  /**
885
- * Determines if the given tile can be refined
886
- * @param {QuadtreeTile} tile The tile to check.
887
- * @returns {boolean} True if the tile can be refined, false if it cannot.
1422
+ * @param {Rectangle} tileRectangle
1423
+ * @param {Rectangle} cartographicLimitRectangle
1424
+ * @ignore
888
1425
  */
889
- GlobeSurfaceTileProvider.prototype.canRefine = function (tile) {
890
- // Only allow refinement it we know whether or not the children of this tile exist.
891
- // For a tileset with `availability`, we'll always be able to refine.
892
- // We can ask for availability of _any_ child tile because we only need to confirm
893
- // that we get a yes or no answer, it doesn't matter what the answer is.
894
- if (defined(tile.data.terrainData)) {
895
- return true;
1426
+ function clipRectangleAntimeridian(tileRectangle, cartographicLimitRectangle) {
1427
+ // cartographicLimitRectangle may span the IDL, but tiles never will.
1428
+ if (cartographicLimitRectangle.west < cartographicLimitRectangle.east) {
1429
+ return cartographicLimitRectangle;
896
1430
  }
897
- const childAvailable = this.terrainProvider.getTileDataAvailable(
898
- tile.x * 2,
899
- tile.y * 2,
900
- tile.level + 1,
1431
+ const splitRectangle = Rectangle.clone(
1432
+ cartographicLimitRectangle,
1433
+ splitCartographicLimitRectangleScratch,
901
1434
  );
902
- return childAvailable !== undefined;
903
- };
904
-
905
- const readyImageryScratch = [];
906
- const canRenderTraversalStack = [];
1435
+ const tileCenter = Rectangle.center(tileRectangle, rectangleCenterScratch);
1436
+ if (tileCenter.longitude > 0.0) {
1437
+ splitRectangle.east = CesiumMath.PI;
1438
+ } else {
1439
+ splitRectangle.west = -CesiumMath.PI;
1440
+ }
1441
+ return splitRectangle;
1442
+ }
907
1443
 
908
1444
  /**
909
- * Determines if the given not-fully-loaded tile can be rendered without losing detail that
910
- * was present last frame as a result of rendering descendant tiles. This method will only be
911
- * called if this tile's descendants were rendered last frame. If the tile is fully loaded,
912
- * it is assumed that this method will return true and it will not be called.
913
- * @param {QuadtreeTile} tile The tile to check.
914
- * @returns {boolean} True if the tile can be rendered without losing detail.
1445
+ * @param {GlobeSurfaceTileProvider} tileProvider
1446
+ * @param {FrameState} frameState
1447
+ * @ignore
915
1448
  */
916
- GlobeSurfaceTileProvider.prototype.canRenderWithoutLosingDetail = function (
917
- tile,
918
- frameState,
919
- ) {
920
- const surfaceTile = tile.data;
921
-
922
- const readyImagery = readyImageryScratch;
923
- readyImagery.length = this._imageryLayers.length;
924
-
925
- let terrainReady = false;
926
- let initialImageryState = false;
927
- let imagery;
928
-
929
- if (defined(surfaceTile)) {
930
- // We can render even with non-ready terrain as long as all our rendered descendants
931
- // are missing terrain geometry too. i.e. if we rendered fills for more detailed tiles
932
- // last frame, it's ok to render a fill for this tile this frame.
933
- terrainReady = surfaceTile.terrainState === TerrainState.READY;
934
-
935
- // Initially assume all imagery layers are ready, unless imagery hasn't been initialized at all.
936
- initialImageryState = true;
937
-
938
- imagery = surfaceTile.imagery;
1449
+ function isUndergroundVisible(tileProvider, frameState) {
1450
+ if (frameState.cameraUnderground) {
1451
+ return true;
939
1452
  }
940
1453
 
941
- let i;
942
- let len;
943
-
944
- for (i = 0, len = readyImagery.length; i < len; ++i) {
945
- readyImagery[i] = initialImageryState;
1454
+ if (frameState.globeTranslucencyState.translucent) {
1455
+ return true;
946
1456
  }
947
1457
 
948
- if (defined(imagery)) {
949
- for (i = 0, len = imagery.length; i < len; ++i) {
950
- const tileImagery = imagery[i];
951
- const loadingImagery = tileImagery.loadingImagery;
952
- const isReady =
953
- !defined(loadingImagery) ||
954
- loadingImagery.state === ImageryState.FAILED ||
955
- loadingImagery.state === ImageryState.INVALID;
956
- const layerIndex = (
957
- tileImagery.loadingImagery || tileImagery.readyImagery
958
- ).imageryLayer._layerIndex;
959
-
960
- // For a layer to be ready, all tiles belonging to that layer must be ready.
961
- readyImagery[layerIndex] = isReady && readyImagery[layerIndex];
962
- }
1458
+ if (tileProvider.backFaceCulling) {
1459
+ return false;
963
1460
  }
964
1461
 
965
- const lastFrame = this.quadtree._lastSelectionFrameNumber;
966
-
967
- // Traverse the descendants looking for one with terrain or imagery that is not loaded on this tile.
968
- const stack = canRenderTraversalStack;
969
- stack.length = 0;
970
- stack.push(
971
- tile.southwestChild,
972
- tile.southeastChild,
973
- tile.northwestChild,
974
- tile.northeastChild,
975
- );
976
-
977
- while (stack.length > 0) {
978
- const descendant = stack.pop();
979
- const lastFrameSelectionResult =
980
- descendant._lastSelectionResultFrame === lastFrame
981
- ? descendant._lastSelectionResult
982
- : TileSelectionResult.NONE;
983
-
984
- if (lastFrameSelectionResult === TileSelectionResult.RENDERED) {
985
- const descendantSurface = descendant.data;
986
-
987
- if (!defined(descendantSurface)) {
988
- // Descendant has no data, so it can't block rendering.
989
- continue;
990
- }
991
-
992
- if (
993
- !terrainReady &&
994
- descendant.data.terrainState === TerrainState.READY
995
- ) {
996
- // Rendered descendant has real terrain, but we don't. Rendering is blocked.
997
- return false;
998
- }
999
-
1000
- const descendantImagery = descendant.data.imagery;
1001
- for (i = 0, len = descendantImagery.length; i < len; ++i) {
1002
- const descendantTileImagery = descendantImagery[i];
1003
- const descendantLoadingImagery = descendantTileImagery.loadingImagery;
1004
- const descendantIsReady =
1005
- !defined(descendantLoadingImagery) ||
1006
- descendantLoadingImagery.state === ImageryState.FAILED ||
1007
- descendantLoadingImagery.state === ImageryState.INVALID;
1008
- const descendantLayerIndex = (
1009
- descendantTileImagery.loadingImagery ||
1010
- descendantTileImagery.readyImagery
1011
- ).imageryLayer._layerIndex;
1012
-
1013
- // If this imagery tile of a descendant is ready but the layer isn't ready in this tile,
1014
- // then rendering is blocked.
1015
- if (descendantIsReady && !readyImagery[descendantLayerIndex]) {
1016
- return false;
1017
- }
1018
- }
1019
- } else if (lastFrameSelectionResult === TileSelectionResult.REFINED) {
1020
- stack.push(
1021
- descendant.southwestChild,
1022
- descendant.southeastChild,
1023
- descendant.northwestChild,
1024
- descendant.northeastChild,
1025
- );
1026
- }
1462
+ const clippingPlanes = tileProvider._clippingPlanes;
1463
+ if (defined(clippingPlanes) && clippingPlanes.enabled) {
1464
+ return true;
1027
1465
  }
1028
1466
 
1029
- return true;
1030
- };
1031
-
1032
- const tileDirectionScratch = new Cartesian3();
1033
-
1034
- /**
1035
- * Determines the priority for loading this tile. Lower priority values load sooner.
1036
- * @param {QuadtreeTile} tile The tile.
1037
- * @param {FrameState} frameState The frame state.
1038
- * @returns {number} The load priority value.
1039
- */
1040
- GlobeSurfaceTileProvider.prototype.computeTileLoadPriority = function (
1041
- tile,
1042
- frameState,
1043
- ) {
1044
- const surfaceTile = tile.data;
1045
- if (surfaceTile === undefined) {
1046
- return 0.0;
1467
+ const clippingPolygons = tileProvider._clippingPolygons;
1468
+ if (defined(clippingPolygons) && clippingPolygons.enabled) {
1469
+ return true;
1047
1470
  }
1048
1471
 
1049
- const obb = surfaceTile.tileBoundingRegion.boundingVolume;
1050
- if (obb === undefined) {
1051
- return 0.0;
1472
+ if (
1473
+ !Rectangle.equals(
1474
+ tileProvider.cartographicLimitRectangle,
1475
+ Rectangle.MAX_VALUE,
1476
+ )
1477
+ ) {
1478
+ return true;
1052
1479
  }
1053
1480
 
1054
- const cameraPosition = frameState.camera.positionWC;
1055
- const cameraDirection = frameState.camera.directionWC;
1056
- const tileDirection = Cartesian3.subtract(
1057
- obb.center,
1058
- cameraPosition,
1059
- tileDirectionScratch,
1060
- );
1061
- const magnitude = Cartesian3.magnitude(tileDirection);
1062
- if (magnitude < CesiumMath.EPSILON5) {
1063
- return 0.0;
1064
- }
1065
- Cartesian3.divideByScalar(tileDirection, magnitude, tileDirection);
1066
- return (
1067
- (1.0 - Cartesian3.dot(tileDirection, cameraDirection)) * tile._distance
1068
- );
1069
- };
1481
+ return false;
1482
+ }
1483
+
1484
+ const readyImageryScratch = [];
1485
+ const canRenderTraversalStack = [];
1486
+
1487
+ const tileDirectionScratch = new Cartesian3();
1070
1488
 
1071
1489
  const modifiedModelViewScratch = new Matrix4();
1072
1490
  const modifiedModelViewProjectionScratch = new Matrix4();
@@ -1078,49 +1496,142 @@ const centerEyeScratch = new Cartesian3();
1078
1496
  const southwestScratch = new Cartesian3();
1079
1497
  const northeastScratch = new Cartesian3();
1080
1498
 
1499
+ // How many world copies to test and render on either side of the camera's
1500
+ // own world when Columbus repeat worlds are enabled. Five visible worlds is
1501
+ // far beyond any practical viewport while bounding worst-case command count.
1502
+ const COLUMBUS_MAX_EXTRA_WORLDS = 2;
1503
+
1504
+ const columbusRepeatSphereScratch = new BoundingSphere();
1505
+ const columbusNearestCenterScratch = new Cartesian3();
1506
+
1507
+ const DEFAULT_COLUMBUS_WORLD_OFFSETS = [0.0];
1508
+ const COLUMBUS_VISIBILITY_WORLD_OFFSETS = [];
1509
+
1510
+ /**
1511
+ * Whether repeat worlds are enabled for this frame. Supported in 2D and
1512
+ * Columbus View; other modes never repeat.
1513
+ *
1514
+ * @private
1515
+ */
1516
+ function isColumbusRepeatActive(frameState) {
1517
+ return (
1518
+ frameState.columbusRepeatWorlds === true &&
1519
+ (frameState.mode === SceneMode.SCENE2D ||
1520
+ frameState.mode === SceneMode.COLUMBUS_VIEW)
1521
+ );
1522
+ }
1523
+
1524
+ /**
1525
+ * The projected width, in meters, of one full world (360° of longitude) under
1526
+ * the scene's map projection. Cached per projection instance.
1527
+ *
1528
+ * @private
1529
+ */
1530
+ function getColumbusWorldWidth(tileProvider, frameState) {
1531
+ return ColumbusWorlds.getWorldWidth(frameState.mapProjection);
1532
+ }
1533
+
1081
1534
  /**
1082
- * Shows a specified tile in this frame. The provider can cause the tile to be shown by adding
1083
- * render commands to the commandList, or use any other method as appropriate. The tile is not
1084
- * expected to be visible next frame as well, unless this method is called next frame, too.
1535
+ * Computes the world offsets, in projected meters, at which translated copies
1536
+ * of the given Columbus-view bounding sphere are visible. Offset 0 (the tile
1537
+ * itself) is only included when the sphere is visible. The result is a shared
1538
+ * scratch array; consume it before this is called again.
1085
1539
  *
1086
- * @param {QuadtreeTile} tile The tile instance.
1087
- * @param {FrameState} frameState The state information of the current rendering frame.
1540
+ * @private
1088
1541
  */
1089
- GlobeSurfaceTileProvider.prototype.showTileThisFrame = function (
1090
- tile,
1091
- frameState,
1542
+ function computeColumbusWorldOffsets(
1543
+ sphere,
1544
+ cullingVolume,
1545
+ cameraY,
1546
+ worldWidth,
1547
+ result,
1092
1548
  ) {
1093
- let readyTextureCount = 0;
1094
- const tileImageryCollection = tile.data.imagery;
1095
- for (let i = 0, len = tileImageryCollection.length; i < len; ++i) {
1096
- const tileImagery = tileImageryCollection[i];
1097
- if (
1098
- defined(tileImagery.readyImagery) &&
1099
- tileImagery.readyImagery.imageryLayer.alpha !== 0.0
1100
- ) {
1101
- ++readyTextureCount;
1549
+ result.length = 0;
1550
+ const cameraWorld = Math.round(cameraY / worldWidth);
1551
+ const testSphere = columbusRepeatSphereScratch;
1552
+ for (
1553
+ let w = cameraWorld - COLUMBUS_MAX_EXTRA_WORLDS;
1554
+ w <= cameraWorld + COLUMBUS_MAX_EXTRA_WORLDS;
1555
+ ++w
1556
+ ) {
1557
+ const offset = w * worldWidth;
1558
+ Cartesian3.clone(sphere.center, testSphere.center);
1559
+ testSphere.center.y += offset;
1560
+ testSphere.radius = sphere.radius;
1561
+ if (cullingVolume.computeVisibility(testSphere) !== Intersect.OUTSIDE) {
1562
+ result.push(offset);
1102
1563
  }
1103
1564
  }
1565
+ return result;
1566
+ }
1104
1567
 
1105
- let tileSet = this._tilesToRenderByTextureCount[readyTextureCount];
1106
- if (!defined(tileSet)) {
1107
- tileSet = [];
1108
- this._tilesToRenderByTextureCount[readyTextureCount] = tileSet;
1568
+ /**
1569
+ * Distance from the camera to the nearest visible copy of the given sphere,
1570
+ * used for LOD (SSE) and fog so a copy rendered under the camera is treated
1571
+ * as near even though the tile's primary position is a world away.
1572
+ *
1573
+ * @private
1574
+ */
1575
+ function nearestColumbusSphereDistance(cameraPosition, sphere, offsets) {
1576
+ let nearest = Number.POSITIVE_INFINITY;
1577
+ const center = columbusNearestCenterScratch;
1578
+ for (let i = 0; i < offsets.length; ++i) {
1579
+ Cartesian3.clone(sphere.center, center);
1580
+ center.y += offsets[i];
1581
+ nearest = Math.min(
1582
+ nearest,
1583
+ Math.max(
1584
+ 0.0,
1585
+ Cartesian3.distance(cameraPosition, center) - sphere.radius,
1586
+ ),
1587
+ );
1109
1588
  }
1589
+ return nearest;
1590
+ }
1110
1591
 
1111
- tileSet.push(tile);
1592
+ const columbusTileSphereScratch = new BoundingSphere();
1112
1593
 
1594
+ /**
1595
+ * Builds the Columbus-view (height, u, v) bounding sphere for a tile and
1596
+ * computes which world copies of it are visible. Returns undefined when the
1597
+ * tile's min/max heights are not known yet; returns an empty array when
1598
+ * neither the tile nor any copy is visible. The sphere is left in
1599
+ * columbusTileSphereScratch for immediate distance computations.
1600
+ *
1601
+ * @private
1602
+ */
1603
+ function computeColumbusTileWorldOffsets(tileProvider, tile, frameState) {
1113
1604
  const surfaceTile = tile.data;
1114
- if (!defined(surfaceTile.vertexArray)) {
1115
- this._hasFillTilesThisFrame = true;
1116
- } else {
1117
- this._hasLoadedTilesThisFrame = true;
1605
+ const tileBoundingRegion = surfaceTile.tileBoundingRegion;
1606
+ if (
1607
+ surfaceTile.boundingVolumeSourceTile === undefined ||
1608
+ !defined(tileBoundingRegion)
1609
+ ) {
1610
+ return undefined;
1118
1611
  }
1119
-
1120
- const debug = this._debug;
1121
- ++debug.tilesRendered;
1122
- debug.texturesRendered += readyTextureCount;
1123
- };
1612
+ const sphere = BoundingSphere.fromRectangleWithHeights2D(
1613
+ tile.rectangle,
1614
+ frameState.mapProjection,
1615
+ tileBoundingRegion.minimumHeight,
1616
+ tileBoundingRegion.maximumHeight,
1617
+ columbusTileSphereScratch,
1618
+ );
1619
+ // fromRectangleWithHeights2D returns the sphere in projected
1620
+ // (u, v, height) order; shuffle to the Columbus world axes (height, u, v).
1621
+ Cartesian3.fromElements(
1622
+ sphere.center.z,
1623
+ sphere.center.x,
1624
+ sphere.center.y,
1625
+ sphere.center,
1626
+ );
1627
+ return computeColumbusWorldOffsets(
1628
+ sphere,
1629
+ frameState.cullingVolume,
1630
+ frameState.camera.positionWC.y,
1631
+ getColumbusWorldWidth(tileProvider, frameState),
1632
+ COLUMBUS_VISIBILITY_WORLD_OFFSETS,
1633
+ );
1634
+ }
1124
1635
 
1125
1636
  const cornerPositionsScratch = [
1126
1637
  new Cartesian3(),
@@ -1137,7 +1648,9 @@ function computeOccludeePoint(
1137
1648
  maximumHeight,
1138
1649
  result,
1139
1650
  ) {
1651
+ /** @type {EllipsoidalOccluder} */
1140
1652
  const ellipsoidalOccluder = tileProvider.quadtree._occluders.ellipsoid;
1653
+ // @ts-expect-error Missing types.
1141
1654
  const ellipsoid = ellipsoidalOccluder.ellipsoid;
1142
1655
 
1143
1656
  const cornerPositions = cornerPositionsScratch;
@@ -1179,69 +1692,13 @@ function computeOccludeePoint(
1179
1692
  }
1180
1693
 
1181
1694
  /**
1182
- * Gets the distance from the camera to the closest point on the tile. This is used for level-of-detail selection.
1183
- *
1184
- * @param {QuadtreeTile} tile The tile instance.
1185
- * @param {FrameState} frameState The state information of the current rendering frame.
1186
- *
1187
- * @returns {number} The distance from the camera to the closest point on the tile, in meters.
1695
+ * @param {QuadtreeTile} tile
1696
+ * @param {GlobeSurfaceTileProvider} tileProvider
1697
+ * @param {FrameState} frameState
1698
+ * @ignore
1188
1699
  */
1189
- GlobeSurfaceTileProvider.prototype.computeDistanceToTile = function (
1190
- tile,
1191
- frameState,
1192
- ) {
1193
- // The distance should be:
1194
- // 1. the actual distance to the tight-fitting bounding volume, or
1195
- // 2. a distance that is equal to or greater than the actual distance to the tight-fitting bounding volume.
1196
- //
1197
- // When we don't know the min/max heights for a tile, but we do know the min/max of an ancestor tile, we can
1198
- // build a tight-fitting bounding volume horizontally, but not vertically. The min/max heights from the
1199
- // ancestor will likely form a volume that is much bigger than it needs to be. This means that the volume may
1200
- // be deemed to be much closer to the camera than it really is, causing us to select tiles that are too detailed.
1201
- // Loading too-detailed tiles is super expensive, so we don't want to do that. We don't know where the child
1202
- // tile really lies within the parent range of heights, but we _do_ know the child tile can't be any closer than
1203
- // the ancestor height surface (min or max) that is _farthest away_ from the camera. So if we compute distance
1204
- // based on that conservative metric, we may end up loading tiles that are not detailed enough, but that's much
1205
- // better (faster) than loading tiles that are too detailed.
1206
-
1207
- updateTileBoundingRegion(tile, this, frameState);
1208
-
1209
- const surfaceTile = tile.data;
1210
- const boundingVolumeSourceTile = surfaceTile.boundingVolumeSourceTile;
1211
- if (boundingVolumeSourceTile === undefined) {
1212
- // Can't find any min/max heights anywhere? Ok, let's just say the
1213
- // tile is really far away so we'll load and render it rather than
1214
- // refining.
1215
- return 9999999999.0;
1216
- }
1217
-
1218
- const tileBoundingRegion = surfaceTile.tileBoundingRegion;
1219
- const min = tileBoundingRegion.minimumHeight;
1220
- const max = tileBoundingRegion.maximumHeight;
1221
-
1222
- if (surfaceTile.boundingVolumeSourceTile !== tile) {
1223
- const cameraHeight = frameState.camera.positionCartographic.height;
1224
- const distanceToMin = Math.abs(cameraHeight - min);
1225
- const distanceToMax = Math.abs(cameraHeight - max);
1226
- if (distanceToMin > distanceToMax) {
1227
- tileBoundingRegion.minimumHeight = min;
1228
- tileBoundingRegion.maximumHeight = min;
1229
- } else {
1230
- tileBoundingRegion.minimumHeight = max;
1231
- tileBoundingRegion.maximumHeight = max;
1232
- }
1233
- }
1234
-
1235
- const result = tileBoundingRegion.distanceToCamera(frameState);
1236
-
1237
- tileBoundingRegion.minimumHeight = min;
1238
- tileBoundingRegion.maximumHeight = max;
1239
-
1240
- return result;
1241
- };
1242
-
1243
1700
  function updateTileBoundingRegion(tile, tileProvider, frameState) {
1244
- let surfaceTile = tile.data;
1701
+ let surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
1245
1702
  if (surfaceTile === undefined) {
1246
1703
  surfaceTile = tile.data = new GlobeSurfaceTile();
1247
1704
  }
@@ -1291,7 +1748,9 @@ function updateTileBoundingRegion(tile, tileProvider, frameState) {
1291
1748
 
1292
1749
  let ancestorTile = tile.parent;
1293
1750
  while (ancestorTile !== undefined) {
1294
- const ancestorSurfaceTile = ancestorTile.data;
1751
+ const ancestorSurfaceTile = /** @type {GlobeSurfaceTile} */ (
1752
+ ancestorTile.data
1753
+ );
1295
1754
  if (ancestorSurfaceTile !== undefined) {
1296
1755
  const ancestorMesh = ancestorSurfaceTile.mesh;
1297
1756
  const ancestorTerrainData = ancestorSurfaceTile.terrainData;
@@ -1393,256 +1852,58 @@ function updateTileBoundingRegion(tile, tileProvider, frameState) {
1393
1852
  }
1394
1853
  }
1395
1854
 
1396
- /**
1397
- * Returns true if this object was destroyed; otherwise, false.
1398
- * <br /><br />
1399
- * If this object was destroyed, it should not be used; calling any function other than
1400
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception.
1401
- *
1402
- * @returns {boolean} True if this object was destroyed; otherwise, false.
1403
- *
1404
- * @see GlobeSurfaceTileProvider#destroy
1405
- */
1406
- GlobeSurfaceTileProvider.prototype.isDestroyed = function () {
1407
- return false;
1408
- };
1409
-
1410
- /**
1411
- * Destroys the WebGL resources held by this object. Destroying an object allows for deterministic
1412
- * release of WebGL resources, instead of relying on the garbage collector to destroy this object.
1413
- * <br /><br />
1414
- * Once an object is destroyed, it should not be used; calling any function other than
1415
- * <code>isDestroyed</code> will result in a {@link DeveloperError} exception. Therefore,
1416
- * assign the return value (<code>undefined</code>) to the object as done in the example.
1417
- *
1418
- * @exception {DeveloperError} This object was destroyed, i.e., destroy() was called.
1419
- *
1420
- *
1421
- * @example
1422
- * provider = provider && provider();
1423
- *
1424
- * @see GlobeSurfaceTileProvider#isDestroyed
1425
- */
1426
- GlobeSurfaceTileProvider.prototype.destroy = function () {
1427
- this._tileProvider = this._tileProvider && this._tileProvider.destroy();
1428
- this._clippingPlanes = this._clippingPlanes && this._clippingPlanes.destroy();
1429
- this._clippingPolygons =
1430
- this._clippingPolygons && this._clippingPolygons.destroy();
1431
- this._removeLayerAddedListener =
1432
- this._removeLayerAddedListener && this._removeLayerAddedListener();
1433
- this._removeLayerRemovedListener =
1434
- this._removeLayerRemovedListener && this._removeLayerRemovedListener();
1435
- this._removeLayerMovedListener =
1436
- this._removeLayerMovedListener && this._removeLayerMovedListener();
1437
- this._removeLayerShownListener =
1438
- this._removeLayerShownListener && this._removeLayerShownListener();
1439
-
1440
- return destroyObject(this);
1441
- };
1442
-
1443
1855
  function getTileReadyCallback(tileImageriesToFree, layer, terrainProvider) {
1444
1856
  return function (tile) {
1445
1857
  let tileImagery;
1446
1858
  let imagery;
1447
1859
  let startIndex = -1;
1448
- const tileImageryCollection = tile.data.imagery;
1449
- const length = tileImageryCollection.length;
1450
- let i;
1451
- for (i = 0; i < length; ++i) {
1452
- tileImagery = tileImageryCollection[i];
1453
- imagery = tileImagery.readyImagery ?? tileImagery.loadingImagery;
1454
- if (imagery.imageryLayer === layer) {
1455
- startIndex = i;
1456
- break;
1457
- }
1458
- }
1459
-
1460
- if (startIndex !== -1) {
1461
- const endIndex = startIndex + tileImageriesToFree;
1462
- tileImagery = tileImageryCollection[endIndex];
1463
- imagery = defined(tileImagery)
1464
- ? (tileImagery.readyImagery ?? tileImagery.loadingImagery)
1465
- : undefined;
1466
- if (!defined(imagery) || imagery.imageryLayer !== layer) {
1467
- // Return false to keep the callback if we have to wait on the skeletons
1468
- // Return true to remove the callback if something went wrong
1469
- return !layer._createTileImagerySkeletons(
1470
- tile,
1471
- terrainProvider,
1472
- endIndex,
1473
- );
1474
- }
1475
-
1476
- for (i = startIndex; i < endIndex; ++i) {
1477
- tileImageryCollection[i].freeResources();
1478
- }
1479
-
1480
- tileImageryCollection.splice(startIndex, tileImageriesToFree);
1481
- }
1482
-
1483
- return true; // Everything is done, so remove the callback
1484
- };
1485
- }
1486
-
1487
- GlobeSurfaceTileProvider.prototype._onLayerAdded = function (layer, index) {
1488
- if (this.isDestroyed()) {
1489
- return;
1490
- }
1491
-
1492
- if (layer.show) {
1493
- const terrainProvider = this._terrainProvider;
1494
-
1495
- const that = this;
1496
- const tileImageryUpdatedEvent = this._imageryLayersUpdatedEvent;
1497
- const reloadFunction = function () {
1498
- // Clear the layer's cache
1499
- layer._imageryCache = {};
1500
-
1501
- that._quadtree.forEachLoadedTile(function (tile) {
1502
- // If this layer is still waiting to for the loaded callback, just return
1503
- if (defined(tile._loadedCallbacks[layer._layerIndex])) {
1504
- return;
1505
- }
1506
-
1507
- let i;
1508
-
1509
- // Figure out how many TileImageries we will need to remove and where to insert new ones
1510
- const tileImageryCollection = tile.data.imagery;
1511
- const length = tileImageryCollection.length;
1512
- let startIndex = -1;
1513
- let tileImageriesToFree = 0;
1514
- for (i = 0; i < length; ++i) {
1515
- const tileImagery = tileImageryCollection[i];
1516
- const imagery =
1517
- tileImagery.readyImagery ?? tileImagery.loadingImagery;
1518
- if (imagery.imageryLayer === layer) {
1519
- if (startIndex === -1) {
1520
- startIndex = i;
1521
- }
1522
-
1523
- ++tileImageriesToFree;
1524
- } else if (startIndex !== -1) {
1525
- // iterated past the section of TileImageries belonging to this layer, no need to continue.
1526
- break;
1527
- }
1528
- }
1529
-
1530
- if (startIndex === -1) {
1531
- return;
1532
- }
1533
-
1534
- // Insert immediately after existing TileImageries
1535
- const insertionPoint = startIndex + tileImageriesToFree;
1536
-
1537
- // Create new TileImageries for all loaded tiles
1538
- if (
1539
- layer._createTileImagerySkeletons(
1540
- tile,
1541
- terrainProvider,
1542
- insertionPoint,
1543
- )
1544
- ) {
1545
- // Add callback to remove old TileImageries when the new TileImageries are ready
1546
- tile._loadedCallbacks[layer._layerIndex] = getTileReadyCallback(
1547
- tileImageriesToFree,
1548
- layer,
1549
- terrainProvider,
1550
- );
1551
-
1552
- tile.state = QuadtreeTileLoadState.LOADING;
1553
- }
1554
- });
1555
- };
1556
-
1557
- if (layer.ready) {
1558
- const imageryProvider = layer.imageryProvider;
1559
- imageryProvider._reload = reloadFunction;
1560
- }
1561
-
1562
- // create TileImageries for this layer for all previously loaded tiles
1563
- this._quadtree.forEachLoadedTile(function (tile) {
1564
- if (layer._createTileImagerySkeletons(tile, terrainProvider)) {
1565
- tile.state = QuadtreeTileLoadState.LOADING;
1566
-
1567
- // Tiles that are not currently being rendered need to load the new layer before they're renderable.
1568
- // We don't mark the rendered tiles non-renderable, though, because that would make the globe disappear.
1569
- if (
1570
- tile.level !== 0 &&
1571
- (tile._lastSelectionResultFrame !==
1572
- that.quadtree._lastSelectionFrameNumber ||
1573
- tile._lastSelectionResult !== TileSelectionResult.RENDERED)
1574
- ) {
1575
- tile.renderable = false;
1576
- }
1577
- }
1578
- });
1579
-
1580
- this._layerOrderChanged = true;
1581
- tileImageryUpdatedEvent.raiseEvent();
1582
- }
1583
- };
1584
-
1585
- GlobeSurfaceTileProvider.prototype._onLayerRemoved = function (layer, index) {
1586
- // destroy TileImagerys for this layer for all previously loaded tiles
1587
- this._quadtree.forEachLoadedTile(function (tile) {
1588
- const tileImageryCollection = tile.data.imagery;
1589
-
1590
- let startIndex = -1;
1591
- let numDestroyed = 0;
1592
- for (let i = 0, len = tileImageryCollection.length; i < len; ++i) {
1593
- const tileImagery = tileImageryCollection[i];
1594
- let imagery = tileImagery.loadingImagery;
1595
- if (!defined(imagery)) {
1596
- imagery = tileImagery.readyImagery;
1597
- }
1860
+ const tileImageryCollection = tile.data.imagery;
1861
+ const length = tileImageryCollection.length;
1862
+ let i;
1863
+ for (i = 0; i < length; ++i) {
1864
+ tileImagery = tileImageryCollection[i];
1865
+ imagery = tileImagery.readyImagery ?? tileImagery.loadingImagery;
1598
1866
  if (imagery.imageryLayer === layer) {
1599
- if (startIndex === -1) {
1600
- startIndex = i;
1601
- }
1602
-
1603
- tileImagery.freeResources();
1604
- ++numDestroyed;
1605
- } else if (startIndex !== -1) {
1606
- // iterated past the section of TileImagerys belonging to this layer, no need to continue.
1867
+ startIndex = i;
1607
1868
  break;
1608
1869
  }
1609
1870
  }
1610
1871
 
1611
1872
  if (startIndex !== -1) {
1612
- tileImageryCollection.splice(startIndex, numDestroyed);
1613
- }
1614
- });
1615
-
1616
- if (defined(layer.imageryProvider)) {
1617
- layer.imageryProvider._reload = undefined;
1618
- }
1873
+ const endIndex = startIndex + tileImageriesToFree;
1874
+ tileImagery = tileImageryCollection[endIndex];
1875
+ imagery = defined(tileImagery)
1876
+ ? (tileImagery.readyImagery ?? tileImagery.loadingImagery)
1877
+ : undefined;
1878
+ if (!defined(imagery) || imagery.imageryLayer !== layer) {
1879
+ // Return false to keep the callback if we have to wait on the skeletons
1880
+ // Return true to remove the callback if something went wrong
1881
+ return !layer._createTileImagerySkeletons(
1882
+ tile,
1883
+ terrainProvider,
1884
+ endIndex,
1885
+ );
1886
+ }
1619
1887
 
1620
- this._imageryLayersUpdatedEvent.raiseEvent();
1621
- };
1888
+ for (i = startIndex; i < endIndex; ++i) {
1889
+ tileImageryCollection[i].freeResources();
1890
+ }
1622
1891
 
1623
- GlobeSurfaceTileProvider.prototype._onLayerMoved = function (
1624
- layer,
1625
- newIndex,
1626
- oldIndex,
1627
- ) {
1628
- this._layerOrderChanged = true;
1629
- this._imageryLayersUpdatedEvent.raiseEvent();
1630
- };
1892
+ tileImageryCollection.splice(startIndex, tileImageriesToFree);
1893
+ }
1631
1894
 
1632
- GlobeSurfaceTileProvider.prototype._onLayerShownOrHidden = function (
1633
- layer,
1634
- index,
1635
- show,
1636
- ) {
1637
- if (show) {
1638
- this._onLayerAdded(layer, index);
1639
- } else {
1640
- this._onLayerRemoved(layer, index);
1641
- }
1642
- };
1895
+ return true; // Everything is done, so remove the callback
1896
+ };
1897
+ }
1643
1898
 
1644
1899
  const scratchClippingPlanesMatrix = new Matrix4();
1645
1900
  const scratchInverseTransposeClippingPlanesMatrix = new Matrix4();
1901
+
1902
+ /**
1903
+ * @param {FrameState} frameState
1904
+ * @param {GlobeSurfaceTileProvider} globeSurfaceTileProvider
1905
+ * @ignore
1906
+ */
1646
1907
  function createTileUniformMap(frameState, globeSurfaceTileProvider) {
1647
1908
  const uniformMap = {
1648
1909
  u_initialColor: function () {
@@ -1853,6 +2114,7 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
1853
2114
  return frameState.context.defaultTexture;
1854
2115
  },
1855
2116
  u_clippingExtents: function () {
2117
+ // @ts-expect-error Missing types.
1856
2118
  const texture = globeSurfaceTileProvider._clippingPolygons.extentsTexture;
1857
2119
  if (defined(texture)) {
1858
2120
  return texture;
@@ -1889,6 +2151,52 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
1889
2151
  u_vertexShadowDarkness: function () {
1890
2152
  return this.properties.vertexShadowDarkness;
1891
2153
  },
2154
+ u_vectorSegmentTexture: function () {
2155
+ return (
2156
+ this.properties.vectorSegmentTexture ??
2157
+ frameState.context.defaultTexture
2158
+ );
2159
+ },
2160
+ u_vectorWidthTexture: function () {
2161
+ return (
2162
+ this.properties.vectorWidthTexture ?? frameState.context.defaultTexture
2163
+ );
2164
+ },
2165
+ u_vectorColorTexture: function () {
2166
+ return (
2167
+ this.properties.vectorColorTexture ?? frameState.context.defaultTexture
2168
+ );
2169
+ },
2170
+ u_vectorSegmentPrimitiveIndicesTexture: function () {
2171
+ return (
2172
+ this.properties.vectorSegmentPrimitiveIndicesTexture ??
2173
+ frameState.context.defaultTexture
2174
+ );
2175
+ },
2176
+ u_vectorGridCellIndicesTexture: function () {
2177
+ return (
2178
+ this.properties.vectorGridCellIndicesTexture ??
2179
+ frameState.context.defaultTexture
2180
+ );
2181
+ },
2182
+ u_vectorPolygonEdgeTexture: function () {
2183
+ return (
2184
+ this.properties.vectorPolygonEdgeTexture ??
2185
+ frameState.context.defaultTexture
2186
+ );
2187
+ },
2188
+ u_vectorPolygonEdgePrimitiveIndicesTexture: function () {
2189
+ return (
2190
+ this.properties.vectorPolygonEdgePrimitiveIndicesTexture ??
2191
+ frameState.context.defaultTexture
2192
+ );
2193
+ },
2194
+ u_vectorPolygonGridCellIndicesTexture: function () {
2195
+ return (
2196
+ this.properties.vectorPolygonGridCellIndicesTexture ??
2197
+ frameState.context.defaultTexture
2198
+ );
2199
+ },
1892
2200
 
1893
2201
  // make a separate object so that changes to the properties are seen on
1894
2202
  // derived commands that combine another uniform map with this one.
@@ -1961,6 +2269,15 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
1961
2269
  undergroundColorAlphaByDistance: new Cartesian4(),
1962
2270
  lambertDiffuseMultiplier: 0.0,
1963
2271
  vertexShadowDarkness: 0.0,
2272
+
2273
+ vectorSegmentTexture: undefined,
2274
+ vectorWidthTexture: undefined,
2275
+ vectorColorTexture: undefined,
2276
+ vectorSegmentPrimitiveIndicesTexture: undefined,
2277
+ vectorGridCellIndicesTexture: undefined,
2278
+ vectorPolygonEdgeTexture: undefined,
2279
+ vectorPolygonEdgePrimitiveIndicesTexture: undefined,
2280
+ vectorPolygonGridCellIndicesTexture: undefined,
1964
2281
  },
1965
2282
  };
1966
2283
 
@@ -1971,8 +2288,13 @@ function createTileUniformMap(frameState, globeSurfaceTileProvider) {
1971
2288
  return uniformMap;
1972
2289
  }
1973
2290
 
1974
- function createWireframeVertexArrayIfNecessary(context, provider, tile) {
1975
- const surfaceTile = tile.data;
2291
+ /**
2292
+ * @param {Context} context
2293
+ * @param {QuadtreeTile} tile
2294
+ * @ignore
2295
+ */
2296
+ function createWireframeVertexArrayIfNecessary(context, tile) {
2297
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
1976
2298
 
1977
2299
  let mesh;
1978
2300
  let vertexArray;
@@ -2046,8 +2368,22 @@ function createWireframeVertexArray(context, vertexArray, terrainMesh) {
2046
2368
  });
2047
2369
  }
2048
2370
 
2371
+ /**
2372
+ * @type {Function}
2373
+ * @ignore
2374
+ */
2049
2375
  let getDebugOrientedBoundingBox;
2376
+
2377
+ /**
2378
+ * @type {Function}
2379
+ * @ignore
2380
+ */
2050
2381
  let getDebugBoundingSphere;
2382
+
2383
+ /**
2384
+ * @type {VoidFunction}
2385
+ * @ignore
2386
+ */
2051
2387
  let debugDestroyPrimitive;
2052
2388
 
2053
2389
  (function () {
@@ -2060,9 +2396,15 @@ let debugDestroyPrimitive;
2060
2396
  geometry: new SphereOutlineGeometry({ radius: 1.0 }),
2061
2397
  });
2062
2398
  let modelMatrix = new Matrix4();
2399
+ /** @type {OrientedBoundingBox|BoundingSphere} */
2063
2400
  let previousVolume;
2401
+ /** @type {Primitive} */
2064
2402
  let primitive;
2065
2403
 
2404
+ /**
2405
+ * @param {unknown} instance
2406
+ * @returns {Primitive}
2407
+ */
2066
2408
  function createDebugPrimitive(instance) {
2067
2409
  return new Primitive({
2068
2410
  geometryInstances: instance,
@@ -2074,6 +2416,10 @@ let debugDestroyPrimitive;
2074
2416
  });
2075
2417
  }
2076
2418
 
2419
+ /**
2420
+ * @param {OrientedBoundingBox} obb
2421
+ * @param {Color} color
2422
+ */
2077
2423
  getDebugOrientedBoundingBox = function (obb, color) {
2078
2424
  if (obb === previousVolume) {
2079
2425
  return primitive;
@@ -2088,6 +2434,7 @@ let debugDestroyPrimitive;
2088
2434
  );
2089
2435
 
2090
2436
  instanceOBB.modelMatrix = modelMatrix;
2437
+ // @ts-expect-error Missing types.
2091
2438
  instanceOBB.attributes.color =
2092
2439
  ColorGeometryInstanceAttribute.fromColor(color);
2093
2440
 
@@ -2095,6 +2442,11 @@ let debugDestroyPrimitive;
2095
2442
  return primitive;
2096
2443
  };
2097
2444
 
2445
+ /**
2446
+ * @param {BoundingSphere} sphere
2447
+ * @param {Color} color
2448
+ * @returns {Primitive}
2449
+ */
2098
2450
  getDebugBoundingSphere = function (sphere, color) {
2099
2451
  if (sphere === previousVolume) {
2100
2452
  return primitive;
@@ -2110,6 +2462,7 @@ let debugDestroyPrimitive;
2110
2462
  );
2111
2463
 
2112
2464
  instanceSphere.modelMatrix = modelMatrix;
2465
+ // @ts-expect-error Missing types.
2113
2466
  instanceSphere.attributes.color =
2114
2467
  ColorGeometryInstanceAttribute.fromColor(color);
2115
2468
 
@@ -2127,6 +2480,11 @@ let debugDestroyPrimitive;
2127
2480
  })();
2128
2481
 
2129
2482
  const otherPassesInitialColor = new Cartesian4(0.0, 0.0, 0.0, 0.0);
2483
+
2484
+ /**
2485
+ * @type {GlobeSurfaceShaderSetOptions}
2486
+ * @ignore
2487
+ */
2130
2488
  const surfaceShaderSetOptionsScratch = {
2131
2489
  frameState: undefined,
2132
2490
  surfaceTile: undefined,
@@ -2136,6 +2494,9 @@ const surfaceShaderSetOptionsScratch = {
2136
2494
  applyHue: undefined,
2137
2495
  applySaturation: undefined,
2138
2496
  applyGamma: undefined,
2497
+ applyToneMatch: undefined,
2498
+ applyToneMatchEdge: undefined,
2499
+ applyToneMatchCross: undefined,
2139
2500
  applyAlpha: undefined,
2140
2501
  applyDayNightAlpha: undefined,
2141
2502
  applySplit: undefined,
@@ -2268,8 +2629,14 @@ function getNeighborImageryLevel(neighborTile, imageryLayer) {
2268
2629
  // filled; reused across units and tiles every frame.
2269
2630
  const edgeNeighborLevelsScratch = new Array(4);
2270
2631
 
2632
+ /**
2633
+ * @param {GlobeSurfaceTileProvider} tileProvider
2634
+ * @param {QuadtreeTile} tile
2635
+ * @param {FrameState} frameState
2636
+ * @ignore
2637
+ */
2271
2638
  function addDrawCommandsForTile(tileProvider, tile, frameState) {
2272
- const surfaceTile = tile.data;
2639
+ const surfaceTile = /** @type {GlobeSurfaceTile} */ (tile.data);
2273
2640
 
2274
2641
  if (!defined(surfaceTile.vertexArray)) {
2275
2642
  if (surfaceTile.fill === undefined) {
@@ -2295,6 +2662,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
2295
2662
  }
2296
2663
  }
2297
2664
 
2665
+ // @ts-expect-error Missing types.
2298
2666
  let maxTextures = ContextLimits.maximumTextureImageUnits;
2299
2667
 
2300
2668
  let waterMaskTexture = surfaceTile.waterMaskTexture;
@@ -2336,14 +2704,17 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
2336
2704
  const showOceanWaves = showReflectiveOcean && defined(oceanNormalMap);
2337
2705
  const terrainProvider = tileProvider.terrainProvider;
2338
2706
  const hasVertexNormals =
2707
+ // @ts-expect-error Missing types.
2339
2708
  defined(terrainProvider) && tileProvider.terrainProvider.hasVertexNormals;
2340
2709
  const enableFog =
2341
2710
  frameState.fog.enabled && frameState.fog.renderable && !cameraUnderground;
2342
2711
  const showGroundAtmosphere =
2343
2712
  tileProvider.showGroundAtmosphere && frameState.mode === SceneMode.SCENE3D;
2344
2713
  const castShadows =
2714
+ // @ts-expect-error https://github.com/CesiumGS/cesium/issues/13420
2345
2715
  ShadowMode.castShadows(tileProvider.shadows) && !translucent;
2346
2716
  const receiveShadows =
2717
+ // @ts-expect-error https://github.com/CesiumGS/cesium/issues/13420
2347
2718
  ShadowMode.receiveShadows(tileProvider.shadows) && !translucent;
2348
2719
 
2349
2720
  const hueShift = tileProvider.hueShift;
@@ -2377,6 +2748,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
2377
2748
  }
2378
2749
  if (
2379
2750
  defined(tileProvider.clippingPlanes) &&
2751
+ // @ts-expect-error Missing types.
2380
2752
  tileProvider.clippingPlanes.enabled
2381
2753
  ) {
2382
2754
  --maxTextures;
@@ -2442,10 +2814,11 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
2442
2814
  }
2443
2815
 
2444
2816
  if (
2445
- frameState.mode === SceneMode.SCENE2D &&
2817
+ (frameState.mode === SceneMode.SCENE2D ||
2818
+ frameState.mode === SceneMode.COLUMBUS_VIEW) &&
2446
2819
  encoding.quantization === TerrainQuantization.BITS12
2447
2820
  ) {
2448
- // In 2D, the texture coordinates of the tile are interpolated over the rectangle to get the position in the vertex shader.
2821
+ // In 2D and Columbus View, the texture coordinates of the tile are interpolated over the rectangle to get the position in the vertex shader.
2449
2822
  // When the texture coordinates are quantized, error is introduced. This can be seen through the 1px wide cracking
2450
2823
  // between the quantized tiles in 2D. To compensate for the error, move the expand the rectangle in each direction by
2451
2824
  // half the error amount.
@@ -2507,7 +2880,7 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
2507
2880
  surfaceShaderSetOptions.hasExaggeration = hasExaggeration;
2508
2881
 
2509
2882
  const tileImageryCollection = surfaceTile.imagery;
2510
- let imageryIndex = 0;
2883
+ let imageryIndex;
2511
2884
  const imageryLen = tileImageryCollection.length;
2512
2885
 
2513
2886
  const showSkirts =
@@ -2543,744 +2916,818 @@ function addDrawCommandsForTile(tileProvider, tile, frameState) {
2543
2916
  }
2544
2917
  }
2545
2918
 
2546
- do {
2547
- let numberOfDayTextures = 0;
2919
+ // Columbus repeat worlds: render a translated copy of this tile for every
2920
+ // visible world offset. Copy w is placed at u + w*worldWidth by shifting
2921
+ // the RTC center along the map-u axis; the projected tile rectangle is
2922
+ // RTC-relative, so it must NOT be shifted again (shifting both would move
2923
+ // the copy by 2*w*worldWidth). The vertex array and imagery textures are
2924
+ // shared with the primary tile, so copies cost no extra tile loads or
2925
+ // texture memory.
2926
+ let worldOffsets = DEFAULT_COLUMBUS_WORLD_OFFSETS;
2927
+ let baseRtcY = 0.0;
2928
+ if (isColumbusRepeatActive(frameState)) {
2929
+ const copyOffsets = computeColumbusTileWorldOffsets(
2930
+ tileProvider,
2931
+ tile,
2932
+ frameState,
2933
+ );
2934
+ if (defined(copyOffsets) && copyOffsets.length > 0) {
2935
+ worldOffsets = copyOffsets;
2936
+ baseRtcY = rtc.y;
2937
+ }
2938
+ }
2548
2939
 
2549
- let command;
2550
- let uniformMap;
2940
+ for (let worldIndex = 0; worldIndex < worldOffsets.length; ++worldIndex) {
2941
+ const worldOffset = worldOffsets[worldIndex];
2942
+ if (worldOffsets !== DEFAULT_COLUMBUS_WORLD_OFFSETS) {
2943
+ // rtc is the rtcScratch center in Columbus view; shift it along the
2944
+ // map-u axis so per-vertex RTC math stays numerically identical.
2945
+ rtc.y = baseRtcY + worldOffset;
2946
+ }
2947
+ imageryIndex = 0;
2551
2948
 
2552
- if (tileProvider._drawCommands.length <= tileProvider._usedDrawCommands) {
2553
- command = new DrawCommand();
2554
- command.owner = tile;
2555
- command.cull = false;
2556
- command.boundingVolume = new BoundingSphere();
2557
- command.orientedBoundingBox = undefined;
2949
+ do {
2950
+ let numberOfDayTextures = 0;
2558
2951
 
2559
- uniformMap = createTileUniformMap(frameState, tileProvider);
2952
+ let command;
2953
+ let uniformMap;
2560
2954
 
2561
- tileProvider._drawCommands.push(command);
2562
- tileProvider._uniformMaps.push(uniformMap);
2563
- } else {
2564
- command = tileProvider._drawCommands[tileProvider._usedDrawCommands];
2565
- uniformMap = tileProvider._uniformMaps[tileProvider._usedDrawCommands];
2566
- }
2955
+ if (tileProvider._drawCommands.length <= tileProvider._usedDrawCommands) {
2956
+ command = new DrawCommand();
2957
+ command.owner = tile;
2958
+ command.cull = false;
2959
+ command.boundingVolume = new BoundingSphere();
2960
+ command.orientedBoundingBox = undefined;
2567
2961
 
2568
- command.owner = tile;
2962
+ uniformMap = createTileUniformMap(frameState, tileProvider);
2569
2963
 
2570
- ++tileProvider._usedDrawCommands;
2964
+ tileProvider._drawCommands.push(command);
2965
+ tileProvider._uniformMaps.push(uniformMap);
2966
+ } else {
2967
+ command = tileProvider._drawCommands[tileProvider._usedDrawCommands];
2968
+ uniformMap = tileProvider._uniformMaps[tileProvider._usedDrawCommands];
2969
+ }
2571
2970
 
2572
- if (tile === tileProvider._debug.boundingSphereTile) {
2573
- const obb = tileBoundingRegion.boundingVolume;
2574
- const boundingSphere = tileBoundingRegion.boundingSphere;
2575
- // If a debug primitive already exists for this tile, it will not be
2576
- // re-created, to avoid allocation every frame. If it were possible
2577
- // to have more than one selected tile, this would have to change.
2578
- if (defined(obb)) {
2579
- getDebugOrientedBoundingBox(obb, Color.RED).update(frameState);
2580
- } else if (defined(boundingSphere)) {
2581
- getDebugBoundingSphere(boundingSphere, Color.RED).update(frameState);
2971
+ command.owner = tile;
2972
+ ++tileProvider._usedDrawCommands;
2973
+
2974
+ if (tile === tileProvider._debug.boundingSphereTile) {
2975
+ // @ts-expect-error Missing types.
2976
+ const obb = tileBoundingRegion.boundingVolume;
2977
+ // @ts-expect-error Missing types.
2978
+ const boundingSphere = tileBoundingRegion.boundingSphere;
2979
+ // If a debug primitive already exists for this tile, it will not be
2980
+ // re-created, to avoid allocation every frame. If it were possible
2981
+ // to have more than one selected tile, this would have to change.
2982
+ if (defined(obb)) {
2983
+ getDebugOrientedBoundingBox(obb, Color.RED).update(frameState);
2984
+ } else if (defined(boundingSphere)) {
2985
+ getDebugBoundingSphere(boundingSphere, Color.RED).update(frameState);
2986
+ }
2987
+ }
2988
+
2989
+ const uniformMapProperties = uniformMap.properties;
2990
+ Cartesian4.clone(initialColor, uniformMapProperties.initialColor);
2991
+ uniformMapProperties.oceanNormalMap = oceanNormalMap;
2992
+ uniformMapProperties.lightingFadeDistance.x =
2993
+ tileProvider.lightingFadeOutDistance;
2994
+ uniformMapProperties.lightingFadeDistance.y =
2995
+ tileProvider.lightingFadeInDistance;
2996
+ uniformMapProperties.nightFadeDistance.x =
2997
+ tileProvider.nightFadeOutDistance;
2998
+ uniformMapProperties.nightFadeDistance.y =
2999
+ tileProvider.nightFadeInDistance;
3000
+ uniformMapProperties.atmosphereLightIntensity =
3001
+ tileProvider.atmosphereLightIntensity;
3002
+ uniformMapProperties.atmosphereRayleighCoefficient =
3003
+ tileProvider.atmosphereRayleighCoefficient;
3004
+ uniformMapProperties.atmosphereMieCoefficient =
3005
+ tileProvider.atmosphereMieCoefficient;
3006
+ uniformMapProperties.atmosphereRayleighScaleHeight =
3007
+ tileProvider.atmosphereRayleighScaleHeight;
3008
+ uniformMapProperties.atmosphereMieScaleHeight =
3009
+ tileProvider.atmosphereMieScaleHeight;
3010
+ uniformMapProperties.atmosphereMieAnisotropy =
3011
+ tileProvider.atmosphereMieAnisotropy;
3012
+ uniformMapProperties.zoomedOutOceanSpecularIntensity =
3013
+ tileProvider.zoomedOutOceanSpecularIntensity;
3014
+
3015
+ const frontFaceAlphaByDistanceFinal = cameraUnderground
3016
+ ? backFaceAlphaByDistance
3017
+ : frontFaceAlphaByDistance;
3018
+ const backFaceAlphaByDistanceFinal = cameraUnderground
3019
+ ? frontFaceAlphaByDistance
3020
+ : backFaceAlphaByDistance;
3021
+
3022
+ if (defined(frontFaceAlphaByDistanceFinal)) {
3023
+ Cartesian4.fromElements(
3024
+ frontFaceAlphaByDistanceFinal.near,
3025
+ frontFaceAlphaByDistanceFinal.nearValue,
3026
+ frontFaceAlphaByDistanceFinal.far,
3027
+ frontFaceAlphaByDistanceFinal.farValue,
3028
+ uniformMapProperties.frontFaceAlphaByDistance,
3029
+ );
3030
+ Cartesian4.fromElements(
3031
+ backFaceAlphaByDistanceFinal.near,
3032
+ backFaceAlphaByDistanceFinal.nearValue,
3033
+ backFaceAlphaByDistanceFinal.far,
3034
+ backFaceAlphaByDistanceFinal.farValue,
3035
+ uniformMapProperties.backFaceAlphaByDistance,
3036
+ );
2582
3037
  }
2583
- }
2584
3038
 
2585
- const uniformMapProperties = uniformMap.properties;
2586
- Cartesian4.clone(initialColor, uniformMapProperties.initialColor);
2587
- uniformMapProperties.oceanNormalMap = oceanNormalMap;
2588
- uniformMapProperties.lightingFadeDistance.x =
2589
- tileProvider.lightingFadeOutDistance;
2590
- uniformMapProperties.lightingFadeDistance.y =
2591
- tileProvider.lightingFadeInDistance;
2592
- uniformMapProperties.nightFadeDistance.x =
2593
- tileProvider.nightFadeOutDistance;
2594
- uniformMapProperties.nightFadeDistance.y = tileProvider.nightFadeInDistance;
2595
- uniformMapProperties.atmosphereLightIntensity =
2596
- tileProvider.atmosphereLightIntensity;
2597
- uniformMapProperties.atmosphereRayleighCoefficient =
2598
- tileProvider.atmosphereRayleighCoefficient;
2599
- uniformMapProperties.atmosphereMieCoefficient =
2600
- tileProvider.atmosphereMieCoefficient;
2601
- uniformMapProperties.atmosphereRayleighScaleHeight =
2602
- tileProvider.atmosphereRayleighScaleHeight;
2603
- uniformMapProperties.atmosphereMieScaleHeight =
2604
- tileProvider.atmosphereMieScaleHeight;
2605
- uniformMapProperties.atmosphereMieAnisotropy =
2606
- tileProvider.atmosphereMieAnisotropy;
2607
- uniformMapProperties.zoomedOutOceanSpecularIntensity =
2608
- tileProvider.zoomedOutOceanSpecularIntensity;
2609
-
2610
- const frontFaceAlphaByDistanceFinal = cameraUnderground
2611
- ? backFaceAlphaByDistance
2612
- : frontFaceAlphaByDistance;
2613
- const backFaceAlphaByDistanceFinal = cameraUnderground
2614
- ? frontFaceAlphaByDistance
2615
- : backFaceAlphaByDistance;
2616
-
2617
- if (defined(frontFaceAlphaByDistanceFinal)) {
2618
- Cartesian4.fromElements(
2619
- frontFaceAlphaByDistanceFinal.near,
2620
- frontFaceAlphaByDistanceFinal.nearValue,
2621
- frontFaceAlphaByDistanceFinal.far,
2622
- frontFaceAlphaByDistanceFinal.farValue,
2623
- uniformMapProperties.frontFaceAlphaByDistance,
2624
- );
2625
3039
  Cartesian4.fromElements(
2626
- backFaceAlphaByDistanceFinal.near,
2627
- backFaceAlphaByDistanceFinal.nearValue,
2628
- backFaceAlphaByDistanceFinal.far,
2629
- backFaceAlphaByDistanceFinal.farValue,
2630
- uniformMapProperties.backFaceAlphaByDistance,
3040
+ undergroundColorAlphaByDistance.near,
3041
+ undergroundColorAlphaByDistance.nearValue,
3042
+ undergroundColorAlphaByDistance.far,
3043
+ undergroundColorAlphaByDistance.farValue,
3044
+ uniformMapProperties.undergroundColorAlphaByDistance,
2631
3045
  );
2632
- }
3046
+ Color.clone(undergroundColor, uniformMapProperties.undergroundColor);
3047
+
3048
+ uniformMapProperties.lambertDiffuseMultiplier = lambertDiffuseMultiplier;
3049
+ uniformMapProperties.vertexShadowDarkness = vertexShadowDarkness;
3050
+
3051
+ const highlightFillTile =
3052
+ !defined(surfaceTile.vertexArray) &&
3053
+ defined(tileProvider.fillHighlightColor) &&
3054
+ tileProvider.fillHighlightColor.alpha > 0.0;
3055
+ if (highlightFillTile) {
3056
+ Color.clone(
3057
+ tileProvider.fillHighlightColor,
3058
+ uniformMapProperties.fillHighlightColor,
3059
+ );
3060
+ }
2633
3061
 
2634
- Cartesian4.fromElements(
2635
- undergroundColorAlphaByDistance.near,
2636
- undergroundColorAlphaByDistance.nearValue,
2637
- undergroundColorAlphaByDistance.far,
2638
- undergroundColorAlphaByDistance.farValue,
2639
- uniformMapProperties.undergroundColorAlphaByDistance,
2640
- );
2641
- Color.clone(undergroundColor, uniformMapProperties.undergroundColor);
2642
-
2643
- uniformMapProperties.lambertDiffuseMultiplier = lambertDiffuseMultiplier;
2644
- uniformMapProperties.vertexShadowDarkness = vertexShadowDarkness;
2645
-
2646
- const highlightFillTile =
2647
- !defined(surfaceTile.vertexArray) &&
2648
- defined(tileProvider.fillHighlightColor) &&
2649
- tileProvider.fillHighlightColor.alpha > 0.0;
2650
- if (highlightFillTile) {
2651
- Color.clone(
2652
- tileProvider.fillHighlightColor,
2653
- uniformMapProperties.fillHighlightColor,
3062
+ uniformMapProperties.verticalExaggerationAndRelativeHeight.x =
3063
+ exaggeration;
3064
+ uniformMapProperties.verticalExaggerationAndRelativeHeight.y =
3065
+ exaggerationRelativeHeight;
3066
+
3067
+ uniformMapProperties.center3D = mesh.center;
3068
+ Cartesian3.clone(rtc, uniformMapProperties.rtc);
3069
+
3070
+ Cartesian4.clone(tileRectangle, uniformMapProperties.tileRectangle);
3071
+ uniformMapProperties.southAndNorthLatitude.x = southLatitude;
3072
+ uniformMapProperties.southAndNorthLatitude.y = northLatitude;
3073
+ uniformMapProperties.southMercatorYAndOneOverHeight.x = southMercatorY;
3074
+ uniformMapProperties.southMercatorYAndOneOverHeight.y =
3075
+ oneOverMercatorHeight;
3076
+
3077
+ // Convert tile limiter rectangle from cartographic to texture space using the tileRectangle.
3078
+ const localizedCartographicLimitRectangle =
3079
+ localizedCartographicLimitRectangleScratch;
3080
+ const cartographicLimitRectangle = clipRectangleAntimeridian(
3081
+ tile.rectangle,
3082
+ tileProvider.cartographicLimitRectangle,
2654
3083
  );
2655
- }
2656
-
2657
- uniformMapProperties.verticalExaggerationAndRelativeHeight.x = exaggeration;
2658
- uniformMapProperties.verticalExaggerationAndRelativeHeight.y =
2659
- exaggerationRelativeHeight;
2660
-
2661
- uniformMapProperties.center3D = mesh.center;
2662
- Cartesian3.clone(rtc, uniformMapProperties.rtc);
2663
-
2664
- Cartesian4.clone(tileRectangle, uniformMapProperties.tileRectangle);
2665
- uniformMapProperties.southAndNorthLatitude.x = southLatitude;
2666
- uniformMapProperties.southAndNorthLatitude.y = northLatitude;
2667
- uniformMapProperties.southMercatorYAndOneOverHeight.x = southMercatorY;
2668
- uniformMapProperties.southMercatorYAndOneOverHeight.y =
2669
- oneOverMercatorHeight;
2670
-
2671
- // Convert tile limiter rectangle from cartographic to texture space using the tileRectangle.
2672
- const localizedCartographicLimitRectangle =
2673
- localizedCartographicLimitRectangleScratch;
2674
- const cartographicLimitRectangle = clipRectangleAntimeridian(
2675
- tile.rectangle,
2676
- tileProvider.cartographicLimitRectangle,
2677
- );
2678
3084
 
2679
- const localizedTranslucencyRectangle =
2680
- localizedTranslucencyRectangleScratch;
2681
- const clippedTranslucencyRectangle = clipRectangleAntimeridian(
2682
- tile.rectangle,
2683
- translucencyRectangle,
2684
- );
3085
+ const localizedTranslucencyRectangle =
3086
+ localizedTranslucencyRectangleScratch;
3087
+ const clippedTranslucencyRectangle = clipRectangleAntimeridian(
3088
+ tile.rectangle,
3089
+ translucencyRectangle,
3090
+ );
2685
3091
 
2686
- Cartesian3.fromElements(
2687
- hueShift,
2688
- saturationShift,
2689
- brightnessShift,
2690
- uniformMapProperties.hsbShift,
2691
- );
3092
+ Cartesian3.fromElements(
3093
+ hueShift,
3094
+ saturationShift,
3095
+ brightnessShift,
3096
+ uniformMapProperties.hsbShift,
3097
+ );
2692
3098
 
2693
- const cartographicTileRectangle = tile.rectangle;
2694
- const inverseTileWidth = 1.0 / cartographicTileRectangle.width;
2695
- const inverseTileHeight = 1.0 / cartographicTileRectangle.height;
2696
- localizedCartographicLimitRectangle.x =
2697
- (cartographicLimitRectangle.west - cartographicTileRectangle.west) *
2698
- inverseTileWidth;
2699
- localizedCartographicLimitRectangle.y =
2700
- (cartographicLimitRectangle.south - cartographicTileRectangle.south) *
2701
- inverseTileHeight;
2702
- localizedCartographicLimitRectangle.z =
2703
- (cartographicLimitRectangle.east - cartographicTileRectangle.west) *
2704
- inverseTileWidth;
2705
- localizedCartographicLimitRectangle.w =
2706
- (cartographicLimitRectangle.north - cartographicTileRectangle.south) *
2707
- inverseTileHeight;
2708
-
2709
- Cartesian4.clone(
2710
- localizedCartographicLimitRectangle,
2711
- uniformMapProperties.localizedCartographicLimitRectangle,
2712
- );
3099
+ const cartographicTileRectangle = tile.rectangle;
3100
+ const inverseTileWidth = 1.0 / cartographicTileRectangle.width;
3101
+ const inverseTileHeight = 1.0 / cartographicTileRectangle.height;
3102
+ localizedCartographicLimitRectangle.x =
3103
+ (cartographicLimitRectangle.west - cartographicTileRectangle.west) *
3104
+ inverseTileWidth;
3105
+ localizedCartographicLimitRectangle.y =
3106
+ (cartographicLimitRectangle.south - cartographicTileRectangle.south) *
3107
+ inverseTileHeight;
3108
+ localizedCartographicLimitRectangle.z =
3109
+ (cartographicLimitRectangle.east - cartographicTileRectangle.west) *
3110
+ inverseTileWidth;
3111
+ localizedCartographicLimitRectangle.w =
3112
+ (cartographicLimitRectangle.north - cartographicTileRectangle.south) *
3113
+ inverseTileHeight;
3114
+
3115
+ Cartesian4.clone(
3116
+ localizedCartographicLimitRectangle,
3117
+ uniformMapProperties.localizedCartographicLimitRectangle,
3118
+ );
2713
3119
 
2714
- localizedTranslucencyRectangle.x =
2715
- (clippedTranslucencyRectangle.west - cartographicTileRectangle.west) *
2716
- inverseTileWidth;
2717
- localizedTranslucencyRectangle.y =
2718
- (clippedTranslucencyRectangle.south - cartographicTileRectangle.south) *
2719
- inverseTileHeight;
2720
- localizedTranslucencyRectangle.z =
2721
- (clippedTranslucencyRectangle.east - cartographicTileRectangle.west) *
2722
- inverseTileWidth;
2723
- localizedTranslucencyRectangle.w =
2724
- (clippedTranslucencyRectangle.north - cartographicTileRectangle.south) *
2725
- inverseTileHeight;
2726
-
2727
- Cartesian4.clone(
2728
- localizedTranslucencyRectangle,
2729
- uniformMapProperties.localizedTranslucencyRectangle,
2730
- );
3120
+ localizedTranslucencyRectangle.x =
3121
+ (clippedTranslucencyRectangle.west - cartographicTileRectangle.west) *
3122
+ inverseTileWidth;
3123
+ localizedTranslucencyRectangle.y =
3124
+ (clippedTranslucencyRectangle.south - cartographicTileRectangle.south) *
3125
+ inverseTileHeight;
3126
+ localizedTranslucencyRectangle.z =
3127
+ (clippedTranslucencyRectangle.east - cartographicTileRectangle.west) *
3128
+ inverseTileWidth;
3129
+ localizedTranslucencyRectangle.w =
3130
+ (clippedTranslucencyRectangle.north - cartographicTileRectangle.south) *
3131
+ inverseTileHeight;
3132
+
3133
+ Cartesian4.clone(
3134
+ localizedTranslucencyRectangle,
3135
+ uniformMapProperties.localizedTranslucencyRectangle,
3136
+ );
2731
3137
 
2732
- // For performance, render fog only when fog is enabled and the effect of
2733
- // fog would be non-negligible. This prevents the shader from running when
2734
- // the camera is in space, for example.
2735
- const applyFog =
2736
- enableFog &&
2737
- CesiumMath.fog(tile._distance, frameState.fog.density) >
2738
- CesiumMath.EPSILON3;
2739
- colorCorrect = colorCorrect && (applyFog || showGroundAtmosphere);
2740
-
2741
- let applyBrightness = false;
2742
- let applyContrast = false;
2743
- let applyHue = false;
2744
- let applySaturation = false;
2745
- let applyGamma = false;
2746
- let applyAlpha = false;
2747
- let applyDayNightAlpha = false;
2748
- let applyToneMatch = false;
2749
- let applyToneMatchEdge = false;
2750
- let applyToneMatchCross = false;
2751
- let crossUnits = 0;
2752
- let applySplit = false;
2753
- let applyCutout = false;
2754
- let applyColorToAlpha = false;
2755
-
2756
- while (numberOfDayTextures < maxTextures && imageryIndex < imageryLen) {
2757
- const tileImagery = tileImageryCollection[imageryIndex];
2758
- const imagery = tileImagery.readyImagery;
2759
- ++imageryIndex;
2760
-
2761
- if (!defined(imagery) || imagery.imageryLayer.alpha === 0.0) {
2762
- continue;
2763
- }
3138
+ // For performance, render fog only when fog is enabled and the effect of
3139
+ // fog would be non-negligible. This prevents the shader from running when
3140
+ // the camera is in space, for example.
3141
+ const applyFog =
3142
+ enableFog &&
3143
+ CesiumMath.fog(tile._distance, frameState.fog.density) >
3144
+ CesiumMath.EPSILON3;
3145
+ colorCorrect = colorCorrect && (applyFog || showGroundAtmosphere);
3146
+
3147
+ let applyBrightness = false;
3148
+ let applyContrast = false;
3149
+ let applyHue = false;
3150
+ let applySaturation = false;
3151
+ let applyGamma = false;
3152
+ let applyAlpha = false;
3153
+ let applyDayNightAlpha = false;
3154
+ let applyToneMatch = false;
3155
+ let applyToneMatchEdge = false;
3156
+ let applyToneMatchCross = false;
3157
+ let crossUnits = 0;
3158
+ let applySplit = false;
3159
+ let applyCutout = false;
3160
+ let applyColorToAlpha = false;
3161
+
3162
+ while (numberOfDayTextures < maxTextures && imageryIndex < imageryLen) {
3163
+ const tileImagery = tileImageryCollection[imageryIndex];
3164
+ const imagery = tileImagery.readyImagery;
3165
+ ++imageryIndex;
3166
+
3167
+ if (!defined(imagery) || imagery.imageryLayer.alpha === 0.0) {
3168
+ continue;
3169
+ }
2764
3170
 
2765
- const texture = tileImagery.useWebMercatorT
2766
- ? imagery.textureWebMercator
2767
- : imagery.texture;
2768
-
2769
- //>>includeStart('debug', pragmas.debug);
2770
- if (!defined(texture)) {
2771
- // Our "ready" texture isn't actually ready. This should never happen.
2772
- //
2773
- // Side note: It IS possible for it to not be in the READY ImageryState, though.
2774
- // This can happen when a single imagery tile is shared by two terrain tiles (common)
2775
- // and one of them (A) needs a geographic version of the tile because it is near the poles,
2776
- // and the other (B) does not. B can and will transition the imagery tile to the READY state
2777
- // without reprojecting to geographic. Then, later, A will deem that same tile not-ready-yet
2778
- // because it only has the Web Mercator texture, and flip it back to the TRANSITIONING state.
2779
- // The imagery tile won't be in the READY state anymore, but it's still READY enough for B's
2780
- // purposes.
2781
- throw new DeveloperError("readyImagery is not actually ready!");
2782
- }
2783
- //>>includeEnd('debug');
3171
+ const texture = tileImagery.useWebMercatorT
3172
+ ? imagery.textureWebMercator
3173
+ : imagery.texture;
3174
+
3175
+ //>>includeStart('debug', pragmas.debug);
3176
+ if (!defined(texture)) {
3177
+ // Our "ready" texture isn't actually ready. This should never happen.
3178
+ //
3179
+ // Side note: It IS possible for it to not be in the READY ImageryState, though.
3180
+ // This can happen when a single imagery tile is shared by two terrain tiles (common)
3181
+ // and one of them (A) needs a geographic version of the tile because it is near the poles,
3182
+ // and the other (B) does not. B can and will transition the imagery tile to the READY state
3183
+ // without reprojecting to geographic. Then, later, A will deem that same tile not-ready-yet
3184
+ // because it only has the Web Mercator texture, and flip it back to the TRANSITIONING state.
3185
+ // The imagery tile won't be in the READY state anymore, but it's still READY enough for B's
3186
+ // purposes.
3187
+ throw new DeveloperError("readyImagery is not actually ready!");
3188
+ }
3189
+ //>>includeEnd('debug');
2784
3190
 
2785
- const imageryLayer = imagery.imageryLayer;
3191
+ const imageryLayer = imagery.imageryLayer;
2786
3192
 
2787
- if (!defined(tileImagery.textureTranslationAndScale)) {
2788
- tileImagery.textureTranslationAndScale =
2789
- imageryLayer._calculateTextureTranslationAndScale(tile, tileImagery);
2790
- }
3193
+ if (!defined(tileImagery.textureTranslationAndScale)) {
3194
+ tileImagery.textureTranslationAndScale =
3195
+ imageryLayer._calculateTextureTranslationAndScale(
3196
+ tile,
3197
+ tileImagery,
3198
+ );
3199
+ }
2791
3200
 
2792
- uniformMapProperties.dayTextures[numberOfDayTextures] = texture;
2793
- uniformMapProperties.dayTextureTranslationAndScale[numberOfDayTextures] =
2794
- tileImagery.textureTranslationAndScale;
2795
- uniformMapProperties.dayTextureTexCoordsRectangle[numberOfDayTextures] =
2796
- tileImagery.textureCoordinateRectangle;
2797
- uniformMapProperties.dayTextureUseWebMercatorT[numberOfDayTextures] =
2798
- tileImagery.useWebMercatorT;
2799
-
2800
- uniformMapProperties.dayTextureAlpha[numberOfDayTextures] =
2801
- imageryLayer.alpha;
2802
- applyAlpha =
2803
- applyAlpha ||
2804
- uniformMapProperties.dayTextureAlpha[numberOfDayTextures] !== 1.0;
2805
-
2806
- uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] =
2807
- imageryLayer.nightAlpha;
2808
- applyDayNightAlpha =
2809
- applyDayNightAlpha ||
2810
- uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] !== 1.0;
2811
-
2812
- uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] =
2813
- imageryLayer.dayAlpha;
2814
- applyDayNightAlpha =
2815
- applyDayNightAlpha ||
2816
- uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] !== 1.0;
2817
-
2818
- uniformMapProperties.dayTextureBrightness[numberOfDayTextures] =
2819
- imageryLayer.brightness;
2820
- applyBrightness =
2821
- applyBrightness ||
2822
- uniformMapProperties.dayTextureBrightness[numberOfDayTextures] !==
2823
- ImageryLayer.DEFAULT_BRIGHTNESS;
2824
-
2825
- uniformMapProperties.dayTextureContrast[numberOfDayTextures] =
2826
- imageryLayer.contrast;
2827
- applyContrast =
2828
- applyContrast ||
2829
- uniformMapProperties.dayTextureContrast[numberOfDayTextures] !==
2830
- ImageryLayer.DEFAULT_CONTRAST;
2831
-
2832
- uniformMapProperties.dayTextureHue[numberOfDayTextures] =
2833
- imageryLayer.hue;
2834
- applyHue =
2835
- applyHue ||
2836
- uniformMapProperties.dayTextureHue[numberOfDayTextures] !==
2837
- ImageryLayer.DEFAULT_HUE;
2838
-
2839
- uniformMapProperties.dayTextureSaturation[numberOfDayTextures] =
2840
- imageryLayer.saturation;
2841
- applySaturation =
2842
- applySaturation ||
2843
- uniformMapProperties.dayTextureSaturation[numberOfDayTextures] !==
2844
- ImageryLayer.DEFAULT_SATURATION;
2845
-
2846
- uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] =
2847
- 1.0 / imageryLayer.gamma;
2848
- applyGamma =
2849
- applyGamma ||
2850
- uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] !==
2851
- 1.0 / ImageryLayer.DEFAULT_GAMMA;
2852
-
2853
- const levelCorrection = imageryLayer._getLevelColorCorrection(
2854
- imagery.level,
2855
- );
2856
- applyToneMatch = applyToneMatch || defined(levelCorrection);
3201
+ uniformMapProperties.dayTextures[numberOfDayTextures] = texture;
3202
+ uniformMapProperties.dayTextureTranslationAndScale[
3203
+ numberOfDayTextures
3204
+ ] = tileImagery.textureTranslationAndScale;
3205
+ uniformMapProperties.dayTextureTexCoordsRectangle[numberOfDayTextures] =
3206
+ tileImagery.textureCoordinateRectangle;
3207
+ uniformMapProperties.dayTextureUseWebMercatorT[numberOfDayTextures] =
3208
+ tileImagery.useWebMercatorT;
3209
+
3210
+ uniformMapProperties.dayTextureAlpha[numberOfDayTextures] =
3211
+ imageryLayer.alpha;
3212
+ applyAlpha =
3213
+ applyAlpha ||
3214
+ uniformMapProperties.dayTextureAlpha[numberOfDayTextures] !== 1.0;
3215
+
3216
+ uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] =
3217
+ imageryLayer.nightAlpha;
3218
+ applyDayNightAlpha =
3219
+ applyDayNightAlpha ||
3220
+ uniformMapProperties.dayTextureNightAlpha[numberOfDayTextures] !==
3221
+ 1.0;
3222
+
3223
+ uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] =
3224
+ imageryLayer.dayAlpha;
3225
+ applyDayNightAlpha =
3226
+ applyDayNightAlpha ||
3227
+ uniformMapProperties.dayTextureDayAlpha[numberOfDayTextures] !== 1.0;
3228
+
3229
+ uniformMapProperties.dayTextureBrightness[numberOfDayTextures] =
3230
+ imageryLayer.brightness;
3231
+ applyBrightness =
3232
+ applyBrightness ||
3233
+ uniformMapProperties.dayTextureBrightness[numberOfDayTextures] !==
3234
+ ImageryLayer.DEFAULT_BRIGHTNESS;
3235
+
3236
+ uniformMapProperties.dayTextureContrast[numberOfDayTextures] =
3237
+ imageryLayer.contrast;
3238
+ applyContrast =
3239
+ applyContrast ||
3240
+ uniformMapProperties.dayTextureContrast[numberOfDayTextures] !==
3241
+ ImageryLayer.DEFAULT_CONTRAST;
3242
+
3243
+ uniformMapProperties.dayTextureHue[numberOfDayTextures] =
3244
+ imageryLayer.hue;
3245
+ applyHue =
3246
+ applyHue ||
3247
+ uniformMapProperties.dayTextureHue[numberOfDayTextures] !==
3248
+ ImageryLayer.DEFAULT_HUE;
3249
+
3250
+ uniformMapProperties.dayTextureSaturation[numberOfDayTextures] =
3251
+ imageryLayer.saturation;
3252
+ applySaturation =
3253
+ applySaturation ||
3254
+ uniformMapProperties.dayTextureSaturation[numberOfDayTextures] !==
3255
+ ImageryLayer.DEFAULT_SATURATION;
3256
+
3257
+ uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] =
3258
+ 1.0 / imageryLayer.gamma;
3259
+ applyGamma =
3260
+ applyGamma ||
3261
+ uniformMapProperties.dayTextureOneOverGamma[numberOfDayTextures] !==
3262
+ 1.0 / ImageryLayer.DEFAULT_GAMMA;
3263
+
3264
+ const levelCorrection = imageryLayer._getLevelColorCorrection(
3265
+ imagery.level,
3266
+ );
3267
+ applyToneMatch = applyToneMatch || defined(levelCorrection);
3268
+
3269
+ let toneGain =
3270
+ uniformMapProperties.dayTextureToneGain[numberOfDayTextures];
3271
+ if (!defined(toneGain)) {
3272
+ toneGain = new Cartesian3(1.0, 1.0, 1.0);
3273
+ uniformMapProperties.dayTextureToneGain[numberOfDayTextures] =
3274
+ toneGain;
3275
+ }
3276
+ if (defined(levelCorrection)) {
3277
+ Cartesian3.clone(levelCorrection.gain, toneGain);
3278
+ } else {
3279
+ toneGain.x = 1.0;
3280
+ toneGain.y = 1.0;
3281
+ toneGain.z = 1.0;
3282
+ }
2857
3283
 
2858
- let toneGain =
2859
- uniformMapProperties.dayTextureToneGain[numberOfDayTextures];
2860
- if (!defined(toneGain)) {
2861
- toneGain = new Cartesian3(1.0, 1.0, 1.0);
2862
- uniformMapProperties.dayTextureToneGain[numberOfDayTextures] = toneGain;
2863
- }
2864
- if (defined(levelCorrection)) {
2865
- Cartesian3.clone(levelCorrection.gain, toneGain);
2866
- } else {
2867
- toneGain.x = 1.0;
2868
- toneGain.y = 1.0;
2869
- toneGain.z = 1.0;
2870
- }
3284
+ let toneBias =
3285
+ uniformMapProperties.dayTextureToneBias[numberOfDayTextures];
3286
+ if (!defined(toneBias)) {
3287
+ toneBias = new Cartesian3(0.0, 0.0, 0.0);
3288
+ uniformMapProperties.dayTextureToneBias[numberOfDayTextures] =
3289
+ toneBias;
3290
+ }
3291
+ if (defined(levelCorrection)) {
3292
+ Cartesian3.clone(levelCorrection.bias, toneBias);
3293
+ } else {
3294
+ toneBias.x = 0.0;
3295
+ toneBias.y = 0.0;
3296
+ toneBias.z = 0.0;
3297
+ }
2871
3298
 
2872
- let toneBias =
2873
- uniformMapProperties.dayTextureToneBias[numberOfDayTextures];
2874
- if (!defined(toneBias)) {
2875
- toneBias = new Cartesian3(0.0, 0.0, 0.0);
2876
- uniformMapProperties.dayTextureToneBias[numberOfDayTextures] = toneBias;
2877
- }
2878
- if (defined(levelCorrection)) {
2879
- Cartesian3.clone(levelCorrection.bias, toneBias);
2880
- } else {
2881
- toneBias.x = 0.0;
2882
- toneBias.y = 0.0;
2883
- toneBias.z = 0.0;
2884
- }
3299
+ // Edge-band fade of this texture's correction toward the adjacent
3300
+ // coarser tile's correction. Only the finer side of a LOD boundary
3301
+ // fades; same-level and finer neighbors leave the edge at this
3302
+ // texture's own correction, so the fade is a no-op there.
3303
+ const levelEdgeBlend = imageryLayer.levelColorEdgeBlend;
3304
+ if (defined(levelCorrection) && levelEdgeBlend > 0.0) {
3305
+ applyToneMatchEdge = true;
3306
+ }
3307
+ const edgeBaseIndex = numberOfDayTextures * 4;
3308
+ // Cross-fade bookkeeping: imagery level of each edge's neighbor, plus
3309
+ // the dominant (longest shared edge) coarser neighbor whose ancestor
3310
+ // texture will be bound for content cross-fading below.
3311
+ let dominantCrossLevel;
3312
+ let dominantCrossOverlap = 0.0;
3313
+ for (let edgeIndex = 0; edgeIndex < 4; ++edgeIndex) {
3314
+ let edgeGain =
3315
+ uniformMapProperties.dayTextureToneEdgeGain[
3316
+ edgeBaseIndex + edgeIndex
3317
+ ];
3318
+ if (!defined(edgeGain)) {
3319
+ edgeGain = new Cartesian3();
3320
+ uniformMapProperties.dayTextureToneEdgeGain[
3321
+ edgeBaseIndex + edgeIndex
3322
+ ] = edgeGain;
3323
+ }
3324
+ let edgeBias =
3325
+ uniformMapProperties.dayTextureToneEdgeBias[
3326
+ edgeBaseIndex + edgeIndex
3327
+ ];
3328
+ if (!defined(edgeBias)) {
3329
+ edgeBias = new Cartesian3();
3330
+ uniformMapProperties.dayTextureToneEdgeBias[
3331
+ edgeBaseIndex + edgeIndex
3332
+ ] = edgeBias;
3333
+ }
2885
3334
 
2886
- // Edge-band fade of this texture's correction toward the adjacent
2887
- // coarser tile's correction. Only the finer side of a LOD boundary
2888
- // fades; same-level and finer neighbors leave the edge at this
2889
- // texture's own correction, so the fade is a no-op there.
2890
- const levelEdgeBlend = imageryLayer.levelColorEdgeBlend;
2891
- if (defined(levelCorrection) && levelEdgeBlend > 0.0) {
2892
- applyToneMatchEdge = true;
2893
- }
2894
- const edgeBaseIndex = numberOfDayTextures * 4;
2895
- // Cross-fade bookkeeping: imagery level of each edge's neighbor, plus
2896
- // the dominant (longest shared edge) coarser neighbor whose ancestor
2897
- // texture will be bound for content cross-fading below.
2898
- let dominantCrossLevel;
2899
- let dominantCrossOverlap = 0.0;
2900
- for (let edgeIndex = 0; edgeIndex < 4; ++edgeIndex) {
2901
- let edgeGain =
2902
- uniformMapProperties.dayTextureToneEdgeGain[
2903
- edgeBaseIndex + edgeIndex
2904
- ];
2905
- if (!defined(edgeGain)) {
2906
- edgeGain = new Cartesian3();
2907
- uniformMapProperties.dayTextureToneEdgeGain[
3335
+ edgeNeighborLevelsScratch[edgeIndex] = undefined;
3336
+ uniformMapProperties.dayTextureToneEdgeBlend[
2908
3337
  edgeBaseIndex + edgeIndex
2909
- ] = edgeGain;
3338
+ ] = 0.0;
3339
+ if (defined(levelCorrection) && levelEdgeBlend > 0.0) {
3340
+ const neighbor = findAdjacentRenderedTile(
3341
+ getRenderedTilesFlat(tileProvider, frameState.frameNumber),
3342
+ tile.rectangle,
3343
+ edgeIndex,
3344
+ );
3345
+ const neighborLevel = defined(neighbor.tile)
3346
+ ? getNeighborImageryLevel(neighbor.tile, imageryLayer)
3347
+ : undefined;
3348
+ edgeNeighborLevelsScratch[edgeIndex] = neighborLevel;
3349
+ if (defined(neighborLevel) && neighborLevel < imagery.level) {
3350
+ if (neighbor.overlap > dominantCrossOverlap) {
3351
+ dominantCrossOverlap = neighbor.overlap;
3352
+ dominantCrossLevel = neighborLevel;
3353
+ }
3354
+ const neighborCorrection =
3355
+ imageryLayer._getLevelColorCorrection(neighborLevel);
3356
+ if (defined(neighborCorrection)) {
3357
+ Cartesian3.clone(neighborCorrection.gain, edgeGain);
3358
+ Cartesian3.clone(neighborCorrection.bias, edgeBias);
3359
+ uniformMapProperties.dayTextureToneEdgeBlend[
3360
+ edgeBaseIndex + edgeIndex
3361
+ ] = levelEdgeBlend;
3362
+ continue;
3363
+ }
3364
+ }
3365
+ }
3366
+ Cartesian3.clone(toneGain, edgeGain);
3367
+ Cartesian3.clone(toneBias, edgeBias);
2910
3368
  }
2911
- let edgeBias =
2912
- uniformMapProperties.dayTextureToneEdgeBias[
2913
- edgeBaseIndex + edgeIndex
3369
+
3370
+ // Content cross-fade: bind the ancestor imagery at the dominant coarser
3371
+ // neighbor's level (the very source texture the coarser side renders).
3372
+ // Near edges facing that neighbor, the shader blends the tile's full
3373
+ // rendered result with the ancestor's rendering, making both sides of
3374
+ // the boundary pixel-identical at the shared edge regardless of whether
3375
+ // the residual step came from correction limits or content differences.
3376
+ // Falls back to the correction fade above when the ancestor texture is
3377
+ // not resident, the level gap is too large (the ancestor would be
3378
+ // minified beyond recognition), the sampler budget is exhausted, or the
3379
+ // layer opts out. Edges whose coarser neighbor is at a different level
3380
+ // keep the correction fade (single bound ancestor per texture).
3381
+ // Every unit gets valid values (identity when unbound): a command's
3382
+ // shader is the CROSS variant if ANY unit bound, and the pooled uniform
3383
+ // arrays must not contain holes or stale entries for the others.
3384
+ let crossGain =
3385
+ uniformMapProperties.dayTextureCrossGain[numberOfDayTextures];
3386
+ if (!defined(crossGain)) {
3387
+ crossGain = new Cartesian3(1.0, 1.0, 1.0);
3388
+ uniformMapProperties.dayTextureCrossGain[numberOfDayTextures] =
3389
+ crossGain;
3390
+ }
3391
+ let crossBias =
3392
+ uniformMapProperties.dayTextureCrossBias[numberOfDayTextures];
3393
+ if (!defined(crossBias)) {
3394
+ crossBias = new Cartesian3(0.0, 0.0, 0.0);
3395
+ uniformMapProperties.dayTextureCrossBias[numberOfDayTextures] =
3396
+ crossBias;
3397
+ }
3398
+ let crossTranslationAndScale =
3399
+ uniformMapProperties.dayTextureCrossTranslationAndScale[
3400
+ numberOfDayTextures
2914
3401
  ];
2915
- if (!defined(edgeBias)) {
2916
- edgeBias = new Cartesian3();
2917
- uniformMapProperties.dayTextureToneEdgeBias[
2918
- edgeBaseIndex + edgeIndex
2919
- ] = edgeBias;
3402
+ if (!defined(crossTranslationAndScale)) {
3403
+ crossTranslationAndScale = new Cartesian4(0.0, 0.0, 1.0, 1.0);
3404
+ uniformMapProperties.dayTextureCrossTranslationAndScale[
3405
+ numberOfDayTextures
3406
+ ] = crossTranslationAndScale;
2920
3407
  }
2921
3408
 
2922
- edgeNeighborLevelsScratch[edgeIndex] = undefined;
2923
- uniformMapProperties.dayTextureToneEdgeBlend[
2924
- edgeBaseIndex + edgeIndex
2925
- ] = 0.0;
2926
- if (defined(levelCorrection) && levelEdgeBlend > 0.0) {
2927
- const neighbor = findAdjacentRenderedTile(
2928
- getRenderedTilesFlat(tileProvider, frameState.frameNumber),
2929
- tile.rectangle,
2930
- edgeIndex,
2931
- );
2932
- const neighborLevel = defined(neighbor.tile)
2933
- ? getNeighborImageryLevel(neighbor.tile, imageryLayer)
2934
- : undefined;
2935
- edgeNeighborLevelsScratch[edgeIndex] = neighborLevel;
2936
- if (defined(neighborLevel) && neighborLevel < imagery.level) {
2937
- if (neighbor.overlap > dominantCrossOverlap) {
2938
- dominantCrossOverlap = neighbor.overlap;
2939
- dominantCrossLevel = neighborLevel;
3409
+ let crossTexture = texture;
3410
+ if (
3411
+ defined(levelCorrection) &&
3412
+ levelEdgeBlend > 0.0 &&
3413
+ imageryLayer.levelColorEdgeCrossFade &&
3414
+ defined(dominantCrossLevel) &&
3415
+ imagery.level - dominantCrossLevel <= 4 &&
3416
+ numberOfDayTextures + crossUnits + 1 <= maxTextures
3417
+ ) {
3418
+ let ancestor = imagery.parent;
3419
+ while (defined(ancestor) && ancestor.level > dominantCrossLevel) {
3420
+ ancestor = ancestor.parent;
3421
+ }
3422
+ const ancestorTexture =
3423
+ defined(ancestor) &&
3424
+ ancestor.level === dominantCrossLevel &&
3425
+ ancestor.state === ImageryState.READY
3426
+ ? tileImagery.useWebMercatorT
3427
+ ? ancestor.textureWebMercator
3428
+ : ancestor.texture
3429
+ : undefined;
3430
+ if (defined(ancestorTexture)) {
3431
+ crossTexture = ancestorTexture;
3432
+ ++crossUnits;
3433
+ applyToneMatchCross = true;
3434
+
3435
+ const crossCorrection =
3436
+ imageryLayer._getLevelColorCorrection(dominantCrossLevel);
3437
+ if (defined(crossCorrection)) {
3438
+ Cartesian3.clone(crossCorrection.gain, crossGain);
3439
+ Cartesian3.clone(crossCorrection.bias, crossBias);
2940
3440
  }
2941
- const neighborCorrection =
2942
- imageryLayer._getLevelColorCorrection(neighborLevel);
2943
- if (defined(neighborCorrection)) {
2944
- Cartesian3.clone(neighborCorrection.gain, edgeGain);
2945
- Cartesian3.clone(neighborCorrection.bias, edgeBias);
2946
- uniformMapProperties.dayTextureToneEdgeBlend[
3441
+ imageryLayer._calculateImageryTranslationAndScale(
3442
+ tile,
3443
+ ancestor,
3444
+ tileImagery.useWebMercatorT,
3445
+ crossTranslationAndScale,
3446
+ );
3447
+
3448
+ for (let edgeIndex = 0; edgeIndex < 4; ++edgeIndex) {
3449
+ uniformMapProperties.dayTextureCrossBlend[
2947
3450
  edgeBaseIndex + edgeIndex
2948
- ] = levelEdgeBlend;
2949
- continue;
3451
+ ] =
3452
+ edgeNeighborLevelsScratch[edgeIndex] === dominantCrossLevel
3453
+ ? levelEdgeBlend
3454
+ : 0.0;
2950
3455
  }
2951
3456
  }
2952
3457
  }
2953
- Cartesian3.clone(toneGain, edgeGain);
2954
- Cartesian3.clone(toneBias, edgeBias);
2955
- }
2956
-
2957
- // Content cross-fade: bind the ancestor imagery at the dominant coarser
2958
- // neighbor's level (the very source texture the coarser side renders).
2959
- // Near edges facing that neighbor, the shader blends the tile's full
2960
- // rendered result with the ancestor's rendering, making both sides of
2961
- // the boundary pixel-identical at the shared edge regardless of whether
2962
- // the residual step came from correction limits or content differences.
2963
- // Falls back to the correction fade above when the ancestor texture is
2964
- // not resident, the level gap is too large (the ancestor would be
2965
- // minified beyond recognition), the sampler budget is exhausted, or the
2966
- // layer opts out. Edges whose coarser neighbor is at a different level
2967
- // keep the correction fade (single bound ancestor per texture).
2968
- // Every unit gets valid values (identity when unbound): a command's
2969
- // shader is the CROSS variant if ANY unit bound, and the pooled uniform
2970
- // arrays must not contain holes or stale entries for the others.
2971
- let crossGain =
2972
- uniformMapProperties.dayTextureCrossGain[numberOfDayTextures];
2973
- if (!defined(crossGain)) {
2974
- crossGain = new Cartesian3(1.0, 1.0, 1.0);
2975
- uniformMapProperties.dayTextureCrossGain[numberOfDayTextures] =
2976
- crossGain;
2977
- }
2978
- let crossBias =
2979
- uniformMapProperties.dayTextureCrossBias[numberOfDayTextures];
2980
- if (!defined(crossBias)) {
2981
- crossBias = new Cartesian3(0.0, 0.0, 0.0);
2982
- uniformMapProperties.dayTextureCrossBias[numberOfDayTextures] =
2983
- crossBias;
2984
- }
2985
- let crossTranslationAndScale =
2986
- uniformMapProperties.dayTextureCrossTranslationAndScale[
2987
- numberOfDayTextures
2988
- ];
2989
- if (!defined(crossTranslationAndScale)) {
2990
- crossTranslationAndScale = new Cartesian4(0.0, 0.0, 1.0, 1.0);
2991
- uniformMapProperties.dayTextureCrossTranslationAndScale[
2992
- numberOfDayTextures
2993
- ] = crossTranslationAndScale;
2994
- }
2995
-
2996
- let crossTexture = texture;
2997
- if (
2998
- defined(levelCorrection) &&
2999
- levelEdgeBlend > 0.0 &&
3000
- imageryLayer.levelColorEdgeCrossFade &&
3001
- defined(dominantCrossLevel) &&
3002
- imagery.level - dominantCrossLevel <= 4 &&
3003
- numberOfDayTextures + crossUnits + 1 <= maxTextures
3004
- ) {
3005
- let ancestor = imagery.parent;
3006
- while (defined(ancestor) && ancestor.level > dominantCrossLevel) {
3007
- ancestor = ancestor.parent;
3008
- }
3009
- const ancestorTexture =
3010
- defined(ancestor) &&
3011
- ancestor.level === dominantCrossLevel &&
3012
- ancestor.state === ImageryState.READY
3013
- ? tileImagery.useWebMercatorT
3014
- ? ancestor.textureWebMercator
3015
- : ancestor.texture
3016
- : undefined;
3017
- if (defined(ancestorTexture)) {
3018
- crossTexture = ancestorTexture;
3019
- ++crossUnits;
3020
- applyToneMatchCross = true;
3021
-
3022
- const crossCorrection =
3023
- imageryLayer._getLevelColorCorrection(dominantCrossLevel);
3024
- if (defined(crossCorrection)) {
3025
- Cartesian3.clone(crossCorrection.gain, crossGain);
3026
- Cartesian3.clone(crossCorrection.bias, crossBias);
3027
- }
3028
- imageryLayer._calculateImageryTranslationAndScale(
3029
- tile,
3030
- ancestor,
3031
- tileImagery.useWebMercatorT,
3032
- crossTranslationAndScale,
3033
- );
3034
-
3458
+ if (crossTexture === texture) {
3459
+ crossGain.x = 1.0;
3460
+ crossGain.y = 1.0;
3461
+ crossGain.z = 1.0;
3462
+ crossBias.x = 0.0;
3463
+ crossBias.y = 0.0;
3464
+ crossBias.z = 0.0;
3465
+ crossTranslationAndScale.x = 0.0;
3466
+ crossTranslationAndScale.y = 0.0;
3467
+ crossTranslationAndScale.z = 1.0;
3468
+ crossTranslationAndScale.w = 1.0;
3035
3469
  for (let edgeIndex = 0; edgeIndex < 4; ++edgeIndex) {
3036
3470
  uniformMapProperties.dayTextureCrossBlend[
3037
3471
  edgeBaseIndex + edgeIndex
3038
- ] =
3039
- edgeNeighborLevelsScratch[edgeIndex] === dominantCrossLevel
3040
- ? levelEdgeBlend
3041
- : 0.0;
3472
+ ] = 0.0;
3042
3473
  }
3043
3474
  }
3044
- }
3045
- if (crossTexture === texture) {
3046
- crossGain.x = 1.0;
3047
- crossGain.y = 1.0;
3048
- crossGain.z = 1.0;
3049
- crossBias.x = 0.0;
3050
- crossBias.y = 0.0;
3051
- crossBias.z = 0.0;
3052
- crossTranslationAndScale.x = 0.0;
3053
- crossTranslationAndScale.y = 0.0;
3054
- crossTranslationAndScale.z = 1.0;
3055
- crossTranslationAndScale.w = 1.0;
3056
- for (let edgeIndex = 0; edgeIndex < 4; ++edgeIndex) {
3057
- uniformMapProperties.dayTextureCrossBlend[edgeBaseIndex + edgeIndex] =
3058
- 0.0;
3475
+ uniformMapProperties.dayTextureCrossTexture[numberOfDayTextures] =
3476
+ crossTexture;
3477
+
3478
+ uniformMapProperties.dayTextureSplit[numberOfDayTextures] =
3479
+ imageryLayer.splitDirection;
3480
+ applySplit =
3481
+ applySplit ||
3482
+ uniformMapProperties.dayTextureSplit[numberOfDayTextures] !== 0.0;
3483
+
3484
+ // Update cutout rectangle
3485
+ let dayTextureCutoutRectangle =
3486
+ uniformMapProperties.dayTextureCutoutRectangles[numberOfDayTextures];
3487
+ if (!defined(dayTextureCutoutRectangle)) {
3488
+ dayTextureCutoutRectangle =
3489
+ uniformMapProperties.dayTextureCutoutRectangles[
3490
+ numberOfDayTextures
3491
+ ] = new Cartesian4();
3059
3492
  }
3060
- }
3061
- uniformMapProperties.dayTextureCrossTexture[numberOfDayTextures] =
3062
- crossTexture;
3063
-
3064
- uniformMapProperties.dayTextureSplit[numberOfDayTextures] =
3065
- imageryLayer.splitDirection;
3066
- applySplit =
3067
- applySplit ||
3068
- uniformMapProperties.dayTextureSplit[numberOfDayTextures] !== 0.0;
3069
-
3070
- // Update cutout rectangle
3071
- let dayTextureCutoutRectangle =
3072
- uniformMapProperties.dayTextureCutoutRectangles[numberOfDayTextures];
3073
- if (!defined(dayTextureCutoutRectangle)) {
3074
- dayTextureCutoutRectangle =
3075
- uniformMapProperties.dayTextureCutoutRectangles[numberOfDayTextures] =
3076
- new Cartesian4();
3493
+
3494
+ Cartesian4.clone(Cartesian4.ZERO, dayTextureCutoutRectangle);
3495
+ if (defined(imageryLayer.cutoutRectangle)) {
3496
+ const cutoutRectangle = clipRectangleAntimeridian(
3497
+ cartographicTileRectangle,
3498
+ imageryLayer.cutoutRectangle,
3499
+ );
3500
+ const intersection = Rectangle.simpleIntersection(
3501
+ cutoutRectangle,
3502
+ cartographicTileRectangle,
3503
+ rectangleIntersectionScratch,
3504
+ );
3505
+ applyCutout = defined(intersection) || applyCutout;
3506
+
3507
+ dayTextureCutoutRectangle.x =
3508
+ (cutoutRectangle.west - cartographicTileRectangle.west) *
3509
+ inverseTileWidth;
3510
+ dayTextureCutoutRectangle.y =
3511
+ (cutoutRectangle.south - cartographicTileRectangle.south) *
3512
+ inverseTileHeight;
3513
+ dayTextureCutoutRectangle.z =
3514
+ (cutoutRectangle.east - cartographicTileRectangle.west) *
3515
+ inverseTileWidth;
3516
+ dayTextureCutoutRectangle.w =
3517
+ (cutoutRectangle.north - cartographicTileRectangle.south) *
3518
+ inverseTileHeight;
3519
+ }
3520
+
3521
+ // Update color to alpha
3522
+ let colorToAlpha =
3523
+ uniformMapProperties.colorsToAlpha[numberOfDayTextures];
3524
+ if (!defined(colorToAlpha)) {
3525
+ colorToAlpha = uniformMapProperties.colorsToAlpha[
3526
+ numberOfDayTextures
3527
+ ] = new Cartesian4();
3528
+ }
3529
+
3530
+ const hasColorToAlpha =
3531
+ defined(imageryLayer.colorToAlpha) &&
3532
+ imageryLayer.colorToAlphaThreshold > 0.0;
3533
+ applyColorToAlpha = applyColorToAlpha || hasColorToAlpha;
3534
+
3535
+ if (hasColorToAlpha) {
3536
+ const color = imageryLayer.colorToAlpha;
3537
+ colorToAlpha.x = color.red;
3538
+ colorToAlpha.y = color.green;
3539
+ colorToAlpha.z = color.blue;
3540
+ colorToAlpha.w = imageryLayer.colorToAlphaThreshold;
3541
+ } else {
3542
+ colorToAlpha.w = -1.0;
3543
+ }
3544
+
3545
+ if (defined(imagery.credits)) {
3546
+ const credits = imagery.credits;
3547
+ for (
3548
+ let creditIndex = 0, creditLength = credits.length;
3549
+ creditIndex < creditLength;
3550
+ ++creditIndex
3551
+ ) {
3552
+ creditDisplay.addCreditToNextFrame(credits[creditIndex]);
3553
+ }
3554
+ }
3555
+
3556
+ ++numberOfDayTextures;
3077
3557
  }
3078
3558
 
3079
- Cartesian4.clone(Cartesian4.ZERO, dayTextureCutoutRectangle);
3080
- if (defined(imageryLayer.cutoutRectangle)) {
3081
- const cutoutRectangle = clipRectangleAntimeridian(
3082
- cartographicTileRectangle,
3083
- imageryLayer.cutoutRectangle,
3084
- );
3085
- const intersection = Rectangle.simpleIntersection(
3086
- cutoutRectangle,
3087
- cartographicTileRectangle,
3088
- rectangleIntersectionScratch,
3559
+ // trim texture array to the used length so we don't end up using old textures
3560
+ // which might get destroyed eventually
3561
+ uniformMapProperties.dayTextures.length = numberOfDayTextures;
3562
+ uniformMapProperties.dayTextureToneEdgeGain.length =
3563
+ numberOfDayTextures * 4;
3564
+ uniformMapProperties.dayTextureToneEdgeBias.length =
3565
+ numberOfDayTextures * 4;
3566
+ uniformMapProperties.dayTextureToneEdgeBlend.length =
3567
+ numberOfDayTextures * 4;
3568
+ uniformMapProperties.dayTextureCrossTexture.length = numberOfDayTextures;
3569
+ uniformMapProperties.dayTextureCrossTranslationAndScale.length =
3570
+ numberOfDayTextures;
3571
+ uniformMapProperties.dayTextureCrossGain.length = numberOfDayTextures;
3572
+ uniformMapProperties.dayTextureCrossBias.length = numberOfDayTextures;
3573
+ uniformMapProperties.dayTextureCrossBlend.length =
3574
+ numberOfDayTextures * 4;
3575
+ uniformMapProperties.waterMask = waterMaskTexture;
3576
+ Cartesian4.clone(
3577
+ waterMaskTranslationAndScale,
3578
+ uniformMapProperties.waterMaskTranslationAndScale,
3579
+ );
3580
+
3581
+ uniformMapProperties.minMaxHeight.x = encoding.minimumHeight;
3582
+ uniformMapProperties.minMaxHeight.y = encoding.maximumHeight;
3583
+ Matrix4.clone(encoding.matrix, uniformMapProperties.scaleAndBias);
3584
+
3585
+ // update clipping planes
3586
+ const clippingPlanes = tileProvider._clippingPlanes;
3587
+ const clippingPlanesEnabled =
3588
+ defined(clippingPlanes) && clippingPlanes.enabled && tile.isClipped;
3589
+ if (clippingPlanesEnabled) {
3590
+ uniformMapProperties.clippingPlanesEdgeColor = Color.clone(
3591
+ clippingPlanes.edgeColor,
3592
+ uniformMapProperties.clippingPlanesEdgeColor,
3089
3593
  );
3090
- applyCutout = defined(intersection) || applyCutout;
3091
-
3092
- dayTextureCutoutRectangle.x =
3093
- (cutoutRectangle.west - cartographicTileRectangle.west) *
3094
- inverseTileWidth;
3095
- dayTextureCutoutRectangle.y =
3096
- (cutoutRectangle.south - cartographicTileRectangle.south) *
3097
- inverseTileHeight;
3098
- dayTextureCutoutRectangle.z =
3099
- (cutoutRectangle.east - cartographicTileRectangle.west) *
3100
- inverseTileWidth;
3101
- dayTextureCutoutRectangle.w =
3102
- (cutoutRectangle.north - cartographicTileRectangle.south) *
3103
- inverseTileHeight;
3594
+ uniformMapProperties.clippingPlanesEdgeWidth = clippingPlanes.edgeWidth;
3104
3595
  }
3105
3596
 
3106
- // Update color to alpha
3107
- let colorToAlpha =
3108
- uniformMapProperties.colorsToAlpha[numberOfDayTextures];
3109
- if (!defined(colorToAlpha)) {
3110
- colorToAlpha = uniformMapProperties.colorsToAlpha[numberOfDayTextures] =
3111
- new Cartesian4();
3597
+ // update vector collections clamped to terrain
3598
+ const vectorData = surfaceTile.vectorData;
3599
+ if (defined(vectorData)) {
3600
+ uniformMapProperties.vectorSegmentTexture =
3601
+ vectorData.polylineSegmentTexture;
3602
+ uniformMapProperties.vectorWidthTexture = vectorData.widthTexture;
3603
+ uniformMapProperties.vectorColorTexture = vectorData.colorTexture;
3604
+ uniformMapProperties.vectorSegmentPrimitiveIndicesTexture =
3605
+ vectorData.polylineSegmentPrimitiveIndicesTexture;
3606
+ uniformMapProperties.vectorGridCellIndicesTexture =
3607
+ vectorData.polylineGridCellIndicesTexture;
3608
+ uniformMapProperties.vectorPolygonEdgeTexture =
3609
+ vectorData.polygonEdgeTexture;
3610
+ uniformMapProperties.vectorPolygonEdgePrimitiveIndicesTexture =
3611
+ vectorData.polygonEdgePrimitiveIndicesTexture;
3612
+ uniformMapProperties.vectorPolygonGridCellIndicesTexture =
3613
+ vectorData.polygonGridCellIndicesTexture;
3112
3614
  }
3113
3615
 
3114
- const hasColorToAlpha =
3115
- defined(imageryLayer.colorToAlpha) &&
3116
- imageryLayer.colorToAlphaThreshold > 0.0;
3117
- applyColorToAlpha = applyColorToAlpha || hasColorToAlpha;
3118
-
3119
- if (hasColorToAlpha) {
3120
- const color = imageryLayer.colorToAlpha;
3121
- colorToAlpha.x = color.red;
3122
- colorToAlpha.y = color.green;
3123
- colorToAlpha.z = color.blue;
3124
- colorToAlpha.w = imageryLayer.colorToAlphaThreshold;
3125
- } else {
3126
- colorToAlpha.w = -1.0;
3616
+ // update clipping polygons
3617
+ const clippingPolygons = tileProvider._clippingPolygons;
3618
+ const clippingPolygonsEnabled =
3619
+ defined(clippingPolygons) &&
3620
+ clippingPolygons.enabled &&
3621
+ clippingPolygons.length > 0 &&
3622
+ tile.isClipped;
3623
+
3624
+ surfaceShaderSetOptions.numberOfDayTextures = numberOfDayTextures;
3625
+ surfaceShaderSetOptions.applyBrightness = applyBrightness;
3626
+ surfaceShaderSetOptions.applyContrast = applyContrast;
3627
+ surfaceShaderSetOptions.applyHue = applyHue;
3628
+ surfaceShaderSetOptions.applySaturation = applySaturation;
3629
+ surfaceShaderSetOptions.applyGamma = applyGamma;
3630
+ surfaceShaderSetOptions.applyToneMatch = applyToneMatch;
3631
+ surfaceShaderSetOptions.applyToneMatchEdge = applyToneMatchEdge;
3632
+ surfaceShaderSetOptions.applyToneMatchCross = applyToneMatchCross;
3633
+ surfaceShaderSetOptions.applyAlpha = applyAlpha;
3634
+ surfaceShaderSetOptions.applyDayNightAlpha = applyDayNightAlpha;
3635
+ surfaceShaderSetOptions.applySplit = applySplit;
3636
+ surfaceShaderSetOptions.enableFog = applyFog;
3637
+ surfaceShaderSetOptions.enableClippingPlanes = clippingPlanesEnabled;
3638
+ surfaceShaderSetOptions.clippingPlanes = clippingPlanes;
3639
+ surfaceShaderSetOptions.enableClippingPolygons = clippingPolygonsEnabled;
3640
+ surfaceShaderSetOptions.clippingPolygons = clippingPolygons;
3641
+ surfaceShaderSetOptions.hasImageryLayerCutout = applyCutout;
3642
+ surfaceShaderSetOptions.colorCorrect = colorCorrect;
3643
+ surfaceShaderSetOptions.highlightFillTile = highlightFillTile;
3644
+ surfaceShaderSetOptions.colorToAlpha = applyColorToAlpha;
3645
+ surfaceShaderSetOptions.showUndergroundColor = showUndergroundColor;
3646
+ surfaceShaderSetOptions.translucent = translucent;
3647
+
3648
+ let count = surfaceTile.renderedMesh.indices.length;
3649
+ if (!showSkirts) {
3650
+ count = surfaceTile.renderedMesh.indexCountWithoutSkirts;
3127
3651
  }
3128
3652
 
3129
- if (defined(imagery.credits)) {
3130
- const credits = imagery.credits;
3131
- for (
3132
- let creditIndex = 0, creditLength = credits.length;
3133
- creditIndex < creditLength;
3134
- ++creditIndex
3135
- ) {
3136
- creditDisplay.addCreditToNextFrame(credits[creditIndex]);
3653
+ command.shaderProgram = tileProvider._surfaceShaderSet.getShaderProgram(
3654
+ surfaceShaderSetOptions,
3655
+ );
3656
+ command.castShadows = castShadows;
3657
+ command.receiveShadows = receiveShadows;
3658
+ command.renderState = renderState;
3659
+ command.primitiveType = PrimitiveType.TRIANGLES;
3660
+ command.vertexArray =
3661
+ surfaceTile.vertexArray || surfaceTile.fill.vertexArray;
3662
+ command.count = count;
3663
+ command.uniformMap = uniformMap;
3664
+ command.pass = Pass.GLOBE;
3665
+
3666
+ if (tileProvider._debug.wireframe) {
3667
+ createWireframeVertexArrayIfNecessary(context, tile);
3668
+ if (defined(surfaceTile.wireframeVertexArray)) {
3669
+ command.vertexArray = surfaceTile.wireframeVertexArray;
3670
+ command.primitiveType = PrimitiveType.LINES;
3671
+ command.count = count * 2;
3137
3672
  }
3138
3673
  }
3139
3674
 
3140
- ++numberOfDayTextures;
3141
- }
3142
-
3143
- // trim texture array to the used length so we don't end up using old textures
3144
- // which might get destroyed eventually
3145
- uniformMapProperties.dayTextures.length = numberOfDayTextures;
3146
- uniformMapProperties.dayTextureToneEdgeGain.length =
3147
- numberOfDayTextures * 4;
3148
- uniformMapProperties.dayTextureToneEdgeBias.length =
3149
- numberOfDayTextures * 4;
3150
- uniformMapProperties.dayTextureToneEdgeBlend.length =
3151
- numberOfDayTextures * 4;
3152
- uniformMapProperties.dayTextureCrossTexture.length = numberOfDayTextures;
3153
- uniformMapProperties.dayTextureCrossTranslationAndScale.length =
3154
- numberOfDayTextures;
3155
- uniformMapProperties.dayTextureCrossGain.length = numberOfDayTextures;
3156
- uniformMapProperties.dayTextureCrossBias.length = numberOfDayTextures;
3157
- uniformMapProperties.dayTextureCrossBlend.length = numberOfDayTextures * 4;
3158
- uniformMapProperties.waterMask = waterMaskTexture;
3159
- Cartesian4.clone(
3160
- waterMaskTranslationAndScale,
3161
- uniformMapProperties.waterMaskTranslationAndScale,
3162
- );
3163
-
3164
- uniformMapProperties.minMaxHeight.x = encoding.minimumHeight;
3165
- uniformMapProperties.minMaxHeight.y = encoding.maximumHeight;
3166
- Matrix4.clone(encoding.matrix, uniformMapProperties.scaleAndBias);
3167
-
3168
- // update clipping planes
3169
- const clippingPlanes = tileProvider._clippingPlanes;
3170
- const clippingPlanesEnabled =
3171
- defined(clippingPlanes) && clippingPlanes.enabled && tile.isClipped;
3172
- if (clippingPlanesEnabled) {
3173
- uniformMapProperties.clippingPlanesEdgeColor = Color.clone(
3174
- clippingPlanes.edgeColor,
3175
- uniformMapProperties.clippingPlanesEdgeColor,
3176
- );
3177
- uniformMapProperties.clippingPlanesEdgeWidth = clippingPlanes.edgeWidth;
3178
- }
3179
-
3180
- // update clipping polygons
3181
- const clippingPolygons = tileProvider._clippingPolygons;
3182
- const clippingPolygonsEnabled =
3183
- defined(clippingPolygons) && clippingPolygons.enabled && tile.isClipped;
3184
-
3185
- surfaceShaderSetOptions.numberOfDayTextures = numberOfDayTextures;
3186
- surfaceShaderSetOptions.applyBrightness = applyBrightness;
3187
- surfaceShaderSetOptions.applyContrast = applyContrast;
3188
- surfaceShaderSetOptions.applyHue = applyHue;
3189
- surfaceShaderSetOptions.applySaturation = applySaturation;
3190
- surfaceShaderSetOptions.applyGamma = applyGamma;
3191
- surfaceShaderSetOptions.applyToneMatch = applyToneMatch;
3192
- surfaceShaderSetOptions.applyToneMatchEdge = applyToneMatchEdge;
3193
- surfaceShaderSetOptions.applyToneMatchCross = applyToneMatchCross;
3194
- surfaceShaderSetOptions.applyAlpha = applyAlpha;
3195
- surfaceShaderSetOptions.applyDayNightAlpha = applyDayNightAlpha;
3196
- surfaceShaderSetOptions.applySplit = applySplit;
3197
- surfaceShaderSetOptions.enableFog = applyFog;
3198
- surfaceShaderSetOptions.enableClippingPlanes = clippingPlanesEnabled;
3199
- surfaceShaderSetOptions.clippingPlanes = clippingPlanes;
3200
- surfaceShaderSetOptions.enableClippingPolygons = clippingPolygonsEnabled;
3201
- surfaceShaderSetOptions.clippingPolygons = clippingPolygons;
3202
- surfaceShaderSetOptions.hasImageryLayerCutout = applyCutout;
3203
- surfaceShaderSetOptions.colorCorrect = colorCorrect;
3204
- surfaceShaderSetOptions.highlightFillTile = highlightFillTile;
3205
- surfaceShaderSetOptions.colorToAlpha = applyColorToAlpha;
3206
- surfaceShaderSetOptions.showUndergroundColor = showUndergroundColor;
3207
- surfaceShaderSetOptions.translucent = translucent;
3208
-
3209
- let count = surfaceTile.renderedMesh.indices.length;
3210
- if (!showSkirts) {
3211
- count = surfaceTile.renderedMesh.indexCountWithoutSkirts;
3212
- }
3213
-
3214
- command.shaderProgram = tileProvider._surfaceShaderSet.getShaderProgram(
3215
- surfaceShaderSetOptions,
3216
- );
3217
- command.castShadows = castShadows;
3218
- command.receiveShadows = receiveShadows;
3219
- command.renderState = renderState;
3220
- command.primitiveType = PrimitiveType.TRIANGLES;
3221
- command.vertexArray =
3222
- surfaceTile.vertexArray || surfaceTile.fill.vertexArray;
3223
- command.count = count;
3224
- command.uniformMap = uniformMap;
3225
- command.pass = Pass.GLOBE;
3226
-
3227
- if (tileProvider._debug.wireframe) {
3228
- createWireframeVertexArrayIfNecessary(context, tileProvider, tile);
3229
- if (defined(surfaceTile.wireframeVertexArray)) {
3230
- command.vertexArray = surfaceTile.wireframeVertexArray;
3231
- command.primitiveType = PrimitiveType.LINES;
3232
- command.count = count * 2;
3233
- }
3234
- }
3675
+ const boundingVolume = command.boundingVolume;
3676
+ const orientedBoundingBox = command.orientedBoundingBox;
3235
3677
 
3236
- const boundingVolume = command.boundingVolume;
3237
- const orientedBoundingBox = command.orientedBoundingBox;
3678
+ if (frameState.mode !== SceneMode.SCENE3D) {
3679
+ BoundingSphere.fromRectangleWithHeights2D(
3680
+ tile.rectangle,
3681
+ frameState.mapProjection,
3682
+ tileBoundingRegion.minimumHeight,
3683
+ tileBoundingRegion.maximumHeight,
3684
+ boundingVolume,
3685
+ );
3686
+ Cartesian3.fromElements(
3687
+ boundingVolume.center.z,
3688
+ boundingVolume.center.x,
3689
+ boundingVolume.center.y,
3690
+ boundingVolume.center,
3691
+ );
3238
3692
 
3239
- if (frameState.mode !== SceneMode.SCENE3D) {
3240
- BoundingSphere.fromRectangleWithHeights2D(
3241
- tile.rectangle,
3242
- frameState.mapProjection,
3243
- tileBoundingRegion.minimumHeight,
3244
- tileBoundingRegion.maximumHeight,
3245
- boundingVolume,
3246
- );
3247
- Cartesian3.fromElements(
3248
- boundingVolume.center.z,
3249
- boundingVolume.center.x,
3250
- boundingVolume.center.y,
3251
- boundingVolume.center,
3252
- );
3693
+ if (worldOffset !== 0.0) {
3694
+ // Shift this copy along the map-u world axis for frustum culling,
3695
+ // shadows, and depth-based picking.
3696
+ boundingVolume.center.y += worldOffset;
3697
+ }
3253
3698
 
3254
- if (frameState.mode === SceneMode.MORPHING) {
3255
- // The result is written into boundingVolume in place (the same object
3256
- // referenced by command.boundingVolume), so the return value is unused.
3257
- BoundingSphere.union(
3699
+ if (frameState.mode === SceneMode.MORPHING) {
3700
+ // The result is written into boundingVolume in place (the same object
3701
+ // referenced by command.boundingVolume), so the return value is unused.
3702
+ BoundingSphere.union(
3703
+ tileBoundingRegion.boundingSphere,
3704
+ boundingVolume,
3705
+ boundingVolume,
3706
+ );
3707
+ }
3708
+ } else {
3709
+ command.boundingVolume = BoundingSphere.clone(
3258
3710
  tileBoundingRegion.boundingSphere,
3259
3711
  boundingVolume,
3260
- boundingVolume,
3712
+ );
3713
+ command.orientedBoundingBox = OrientedBoundingBox.clone(
3714
+ tileBoundingRegion.boundingVolume,
3715
+ orientedBoundingBox,
3261
3716
  );
3262
3717
  }
3263
- } else {
3264
- command.boundingVolume = BoundingSphere.clone(
3265
- tileBoundingRegion.boundingSphere,
3266
- boundingVolume,
3267
- );
3268
- command.orientedBoundingBox = OrientedBoundingBox.clone(
3269
- tileBoundingRegion.boundingVolume,
3270
- orientedBoundingBox,
3271
- );
3272
- }
3273
3718
 
3274
- command.dirty = true;
3719
+ command.dirty = true;
3275
3720
 
3276
- if (translucent) {
3277
- globeTranslucencyState.updateDerivedCommands(command, frameState);
3278
- }
3721
+ if (translucent) {
3722
+ globeTranslucencyState.updateDerivedCommands(command, frameState);
3723
+ }
3279
3724
 
3280
- pushCommand(command, frameState);
3725
+ pushCommand(command, frameState);
3281
3726
 
3282
- renderState = otherPassesRenderState;
3283
- initialColor = otherPassesInitialColor;
3284
- } while (imageryIndex < imageryLen);
3727
+ renderState = otherPassesRenderState;
3728
+ initialColor = otherPassesInitialColor;
3729
+ } while (imageryIndex < imageryLen);
3730
+ } // for worldIndex (Columbus repeat-world copies)
3285
3731
  }
3732
+
3286
3733
  export default GlobeSurfaceTileProvider;